2011년 7월 19일 화요일

패킷 데이터 문자열을 인덱스화하여 빠르게 검색하기

패킷 캡쳐파일을 다루다 보면, 큰 패킷파일을 도대체 어떻게 다뤄야 할까 하는 고민이 들게 마련이다. 이럴때 조금은 유용하게 사용할 수 있는 것이 있다. 패킷 데이터의 문자열을 인덱스 하여 빠르게 검색할 수 있도록 도와주는 것이다. 사용하려는 목적에 따라 다르겠지만, 이것을 응용해서 여러분들에게 딱 맞는 소프트웨어로도 변신할 수 있다.

일단, 프로그램 이름은 'tcpindex' 이다. 문자열들을 인덱스하여 빠르게 검색할 수 있도록 도와준다. Pcap 라이브러리가 기본적으로 사용되고, 텍스트 검색 기능을 위해 CLucene 가 사용되었다. CLucene 는 Lucene 의 C++ 로 포팅된 라이브러리로 빠른 성능의 검색 기능을 제공한다.

윈도우에서도 사용가능하며, 다운로드는 다음 경로를 통해서 할 수 있다.
윈도우 버전은 위 경로에서 바로 받아 사용하면 되고, 리눅스의 경우는 간단히

# ./configure
# make
# make install

과정을 거쳐서 사용하면 된다.

Tip!
나의 경우는 컴파일을 하다 아래와 같은 에러가 나타났다.

# make
stream_packet.h: In member function ‘void
stream_packet_t::read_bytes(uchar*, uint)’:
stream_packet.h:72: error: ‘memcpy’ was not declared in this scope
In file included from tcpindex.h:52,
                from main.cpp:20:
session.h: In constructor ‘session_t::session_t(uint, uint, uchar,
ushort, ushort)’:
session.h:61: warning: deprecated conversion from string constant to ‘char*’
In file included from main.cpp:20:
tcpindex.h: In constructor ‘options::options()’:
tcpindex.h:83: warning: deprecated conversion from string constant to ‘char*’
이런 경우는,
stream_packet.h 에 ' #include <string.h> '를 삽입하고 컴파일을 하면 무리없이 컴파일이 된다.

컴파일을 하고 사용방법을 보면 아래와 같다. 사용 설명은 리눅스 기준이지만, 윈도우의 바이너리 형태도 같다고 보면 된다.

# tcpindex -h
Usage: tcpindex [OPTIONS] [QUERY STRING]
Capture packets on a network interface and index packets containingso they
can be rapidly searched for keywords.

 -D, --list-interfaces  list the available network interfaces
 -i, --interface=INDEX  specify index of the interface to capture packets on
 -l, --index-dir=DIR    specify the directory for the search index (default is
                        'index_data')
 -h, --help             give this help
 -q, --query            specify a keyword query to perform against the index
 -s, --save-data        whether to save session data to individual files as
                        well as the index
 -v, --verbose          output verbose debugging messages

Example usage to capture and index data:
 tcpindex -i 1
Example usage to query:
 tcpindex -q +referer +aol

옵션은 많지 않고, 대충 보아도 사용방법을 눈치챌 수 있을 것이다. -i 는 인터페이스를 지정하고 -l 은 인덱스 경로 그리고 -q 는 쿼리를 뜻한다. -D 는 사용가능한 인터페이스 목록을 보여준다.

# tcpindex -D
1: eth0
   (null)
2: any
   Pseudo-device that captures on all interfaces
3: lo
   (null)
No interface specified.

일단, -i 로 인터페이스를 지정하고 실행해 보자. 인덱스 경로를 따로 지정하지 않으면 프로그램을 실행한 경로 기준으로 인덱스 파일이 생성된다.

# tcpindex -i eth0
중지는 Ctrl+C 를 눌러서 하면 된다. 이후, ls 로 목록을 살펴보면 아래와 같다:

# ls
index_data

TCP-192.168.0.203_39551-174.37.113.144_80
TCP-192.168.0.203_39552-174.37.113.144_80
TCP-192.168.0.203_39553-174.37.113.144_80
TCP-192.168.0.203_40924-74.125.127.128_80
TCP-192.168.0.203_42525-74.125.224.249_80
TCP-192.168.0.203_42530-74.125.224.249_80
TCP-192.168.0.203_44927-74.125.224.235_80
TCP-192.168.0.203_45103-74.125.127.121_80
TCP-192.168.0.203_47094-74.125.127.132_80
TCP-192.168.0.203_49501-74.125.224.243_80
TCP-192.168.0.203_57709-208.70.196.59_80
TCP-192.168.0.203_57710-208.70.196.59_80
TCP-192.168.0.203_57714-208.70.196.59_80
TCP-192.168.0.203_58132-74.125.127.95_80
TCP-192.168.0.203_60412-74.125.224.159_80


TCP 로 처음 시작하며 IP 주소와 포트 번호가 있는 것은 실제 데이터의 문자열 정보가 담겨 있는 것이다. 그리고 index_data 디렉토리 안에 인덱스가 있다.

인덱스를 이용한 검색을 하기 위해서는 -q 옵션을 사용한다. packetinside.com 으로 검색해 보았다.

# tcpindex -q packetinside.com
Searching for: packetinside.com

1. TCP-192.168.0.203_36292-74.125.127.191_80 - 0.18340063
 ; __utmz=150635877.1310986907.36.22.utmcsr=<B>packetinside.com</B>|utmccn=(referral)|utmcmd=referral|utmcct...=<B>packetinside.com</B>|utmccn=(referral)|utmcmd=referral|utmcct=/2011/05/nix.html
If-Modified-Since: Mon.
2. TCP-192.168.0.203_36351-74.125.127.191_80 - 0.16210480
 =150635877.1.10.1310986907; __utmc=150635877;
__utmz=150635877.1310986907.36.22.utmcsr=<B>packetinside.com</B>|utmccn.


Search took: 0 ms.

와우, 빠른 속도로 검색되어 나타난다. * 과 같은 와일드카드 형태도 사용 가능한데 아래와 같이 결과가 보인다.

# tcpindex -q packet*inside
Searching for: packet*inside

1. TCP-192.168.0.203_36292-74.125.127.191_80 - 0.12968384
 .
2. TCP-192.168.0.203_44927-74.125.224.235_80 - 0.12968384
 .

Search took: 0 ms.

~는 Fuzzy 서치 형태인데 알고리즘에 따른 검색이라 그런지, 시간은 조금 더 소요된다.

# tcpindex -q packet~
Searching for: packet~0.5

1. TCP-192.168.0.203_57709-208.70.196.59_80 - 0.22925079
 .
2. TCP-192.168.0.203_57713-208.70.196.59_80 - 0.18340063
 .

Search took: 3 ms.

이외 AND 오퍼레이트 사용도 가능하다.

# tcpindex -q +host "packetinside.com" AND GET
Searching for: +host +packetinside.com +get

# tcpindex -q +host +referer| grep packet
<B>Referer</B>:
http://www.packetinside.com...,firstScrollTime.1571,ol.1912 HTTP/1.1
<B>Referer</B>: http://www.packetinside.com...GET
/dyn-css/authorization.css?targetBlogID=4889001868370773649&zx=ad647330-a785-43be-847d-67c0566003e4
HTTP/1.1
<B>Referer</B>: http://www.packetinside.com.
<B>Referer</B>: http://www.packetinside.com/2011/07/cpugpu-durandal.html
<B>Host</B>: www.packetinside.com
<B>Referer</B>: http://www.packetinside.com/
<B>Host</B>: www.packetinside.com
<B>Referer</B>: http://www.packetinside.com/search/label/winpcap

매칭되는 부분은 <B> 와 </B> 로 둘러 쌓인다. 검색 조건과 관련해서는 Lucene 의 문법 형태를 참고해 보기 바란다. 아주 큰 데이터로 테스트 해보지는 않았지만, 문자열 기준으로 의심스러운 패턴을 찾아내거나 기타 패킷 문자열 검색 형태로는 유용하게 사용될 수 있으리라 생각된다.

도구 자체의 순수 기능만 보기 보다는 이것을 활용해서 다양하게 이용할 수 있다는 것을 잊지만 말자!

[참고]
1. TcpIndex 다운로드
http://www.gotomanage.com/open_source_tools/tcpindex_thankyou
2. Lucene 쿼리 파서 문법
http://lucene.apache.org/java/2_3_2/queryparsersyntax.html
3. Clucene
http://clucene.sourceforge.net/

댓글 없음:

댓글 쓰기