NetCut이라는 프로그램이 있다. 동일 네트워크에 있는 디바이스의 인터넷 연결을 모조리 끊어버리는 소프트웨어인데, 상당히 위험하다. 공공장소에서 인터넷 느리다고 써버리면 잡혀갈 수 있다. (이론상 탐지가 가능하니) 이 포스트에서는 NetCut원리를 분석하려다가 프로그램 사용료 내라고 해서 비슷한 프로그램을 만들고, 이 원리에 대해 포스트해보는 시간을 가져본다.
타겟에게 잘못된 MAC 주소가 담긴 ARP Reply를 보내 타켓이 보내는 정보를 가로채는 기법이다. 정보를 가로챌 수 있다면 끊어낼 수도 있고, 따라서 상대방이 인터넷을 사용하지 못하도록 막을 수 있다.
위 이미지에서 허브나 스위치를 통해 LAN 게이트웨이와 사용자의 연결을 가로챌 수 있다. 이때 사용자의 통신을 LAN 게이트웨이로 이동시키지 않고 그대로 끊어버린다면, 사용자는 인터넷을 정상적으로 사용할 수 없다.
사용자가 인터넷을 사용하기 위해서는 IP주소와 디바이스의 MAC주소를 서로 일치시켜야 한다.
https://github.com/testprocess/automate-arp-spoofing
Python scapy 라이브러리를 활용해서 구현할 수 있다. 아래에 구현 코드를 첨부한다.
from scapy.all import Ether, ARP, srp, send
def spoof(self):
target_mac = self.get_mac()
arp_response = ARP(pdst=self.target, hwdst=target_mac, psrc=self.host, op='is-at')
send(arp_response, verbose=0)
QT5 라이브러리를 사용했다. Javascript 환경에서만 UI를 다뤄왔던 터라 익숙치 않았다. 그래도 상대적으로 쉬운 문법과 잘 적혀있는 공식문서 덕에 어렵지 않게 적용할 수 있었다.
Target IP에는 ARP 패킷을 날릴 대상 컴퓨터, Host IP에는 라우터의 IP를 기입한다. 이후 SendARP 버튼을 클릭하면 다음과 같이 표현되게 구현했다.
잘 날려진다.
사실 여기서 삽질했다. 처음 구현할때 Window UI와 ARP 처리를 하나의 스레드에서 처리하게끔 했다. 당연하게도 ARP가 전송중일때 UI의 버튼은 클릭되지 않았고 다른 제어를 할 수 없었다. UI class와 ARP class를 분리한 상태에서 실행해야지, 안그러면 PyQT에 I/O 블록이 생긴다. 이는 ARP 패킷을 보내는데에 있어 멀티 스레드를 적용해야 함을 의미한다.
PyQT에는 QThread 기능을 지원한다. 연산을 처리하는 동안 UI 단에서 블로킹이 발생하지 않도록 스레드를 적용하자.