2010년 6월 29일 화요일

파일 데이터 다루는데 이만한 도구 없다! 맥가이버 칼이 파일까지...

패킷 분석을 진행하다 보면, 다양한 분석이 필요한 경우가 많다. 패킷을 통해 전송된 데이터를 분석하거나
HEX 값을 바이너리로 변환하거나 등 파일이 추출된 경우 분석하기 위한 다양한 작업이 이어진다.
예를 들어, 패킷파일을 통해 다음의 데이터가 전송된 경우를 보자.

C0C6BD13A42E8523CD25BBE5493E09CB9333C7A06E4A0894C7A582C166B193BAC68EE5005F64114E
F59F630F1B164D51956CE802F380B4E7E6852B5D0F72A6C8E896B4142C80B6356F2D75FEBF4803DC
3D122EAF0CCE0536B01A7211997B770E580BF8F089A94DEE5BE0A4FF9B5CF1A08D368EA6A6E37302
BAE3B68F19ABA2466A2C46A55875DA19BB89184EDE60F9494664EAD9FE29F7E15CE797036F79B4B2

어떤 데이터로 보이는가? 알수없는 의미의 데이터? 암호화된 데이터? 등. 우리는 사전정보를 모르고
패킷파일을 분석하였기 때문에 어떤것인지 알 수 없다. 패킷분석을 통해서 모든 것을 알아낼 수는 없는 것이다.
다만, 최대한 어떤 형태인지 파악은 가능할 것이다. 운이 좋으면 그 형태를 넘어 무엇인지도 알 수 있다.

이번은 어떤 데이터를 해독하는 과정을 설명하기 보단, 파일 데이터등을 다루는데 유용한 도구를 소개하고자 함이다. 위 데이터를 보면 눈썰미가 좋은 사람이라면 HEX 값 이라는 것을 추정해 볼 수 있다. (물론 아닐 수도 있다) 그럼 이 HEX 값이 어떤 실행가능한 형태의 데이터라면 바이너리로 변환이 필요한데, 막상 변환하려고
하면 방법을 모르고 헤매는 경우가 많다. 이럴때 유용하게 사용될 수 있는 SFK(Swiss File Knife) 가 있다.

막상 쉬어보이고 찾으면 쉽게 나올거 같지만, 꼭 필요할땐 정보 찾기가 힘들다 ^^

파일은 다음의 경로에서 다운받을 수 있다.

이 포스팅에서 이용한 예제는 리눅스 기반에서 사용하였지만, 윈도우(Window) 에서도 사용 가능하다는 점!

자, 그럼 위 데이터 값을 tt 라고 저장하고 바이너리로 변환하기 위한 방법은 아래와 같다.

# ./sfk-linux.exe filter tt +hextobin out.dat
26 lines converted, 0 skipped, 1024 output bytes.
md5: 19b5646577f8aeb567a717ac3e84c5d4

tt 의 데이터는 hex 값이니 이것으로 바이너리로 변환하여 out.dat 로 기록하라는 것이다.
그리고 out.dat 를 살펴보면 제대로 변환된 것을 확인할 수 있다. 막상 변환하고 보니 실행파일
형태로는 보이지 않는 어떤 임의의 값으로 추정된다.

# xxd out.dat
0000000: c0c6 bd13 a42e 8523 cd25 bbe5 493e 09cb  .......#.%..I>..
0000010: 9333 c7a0 6e4a 0894 c7a5 82c1 66b1 93ba  .3..nJ......f...
0000020: c68e e500 5f64 114e f59f 630f 1b16 4d51  ...._d.N..c...MQ
0000030: 956c e802 f380 b4e7 e685 2b5d 0f72 a6c8  .l........+].r..
0000040: e896 b414 2c80 b635 6f2d 75fe bf48 03dc  ....,..5o-u..H..
0000050: 3d12 2eaf 0cce 0536 b01a 7211 997b 770e  =......6..r..{w.
0000060: 580b f8f0 89a9 4dee 5be0 a4ff 9b5c f1a0  X.....M.[....\..
0000070: 8d36 8ea6 a6e3 7302 bae3 b68f 19ab a246  .6....s........F

SFK 에는 파일을 다루기 위한 다양한 기능이 많은데, 패킷 관련한 같은 작은 기능도 있다.
예를 들어 아래명령을 보면

# ./sfk-linux.exe udpdump
sfk udpdump [-showle] [...] port

   create human-readable hexdump of UDP socket input,
   for debugging of UDP network applications.

   options:
      -showle  highlights line ending characters CR and LF.
      -wide    dumps 32 input bytes per line.
      -lean    dumps 16 input bytes per line.
      -echo    echo received packets back to sender.
      -pure    lists flat hex characters:
               53464B2D544553540D0A
      -hexsrc  lists hex comma separated values:
               0x53,0x46,0x4B,0x2D,0x54,0x45,0x53,0x54,0x0D,0x0A,
      -decsrc  lists decimal comma separated values:
               83,70,75,45,84,69,83,84,13,10,
      -flat    no hexdump at all, dump characters as they come.
      -nohead  does not show the "received n bytes" message.

   example:
     sfk udpdump 5000
        waits on port 5000 for incoming udp packages.

그렇다, UDP 데이터를 덤프하기 위한 기능을 제공한다. 아래는 UDP 덤프를 하는 것인데 5000 번 포트로
ECHO 기능을 수행하는 것이다. 에코기능이라 하면 받은 데이터를 그대로 다시 리턴해 주는 것이다.

# ./sfk-linux.exe udpdump -echo 5000
[waiting on port 5000 for data.]
[received 21 bytes:]
 >30332030 32203031 20303020 30302030< 03 02 01 00 00 0 00000000
 >30203131 0A<                         0 11.            00000010
[echoing back]

위와 같은 결과를 받았는데, 전송한 것은 아래와 같다.

# echo "03 02 01 00 00 00 11" | nc -vv -u localhost 5000
localhost [127.0.0.1] 5000 (?) open
03 02 01 00 00 00 11
^C sent 21, rcvd 21

로컬호스트 5000 번으로 03 02 01 00 00 00 11 을 전송하니 그대로 다시 돌아왔다. 이런 기능은 애플리케이션
개발이나 기타 용도로 사용하는데도 유용할 것이다.

간단히 HTTP 서버 동작을 하는 기능도 있다. httpserv 옵션을 사용하면 되는데, 기본 포트를 80 번으로 바인딩 하려고 하였지만 이미 사용중이어서 다른 포트인 8080 으로 리스닝을 시도한다.

# ./sfk-linux.exe httpserv
note : cannot bind on port 80, using alternative port 8080.
SFK Instant HTTP Server. For help, type "sfk httpserv -help".
Waiting on port 8080.
^[[A> connect from 127.0.0.1
> GET /test HTTP/1.0

자, 8080 으로 접속하여 시도해 보니, 역시나 접속이 잘 된다.

# telnet localhost 8080
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
GET /test HTTP/1.0

HTTP/1.1 404 no such file

404 no such file: test
Connection closed by foreign host.

아까 위에서 udpdump 를 보았는데, tcpdump 도 있다. UDP 가 아닌 TCP 다.

# ./sfk-linux.exe tcpdump 5000
waiting on port 5000 for connections.
[got connection]
[received request from back with 13 bytes:]
 >54455354 202C2048 4148410D 0A<       TEST , HAHA..    00000000
[received request from back with 1 bytes:]
 >04<                                  .                00000000

# telnet localhost 5000
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
TEST , HAHA
^]
telnet> quit
Connection closed.

이번에는 다른 것으로 로컬호스트 5000 번에 접속하여 GET 요청을 하였다. 이때, Host 필드도 주어
패킷인사이드를 지정하였는데,  앗!! 패킷인사이드 블로그 정보가 출력된다.
분명 로컬호스트로 접속하였는데 어찌. 정보가~ 출력되는가.

# telnet localhost 5000
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
GET / HTTP/1.1
Host:packetinside.com

HTTP/1.1 200 OK
Date: Tue, 08 Jun 2010 02:39:36 GMT
Server: Apache
Connection: close
Transfer-Encoding: chunked
Content-Type: text/html; charset=utf-8

2c38
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Packet Inside/?ㅽ듃?뚰겕 ?⑦궥遺꾩꽍 釉붾줈洹?/title>
<link rel="stylesheet" type="text/css" href="http://rs.textcube.com/service/blog/style/blogDefault.css" />
<link rel="stylesheet" type="text/css" href="http://fs.textcube.com/blog/5/58149/skin/1/style.css" />

이렇게 가능한 것은 forward 기능을 사용하여 패킷인사이드로 트래픽을 포워드 시켰기 때문이다.

# ./sfk-linux.exe tcpdump 5000 -forward packetinside.com:80
waiting on port 5000 for connections, to forward to packetinside.com:80.
[forward-connected to packetinside.com:80]
[received request from back with 16 bytes:]
 >47455420 2F204854 54502F31 2E310D0A< GET / HTTP/1.1.. 00000000
[forwarded 16 bytes]
[received request from back with 23 bytes:]
 >486F7374 3A706163 6B657469 6E736964< Host:packetinsid 00000000
 >652E636F 6D0D0A<                     e.com..          00000010
[forwarded 23 bytes]
[received request from back with 2 bytes:]
 >0D0A<                                ..               00000000
[forwarded 2 bytes]
[received reply from front:]ec]
 >48545450 2F312E31 20323030 204F4B0D< HTTP/1.1 200 OK. 00000000
 >0A446174 653A2054 75652C20 3038204A< .Date: Tue, 08 J 00000010
 >756E2032 30313020 30323A34 303A3332< un 2010 02:40:32 00000020
 >20474D54 0D0A5365 72766572 3A204170<  GMT..Server: Ap 00000030
 >61636865 0D0A436F 6E6E6563 74696F6E< ache..Connection 00000040
 >3A20636C 6F73650D 0A547261 6E736665< : close..Transfe 00000050
 >722D456E 636F6469 6E673A20 6368756E< r-Encoding: chun 00000060

이외, 파일의 MD5 기능이나

# ./sfk-linux.exe md5 readme.txt
683e317301cbb32e942f0f7cc2e958d5        readme.txt

HEX 덤프를 하여 보거나

# ./sfk-linux.exe hexdump readme.txt
readme.txt :
 >74686973 20697320 74686520 73666B20< this is the sfk  00000000
 >62696E61 72792066 6F72206C 696E7578< binary for linux 00000010
 >2E0D0A0D 0A2D2020 706C6561 73652072< .....-  please r 00000020
 >656E616D 6520746F 20277366 6B272062< ename to 'sfk' b 00000030

파일의 문자열 정보등을 볼 수가 있다.

# ./sfk-linux.exe strings bin.dat

SFK 는 너무나 많은 기능을 가지고 있어서, 파일 데이터를 다루는데 있어서는 부족함이 없을 것이다.
이름에서 말해주는 것과 같이 파일을 다루는 분석을 수행한다면 필요한 도구가 될 것이라 생각한다.

From Rigel

댓글 없음:

댓글 쓰기