서론
2021년도 네트워크 보안 및 사용자 인증 실험 프로젝트에서 ARP Spoofing을 이용해 사용자의 트래픽을 가로채고, 자체 SSL 서버를 기반으로 Captive Portal을 제공하는 시스템을 직접 구축했다. 이 글에서는 해당 시스템이 동작하는 전체 흐름과 구현 과정에서 마주친 문제, 그리고 이를 해결한 방식에 대해 기록한다. 꽤나 오랜 시간이 흘렀지만, 최근 블록체인 업계로의 취업이 결정되어 남는 시간을 낭비하기 싫어 이렇게 이전에 했던 일들을 기록하며 시간을 보내려 한다.
초기 Captive Portal 시스템의 경우 유튜브 영상에 나온대로 구현만하면 충분했기 때문에 난이도는 높지 않았지만, https 사이트로의 리다이렉트를 구현하려고 하다보니 생각보다 난이도가 올라간 감이 있었다.
본론
1. ARP Spoofing 시작
우선 핵심은 ARP Spoofing을 통해 클라이언트의 게이트웨이 MAC 주소를 공격자 머신의 MAC 주소로 속이는 것에서 시작한다. 이를 통해 클라이언트 → 서버로 향하는 모든 트래픽을 우리 머신으로 우회시킬 수 있다.

ARP Spoofing의 자세한 설명은 아래 유튜브 내용이 가장 잘 설명하고 있다고 자신한다.
참고 자료:
About ARP(1)
About ARP(2)
About ARP(3)
2. 클라이언트의 Wi-Fi 연결과 HTTPS 접속 시도
사용자가 Wi-Fi에 연결한 뒤 브라우저에서 443 포트(HTTPS)를 이용해 임의의 사이트에 접속한다.
이때 원래는 정상 서버로 트래픽이 가야 하지만, ARP Spoofing으로 인해 모든 패킷이 공격자 머신으로 먼저 들어온다.

3. 캡처된 패킷과 Captive Portal
우회된 패킷은 시스템에서 검사된다.
HTTP(80 포트) 통신 → Captive Portal 페이지로 리다이렉트
HTTPS(443 포트) 통신 → RawSocket 기반 자체 SSL 서버로 강제 연결 후 Captive Portal 페이지로 리다이렉트
여기서 핵심은 HTTPS를 무조건 HTTP로 다운그레이드하지 않고, 자체 SSL 서버를 둬서 정상적인 SSL 핸드셰이크를 흉내낸다는 점이다. 이렇게 하지 않으면 브라우저가 해당 사이트를 신뢰할 수 없는 사이트라고 표시하므로 사용자 경험을 해칠 뿐만 아니라 서비스 자체 신뢰성을 하락시키는 요인이 되기 때문이다.

4. SSL Handshake와 통신 수립
클라이언트와 시스템의 SSL 서버가 Client Hello → Server Hello 과정을 수행한 뒤 TLS 세션이 성립된다. 즉, 사용자는 평소와 같이 HTTPS로 접속한다고 생각하지만 실제로는 우리가 발급한 SSL 서버와 통신 중이다.
이때 인증서(Certificate)는 Let’s Encrypt에서 발급받아 브라우저에서 신뢰할 수 있게 했다.

5. ARP Spoofing 유지와 해제
시스템은 클라이언트가 3001 포트로 특정 GET 요청을 보낼 때까지 ARP Spoofing 감염 상태를 유지한다. 이후 해당 요청이 감지되면, ARP Spoofing을 해제하고 원래의 네트워크 경로를 복구한다.

6. 시스템 구조도
최종적으로 시스템의 구조와 실행 단계는 아래와 같다.
1. Arp Spoofing 시작
2. 사용자가 wifi 연결 후 HTTPS 프로토콜을 통해 어떤 사이트든 접속
3. 패킷이 Arp Spoofing 공격으로 우리 시스템 코어로 들어옴
4. 캡쳐된 패킷은 캡티브 포탈 화면으로 이동시키는데, 443 통신일 경우 rawsocket을 사용하여 리다이렉트 패킷 송신 (반드시 Fin 플래그와 함께 송신해야함 Rst 플래그를 설정하여 송신하면 리다이렉트 되지 않고 그대로 연결이 끊어짐)
5. 클라이언트는 새로운 패킷을 시스템 코어의 ssl server로 송신함
6. 패킷은 시스템의 ssl server로 이동하여 암호화를 위한 client hello, server hello 과정 후 연결 수립
7. 클라이언트가 3001 포트로 GET 패킷을 송신하기 전까지 계속 arp spoofing이 감염된 상태로 유지
8. 클라이언트가 3001 포트로 GET 패킷 송신 후 ARP spoofing 감염을 해제 후 recover 시작

updater 컴포넌트
시스템의 최신 버전을 서비스 제공 업체(우리 팀)의 서버에서 확인하여 최신버전으로 업데이트하라는 안내를 지시하는 컴포넌트
UDP Server/Client
같은 로컬 네트워크에 해당 시스템이 2개 이상 동시에 동작할 경우 ARP Spoofing을 활용한 ARP 테이블의 감염에 문제가 발생할 수 있다. 계속해서 MAC - IP의 매핑 관계가 업데이트 될 것이므로 올바르게 시스템이 동작하지 않을 가능성이 높으므로 동일한 시스템이 동시에 동작하지 않도록 이미 동작 중인 시스템이 있는지 확인하는 용도로 사용된다. broadcast 모드로 설정하여 UDP 패킷을 로컬 네트워크에 전파시켜 응답을 받는 형식이다.
ARP Spoofer
ARP Spoofer는 주기적으로 ARP spoofing packet을 네트워크 내 모든 장치로 송신하여 ARP table이 감염되도록 한다.
net-filter, tcp block 컴포넌트
net-filter의 경우 443, 80 포트와 관련된 모든 데이터를 우선 NFQUEUE에 넣어 해당 패킷을 7번 제목에서 확인할 수 있는 Rule에 따라 처리하는데 tcp block을 사용하여 해당 패킷을 차단하거나 rawsocket 컴포넌트를 사용하여 시스템의 SSL server로 redirect 시키는 역할을 한다.
rawsocket 컴포넌트
ARP Spoofer를 통해 주기적으로 ARP table을 감염시켜도 여러가지 이유로 인해 ARP table이 recover 되는 현상이 발생한다. 그러므로 ARP table이 recover 되어 송신된 정상적인 데이터에 대해 rawsocket으로 다시 감염 packet을 송신하는 역할을 수행하도록 한다.
또한 net-filter로 잡은 시스템의 SSL server의 response 패킷(클라이언트가 443 포트를 사용하는 https 기반 패킷을 사용하여 어떤 사이트에 접속하려고 할 때, netfilter가 해당 패킷을 잡아 시스템의 SSL server로 송신하여 연결을 수립하도록 함) https 기반 통신을 시도하는 443 포트 packet에 대해 시스템의 SSL server로의 redirect 패킷을 송신하기 위해 사용된다.
SSL server
SSL 인증서를 사용하여 ARP table이 감염된 클라이언트와 https 통신을 하기 위한 hand shaking 및 request, response packet을 생성하기 위해 존재한다.
7. 중요한 고려사항
이 시스템은 단순히 모든 HTTPS 패킷을 차단하는 것이 아니다. 아래와 같은 규칙에 기반해 차단하거나 허용하여야 했고, 세밀한 Rule 기반 차단이 필수적이었다.
허용해야 하는 패킷:
우리 시스템 코어로 송수신되는 패킷
우리 서비스 서버로 송수신되는 패킷
클라이언트가 ARP Spoofing 해제를 위해 송신하는 패킷
차단해야 하는 패킷:
클라이언트가 외부 HTTPS로 직접 나가려는 패킷
클라이언트가 외부 HTTP로 직접 나가려는 패킷
결론
결론적으로 해당 프로젝트를 시작하게 된 계기였던 “해킹 공격을 사회에서 이롭게 사용할 수 있는 방법이 없을까?” 라는 고민을 해결한 제품을 만들어볼 수 있었으며, 특히 L7이 아닌 L2, L3, L4에 존재하는 패킷을 L7에서 동작하는 서비스를 사용하여 제어하는 솔루션을 개발해볼 수 있었다. 당시에 해당 아이디어를 가지고 특허 등록까지 목표로 하고 있었는데, 특허 출원까진 마쳤으나, 등록 단계에서 군 입대로 인해 신경을 쓰지 못했었다.
아쉽지만, 로우 레벨 네트워크를 다뤄볼 수 있는 좋은 계기가 되어 주었다. 한 가지 아쉬운 점이 있다면 단순 POC 수준에서 그친 프로젝트라 대규모 트래픽이 있을 때 쓰레드를 관리하는 파트까지 나아가지 못 한게 아쉽다. 이제 남는 시간동안 한번 OS를 개발해보려 한다. 재밌는 프로젝트가 되어줄 것이라 생각한다.
'best of the best > 생활일지' 카테고리의 다른 글
| OTP(One-Time-Password) 개발 (0) | 2022.03.05 |
|---|---|
| BOB 10기 합격 후기 (0) | 2021.07.14 |
댓글