관리 메뉴

개발자비행일지

Python 패킷스니퍼(Python packet sniffer) 본문

▶ 보안

Python 패킷스니퍼(Python packet sniffer)

Cyber0946 2020. 6. 11. 13:45

본 글에서는 scapy라는 툴을 통해 파이썬으로 패킷 스니퍼를 구현하는 내용을 정리해보고자 한다. 

먼저 scapy는 네트워크ㅏ 패킷을 보내거나 캡처, 또는 임의의 패킷을 생성할 수 있도록 도와주는 강력한 파이썬 툴이다. 이러한 기능은 네트워크를 점검하거나, 공격하는데 활용한다. 

먼저 Ubuntu 환경에서 Scapy를 설치하기 위해선 다음의 3가지 과정으로 설치한다. 

물론 pip install scapy도 가능하지만 필자는 import 과정에서 문제가 발생해서 git을 통한 clone 방식을 선택했다. 

1.~$git clone https://github.com/secdev/scapy

1번을 통해서 먼저 scapy를 복사해온뒤

2. cd scapy/를 통해서 scapy 디렉토리로 이동한다. 

3. sudo python setup.py install을 통해 설치한다. 

4. ./run_scapy로 동작을 확인한다.  아래와 같은 화면이 나오면 정상적으로 설치 된 것이다. 

이제 이 scapy를 활용해서 파이썬을 이용한 sniffer를 구현해 보자.

이 코드는 https://webstone.tistory.com/103?category=340217

위 글쓴이께서 작성하신 내용이다. 개인 학습을 위해 이 내용을 정리하는 과정으로 본 글을 작성한다. 

 

sniff()함수를 이용한 패킷 스니퍼 구현하기.

지난 시간때 scapy를 이용하여 간단한 스니퍼를 구현해보았다. 이번 시간에는 scapy에서 제공하는 sniff()함수를 이용하여 패킷 스니퍼를 구현해보자. 소스코드. ※ 부가 설명. sniff()가 캡처한 패킷��

webstone.tistory.com

먼저 

 

from scapy.all import *

#scapy를 사용하기 위해 import 해준다. 

def showpacket(packet):
#패킷을 인자로 받아서, 패킷의 정보를 출력해주는 함수이다. 
    print(packet.show())
#packet.show()는 scapy에서 제공하는 함수로 캡처한 패킷에 대한 정보를 표준출력해준다.

def main(filter):
    sniff(filter = filter, prn = showpacket, count =1)
#sniff()의 인자로는 count , store, prn, filter, iface가 존재한다. 
#여기서 count는 패킷을 캡처하는 횟수를 지정해주는데 0 이면 사용자가 중지할 때 까지 캡처한다. 
#store는 캡처한 패킷의 저장 여부를 결정하고, 네트워크 모니터랑만 원할 때는 0으로 지정한다. 
#prn은 캡처한 패킷을 처리하기 위한 함수를 지정한다. 

#패킷을 받아서, 필터로 거른 다음의 결과를 출력해준다. 

if __name__ == '__main__':
    filter = 'ip'
    main(filter)

실행결과는 다음과 같다. 여기서 sudo를 이용해서 root 권한으로 실행해야 동작된다. 

자 이제 스니핑을 할 수 있다는 것을 확인하였고 이를 이용해서 스니퍼를 만들어 보자. 

 

from scapy.all import *

protocols = {1: 'ICMP', 6: 'TCP'. 17:'UDP'}

def showpacket(packet):
    src_ip = packet[0][1].src
    dst_ip = packet[0][1].dst
    proto  =packet[0][1].proto

     if proto in protocols:
         print('protocol : %s: %s -> %s' %(protocols[proto], src_ip,dst_ip))
         if proto == 1:
             print('type:[%d], code:[%d]' %(packet[0][2].type, packet[0][2].code))

def main(filter):
    sniff(filter =filter, prn = showpacket, count = 0)
#count가 0이므로 모니터링 모드이다.

if __name__ == '__main__':
    main(filter)

여기서 packet는 sniff() 함수가 캡처한 패킷을 의미하며, prn인자로 지정된 showpacket을 통해서 관련 정보를 표준 입출력으로 내보내 준다. 

packet[0][0]은 MAC주소 계층

packet[0][1]은 IP 계층, packet[ip]로도 접근 가능하다.

packet[0][2]은 TCP, UDP, ICMP 계층이며, packet[TCP], packet[UDP], packet[ICMP]로도 접근 가능하다.

실행결과는 다음과 같다. 

'▶ 보안' 카테고리의 다른 글

Heap 구조, Chunk란?  (0) 2021.03.10
Independent Link Padding  (0) 2020.11.30
배너 그래빙(Banner Grabbing)  (0) 2020.11.30
리눅스 find 사용법  (0) 2020.07.13
네트워크 스캔  (0) 2020.06.24