일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- algorithm
- docker
- Util
- postman
- Kotlin
- Android
- TypeScript
- mysql
- HTML
- macos
- python
- React
- css
- AWS
- MongoDB
- sequelize
- Express
- OS
- ubuntu
- Scheduling
- OOAD
- S3
- DATABASE
- Crawling
- typeorm
- linux
- Network
- node.js
- mongoose
- wireshark
- Today
- Total
Seongwon Lim
[Python] Scapy 모듈을 이용한 패킷 스니핑 구현하기 본문
서론
이번 글에서는 파이썬 라이브러리를 이용해서 네트워크 상에서 발생하는 패킷들을 수집 또는 스니핑하는 기능을 간단하게 구현해보고자 한다.
- 개발 환경 : Ubuntu 22.04 LTS
Scapy
파이썬 Scapy는 네트워크 패킷을 전송,분석 및 스니핑 기능을 지원하는 라이브러리이다. 따라서 Scapy를 이용하면
다양한 프로토콜의 패킷을 위조하거나 해석할 수 있으며 또는 캡처하고, 요청 및 응답을 일치시키는 등의 작업을 수행할 수 있다.
- 스니핑(sniffing) : 직역하면 '냄새를 맡다' 라는 의미로, 네트워크 상에서의 의미는 자신이 아닌 다른 상대방(네트워크)들의 패킷 교환을 엿듣는 것을 일컫는다. 다시 말하면, 스니핑은 네트워크 상에서 발생하는 모든 패킷을 모니터링하고 캡처하는 것이라고 생각할 수 있다.
Scapy 설치하기
pip3 install scapy # 또는 pip install scapy
위 명령어를 입력해서 scapy 모듈을 다운 받는다.
혹시라도 설치 후 ModuleNotFoundError: No module named 'scapy' 에러를 마주하는 경우에는
아래 명렁어를 이용하여 설치를 진행한다.
sudo apt-get install python3-scapy
Scapy 코드 작성하기
먼저, 간단하게 네트워크 상에서 발생하는 패킷을 스니핑 해보자.
아래와 같이 파이썬 코드를 입력한다.
from scapy.all import *
def packetHandler(packet):
packet.show()
def sniffing(filter):
sniff(filter=filter, prn=packetHandler, count=1)
if __name__ == '__main__':
filter = 'ip'
sniffing(filter)
해당 코드는 Scapy에서 제공하는 sniff() 함수를 이용해서 네트워크 상에서 발생하는 IP 유형의 패킷을 캡처하는 코드이다.
sniff() 함수 인자의 의미는 다음과 같다.
- filter : 어떤 유형의 패킷을 스니핑 할 것인지 정의한다. 위 코드에서는 IP로 정의했으므로 TCP/IP, UDP/IP 등의 패킷을 캡처한다.
- prn : 패킷을 캡처한 뒤 실행할 함수를 정의한다. 위 코드와 같이 함수명을 정의할 수도 있으며, 람다 형식으로 직접 인자에 실행할 코드를 정의할 수도 있다. 정의한 함수의 인자로는 캡처한 패킷이 들어간다.
- count : 패킷 캡처 횟수를 정의한다. 1의 경우 패킷을 한 번만 캡처하고 종료하며, 0으로 정의한 경우 사용자가 프로그램을 종료할 때까지 패킷 캡처를 반복한다.
위와 같이 코드를 구성한 뒤 프로그램을 실행시키고 특정 웹 사이트에 접속해보자.
결과 확인하기
패킷을 캡처하고 packetHandler 함수를 실행한 뒤, 해당 패킷을 출력한 결과이다.
Mac Address, 5-Tuple(송수신 IP/PORT, 프로토콜) 정보 등을 비롯한 다양한 패킷 정보를 확인할 수 있다.
특정 필드만 추출하고 싶은 경우에는 packetHandler 코드를 다음과 같이 수정하여 추출할 수 있다.
def packetHandler(packet):
#data link layer
print("SRC Mac Address :", packet[0][0].src)
print("DST Mac Address :", packet[0][0].dst)
#network layer
print("SOURCE IP :", packet[0][1].src)
print("DESTINATION IP :", packet[0][1].dst)
print("PROTOCOL :", packet[0][1].proto)
#transport layer
print("SOURCE PORT :", packet[0][2].sport)
print("DESTINATION PORT :", packet[0][2].dport)
- packet[0][0] : 데이터링크 계층 정보를 담고 있으며 packet['Ethernet'] 으로 사용할 수도 있다.
- packet[0][1] : 네트워크 계층 정보를 담고 있으며 packet['IP'] 으로 사용할 수도 있다.
- packet[0][2] : 트랜스포트 계층 정보를 담고 있으며 packet['TCP'] or packet['UDP'] 으로 사용할 수도 있다.
sniff() 함수의 또 다른 인자 및 패킷을 전처리 하는 다양한 방법들은 공식 레퍼런스를 통해 찾아볼 수 있다.
'Python' 카테고리의 다른 글
[Python] nohup을 이용한 파이썬 모듈 백그라운드 실행 (0) | 2023.09.06 |
---|---|
[Python] 문자열 파싱 라이브러리 - Pygrok 설치 및 사용 방법 (0) | 2023.04.14 |
[Python] 약수 개수 구하기 (시간복잡도 고려하기) (0) | 2022.11.19 |
[Python] deque를 이용하여 리스트 회전하기 (0) | 2022.11.02 |
[Python] upper(), lower(), capitalize(), title() 함수 사용법 (0) | 2022.09.20 |