2010년 2월 25일 목요일

[Packet Contest #1] 문제 정답풀이 - 문자열의 패킷 HEX 값 변환하여 암호알아내기

아쉽게도 첫번째 콘테스트에 정답을 제출해 주신 분들은 없었다. 일단, 풀이과정을
설명해 보도록 하겠다. 문제였던 다음의 HEX 코드 값을 패킷 파일로 변경하면
문제의 반은 해결한 것이다. 일단, 다음 패킷내용을 challenge.txt 로 저장해 보자.

00 05 b5 02 02 02 01 01 01 01 01 01 08 00 45 00
00 79 12 34 00 00 ff 06 a3 45 01 01 01 01 c0 a8
03 02 04 d2 16 2e 00 00 00 00 00 00 00 00 50 00
20 00 65 53 00 00 55 47 46 6a 61 32 56 30 53 57
35 7a 61 57 52 6c 4c 6d 4e 76 62 53 41 78 63 33
51 67 55 47 46 6a 61 32 56 30 49 45 4e 6f 59 57
78 73 5a 57 35 6e 5a 53 42 54 62 32 78 32 5a 57
51 73 49 45 4e 76 62 6d 64 79 59 58 52 31 62 47
46 30 61 57 39 75 0a

일전에 text2pcap 을 통해 변환하는 방법에 대해서 설명하였지만, OD 의 특정 포맷에
맞춰서 해야 하다 보니 약간 귀챦은 부분이 있다. 하지만, 생각을 좀더 달리하면 한
라인으로 해당 HEX 값을 나열하는 방법도 있다. 이럴때 쉽게 사용해 볼 수 있는 방법이
tr 을 통해 \n 을 제거해 주고, sed 를 이용해 제일 처음에 00000 를 넣어 주어서 text2pcap
이 인지할 수 있는 포맷형태로 만든다.

$ cat challenge.txt | tr '\n' ' ' | sed 's/^/00000 /' | text2pcap - result.pcap
Input from: Standard input
Output to: result.pcap
Wrote packet of 175 bytes at 0
Read 1 potential packet, wrote 1 packet

위 명령을 통해 result.pcap 으로 쉽게 패킷 파일이 만들어졌다. 위 팁은 가끔 HEX 형태의
아스키 형태만 가지고 분석을 해야 하는 경우 유용하게 사용할 수 있을 것이다.

result.pcap 을 tcpdump 를 통해 읽어 보자.  출발지 IP 1.1.1.1 에서 목적지 IP
192.168.3.2 로 TCP/5678 번에 데이터를 전송하였다.

# tcpdump -XX -r result.pcap
reading from file result.pcap, link-type EN10MB (Ethernet)
10:22:41.000000 IP 1.1.1.1.1234 > 192.168.3.2.5678: . 0:81(81) win 8192
        0x0000:  0005 b502 0202 0101 0101 0101 0800 4500  ..............E.
        0x0010:  0079 1234 0000 ff06 a345 0101 0101 c0a8  .y.4.....E......
        0x0020:  0302 04d2 162e 0000 0000 0000 0000 5000  ..............P.
        0x0030:  2000 6553 0000 5547 466a 6132 5630 5357  ..eS..UGFja2V0SW
        0x0040:  357a 6157 526c 4c6d 4e76 6253 4178 6333  5zaWRlLmNvbSAxc3
        0x0050:  5167 5547 466a 6132 5630 4945 4e6f 5957  QgUGFja2V0IENoYW
        0x0060:  7873 5a57 356e 5a53 4254 6232 7832 5a57  xsZW5nZSBTb2x2ZW
        0x0070:  5173 4945 4e76 626d 6479 5958 5231 6247  QsIENvbmdyYXR1bG
        0x0080:  4630 6157 3975 0a                        F0aW9u.

tshark 를 통해서도 한번 형태를 자세히 들여다 보자

# tshark -V -r result.pcap
Frame 1 (135 bytes on wire, 135 bytes captured)
    Arrival Time: Feb  8, 2010 10:22:41.000000000
    [Time delta from previous captured frame: 0.000000000 seconds]
    [Time delta from previous displayed frame: 0.000000000 seconds]
    [Time since reference or first frame: 0.000000000 seconds]
    Frame Number: 1
    Frame Length: 135 bytes
    Capture Length: 135 bytes
    [Frame is marked: False]
    [Protocols in frame: eth:ip:tcp:data]
Ethernet II, Src: Private_01:01:01 (01:01:01:01:01:01), Dst: Broadcom_02:02:02 (00:05:b5:02:02:02)
    Destination: Broadcom_02:02:02 (00:05:b5:02:02:02)
        Address: Broadcom_02:02:02 (00:05:b5:02:02:02)
        .... ...0 .... .... .... .... = IG bit: Individual address (unicast)
        .... ..0. .... .... .... .... = LG bit: Globally unique address (factory default)
    Source: Private_01:01:01 (01:01:01:01:01:01)
        Address: Private_01:01:01 (01:01:01:01:01:01)
        .... ...1 .... .... .... .... = IG bit: Group address (multicast/broadcast)
        .... ..0. .... .... .... .... = LG bit: Globally unique address (factory default)
    Type: IP (0x0800)
Internet Protocol, Src: 1.1.1.1 (1.1.1.1), Dst: 192.168.3.2 (192.168.3.2)
    Version: 4
    Header length: 20 bytes
    Differentiated Services Field: 0x00 (DSCP 0x00: Default; ECN: 0x00)
        0000 00.. = Differentiated Services Codepoint: Default (0x00)
        .... ..0. = ECN-Capable Transport (ECT): 0
        .... ...0 = ECN-CE: 0
    Total Length: 121
    Identification: 0x1234 (4660)
    Flags: 0x00
        0... = Reserved bit: Not set
        .0.. = Don't fragment: Not set
        ..0. = More fragments: Not set
    Fragment offset: 0
    Time to live: 255
    Protocol: TCP (0x06)
    Header checksum: 0xa345 [incorrect, should be 0xe39e]
        [Good: False]
        [Bad : True]
    Source: 1.1.1.1 (1.1.1.1)
    Destination: 192.168.3.2 (192.168.3.2)
Transmission Control Protocol, Src Port: search-agent (1234), Dst Port: rrac (5678), Seq: 1, Len: 81
    Source port: search-agent (1234)
    Destination port: rrac (5678)
    Sequence number: 1    (relative sequence number)
    [Next sequence number: 82    (relative sequence number)]
    Header length: 20 bytes
    Flags: 0x00 ()
        0... .... = Congestion Window Reduced (CWR): Not set
        .0.. .... = ECN-Echo: Not set
        ..0. .... = Urgent: Not set
        ...0 .... = Acknowledgment: Not set
        .... 0... = Push: Not set
        .... .0.. = Reset: Not set
        .... ..0. = Syn: Not set
        .... ...0 = Fin: Not set
    Window size: 8192
    Checksum: 0x6553 [correct]
        [Good Checksum: True]
        [Bad Checksum: False]
Data (81 bytes)

0000  55 47 46 6a 61 32 56 30 53 57 35 7a 61 57 52 6c   UGFja2V0SW5zaWRl
0010  4c 6d 4e 76 62 53 41 78 63 33 51 67 55 47 46 6a   LmNvbSAxc3QgUGFj
0020  61 32 56 30 49 45 4e 6f 59 57 78 73 5a 57 35 6e   a2V0IENoYWxsZW5n
0030  5a 53 42 54 62 32 78 32 5a 57 51 73 49 45 4e 76   ZSBTb2x2ZWQsIENv
0040  62 6d 64 79 59 58 52 31 62 47 46 30 61 57 39 75   bmdyYXR1bGF0aW9u
0050  0a                                                .
    Data: 5547466A613256305357357A6157526C4C6D4E7662534178...

추가적인 정보를 더 볼 수 있는데, 들여다 보니 출발지와 목적지의 맥주소가 어딘가 이상하다.

Private_01:01:01 (01:01:01:01:01:01), Dst: Broadcom_02:02:02 (00:05:b5:02:02:02)

조작된 것임을 쉽게 추정해 볼 수 있다. 목적지의 맥주소는 제조회사가 Broadcom
으로 보이는데 출발지와 목적지를 맥을 봤을때, 목적지의 Broadcom 부분도 의도적으로
고쳐진 것으로 보인다. (실제 필자가 고치기도 하였지만 ㅋㅋ )
또 IP 헤더의 체크썸을 보면 값이 잘못 되어 있다.

Header checksum: 0xa345 [incorrect, should be 0xe39e]

원래는 0xe39e 의 값을 갖고 있어야 하지만 0xa345 로, 조작될 가능성이 높은 부분임을
알 수 있다. 자, 그리고 데이터를 보면 81 바이트로 암호같은 문자열이 연속으로 놓여있다.
많이 접해 보신분들은 쉽게 눈치를 챌 수 있겠지만, BASE64 로 인코딩된 데이터이다.
BASE64 는 이메일에서 인코딩 방법으로 많이 쓰인다.  자, 그럼 BASE64 데이터임을
추정하였으니 아래와 같이 해독해 보자.

$ perl -MMIME::Base64 -e 'print decode_base64("UGFja2V0SW5zaWRlLmNvbSAxc3QgUGFja2V0IENoYWxsZW5nZSBTb2x2ZWQsIENvbmdyYXR1bGF0aW9u")'
PacketInside.com 1st Packet Challenge Solved, Congratulation

펄의 MIME:Base64 모듈을 이용해 위 데이터를 디코딩하면 위와 같은 결과를 얻을 수 있다.
바로, 이번 문제의 정답이다.

이번 문제는 앞서 배운 text2pcap 의 사용방법과 효과적으로 쓸수 있는 방법을 통해
패킷파일로 만들어보고 그 안에서 문제의 정답과정을 찾고 패킷의 잘못된 부분을
추정해 볼 수 있다.

2010년 2월 23일 화요일

PCAP 파일을 파헤쳐 보자 - 그 두번째 이야기


PCAP 파일 포맷 구조는 복잡한 부분이 크게 없다. 물론, 직접 바이너리 파일을 들여다 볼 일도 드물다. 단순히 패킷 파일을 분석하는 분석가 입장이라면, 와이어샤크 같은 분석기를 통해서 보면 되기 때문에 어려운 부분은 없다. 하지만, 패킷 분석 전문가를 꿈꾸는 당신이라는 PCAP 파일 포맷 정도는 익혀야 하지 않을까?

그렇다면 pcap 파일 포맷을 좀더 쉽게 볼 수 있는 방법은 없을까? 010 에디터(http://www.010editor.com)
의 기능중 템플리트 기능을 사용하면 바이너리 데이터를 템플리트 형식에 맞게 파싱해 준다.

사용하기 위해서는 다음의 사이트에서 PCAP 템플리트를 받아서 프로그램에 등록하자.

그리고 PCAP 데이터를 읽어들이면 아래 그림과 같이 PCAP 헤더 정보와 다수의 레코드를 볼 수 있다.
와이어샤크와 같이 각 패킷 정보를 세부적으로 보여주는 것이 아니라 PCAP 파일 포맷의 관점에서
보여주는 것이므로 포맷 형태를 이해하는데 참고하면 될 것이다.


워낙 포맷 자체가 간단하기 때문에, 이러한 구조로 만들어져 있고 한번 경험 삼아서 살펴보면 될 것이다.

2010년 2월 22일 월요일

PCAP 파일을 파헤쳐 보자 - 그 첫번째 이야기


패킷 분석을 하면서 가장 많이 듣는 단어중의 하나가 PCAP 이 아닐까 생각한다.
네트웍을 분석하다, 문제가 있다면 흔히 "그러면 PCAP 파일좀 전송해 달라고 한다"
PCAP 은 Packet Capture 의미로 네트워크 트래픽을 캡쳐하기 위한
API 로 구성이 되어 있다. 윈도우로 포팅되어 있는 것은 WinPcap 이며, 유닉스 환경에서는
libpcap 이다.

libpcap 과 winpcap 라이브러리를 이용하여 캡쳐된 패킷을 파일로 저장하거나,
저장된 패킷을 읽고 또는 다른 프로그램에서 라이브러리를 이용해 패킷파일을
분석/편집 등을 할 수 있다. 이를 이용한 대표적인 패킷 캡쳐 프로그램이 tcpdump 나
wireshark 이다.  

자 그럼, 여기서 자주 다루고 있는 패킷파일의 내부를 깊게 살펴 보자.

패킷파일은 크게 다음과 같은 포맷 형태로 구성이 되어 있다.

PCAP 파일헤더 | 패킷 헤더 | 패킷 데이터 | 패킷 헤더 | 패킷 데이터 | 패킷 헤더 | 패킷 데이터 | ... | ...

제일 처음에 PCAP 포맷을 뜻하는 헤더가 오고 이후 각 패킷의 헤더와 데이터 정보가
쌓이게 된다. 헤더 구조체는 아래와 같으며,

struct pcap_file_header {
        bpf_u_int32 magic;
        u_short version_major;
        u_short version_minor;
        bpf_int32 thiszone;     /* gmt to local correction */
        bpf_u_int32 sigfigs;    /* accuracy of timestamps */
        bpf_u_int32 snaplen;    /* max length saved portion of each pkt */
        bpf_u_int32 linktype;   /* data link type (LINKTYPE_*) */
};

매직넘버는 고정된 값으로 0xa1b2c3d4 이다. 버전 Major, Minor 는 패킷 파일 포맷 버전을
뜻하며,  thiszone, sigfigs 는 시간과 관련한 것이고 snaplen 은 캡쳐된 패킷의 길이 network 은
데이터 링크 타입이다.  패킷 헤더 레코드는 아래와 같다.

typedef struct pcaprec_hdr_s {
        guint32 ts_sec;         /* timestamp seconds */
        guint32 ts_usec;        /* timestamp microseconds */
        guint32 incl_len;       /* number of octets of packet saved in file */
        guint32 orig_len;       /* actual length of packet */
} pcaprec_hdr_t;

좀더 쉽게 설명하기 위해 아래 예제 화면을 보자. 제일 처음에 패킷파일 헤더인 매직넘버가 나오고, 패킷 헤더 시작부분과 실제 패킷 데이터 시작 부분을 볼 수 있다. 캡쳐된 패킷의 길이가 66 bytes 나오는데 패킷 데이터 시작 전 4바이트는 실제 패킷의 길이다. 0x00000042 를 계산해보면 66 값을 얻을 수 있다. 단지 위 구조체에 값을 맞춰보기만 하면 된다.

[그림] PCAP 파일 포맷 형태 예제

이 헤더가 끝난 다음 에 또 패킷 헤더와 데이터가 붙으며 계속 이런 구조로 저장이 되는 것이다. 알고보면 구조는 상당히 간단한 형태로 구성이 되어 있다. 파일의 첫 4 바이트만 보아도 아 ~ 패킷 파일인가 보다 하고 추측해 볼 수 있을 것이다. 더불어 외우기도 쉽지 않은가요. 1234 와 ABCD :-)

2010년 2월 18일 목요일

[Packet Contest #1] 문자열의 패킷 HEX 값을 분석하라!

모두들 구정 명절은 잘 보내셨는지요? 패킷과 관련한 내용을 다루고 있는
패킷인사이드(packetinside.com)도 블로그를 개설한지 2달이 넘었습니다.
앞으로 게시한 글을 좀더 쉽게 접근해 볼 수 있도록 Contest 형태의 문제를 내보려고 합니다.

과거에 게시된 글을 읽어보고 문제를 풀어나가며, 패킷 분석을 쉽게 이해해 볼 수 있도록
하고자 함입니다.  그 첫번째 대상으로 쉬운 주제를 잡아보았습니다.

문제) 다음은 패킷의 HEX 값 이다. 다음 값을 통해 암호화된 문자열을 해독하고,
풀이과정을 최대한 세부적으로 기술하시오.
의도) 스트링으로 기술된 HEX 값을 분석하는 과정을 배워보자.

00 05 b5 02 02 02 01 01 01 01 01 01 08 00 45 00
00 79 12 34 00 00 ff 06 a3 45 01 01 01 01 c0 a8
03 02 04 d2 16 2e 00 00 00 00 00 00 00 00 50 00
20 00 65 53 00 00 55 47 46 6a 61 32 56 30 53 57
35 7a 61 57 52 6c 4c 6d 4e 76 62 53 41 78 63 33
51 67 55 47 46 6a 61 32 56 30 49 45 4e 6f 59 57
78 73 5a 57 35 6e 5a 53 42 54 62 32 78 32 5a 57
51 73 49 45 4e 76 62 6d 64 79 59 58 52 31 62 47
46 30 61 57 39 75 0a

재미삼아 해 보시고요, 문제를 푸신 분들은 그 과정을 댓글로 남겨주세요.
풀이과정을 게시할 때, 정답을 보내신 분들의 풀이 과정을 추가로 만들어
함께 공유할 수 있도록 하겠습니다.

다만, 우려되는건 아직 이 블로그의 방문자가 많지 않아 얼마나 참여를 할지가
의문이네요. 그렇지만 꾸준히 계속 한다면 분명 많아지겠죠! :-)

@Rigel

2010년 2월 10일 수요일

아이폰(iPhone)에서도 패킷 캡쳐를 할 수 있다고!

모바일 장치인 아이폰에서도 패킷을 덤프해 보자. 아이폰에서 네트워크 패킷 데이터를 캡쳐할 수 있는 도구를 하나 소개하고자 한다. Pirni 라고 패킷 데이터를 덤프하여 파일로 저장해 주는 역할을 해 준다. 이 저장한 패킷은 와이어샤크나 tcpdump 를 통해 분석을 똑 같이 할 수 있다. Pirni 는 아이폰과 아이팟터치 에서만 사용이 가능하며, 아이폰의 첫 번째 패킷 스니퍼로 알려져 있다. 이걸 사용하기 위해서는 OS 버전이 3.0 이상되어야 하며, 탈옥된 아이폰을 사용하고 있어야 한다. 일단, 와이어샤크같이 편한 GUI 환경을 갖고 있지 않으며, 터미널을 통해 수행하게 된다.


옆 화면은 목적지 포트가 80 번인 패킷에 대해 log.pcap 으로 저장하는 것이다. 초기 실행되는 로그를 보면 패킷 포워딩이라는 것이 보인다. Promiscious 모드를 사용할 수 없어, ARP 스푸핑을 통해 라우팅을 다른쪽으로 우회시켜 포워딩 하는 형태로 패킷 데이터를 덤프뜬다.

아직은 많은 기능을 가지고 있지 않고, 몇 가지 사용예제를 소개하면 아래와 같다. 굳이 설명을 하지 않더라도 아래 예제를 보면 어떤 의미인지 추측이 될 것이다.

        pirni -s 192.168.0.1 -o log.pcap
        pirni -s 192.168.0.1 -d 192.168.0.128 -f "tcp dst port 80" -o log.pcap
        pirni -i en1 -s 192.168.0.1 -d 255.255.255.0 -o log.pcap

앞서 말한것과 같이 pirni 는 단순히 패킷 덤프를 하는 기능만을 가지고 있어, 분석형태로 사용하기는 힘들다. 그래서 사용하는 것이 derv 라는 것이 있다. 이것은 패킷 캡쳐된 패킷 파일을 파싱하는 스크립트를 포함하고 있는 것이다. derv.sh 는 실시간으로 패킷을 읽어 정보를 보여주므로 tcpdump 와 비슷할 수도 있겠다. 하지만, 기능은 많이 제한되어 있다는 점.

나에겐 아직 아이폰이 없어, 주변에 설치한 분의 아이폰 화면을 소개한다. :-)


아이폰에서 패킷 캡쳐에 관심있는 분들이라면 다음 페이지를 참고해 설치해 보면 된다.

1) Pirni 사용 가이드
2) Derv 설치방법
3) Script add-on for Pirni, a native iPhone/iPodTouch network packet sniffer.

2010년 2월 5일 금요일

국회서 패킷 감청에 대한 문제와 개선방향 토론회 열려

몇일 전 , 정확히 말하면 2월 1일 국회에서 '패킷 감청의 문제점과 개선방향 토론회'가 열렸다고 한다. 패킷 감청 문제가 얼마나 심각하고, 어렵지 않게 할 수 있다는 것을 시연을 통해 보여주었다고 한다. 이와 관련 기사는 2월2일 오전에 보도가 된것 같고, 기사에 패킷 감청 소프트웨어로 여기서 많이 다루고 있는 와이어샤크(WireShark)가 언급이 되었다. 기사의 영향인가, 그날 와이어샤크로 검색을 하여 방문한 사용자가 급격히 늘은 것으로 판단된다.  

기사의 내용을 잠깐 살펴보면 메신저, 메일, 비밀번호 감청등을 할 수 있고, 쉽게 알 수 있다는 점으로 패킷 감청의 문제에 대해서 꼬집고 있다. 여러분들도 모두 알다시피 흘러다니는 패킷을 보게되면 암호화 되지 않은 데이터는 모두 확인이 가능하다. 다음 그림은 한 기사에서 언급된 이미지다.


와이어샤크에서 http.content_type contains "text/html' 이라는 필터를 사용하여 text/html 이 포함된 컨텐츠 타입만 출력을 시킨 것이다. 그런데 하단의 이메일 내용을 보면, 와이어샤크에서는 이렇게 한 화면에 보여주는 기능이 없다. 물론, 필자가 아직 모르고 있는 기능일지도 모르지만, 이런식으로 보여주는 유사한 기능이라면 오른쪽 클릭에서 나타나는 'Follow TCP Stream' 이다.  더군다나 Follow TCP Stream 으로 보면 위와 같이 이메일 형태가 깨끗하게만은 나오지 않을 것이다. 위 그림으로 추정해 HTTP 프로토콜을 통한 것이고, 캐리지 리턴 값등 여러 캐릭터가 추가로 보여지는것이 맞았을 것이다.  화면의 출력된 형태는 와이어샤크의 레이아웃을 통해 보이지만, sniff-http 라는 부분은 와이어샤크에 없는 내용이다. 아래 부분의 이메일 부분은 다른 스니핑 프로그램을 통해 나오면 화면을 가져다 붙인 것으로 추정된다.

이 그림을 꼬집자는 것은 아니고, 와이어샤크를 사용하는 분들에게 혼란을 줄 소지가 있기 때문이다. 이 프로그램이 패킷감청의 전문프로그램인양 말이다.

전문적으로 특정 프로토콜을 스니핑 하는 프로그램은 사용자가 보기 쉽게 변환 작업을 거쳐 보여준다. 그렇기 때문에 위 이메일 내용 형태와 같이 보기도 쉽다. 인터넷만 찾아봐도 MSN, 이메일 등 전문적인 스니핑 프로그램을 찾아볼 수 있다.

여러분들은 패킷 감청에 대해서 어떻게 생각하나? 분명 우리가 아무런 암호화 없이 인터넷을 사용한다면 모든 내용이 철저하게 다 노출될 수 있다. 그렇기 때문에 암호화 프로그램이 나와있고 중요 내용은 암호화를 사용한다. 암호화를 하게 되면 그만큼 해독이 어려워지기 때문이다. 하지만, 과연 인터넷을 사용하는 인구중 몇 %나 이런 보안을 신경쓰며 일일이 인터넷을 할까?  패킷 감청은 불법적인 전화도청과 전혀 다를바가 없다. 그렇기 때문에 합법화 되어서는 안된다. 하지만, 일반 사람들이 패킷 이라는 걸 얼마나 알까. ISP(Internet Service Provider)의 도움만 있다면 흘러다니는 트래픽의 많은 부분을 감청할 수 있다. 정부기관이 아니더라도 패킷 감청은 누구나 할 수 있다. 하지만, 패킷 데이터를 덤프하는 과정에서 그 범위는 한정된다.

어찌되었던 누군가가 쉽게 엿볼 수 있는 상황이 될 수도 있다는 것이다. 그러므로 인터넷 환경의 통신은 스스로가 주의하는것이 더욱 필요하다. telnet 대신 SSH 를 사용하는 것 같이 항상 보안을 염두해 두고 사용하는 것이 바람직 하다. 지금 누군가 당신을 엿보고 있다고 생각하면 말이다.

[관련기사]
1) 메신저·메일·비밀번호 낱낱이 기술로도 못막는 ‘무제한 감청’
http://media.daum.net/society/others/view.html?cateid=1067&newsid=20100202083015841&p=hani&RIGHT_COMM=R11
2) 국회서 최초의 패킷감청 토론회 펼쳐

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 값을 이용해 패킷 데이터로 만드는 과정을 설명하면서 몇 가지 다루어 본 것이다. 앞으로 몇 가지 패킷 생성 도구에 대해서 언급해 볼 것이다.


2010년 2월 1일 월요일

패킷분석정보, 자원은 무궁무진 하다.

제목과 같이, 여러분들은 패킷 분석을 하다 필요한 정보를 어디서 얻고 있나요? 많은 경우는 검색엔진을 통해 우선 검색을 해 보지 않을까 생각한다. 분석하다 막히는 경우를 보면,

- 접해보지 않은 프로토콜
  예를들어, 필자는 HSRP 라는 것을 알고 있는데, 이것을 아는 사람은 얼마나 될까?
- 통신에서 이용된 포트번호
- 알수 없는 Payload
  Payload 의 특정 부분 (구분이 갈 만한 문자열) 또는 HEX 값으로 검색

위의 형태등이 있는데. 이때 검색엔진을 통해 위와 같은 내용을 검색해 보면 해당 패킷에 대한 단서를 찾을 수 있다. 사용된 포트번호를 검색해 본다든지, Payload 에 포함된 문구를 검색하다 보면 문제의 실마리를 알 수 있는 경우가 꽤 된다. 이외에 분석도구의 사용방법 및 분석에 필요한 정보를 얻을 수 있는 방법을 몇 가지 정리해 보았더니 다음과 같다.  

- 구글의 북 서비스를 이용 (http://book.google.com)
  아래 이미지와 같이 관련된 책을 무료로 볼 수 있다. 물론, 제한된 페이지 수가 있지만 그래도 꽤 유용하다.
- 검색엔진의 활용. 구글의 방대한 데이터베이스는 정보를 빠르게 얻게 해 줄 것이다.
  포트번호,Payload 등을 검색 키워드로 사용해 본다.
- PacketInside.com 의 검색 활용
  패킷 인사이드의 블로그 내용을 우선 검색해 보면 참고할 만한 글이 많을 것이다.
- 각종 분석도구의 도움말 파일 참고
  분석도구의 MAN 페이지 또는 도움말 파일은 정리가 잘 되어 있다. 참고로 와이어샤크의 도움말 파일은
  도움이 많이 될 것이다.
- 분석 관련 다양한 Case 사례 습득
- 인터넷에 공개된 패킷 파일 예제를 통합 분석 Skill 함양
  구글에서 filetype:pcap 으로 검색

자, 이제 패킷 분석의 세계로 Go!Go!