Network Hacking

4일차] Header analysis(Udp, Ip, Ethernet Header)

김현17 2018. 3. 15. 16:56

Sniffer

패킷 가로채기 또는 스니핑은 네트워크 통신 내용을 도청하는 행위이다. 이때 사용되는 도구를 패킷 분석기 또는 패킷 스니퍼라고 하며, 네트워크의 일부나 디지털 네트워크를 통하는 트래픽의 내용을 저장하거나 가로채는 기능을 하는 소프트웨어 또는 하드웨어이다. 파이선 코딩으로 간단한 스니퍼 프로그램을 만들고 Udp header를 분석해 보자.

 

 

[sniffer.py]

# law-socket을 통한 분석으로 socket.AF_PACKET, socket.SOCK_RAW 인자가 들어간다.

# bind에서 통신 목적이 아니기 때문에 eth0장치를 bind 한다.

# sock.recv를 통해 eth0장치의 오고가는 모든 내용을 저장한다.

 

 

# 짧은시간에 수많은 raw_packet이 오가기 때문에 log.txt파일을 생성하여 여기다 리다이렉트를 하며 실행한다.

 

# 이전시간에 만든 UdpEchoServer.py를 켜놓고 UdpEchoClient.py를 실행한다.

 

# UdpEchoServer.py 의 코딩내용. Server에서는 Client가 보낸 문자열을 그대로 받아서 되돌려주는 역할을 한다.

 

# sniffer.py를 중단하고 #>vi log.txt를 통해 vi 키고 문자열 검색으로 주고받은 데이터 'good'을 찾아서 UDP Packet의 정보를 가져오자. 이제 이 UPD Packet을 분석해 보자.

 

 

 

 

[UDP Packet은 다음의 그림처럼 구성되어 있다. UDP Packet에서도 udp header, ip header, ethernet header로 나뉜다 하나하나 살펴보자]

Client Send Packet : b'\x00\x0c)\x10\xf9\x11\x00\x0c)\x10\xf9\x9b\x08\x00E\x00\x00 \x00\x00@\x00@\x11\xb2\x8e\xc0\xa8\x03x\xc0\xa8\x03v\xa0nN \x00\x0c\xb24 good'          

 

Server Receive Packet : b'\x00\x0c)\x10\xf9\x9b\x00\x0c)\x10\xf9\x11\x08\x00E\x00\x00 \x00\x00@\x00@\x11\xb2\x8e\xc0\xa8\x03v\xc0\xa8\x03xN \xa0n\x00\x0c\xb24good\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

 

 

 

1. UDP 의 헤더정보(4계층)

# 그림 요약 --> 2바이트 sorce port   ,  2바이트 Des port  ,  2바이트 UPD length,   2바이트 ckecksum 총 8바이트이다.

# 문자열 good(Paylaod)의 왼쪽 8바이트가 UDP의 header로 고정되어 있다. (규칙)(그림참조)

 

Send하는 Client의 UDP Header에 대한 정보  →   \xa0nN \x00\x0c\xb24   

receive하는 Server의 UDP Header에 대한 정보   →   N \xa0n\x00\x0c\xb24   

바이너리 형태로 되어있기 때문에 struct 모듈을 이용해서  string 형태로 바꿀 수 있다.

 

# Send하는 Client의 Source Port는 임의로 설정된 포트번호 41070, Server는 고정된 port인 20000이 정확하게 나온것을 확인할 수 있다.

# UDP data의 길이(udp header의 길이 8 + data의 길이 4 = 12)와 checksum도 이상 없이 잘 나온다. UDP Header는 정말 간단하게 거의 포트번호만 주고 받는 형식이다.  비 연결성이고 신뢰성이 없으며, 순소화 되지 않은 서비스를 그대로 보여준다. 따라서 빠른 요청과 응답이 필요한 적은 데이터 송신에 유용하다.

 

※ struct 모듈에 관한 내용은 파이선 공식 홈페이지에 잘 정리되어 있다. https://docs.python.org/2/library/struct.html <<< 

struct에 요약적으로 설명하자면 struct — Interpret strings as packed binary data 즉, string을 packed binary data로 변경해준다.

따라서 struct.pack()을 이용하여 string을 binary data로 struct.unpack()을 이용하여 binary data를 string으로 변환할 수 있다.

 

2. ip 헤더정보(3계층)

# udp header 왼쪽 20바이트가 ip header인데 가변 크기이다. 이 역시 struct를 이용해서 string형태로 바꿔보자.
ip header :  E\x00\x00 \x00\x00@\x00@\x11\xb2\x8e\xc0\xa8\x03x\xc0\xa8\x03v

 

 

1). Version & IHL

Version & IHL값은 69인데 한 바이트를 반절 나눠서 쓰고 있다 69를 2진수로 표현하면 0100 0101이고 여기서 상위 0100(4)가 Version

하위 0101(5) IHL이 된다. IPv4, IHL( WORD단위로 헤더 길이 표시 4 X 5 = 20Byte ) 모두 정상 확인.

 

2). Tos
IP 헤더 내에 '서비스 유형' 및 '혼잡 알림'을 나타내는 8 비트 필드이다. 0은 Nomal을 뜻한다.

 

3). Total Length

전체 길이를 뜻한다. udp header(12byte) + ip header(20byte) = 32

 

4). identification  

각 조각이 동일한 데이터그램에 속하면 같은 일련번호를 공유한다.

 

5). IP Flags & Fragment Offset

2바이트 64를 이진수로 표현하면 0100 0000 0000 0000이다. 상위 3개(010)이 IP Flags 나머지가 Fragment Offset을 뜻한다.

※IP Flags 중요! 3비트의 각각에 대한 의미를 알고 있어야 한다.

Flag

첫 번째 bit : 미사용 ( 항상 0이다.)

두 번째 bit(Don't Fragment) : 0으로 셋팅되면 라우터에서 분열이 가능함을 뜻하고 1로 셋팅되면 목적지 컴퓨터가 조각들을 다시 모을 능력이 없기 때문에 중간에 라우터로 하여금 데이터그램을 분열하지 말라는 뜻이다. 

세 번째 bit(MF(More Fragment) : 현재의 조각이 마지막이라면 0, 더 많은 조각이 뒤에 계속 있으면 1을 뜻합니다.   

 

offset

Fragment Offset : 8 바이트 단위로 최초 분열 조각으로부터 어떤 곳에 붙여야하는 위치를 나타낸다.

 

최종 적으로 예를 들면, ethernet의 MPU(최대 보낼 수 있는 데이터)는 1514byte인데 10Mbyte를 보낸다고 여러번 보내야 할 것 이다. 이때 잘려진 데이터의 첫번째 패킷의 IP헤더 값은 MF 값은 1 OFFSET 값은 0이 된다. 중간 패킷들도 MF는 1로 OFFSET은 점점 쌓여가고 마지막 패킷은 MF가 0이되고 OFFSET은 마침표를 찍는다. 즉 받는 HOST는 이 MF와 Offset을 이용하여 조립을 하게되고 이 조각들이 하나의 데이터라는 것을 위에서 배운 id필드를 통해 파악하는 것입니다.   

 

6). TTL


TTL( time to live ) : 64(maximum hop)  Terminater 의 역할을 한다 좀비데이터를 없애준다. 세계가 위의 지도처럼 네트워크로 연결되어있는데 데이터가 목적지를 향하지 못하고 어떠한 오류로 떠돌아다닐 수도 있게된다 그러면 그 좀비데이터는 쌓이게되고 다른 정상 데이터의 길을 막는 현상이 일어 난다. 이를 막아주는 것이 TTL이다 최대 64만큼 이동되고 사라지는 것이다.

 

7). Protocol

protocol type은 17로 나오는데 이는 udp를 뜻한다. 각각의 타입의 번호가 표준으로 정해져 있으니 리눅스에서 /etc/protocols를 통해 확인할 수 있다. 자주 사용하는 tcp(6) 까지는 알아두자.  

 

8). Header Checksum

헤더에 대한 오류를 검출하는 역할을 한다.

 

9). Source Address = 192. 168. 3. 120

 

10). destination Address = 192. 168. 3. 118

 

 

 

3. Ethernet 헤더정보(2계층)

ethernet header : \x00\x0c)\x10\xf9\x11\x00\x0c)\x10\xf9\x9b\x08\x00 (14BYTE 고정크기를 갖는다.)
 

1). Preamble

Physical 계층에서 전송된 비트패턴으로 송신자와 수신자의 동기를 맞추는데 사용된다. 패킷 캡쳐 범위 밖이다.

 

2). Destination Address (6BYTE)

프레임을 수신할 MAC 주소정보가 담겨있다.

 

3). Source Address(6BYTE)

프레임을 송신한 호스트의 MAC주소가 담겨있다.

 

4). Type (2BYTE)

상위계층 프로토콜의 정보를 담고있다. (IP=0x0800 , arp=0x0806)

 

5). Frame Check Sequence(FCS)

프레임 오류를 확인한다. 캡쳐 범위 밖이다.


 

#확인.