헤더 복원을 통한 패킷 스니핑 도구 구현
패킷 분석기 또는 패킷 스니핑 도구를 구현하기 위해서는
동작 속성을 이해해야 한다
→ 무작위 모드(Promiscuous) 는 소니핑과 관련해 아주 중요한 속성
무작위 모드 (Promiscuous Mode)
•
자기 LAN 카드의 MAC 주소와 프레임 헤더의 목적지 MAC 주소가 상이하더라도
•
LAN 카드가 해당 프레임을 수신하는 동작을 의미
→ 무작위 모드는 스니핑 도구를 구현할 때, 가장 먼저 숙지해야 할 내용
Flooding 동작을 보면
•
LAN 카드 ⇒ 일종의 필터 역할
•
또한 허브 장비를 이용한다고 무조건 송신자와 수신자의 데이터가 공격자에게 넘어가지 않는다
if 공격자가 LAN 카드를 무작위 모드로 변경한다면?
→ 무작위 모드가 주소가 상이하더라도 LAN 카드가 해당 프레임을 수신할 것이다
→ 스니핑이 가능..!
LAN 카드 → 무작위모드 변경 명령어
# 무작위모드로 변경
ifconfig eth0 promisc
# 무작위모드 중지
ifconfig eth0 -promisc
Shell
복사
UP BROADCAST RUNNING PROMISC MULTICAST
→ 무작위 모드로 동작한다는 의미
상위 계층 기반의 원시 소켓 방식에 따른 패킷 스니핑 도구
import os
import socket
from struct import *
# OS 모듈을 이용해 무작위 모드 실행
os.system("ifconfig eth0 promisc")
s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_TCP)
s.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
while True:
data = s.recv(65565)
#### IP Header ####
ip_header = data[0:20]
ip_header = unpack("!BBHHHBBH4s4s", ip_header)
# 수신한 데이터에서 20방이트 크기의 IP 헤더 복원
version_ip_header_length = ip_header[0]
version = version_ip_header_length >> 4
ip_header_length = version_ip_header_length & 0xF
ip_header_length = ip_header_length * 4
ttl = ip_header[5]
protocol = ip_header[6]
ip_source_address = socket.inet_ntoa(ip_header[8])
ip_destination_address = socket.inet_ntoa(ip_header[9])
print("IP Header")
print("Version: ", str(version))
print("IP Header Length: ", str(ip_header_length))
print("TTL: ", str(ttl))
print("Protocol: ", str(protocol))
print("Source IP Address: ", str(ip_source_address))
print("Destination IP Address: ", str(ip_destination_address))
print()
#### TCP Header ####
tcp_header = data[ip_header_length : ip_header_length + 20]
tcp_header = unpack("!HHLLBBHHH", tcp_header)
source_port = tcp_header[0]
destination_port = tcp_header[1]
sequence_number = tcp_header[2]
acknowledgment_number = tcp_header[3]
offset_reserved = tcp_header[4]
tcp_header_length = offset_reserved >> 4
window = tcp_header[5]
checksum = tcp_header[6]
urgent_pointer = tcp_header[7]
print("TCP Header")
print("Source Port Number: ", str(source_port))
print("Sequence Number: ", str(sequence_number))
print("Acknowledgment Number: ", str(acknowledgment_number))
print("TCP Header Length: ", str(tcp_header_length))
print("Window: ", str(window))
print("Checksum: ", str(checksum))
print("Urgent Pointer: ", str(urgent_pointer))
print()
#### TCP Payload ####
header_size = ip_header_length + (tcp_header_length * 4)
payload_data_size = len(data) - header_size
tcp_payload_data = data[header_size:]
# 수신한 데이터에서 20바이트 크기의 IP 헤더와, 20바이트 크기의 TCP 헤더를 제외한 나머지 부분이 TCP 페이로드에 해당
print("TCP Payload")
print("TCP Payload Data: ", str(tcp_payload_data))
print()
Python
복사