2010년 2월 2일 화요일

ASCII 형태의 HEX 값을 패킷 파일(PCAP)로 변환해 보자

HEX 덤프파일에서 패킷파일로 변환해야 하는 경우가 발생한다.  HEX 값의 ASCII 내용을 PCAP 파일로 변환할 수 있는 방법은 없는 것일까?

와이어샤크에서 제공하는 유틸리티 중 text2pcap 이라는 것이 있다. 이름만 들어도 텍스트 파일에서 pcap 으로 변환한다는 의미임을 짐작할 수 있다. text2pcap 은 od -Ax -tx1 로 생성된 형태의 HEX 값을 이해할 수 있다. 여기서 od 명령어는 바이너리를 덤프하는 경우 많이 사용하는데, Octal (8진수) 로 덤프해서 보여주는 것이다. 앞서 사용한 -Ax 옵션은 오프셋 표현을 16진수로 하고 -tx1 은 -t 는 출력될 타입 형태를 지정하는데 아래 표와 같이 타입을 16진수로 하고 그 크기는 1로 한다는 의미이다.

 타입 의미
 a 문자의 이름(7비트 ASCII)
 c ASCII 문자 또는 escape 문자
 d 부호가 있는 10진수
 f 부동소수점 수
 o 8진수
 u 부호가 없는 10진수
 x 16진수

ls 명령어를 od 로 살펴보면 아래와 같은 형태로 출력이 된다.

[code]pcap:/tmp# od -Ax -tx1 ls | more
000000 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
000010 02 00 03 00 01 00 00 00 40 9a 04 08 34 00 00 00
000020 60 64 01 00 00 00 00 00 34 00 20 00 08 00 28 00
000030 1b 00 1a 00 06 00 00 00 34 00 00 00 34 80 04 08
000040 34 80 04 08 00 01 00 00 00 01 00 00 05 00 00 00
000050 04 00 00 00 03 00 00 00 34 01 00 00 34 81 04 08
000060 34 81 04 08 13 00 00 00 13 00 00 00 04 00 00 00
000070 01 00 00 00 01 00 00 00 00 00 00 00 00 80 04 08
000080 00 80 04 08 14 5a 01 00 14 5a 01 00 05 00 00 00
000090 00 10 00 00 01 00 00 00 00 60 01 00 00 e0 05 08
[/code]

자, 그럼 text2pcap 의 몇가지 옵션을 살펴보면 다음과 같다.

-l Link 레이어 타입 지정 (기본은 이더넷이다)
-e <l3pid> -e 옵션 뒤에 이더넷 헤더를 지정할 수 있다. -e 0x806 이면 ARP 패킷을 뜻한다.
-i <proto> 프로토콜을 지정
-m 최대 패킷 길이
-u <srcport>,<destport> UDP 출발지,목적지 포트를 지정
-T <srcport>,<destport> TCP 출발지,목적지 포트를 지정

일단 텍스트 파일인 in.txt 를 보면 아래와 같이 HEX 덤프 파일이 ASCII 형태로 저장되어 있다.

pcap:/tmp# more in.txt
000000 00 e0 1e a7 05 6f 00 10 ........
000008 5a a0 b9 12 08 00 46 00 ........
000010 03 68 00 00 00 00 0a 2e ........
000018 ee 33 0f 19 08 7f 0f 19 ........
000020 03 80 94 04 00 00 10 01 ........
000028 16 a2 0a 00 03 50 00 0c ........
000030 01 01 0f 19 03 80 11 01 ........

text2pcap 을 이용해 in.txt 를 out.pcap 으로 변환하는 것이다. 이때 출발지와 목적지 포트를 8888과 9999로 함께 변경한다.

[code bash]pcap:/tmp# text2pcap -T8888,9999 in.txt out.pcap
Input from: in.txt
Output to: out.pcap
Generate dummy Ethernet header: Protocol: 0x800
Generate dummy IP header: Protocol: 6
Generate dummy TCP header: Source port: 8888. Dest port: 9999
Wrote packet of 56 bytes at 0
Read 1 potential packet, wrote 1 packet
[/code]

tcpdump 로 out.pcap 을 확인해 보면 포트가 변경된 것을 알 수 있다.

pcap:/tmp# tcpdump -r out.pcap
reading from file out.pcap, link-type EN10MB (Ethernet)
09:18:18.000000 IP 1.1.1.1.8888 > 2.2.2.2.9999: . 0:56(56) win 8192

또 다른 예로, -e 를 통해 ARP 이더넷 더미 헤더를 생성한다..

[code bash]pcap:/tmp# text2pcap  -e 0x806 in.txt out.pcap
Input from: in.txt
Output to: out.pcap
Generate dummy Ethernet header: Protocol: 0x806
Wrote packet of 56 bytes at 0
Read 1 potential packet, wrote 1 packet
pcap:/tmp# tcpdump -r out.pcap
reading from file out.pcap, link-type EN10MB (Ethernet)
09:19:59.000000 truncated-arp
        0x0000:  00e0 1ea7 056f 0010 5aa0 b912 0800 4600  .....o..Z.....F.
        0x0010:  0368 0000 0000 0a2e ee33 0f19 087f 0f19  .h.......3......
        0x0020:  0380 9404 0000 1001 16a2 0a00 0350 000c  .............P..
        0x0030:  0101 0f19 0380 1101                      ........
[/code]

파일을 변환해 보았는데, 파일 뿐만 아니라 아래와 같은 형태로 od 로 출력된 정보를 리다이렉션 하여 바로 text2pcap 으로 출력 생성도 할 수 있다. stream 파일을 읽어 들여 stream.pcap 으로 저장하는 것이다.

# od -Ax -tx1 stream | text2pcap -m1460 -T1234,1234 - stream.pcap

그럼 이것을 조금 더 응용하여 다음과 같이 사용해 보자.

[code bash]pcap:/tmp# echo "Hello, PacketInside.com" | od -Ax -tx1 | text2pcap -T1234,1234 - stream.pcap
Input from: Standard input
Output to: stream.pcap
Generate dummy Ethernet header: Protocol: 0x800
Generate dummy IP header: Protocol: 6
Generate dummy TCP header: Source port: 1234. Dest port: 1234
Wrote packet of 24 bytes at 0
Read 1 potential packet, wrote 1 packet[/code]

출발지 목적지 포트를 1234 로 설정하고 저장된 파일을 HEX 로 보니 echo 로 입력된 값을 볼 수 있다.
pcap:/tmp# xxd stream.pcap
0000000: d4c3 b2a1 0200 0400 0000 0000 0000 0000  ................
0000010: 0090 0100 0100 0000 794e 564b 0000 0000  ........yNVK....
0000020: 4e00 0000 4e00 0000 0202 0202 0202 0101  N...N...........
0000030: 0101 0101 0800 4500 0040 1234 0000 ff06  ......E..@.4....
0000040: a37e 0101 0101 0202 0202 04d2 04d2 0000  .~..............
0000050: 0000 0000 0000 5000 2000 ed42 0000 4865  ......P. ..B..He
0000060: 6c6c 6f2c 2050 6163 6b65 7449 6e73 6964  llo, PacketInsid
0000070: 652e 636f 6d0a                           e.com.

와이어샤크에서 살펴보면 echo 값이 Payload 로 들어간 것을 알 수 있다.
0000  48 65 6c 6c 6f 2c 20 50 61 63 6b 65 74 49 6e 73   Hello, PacketIns
0010  69 64 65 2e 63 6f 6d 0a                           ide.com.
    Data: 48656C6C6F2C205061636B6574496E736964652E636F6D0A

stream.pcap 은 목적지가 2.2.2.2 로 되어 있었다. 그런데 이걸 다른 IP 로 바꾸고 싶다면. 바이너리 에디터를 통해 직접 해당 IP 를 변경할 수 있다. 2.2.2.2 HEX 값을 찾아 변경하기만 하면 된다.

변경 후 , tcpdump 로 읽어 보니 192.168.0.1 로 변경되었다. 그런데 IP 주소 부분만을 변경하여서 헤더 체크섬 값이 바뀌어 버렸다. 올바르게 라면 체크섬 값은 0xe6d8 로 되어야 한다.

[code bash]pcap:/tmp# tcpdump -r stream.pcap
reading from file stream.pcap, link-type EN10MB (Ethernet)
09:29:45.000000 IP 1.1.1.1.1234 > 192.168.0.1.1234: . 0:24(24) win 8192
[/code]

Header checksum: 0xa37e [incorrect, should be 0xe6d8]

그렇다면 또 체크섬 값도 변경하면 된다.
pcap:/tmp# bvi stream.pcap

지금까지 이 예는 HEX 값 데이터를 직접 수정하는 것을 보여주었지만, 사실은 불편한 방법이긴 하다. 필요에 따라 테스트 하는 과정에서 급하게 필요한 경우 이런 형태로도 사용할 수 있으며, 패킷 생성 도구 등을 이용하면 좀더 쉽게 만들어낼 수 있다.  여기서는 ASCII 형태의 HEX 값을 이용해 패킷 데이터로 만드는 과정을 설명하면서 몇 가지 다루어 본 것이다. 앞으로 몇 가지 패킷 생성 도구에 대해서 언급해 볼 것이다.


댓글 1개:

  1. B8 3B 7A 12 02 FF 39 D1 C8 D7 73 D8 6D E8 1D 68
    59 A9 3B 64 9D 6E 3C A2 F7 E1 38 2F C7 12 54 2C
    03 00 00 29 10 00 00 00 80 00 00 00

    위와 같이 HEX 값만 가지고 있을 경우에는 이 HEX 가 들어있는 파일을 이용해 아래와 같이 해볼 수도 있습니다. (패킷 문제 풀이 포스팅 참고)

    cat hex.txt | tr '\n' ' ' | sed 's/^/00000 /' | text2pcap -i 46 -u 53,23421 - result.pcap
    Input from: Standard input
    Output to: result.pcap
    Generate dummy Ethernet header: Protocol: 0x800
    Generate dummy IP header: Protocol: 17
    Generate dummy UDP header: Source port: 53. Dest port: 23421
    Wrote packet of 884 bytes at 0
    Read 1 potential packet, wrote 1 packet

    해당 HEX 값은 데이터만 있는 Payload 였고, -i 를 통해 이더넷 헤더를 생성해 주고 -u 를 통해 UDP 헤더를 생성해 준 것입니다.

    답글삭제