2012년 12월 31일 월요일

패킷인사이드 3주년, 새해 복 많이 받으세요.


벌써 블로그를 시작한지 3년이 되었습니다. 패킷 관련 정보를 많이 써 온것 같은데도, 아직 여러분들에게 소개할 내용이 많이 남아 있네요.

그만큼 이쪽도 빠르게 변화하고 있다보니 새로운 내용도 많고, 아직도 배워야 할게 많은것 같은 느낌입니다. 찾고 찾다 보면 몰랐던 내용도 많고 인터넷은 정말 드넓다는 것을 다시 한번 배웁니다. 물론, 매번 느끼지만 말이죠 :-)

내년에도 계속 패킷인사이드의 글들은 이어집니다. 언제까지 이어 나갈 수 있을까는 모르겠지만, 한번 끝까지 해 봐야 겠죠. 장기적인 계획으로는 글들이 충분히 모아지면 책으로도 엮어볼까 합니다. 그 시점이 언제일지는 모르겠지만, 제 스스로가 어느정도는 만족해야 겠지요.

둘째 아이도 태어나고 개인적으로도 바쁜 나날을 보내고 있다보니, 글 쓰는 것도 점점 어려워 지고 있습니다. 매년 쓰여지는 포스팅 건수가 줄어들고 있다는 것이 증명해 주고 있습니다. 하하~

이제 내년 까지는 몇 시간 남지 않았습니다. 여러분들 마무리 잘 하시고요, 2013년 한해는 모두 복 많이 받으시고 계획했던 모든 것을 이루길 기원할께요.

/ 패킷인사이드 주인장 드림.

2012년 12월 27일 목요일

콘솔기반의 실시간 웹 로그 분석기 - GoAccess


콘솔기반의 괜챦은 웹 로그 분석기를 보게 되어 소개한다. 회사분의 소개로 보게되었는데, 콘솔기반 치고는 깔끔하게 만들어져 있다. 일반적인 웹 로그 분석 기능은 모두 포함하고 있으며, 아파치의 CLF 또는 XLF 포맷 그리고 W3C 포맷을 지원한다.



실시간으로 로그분석을 해서 볼 수 있다는 점도 장점이고, HTML 리포트 형태로 출력도 지원한다. 속도는 대략 초당 10만 라인 정도 ( 인텔 제온 CPU 2.4 GHz 2GB RAM) 로 빠르게 동작한다. 사용방법도 아주 간단하여 다음과 같이 사용하면 된다.

# goaccess -f /data/apache/logs/access.log -a

컴파일 하기 위해서는 ncurses 라이브러리와 GLib >= 2.0.0 이상이 필요하다. 필요에 따라 MaxMind 사의 GeoIP 도 필요하다.

파일 다운로드 및 추가 정보는 다음 사이트에서 얻을 수 있다.

http://goaccess.prosoftcorp.com/

Curses 를 이용한 프로그램 작성에도 해당 소스를 활용하면 도움이 될 것같다.


2012년 12월 14일 금요일

리눅스 3.7 커널 릴리즈: TCP Fast Open, vxLan 지원

리눅스 3.7 커널이 12월10일에 릴리즈 되었다. 이번 릴리즈는 ARM 64비트 아키텍쳐를 지원하고 서명된 커널 모듈, Btrfs 파일시스템 업데이트, strace 후의 새로운 "perf trace" 도구, 서버측면의 TCP Fast Open 기능, 안정적인 NFS 4.1 등 많은 기능이 업데이트 되었다.

눈에 띄는 변화는 ARM 멀티 플랫폼과 64 비트 지원이다. 싱글 ARM 커널 이미지로 여러 하드웨어에서 부팅이 가능해 졌다. ARM 플랫폼을 지원하도록 배포할때 더욱 쉬워지게 된 것이다.

보안적으로는 서명된 커널모듈을 지원해서, 올바르게 서명되지 않은 모듈은 커널에 로드하지 못하도록 한 것이다. 이 기능은 루트킷등을 이용해 모듈을 추가할 수 없도록 해 보안적으로도 상당히 유용한 기능이다.

네트워크 관점으로 보면 서버 측면에서 TCP Fast Open 을 지원한다. 이미 이 기능은 3.6 커널에서 추가된 것이나 이번 릴리즈는 서버측을 지원하는 것이다. TCP 연결을 맺을때 "Fast Open" 은 더욱 최적화하여 페이지 로드시 4% ~ 41% 정도 속도 향상을 가져온다. 물론 사용되는 환경마다 다르지만 말이다. 이 기능은 추후 블로그에서 다시 한번 소개할 예정이다.

또한 SMBv2 를 지원하고(시험적인 기능) NFS 4.1 이 오랜 기간을 끝내고 드디어 안정 버전으로 릴리즈 되었다. NFS 4.1 의 주 기능은 pNFS 라 하여 패러랠 NFS 을 지원한다. 이로 인해 분산된 여러 서버들 간의 파일시스템에 패러랠한 접근이 가능하다. UDP 프로토콜을 통해 레이어 2 이더넷 패킷을 전송할 수 있는 터널링 프로토콜 vxlan 을 지원한다. vxlan 은 가상화된 환경에서 터널링된 네트워크 환경을 지원하는데 주로 이용된다. VLAN 은 4096 개로 제한되었지만 이것은 24bit 로 확장되어 훨씬 많은 개수를 지원하게 된다. 이것또한 블로그에서 추후 언급할 예정이다.

마지막으로 네트워킹 관점의 변화된 주요 내용은 다음과 같다

  • loopback: set default MTU to 64K (commit)
  • Providing protocol type via system.sockprotoname xattr of /proc/PID/fd entries (commit)
  • Use a per-task frag allocator (commit)
  • Netfilter
    • Add protocol-independent NAT core (commit)
    • Add IPv6 MASQUERADE target (commit)
    • Add IPv6 NETMAP target (commit)
    • Add IPv6 REDIRECT target (commit)
    • Add IPv6 NAT support (commit)
    • Support IPv6 in FTP NAT helper (commit)
    • Support IPv6 in IRC NAT helper (commit)
    • Support IPv6 in SIP NAT helper (commit)
    • Support IPv6 in amanda NAT helper (commit)
    • Add stateless IPv6-to-IPv6 Network Prefix Translation target (commit)
    • Remove xt_NOTRACK (commit)
  • Near Field Communication (NFC): Add an Link Layer Control (LLC) Core layer to HCI (commit), add an shdlc llc module to llc core(commit), LLCP raw socket support (commit)
  • bonding: support for IPv6 transmit hashing (and TCP or UDP over IPv6), bringing IPv6 up to par with IPv4 support in the bonding driver (commit)
  • team: add support for non-Ethernet devices (commit)
  • gre: Support GRE over IPv6 (commit), add GSO support (commit), add GRO capability (commit)
  • packet: Diag core and basic socket info dumping (commit)
  • ethtool: support for setting MDI/MDI-X state for twisted pair wiring (commit)
  • ppp: add 64-bit stats (commit)
  • Add generic netlink support for tcp_metrics (commit)


[참고]
1. 리눅스 커널 3.7 릴리즈
http://kernelnewbies.org/Linux_3.7

2012년 12월 12일 수요일

vi 에서 ^M 문자열 지우기와 유닉스 포맷으로 변경

윈도우에서 만들어진 데이터를 가져와 *NIX 시스템에서 사용하다 보면 윈도우 캐리지 리턴 값이 들어가 있는 경우가 있다. 해당 파일을 열어 보면,

blablabla^M
blabla^M

와 같이 끝에 ^M 에 붙어 있는 것이다. 쉽게 사용할 수 있는 방법은 vi 에디터에서

:%s/^M//g

로 다 제거해 버리면 된다. 여기서 주의할 점은 ^M 이 그냥 입력하면 안되고 Ctrl + v + m 으로 입력해 주어야 한다.

이외 텍스트파일을 검색해서 사용하려고 하는데, 이상하게도 해당 데이터가 들어있는데도 불구하고 검색이 되지 않는 것이었다. vi 로 열어보니 아래와 같이 나온다.

" test-dataset.txt" [dos] 999715L, 16340756C

[dos] 라고 표시가 되고 있다. 이럴때는

:set ff=unix

로 설정하고 w 로 저장해 주면 된다.

윈도우와 *NIX 시스템 사이에 데이터를 주고 받는 과정에서 쉽게 발생될 수 있는 일이므로 알아두자.

2012년 12월 7일 금요일

IP 주소 (ARP Conflict) 충돌에 대한 이야기

네트워크 안에서 한번쯤 IP 충돌을 경험해 본 사람이 있을것이다. 많은 경우는 같은 IP 를 서로 설정해서 사용한 경우이다.

그런데 특정 시스템 접속시 연결이 잘 되다가도 가끔 연결이 안되는 이상한 현상이 발생하였다. 그렇다고 인터페이스에 같은 IP 설정은 더더욱 아니었다. 맥 인증 장비에서 IP 충돌이 난다는 이슈를 접하고 해당 네트워크 대역에 대해서 ARP 스캐닝을 해 보았다.

ARP 스캐닝에는 arp-scan 을 이용하였으며,

# apt-get install arp-scan

으로 쉽게 설치가 가능하다.

이더넷 인터페이스를 지정하기 위하여 -I 를 사용하였고 특정 대역을 넣어주었다. -l 옵션을 사용하면 인터페이스에 설정된 로컬 네트워크 주소를 사용한다. 만약 서브넷이 255.255.0.0 이었다면 B 클래스 대상으로 스캐닝이 될 것이다.

# arp-scan -I eth0 192.168.11.0/24
ioctl: Cannot assign requested address
WARNING: Could not obtain IP address for interface eth0. Using 0.0.0.0 for
the source address, which is probably not what you want.
Either configure eth0 with an IP address, or manually specify the address
with the --arpspa option.
Interface: eth0, datalink type: EN10MB (Ethernet)
Starting arp-scan 1.6 with 256 hosts (http://www.nta-monitor.com/tools/arp-scan/)
192.168.11.39   00:14:22:xx:xx:xx   Dell Inc.
192.168.11.52   00:14:22:xx:xx:xx   Dell Inc.
192.168.11.91   00:04:75:xx:xx:xx  3 Com Corporation
192.168.11.110  00:25:64:xx:xx:xx   (Unknown)
192.168.11.94   08:00:20:xx:xx:xx  SUN MICROSYSTEMS INC.
192.168.11.125  00:1e:c9:xx:xx:xx   (Unknown)
192.168.11.207  00:22:19:xx:xx:xx (Unknown)
192.168.11.208  xx:xx:xx:fa:a8:0d   (Unknown)
192.168.11.209  d4:be:d9:xx:xx:xx   (Unknown)
192.168.11.210  xx:xx:xx:fa:a8:0d   (Unknown)
192.168.11.210 xx:xx:xx:fa:10:1c   (Unknown) (DUP: 2)
192.168.11.214  78:2b:cb:xx:xx:xx (Unknown)
192.168.11.215  78:2b:cb:xx:xx:xx  (Unknown)
[삭제 - 일부는 xx:xx:xx 처리 ]

38 packets received by filter, 0 packets dropped by kernel
Ending arp-scan 1.6: 256 hosts scanned in 1.334 seconds (191.90 hosts/sec).  38 responded

결과와 같이 192.168.11.210 이 2개의 맥 주소를 가지고 있는 것으로 나타난다. fa:a8:0d 와 fa:10:1c 이다. 192.168.11.208 번에 할당된 맥 주소는 fa:a8:0d 이다. 즉, 210 번 IP 에 fa:a8:0d 를 가져서는 안되는 것이다. 이러니 어떤 경우에는 접속이 되다가도 갑자기 끊어져서 접속이 안된다든지의 상황이 발생하는 것이다.

192.168.11.208 ,210 인터페이스를 살펴보았으나 IP 중복 설정은 보이지 않는다. 그럼 도대체 어디서 이게 나타나는 것인가? 일단 208 번이 의심된다. 208 번에서 해당 맥을 가지고 있는 것으로 추정되고 시스템 전체에서 해당 IP 설정이 없는지 찾아보기로 하였다.

# find / -exec grep "11.210" {} \;

11.210 번 문자열을 grep 으로 찾아보았는데, 하나 나타나는 것이 있다. keepalived 설정 파일이었다. 이때 바로 생각이 나는 것이었다. 해당 장비를 사용하기전 로드발랜싱 테스트를 위하여 잠깐 설정을 한적이 있었고, 잊고 있었던 것이다.

/etc/keepalived/keepalived.conf

해당 파일을 살펴보니 역시나 192.168.11.210 IP 가 설정되어 있었다.

해당 데몬을 disable 하고서는 다시 정상으로 돌아왔다. 역시나, 분명 어딘가에는 문제점이 존재한다는 사실!

IP 충돌(ARP Conflict)의 많은 경우는 직접 IP 를 동일하게 설정하거나 또는 필자가 경험했던 것과 같이 관련 소프트에어의 설정에 의한 것 그리고 ARP 테이블에서 지워지지 않고 잘못된 맥 정보를 가지고 있거나 중간 단계의 장비에 의한 문제정도로 생각된다.

/Rigel

[참고]
1. IPv4 Address Conflict Detection
http://tools.ietf.org/html/rfc5227

2012년 12월 5일 수요일

프로세스별 네트워크 활동 추적은 어떻게?

tcpdump, wireshark 도구를 이용해 쉽게 네트워크 트래픽 상태를 감시할 수 있다. 그런데, 어떤 프로세스가 해당 트래픽과 연관되어 있는지 알고자 하는 경우에는 어떻게 해야 하는가 ? 윈도우 사용자라면 ProcessExplorer 로 간단하게 연결 형태 정도를 확인할 수 있고, MS 사의 네트워크 분석기를 이용하면 쉽게 프로세스별 트래픽을 모니터링 할 수 있다.

[참고]

마이크로소프트 네트워크 모니터의 프로세스별 통신 상태
MS사의 새로운 네트워크 분석기, Message Analyzer


리눅스 환경에서는 어떻게 살펴볼까? MS 네트워크 분석기만큼 편리한 것은 없어 보인다. 일단 lsof 로 간단하게 네트워크 연결 상태를 확인해 볼 수 있다.

# lsof -i
로 네트워크 상황을 볼 수 있고 -i :80 , -i @packetinside.com 과 같이 포트 번호 또는 호스트로도 제한할 수 있다. 비슷한 기능의 명령어로는

# netstat -a -p

정도가 될 것같다. 이외 lsof 로 해당 네트워크 프로그램의 오픈된 파일 정보등도 더 살펴볼 수 있다.

$ ping www.packetinside.com
PING ghs.l.google.com (74.125.128.121) 56(84) bytes of data.
64 bytes from hg-in-f121.1e100.net (74.125.128.121): icmp_req=1 ttl=43 time=173 ms
64 bytes from hg-in-f121.1e100.net (74.125.128.121): icmp_req=2 ttl=43 time=183 ms

# ps -ef | grep ping
test   8976  8842  0 08:10 pts/8    00:00:00 ping www.packetinside.com
root      8991  8764  0 08:13 pts/7    00:00:00 grep --color=auto ping

root@banana:~# lsof -p 8976
lsof: WARNING: can't stat() fuse.gvfs-fuse-daemon file system /home/test/.gvfs
      Output information may be incomplete.
COMMAND  PID    USER   FD   TYPE DEVICE SIZE/OFF     NODE NAME
ping    8976 test  cwd    DIR    8,6     4096 16777218 /home/test
ping    8976 test  rtd    DIR    8,6     4096        2 /
ping    8976 test  txt    REG    8,6    35712 16515194 /bin/ping
ping    8976 test  mem    REG    8,6   101192  6816351 /lib/x86_64-linux-gnu/libresolv-2.13.so
ping    8976 test  mem    REG    8,6    27032  6816344 /lib/x86_64-linux-gnu/libnss_dns-2.13.so  
ping    8976 test  mem    REG    8,6    10368  6815809 /lib/libnss_mdns4_minimal.so.2
ping    8976 test  mem    REG    8,6    51736  6816363 /lib/x86_64-linux-gnu/libnss_files-2.13.so
ping    8976 test  mem    REG    8,6  1694008  6816367 /lib/x86_64-linux-gnu/libc-2.13.so
ping    8976 test  mem    REG    8,6   141088  6816365 /lib/x86_64-linux-gnu/ld-2.13.so
ping    8976 test    0u   CHR  136,8      0t0       11 /dev/pts/8
ping    8976 test    1u   CHR  136,8      0t0       11 /dev/pts/8
ping    8976 test    2u   CHR  136,8      0t0       11 /dev/pts/8
ping    8976 test    3u   raw             0t0   243673 00000000:0001->00000000:0000 st=07
root@banana:~#

ping 을 하는 프로세스를 찾고 lsof -p 옵션으로 pid 값을 주고 살펴보면 추가 정보를 얻을 수 있다.

또 strace 를 이용하면 해당 프로세스에서 네트워크 부분만을 확인할 수 도 있다. strace 는 시스템 콜 또는 시그널을 추적할 수 있는데 다음과 같은 몇 가지 옵션을 이용하면 쉽게 확인이 가능하다.

-p : 프로세스 PID 
-f : 현 프로세스가 fork 하는 자식프로세스까지 추적
-e : 지정한 시스템 콜만 추적 , 예를들면 trace=open,close,read,write 는 4개의 시스템 콜만 추적

# strace -p 9016  -f -e trace=network
Process 9016 attached - interrupt to quit
recvmsg(3, {msg_name(16)={sa_family=AF_INET, sin_port=htons(0), sin_addr=inet_addr("74.125.128.121")}, msg_iov(1)=[{"E\0\0T\337B\0\0+\1/4J}\200y\254\24\n(\0\0\10q#8\0&\332\204\276P"..., 192}], msg_controllen=32, {cmsg_len=32, cmsg_level=SOL_SOCKET, cmsg_type=0x1d /* SCM_??? */, ...}, msg_flags=0}, MSG_DONTWAIT) = 84
socket(PF_INET, SOCK_DGRAM|SOCK_NONBLOCK, IPPROTO_IP) = 4
connect(4, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("192.168.1.1")}, 16) = 0
sendto(4, "\277\263\1\0\0\1\0\0\0\0\0\0\003121\003128\003125\00274\7in-a"..., 45, MSG_NOSIGNAL, NULL, 0) = 45
recvfrom(4, "\277\263\201\200\0\1\0\1\0\4\0\4\003121\003128\003125\00274\7in-a"..., 1024, 0, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("192.168.1.1")}, [16]) = 225
sendmsg(3, {msg_name(16)={sa_family=AF_INET, sin_port=htons(0), sin_addr=inet_addr("74.125.128.121")}, msg_iov(1)=[{"\10\0wj#8\0'\333\204\276P\0\0\0\0\374\215\10\0\0\0\0\0\20\21\22\23\24\25\26\27"..., 64}], msg_controllen=0, msg_flags=0}, MSG_CONFIRM) = 64

위와 같이 ping 프로그램이 이용하는 네트워크 시스템 콜을 추적한다.

또는 수동적이지만 프로그램을 동작시키고 해당 소스 포트 또는 목적지 IP , 포트 정보등을 함께 이용하여 필터를 하여 트래픽을 덤프할 수도 있겠다. 이외 nethogs 라는 도구를 이용하면 프로세스별 트래픽양을 확인할 수 있다.

# apt-get install nethogs
# nethogs eth0

NetHogs version 0.7.0

  PID USER     PROGRAM                                 DEV        SENT      RECEIVED
2088  test  pidgin                                  eth0       0.087       1.150 KB/sec
2349  test  remmina                                 eth0       0.077       0.110 KB/sec
2308  test  /usr/lib/firefox/firefox                eth0       0.026       0.026 KB/sec
2986  test  ssh                                     eth0       0.000       0.000 KB/sec
5979  test  ssh                                     eth0       0.000       0.000 KB/sec
2145  test  /opt/google/chrome/chrome               eth0       0.000       0.000 KB/sec
1792  test  ../google/chrome/chrome --type=service  eth0       0.000       0.000 KB/sec
0     root     unknown TCP                                        0.000       0.000 KB/sec

  TOTAL                                                           0.190       1.286 KB/sec

리눅스 환경에서는 윈도우에 비해 프로세스별 감시가 다소 불편한 부분이 있다. 특히 MS 사의 네트워크 분석기는 프로세스별 트래픽 추적을 할 수 있어 해당 기능이 가장 유용한 부분이기도 하다.

추후 리눅스 환경에서 프로세스별 추적에 좀더 유용한 도구가 있다면 다시 소개하도록 하겠다. 그리고 윈도우 사용자는 MS 사의 네트워크 분석기를 이용하면 도움이 될 것이다.

2012년 11월 28일 수요일

Log2Timeline 을 이용한 타임라인 그래프 - 활용편

Log2Timeline 을 이용한 데이터 추출에 대해서 알아보았다. 이번에는 추출한 데이터로 직접 타임라인 그래프를 만들어보자.

우선, 저번 예제에서는 기본으로 CSV 로 추출되는 것을 소개했었고 추출된 CSV 를 이용해 엑셀 같은 곳에서 활용하면 된다. 하지만 이미 언급했듯이 추출된 데이터들을 효과적으로 사용하는데 있어서는 한계가 있다고 했다. 이번 타임라인 그래프도 제한된 화면에 단지 많은 내용이 나타나다 보니 실질적으로 분석가 입장에서는 부족함이 있다.

조금 더 낳은 방법을 추후에 소개하도록 하고, 오늘은 이렇게 사용될 수 있다는 부분을 알아두면 될것 같다. 타임라인 표현에 Simile-Widget 을 사용하였다.  이것을 사용한 이유는 log2timeline 에서 출력 형태로 simile 을 지원해 주기 때문이다.

Simile 위젯에 대한 세부 정보는 다음 사이트를 참고하길 바란다.


http://www.simile-widgets.org/timeline/

사용하기 위해서는 간단히 -o 로 출력 형태를 simile 로 지정해 주면 된다.

# log2timeline -f pcap -o simile -w example.xml timeline.pcap
-----------------------------------------------------------------
      [WARNING]
No timezone has been chosen so the local timezone of this
machine is chosen as the timezone of the suspect drive.

If this is incorrect, then cancel the tool and re-run it
using the -z TIMEZONE parameter to define the suspect drive
timezone settings (and possible time skew with the -s parameter)

(5 second delay has been added to allow you to read this message)
-----------------------------------------------------------------
Start processing file/dir [timeline.pcap] ...
Starting to parse using input modules(s): [pcap]
Local timezone is: Asia/Seoul (KST)
Local timezone is: Asia/Seoul (KST)
Loading output module: simile

example.xml 로 파일이 저장되었다. -z 로 타임존을 지정해 주지 않아서 경고메시지가 나타나고 로컬 컴퓨터의 기본 타임존을 사용하였다. example.xml 파일을 한번 들여다 보자.



화면과 같이 XML 로 구성되어 있는 파일이다.  이벤트의 시간, 타이틀 정보등이 보인다. 이제 이 데이터를 이용해 타임라인을 만들어주기 위한 파일을 만들어야 한다.

다음과 같이 test.html 파일을 만들어 본다.



<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
 <html>
    <head>
        <meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
        <script>Timeline_urlPrefix = "http://static.simile.mit.edu/timeline/api-2.3.1/";;</script>
        <script src="http://static.simile.mit.edu/timeline/api-2.3.1/timeline-api.js?bundle=true" type="text/javascript"></script>
        <script>
        var tl;
        function onLoad() {
        var eventSource = new Timeline.DefaultEventSource();
        var bandInfos = [
        Timeline.createBandInfo({
             eventSource:    eventSource,
    date: "Nov 10 2012 00:00:00 GMT",
            width:          "80%",
            intervalUnit:   Timeline.DateTime.MINUTE,
            intervalPixels: 100
        }),
        Timeline.createBandInfo({
            overview:       true,
            eventSource:    eventSource,
    date: "Nov 10 2012 00:00:00 GMT",
            width:          "20%",
            intervalUnit:   Timeline.DateTime.HOUR,
            intervalPixels: 200
        })
        ];
        bandInfos[1].syncWith = 0;
        bandInfos[1].highlight = true;
        tl = Timeline.create(document.getElementById("my-timeline"), bandInfos);
        Timeline.loadXML("/example.xml", function(xml, url) { eventSource.loadXML(xml, url); });
        }

        var resizeTimerID = null;
        function onResize() {
            if (resizeTimerID == null) {
                resizeTimerID = window.setTimeout(function() {
                    resizeTimerID = null;
                    tl.layout();
                }, 500);
            }
        }
        </script>    
    </head>

    <body onload="onLoad();" onresize="onResize();">
        <div id="my-timeline" style="height: 300px; border: 1px solid #aaa"></div>
        <noscript>
        This page uses Javascript to show you a Timeline. Please enable Javascript in your browser to see the full page. Thank you.
        </noscript>
    </body>

 </html>



위 HTML 파일을 그대로 저장하고 색상을 지정해 표시한 부분만 변경하면 기본적으로 타임라인 그래프 생성하는데 큰 문제는 없다.  createBandInfo 에서 각 이벤트의 출력 시작 날짜를 지정해 준다. 타임라인 데이터의 표시할 시간 형태를 정의하게 되는데 MINUTE, HOUR, DAY, MONTH 와 같은 형태로 사용할 수 있다. 여러분들이 로드하는 패킷 데이터의 시간 분포 형태에 따라 적절히 선택해 주면 된다.

그리고 마지막으로 앞서 만든 XML 파일 명을 지정해 주면 끝이다. 브라우저를 통해 해당 HTML 파일을 로드하면 다음과 같은 화면을 볼 수 있다.


여기서 사용한 패킷 데이터가 특정 시간에 크게 패킷이 모여있다 보니 표현하는데 다소 한계가 있다.

그런데 여기서 잠깐! 위와 같이 화면이 나타나지 않는 분이 있을 것이다. 필자도 처음에 안나와서 왜 그럴까 봤더니 타임존 문제였다. XML 데이터에서 Asia/Seoul 을 GMT 로 변경해 주니 잘 나타났다.

다음번에 시간이 더 허락된다면 Simile 에서 좀더 효과적인 패킷 타임라인을 고민해 보고자 한다. 일단 다음을 기약하며 오늘은 여기까지 ~ :-)

/Rigel

2012년 11월 26일 월요일

Log2Timeline 을 이용한 타임라인 데이터 추출 - 기본편

Log2Timeline 은 데이터에서 타임라인을 만들어 볼 수 있도록 데이터를 생성해준다. 타임라인은 시간대로 나열해 주기 때문에 포렌식 분석하는데 있어서 중요하게 이용되는 부분이기도 하다. 여기에 PCAP 모듈도 있어 PCAP 데이터를 파싱하여 CSV 및 기타 여러 출력형태로 만들어준다. 하지만 Log2Timeline 의 PCAP 파싱 데이터는 그다지 만족스럽지는 못했다. 일단 앞으로 계속 개선될 것이고, 패킷 데이터를 타임라인 형태로 만들어 이용해 볼 수 있다는 개념 자체에 의미를 두자.

우선, 관련 사이트는 다음과 같으며 다운로드 받을 수 있다:

http://log2timeline.net/
https://code.google.com/p/log2timeline/

Log2Timeline 설치 및 기본 사용법 


설치는 어렵지 않다. 펄로 만들어져 있으므로 펄에 익숙한 분들에겐 어렵지 않다. 압축파일을 해제하고 다음과 같은 순서로 진행하면 된다.

# perl Makefile.PL
# make
# make install (as root user)

사용에 있어서 알아두어야 할 옵션으로 -f  와 -o 가 있다. -f 는 입력으로 지정할 데이터 포맷을 나타내고, -o 는 출력 형태를 지정한다. 지원하는 포맷 및 출력형태는 각 옵션 뒤에 list 라고 사용하면 된다.

즉, 입력 데이터 포맷 데이터를 보고 싶은 경우는 -f list 를 사용하면 된다. 상당히 많은 포맷 형태를 지원하고 있다. PCAP 데이터는 제일 하단에 보인다. PCAP 외 다양한 것을 지원하니 포렌식에 이용할때 참고하길 바란다.


마찬가지로 출력 형태도 -o list 로 사용하면 된다.


기본적으로 CSV 로 출력이 된다. -z 는 타임존을 지정하는 것이며, 기본 사용은 아래와 같다:


# log2timeline -f pcap  output.pcap -z Asia/Seoul

우선 출력결과를 한번 살펴보자

# log2timeline -f pcap output.pcap

Start processing file/dir [output.pcap] ...
Starting to parse using input modules(s): [pcap]
Local timezone is: Asia/Seoul (KST)
Local timezone is: Asia/Seoul (KST)
Loading output module: csv
date,time,timezone,MACB,source,sourcetype,type,user,host,short,desc,version,file
name,inode,notes,format,extra
04/02/2012,09:39:09,KST,MACB,NEt,PCAP file,Time Written,-,192.168.10.27,TCP pack
et flags [0x18: PUSH ACK ] 192.168.10.27:3389 -> 192.168.10.40:58274 seq [137323
8656],TCP packet flags [0x18: PUSH ACK ] 192.168.10.27:3389 -> 192.168.10.40:582
74 seq [1373238656],2,output.pcap,16778486,-,Log2t::input::pcap,src-ip: 192.168.
10.27 dst-ip:
04/02/2012,09:39:09,KST,MACB,NEt,PCAP file,Time Written,-,192.168.10.40,TCP pack
et flags [0x10: ACK ] 192.168.10.40:58274 -> 192.168.10.27:3389 seq [3832965561]
,TCP packet flags [0x10: ACK ] 192.168.10.40:58274 -> 192.168.10.27:3389 seq [38
32965561],2,output.pcap,16778486,-,Log2t::input::pcap,src-ip: 192.168.10.40 dst-
ip:


-w 로 저장할 파일을 지정하지 않아 화면으로 출력이 되었는데, 패킷 데이터를 파싱하여 CSV 로 만들어 준다. 아쉬운 것은 많은 필드가 따로 구분이 되지 않고 크게 몇개 정도로만 나뉘어져 있어서 패킷 데이터를 분석하기에는 한계가 있고 전체적인 흐름을 살펴보는 정도로만 보아야 할 것이다.

블로그에서 이와 비슷한 형태로 여러개를 다룬적이 있으니 "그래프" 로 검색하면 다양한 글을 추가로 확인할 수 있고, CSV 를 이용하면 다음 글도 도움이 될 것이다.

와이어샤크(WireShark)의 그래프 기능 활용하기 - 고급편



SQLite 로 저장하여 SQL 쿼리로 조회해 보기 


출력을 CSV 가 아닌 SQLite 로도 저장할 수 있다. 파일 형태의 DB 로 기본적인 SQL 쿼리문을 사용할 수 있다. 어떤 면에서는 쿼리를 이용하면 유용한 데이터 추출도 가능한 부분이 있다.

사용하기 전에 SQLite 모듈이 설치되어 있어야 하는데, 펄에서 아래와 같이 설치할 수 있다.

$ sudo perl -MCPAN -e shell
cpan> install DBI
cpan> install DBD::SQLite

그런데, 필자의 경우 실행시에 다음과 같은 에러가 발생하였다.

[LOG2T] This file is dealt with on line-by-line basis (traditional LOG file parsing), meaning one timestamp object per line
[Log2Timeline] Error occured while parsing output.pcap - The processing has died and therefore it will not be further processed.
However the tool will continue running, trying to parse the next file.
The error that got displayed by the tool is:
Can't call method "execute" on an undefined value at /usr/local/share/perl/5.12.4/Log2t/output/sqlite.pm line 437.

일단 급하게 살펴보니 extra 로 정의된 데이터를 입력하는 것인데, DB 레코드를 살펴보니 PCAP 입장에서는 크게 중요하지 않은것 같아 주석처리를 하였다. ^^;;

# vi /usr/local/share/perl/5.12.4/Log2t/output/sqlite.pm

437 라인의 부분을 임시로 주석처리하여 실행가능

           # execute it
            $self->{'insert_extra'}->execute(
                $sid,

                #$self->{'db'}->quote( $i ),
                #$self->{'db'}->quote( $t_line->{'extra'}->{$i} )
                $i,
                $t_line->{'extra'}->{$i}
                         );

일단 이렇게 하면 정상적으로 실행은 가능하다. -o 로 sqlite 출력 형태를 지정하고 결과를 살펴보자.

# log2timeline -f pcap -o sqlite -w t.sql output.pcap -v -z Asia/Seoul
[LOG2TIMELINE] Testing time zone Asia/Seoul
Start processing file/dir [output.pcap] ...
Starting to parse using input modules(s): [pcap]
[LOG2T] Testing the existence of /usr/local/share/perl/5.12.4/Log2t/output/sqlite.pm
[LOG2T] Setting host timezone (Asia/Seoul)
[LOG2TIMELINE] Testing host time zone Asia/Seoul
[LOG2T] Setting output timezone (Asia/Seoul)
[LOG2TIMELINE] Testing output time zone Asia/Seoul
[LOG2T] Using output: sqlite
Loading output module: sqlite
[LOG2T] Loading input modules (pcap)
[DEBUG] Adding the module pcap.
[LOG2T] Loading module Log2t::input::pcap
[LOG2t] Parsing a single file.
[LOG2T] Starting to parse file output.pcap
[LOG2T] This file is dealt with on line-by-line basis (traditional LOG file parsing), meaning one timestamp object per line
[LOG2T] Parsing of file is completed
DBI::db=HASH(0x23b69f0)->disconnect invalidates 3 active statement handles (either destroy statement handles or call finish on them before disconnecting) at /usr/local/share/perl/5.12.4/Log2t/output/sqlite.pm line 293.
[LOG2T] Done.

t.sql 로 파일이 저장되었는데, 해당 SQLite 를 살펴보기전에 output.cap 의 기본 데이터를 살펴보자.

# capinfos output.pcap
File name:           output.pcap
File type:           Wireshark/tcpdump/... - libpcap
File encapsulation:  Ethernet
Packet size limit:   file hdr: 65535 bytes
Number of packets:   21221
File size:           14749276 bytes
Data size:           14409716 bytes
Capture duration:    430 seconds
Start time:          Mon Apr  2 09:39:09 2012
End time:            Mon Apr  2 09:46:19 2012
Data byte rate:      33531.74 bytes/sec
Data bit rate:       268253.91 bits/sec
Average packet size: 679.03 bytes
Average packet rate: 49.38 packets/sec
Strict time order:   True

총 패킷 건수가 21,221 건이다.  저장한 SQLite 파일을 열어보기 위해서는 SQLite 가 설치되어 있어야 하는데, 패키지 설치 프로그램을 이용하면 쉽게 설치가 가능하다.

데이안 / 우분투의 경우라면

# apt-get install sqlite3 로 하면 된다. SQLite 는 윈도우에서도 사용가능하다. 그러므로 만들어진 t.sql 은 윈도우에서도 당연이 접근 가능하다.

접근할 데이터 파일을 지정하고 실행하면 바로 확인이 가능하다.

# sqlite3  t.sql
SQLite version 3.7.7 2011-06-23 19:49:22
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> .tables
extra     host      records   super     tagged
filename  info      source    tag  

.tables 로 해당 DB 에 존재하는 테이블 정보를 확인할 수 있다.

sqlite> select count(*) from records;
21221

레코드 정보를 카운트 해보니 21,221 건이 맞다. 패킷파일 데이터를 제대로 다 파싱한 모양이다.

sqlite> .schema records
CREATE TABLE records (
  rid INTEGER PRIMARY KEY AUTOINCREMENT,
  short TEXT,
  detailed TEXT,
  srcid INTEGER,
  legacy INT,
  inode INTEGER,
  description TEXT,
  time INTEGER,
  user TEXT,
  fid INTEGER,
  sid INTEGER,
  hid INTEGER,
  hidden INT DEFAULT 0 );
CREATE INDEX record_time ON records(time);
CREATE INDEX user_name ON records(user);

.schema 로 레코드 필드를 확인해 보니 위와 같다.

sqlite> select * from records limit 1;
1|TCP packet flags [0x18: PUSH ACK ] 192.168.10.27:3389 -> 192.168.10.40:58274 seq [1373238656]|TCP packet flags [0x18: PUSH ACK ] 192.168.10.27:3389 -> 192.168.10.40:58274 seq [1373238656]|1|15|0|Time Written|1333327149||1|0|1|0

레코드 테이블에서 데이터 1건만 출력을 해 보았다. CSV 로 저장했던것과 비슷한 형태로 데이터가 저장되어 있다.

sqlite> select count(*) from records where short like '%192.168.10.27%';
971

192.168.10.27 로 short 필드에서 Like 검색을 해 보았고, 카운트를 확인해 보니 971 건 이었다. 데이터가 세부적으로 나뉘어져 있지 않고 크게 들어가 있다 보니 일단 Like 검색을 해야만 했다.

sqlite> select distinct hostname from host;
0.0.0.0
XX.226.51.63
XX.45.215.14
XX.45.215.149
XX.45.215.207
XX.45.215.55
XX.45.229.150
XX.45.229.71
XX.9.164.197

이번에는 호스트 테이블에서 hostname 필드에 대해 distinct 했다. 즉, Unique 한 IP 목록만을 출력하도록 한 것이다.

sqlite> select count(distinct hostname) from host;
130

출력 데이터가 많아서 count 를 이용해 해당 패킷 파일에서 Unique 한 IP 건수는 몇개인지 확인해 본 것이다.

SQL 에 익숙한 사용자라면 보다 다양한 형태로 데이터를 조회해볼 수가 있다. DB 화 되어 있으면 나름 유용한 부분이 분명 있지만, 데이터가 세부적으로 나뉘어 저장되어 있지 않아 가치가 반감된게 아쉬운 부분이다. 추후, DB 저장으로 좀더 뛰어난 도구를 찾아보고 다시 한번 소개해 보고 싶다.

지금까지 Log2Timeline 에 대해서 소개해 보았는데, PCAP 데이터 분석으로는 다소 한계가 있다. 오히려 와이어샤크 같은 곳에서 필드를 구분해 저장하는 것이 더 낳아보이기까지 하다.
그래도 알아두면 다른 로그파일 분석에서도 유용할 것이다.

다음번에는 Log2Timeline 을 이용해 타임라인 그래프를 만들어 보는 것을 소개해 보고자 한다. 이렇게 데이터만 뽑고서 끝낼 수는 없지 않은가?  :-)

/Rigel

2012년 11월 23일 금요일

NMAP 의 친구 NPING 으로 패킷생성을 자유롭게

스캐너로 유명한 NMAP 의 친구 Nping 을 소개한다. Nping 은 네트워크 패킷 생성 도구이자, 그 응답의 시간측정, 분석 기능을 제공한다. Nping 은 다양한 프로토콜을 지원하고 각 프로토콜의 헤더를 조정할 수 있다. Ping 과 같이 어렵지 않게 사용할 수 있다. 네트워크 성능 측정에도 이용될 수 있는데, ARP Poisong, DoS 공격 등과 같은 트래픽 생성도 가능하다. Nping 은 2009년 구글 Summer of Code 로 부터 처음 시작되었다고 한다.

주요기능은,
- TCP, UDP, ICMP, ARP 패킷 생성
- 여러개의 호스트 및 포트 지정 가능
- Non 루트 유저를 위한 모드 제공
- 고급사용을 위한 에코모드
- 이더넷 프레임 생성 지원
- IPv6 지원
- 리눅스, 맥, 윈도우 에서 동작
- 자유롭게 커스트마이징이 가능한 점

다운로드는 Nmap 페이지에서 받을 수 있으며, 링크 경로는 다음과 같다:

http://nmap.org/download.html


Nping 도움말을 보면 누구나 쉽게 사용할 수 있을만큼 어렵지 않다. 다양한 옵션이 존재하고 몇 가지 사용 예제를 살펴보자.


1. ICMP 타입이 time 인 트래픽 전송 

--icmp-type 으로 옵션을 정할 수 있고 --delay 라는 것을 사용해 약간의 지연을 사용하였다.

# nping --icmp --icmp-type time --delay 500ms 192.168.163.131

Starting Nping 0.6.01 ( http://nmap.org/nping ) at 2012-11-12 08:13 KST
SENT (0.0476s) ICMP 192.168.163.1 > 192.168.163.131 Timestamp request (type=13/code=0) ttl=64 id=29186 iplen=40
RCVD (0.0545s) ICMP 192.168.163.131 > 192.168.163.1 Timestamp reply (type=14/code=0) ttl=128 id=6091 iplen=40
SENT (0.5477s) ICMP 192.168.163.1 > 192.168.163.131 Timestamp request (type=13/code=0) ttl=64 id=29186 iplen=40
RCVD (0.5503s) ICMP 192.168.163.131 > 192.168.163.1 Timestamp reply (type=14/code=0) ttl=128 id=6092 iplen=40
SENT (1.0479s) ICMP 192.168.163.1 > 192.168.163.131 Timestamp request (type=13/code=0) ttl=64 id=29186 iplen=40
RCVD (1.0504s) ICMP 192.168.163.131 > 192.168.163.1 Timestamp reply (type=14/code=0) ttl=128 id=6093 iplen=40
SENT (1.5490s) ICMP 192.168.163.1 > 192.168.163.131 Timestamp request (type=13/code=0) ttl=64 id=29186 iplen=40
RCVD (1.5494s) ICMP 192.168.163.131 > 192.168.163.1 Timestamp reply (type=14/code=0) ttl=128 id=6094 iplen=40
SENT (2.0491s) ICMP 192.168.163.1 > 192.168.163.131 Timestamp request (type=13/code=0) ttl=64 id=29186 iplen=40
RCVD (2.0503s) ICMP 192.168.163.131 > 192.168.163.1 Timestamp reply (type=14/code=0) ttl=128 id=6095 iplen=40

Max rtt: 6.901ms | Min rtt: 0.326ms | Avg rtt: 2.694ms
Raw packets sent: 5 (200B) | Rcvd: 5 (200B) | Lost: 0 (0.00%)
Tx time: 2.00268s | Tx bytes/s: 99.87 | Tx pkts/s: 2.50
Rx time: 3.00379s | Rx bytes/s: 66.58 | Rx pkts/s: 1.66
Nping done: 1 IP address pinged in 3.12 seconds

2. 포트 8001 번에 TCP 데이터를 포함해 한번 전송하기 


# nping --tcp --data "0xAAAAAAAA" -p 8001 -c 1 192.168.163.131

HEX 문자열을 이용하는 경우는 --data  를 사용하고 문자열을 나열하는 경우는 --data-string 을 이용한다.

# nping --tcp --data-string "PacketInside.com" -p 8001 -c 1 -v4 192.168.163.131

Starting Nping 0.6.01 ( http://nmap.org/nping ) at 2012-11-12 08:27 KST
SENT (0.0549s) TCP [192.168.163.1:32834 > 192.168.163.131:8001 S seq=3357278597 ack=0 off=5 res=0 win=1480 csum=0xA0C0 urp=0] IP [ver=4 ihl=5 tos=0x00 iplen=56 id=3146 foff=0 ttl=64 proto=6 csum=0xa6a0]
0000   45 00 00 38 0c 4a 00 00  40 06 a6 a0 c0 a8 a3 01  E..8.J..@.......
0010   c0 a8 a3 83 80 42 1f 41  c8 1c 01 85 00 00 00 00  .....B.A........
0020   50 02 05 c8 a0 c0 00 00  50 61 63 6b 65 74 49 6e  P.......PacketIn
0030   73 69 64 65 2e 63 6f 6d                           side.com    

만약 data 크기를 지정하는 경우 --data-length 옵션도 같이 사용한다.

3. 목적지 호스트 포트 80, 443 에 TCP 패킷 전송

# nping -c 1 --tcp -p 80,433 packetinside.com

Starting Nping 0.6.01 ( http://nmap.org/nping ) at 2012-11-12 08:35 KST
SENT (0.1624s) TCP 192.168.10.40:18421 > 216.239.34.21:80 S ttl=64 id=37098 iplen=40  seq=3387806461 win=1480
SENT (1.1626s) TCP 192.168.10.40:18421 > 216.239.34.21:433 S ttl=64 id=37098 iplen=40  seq=3387806461 win=1480

Max rtt: N/A | Min rtt: N/A | Avg rtt: N/A
Raw packets sent: 2 (80B) | Rcvd: 0 (0B) | Lost: 2 (100.00%)
Tx time: 1.00146s | Tx bytes/s: 79.88 | Tx pkts/s: 2.00
Rx time: 2.00254s | Rx bytes/s: 0.00 | Rx pkts/s: 0.00
Nping done: 1 IP address pinged in 2.20 seconds


4. 포트 범위를 지정하여 TCP 패킷 전송 

# nping 192.168.163.135 -c 1 --tcp -p 133-135

Starting Nping 0.6.01 ( http://nmap.org/nping ) at 2012-11-23 08:06 KST
SENT (0.0915s) TCP 192.168.163.1:19166 > 192.168.163.135:133 S ttl=64 id=20239 iplen=40  seq=1059400174 win=1480 
RCVD (0.0919s) TCP 192.168.163.135:133 > 192.168.163.1:19166 RA ttl=128 id=4388 iplen=40  seq=0 win=0 
SENT (1.0921s) TCP 192.168.163.1:19166 > 192.168.163.135:134 S ttl=64 id=20239 iplen=40  seq=1059400174 win=1480 
RCVD (1.0925s) TCP 192.168.163.135:134 > 192.168.163.1:19166 RA ttl=128 id=4390 iplen=40  seq=0 win=0 
SENT (2.0937s) TCP 192.168.163.1:19166 > 192.168.163.135:135 S ttl=64 id=20239 iplen=40  seq=1059400174 win=1480 
RCVD (2.0942s) TCP 192.168.163.135:135 > 192.168.163.1:19166 SA ttl=128 id=4391 iplen=44  seq=705789072 win=8192 <mss 1460>

5. TCP 패킷 생성시 좀더 다양하게 옵션 조절하기 


출발지 IP 는 -S 로 지정하고 ID 값을 9999 그리고 TTL 은 225 로 설정하였다. --badump-ip 를 사용해 의도적으로 잘못된 체크섬 값을 사용하게 했다. 거기다 MTU 도 점보 프레임 크기인 9000 을 사용했다.

# nping -S 1.1.1.1 --id 9999 -ttl 225 --badsum-ip --mtu 9000 --tcp -p 135 192.168.163.133

No.     Time           Source                Destination           Protocol Length Info
   1027 1817.197206000 1.1.1.1               192.168.163.133       TCP      60     24613 > epmap [SYN] Seq=0 Win=1480 Len=0

세부적인 데이터를 tshark 를 통해 다음과 같이 살펴보자. 의도한 대로 데이터가 잘 만들어져 전송되었는지 말이다.

Frame 1027: 60 bytes on wire (480 bits), 60 bytes captured (480 bits) on interface 0
Internet Protocol Version 4, Src: 1.1.1.1 (1.1.1.1), Dst: 192.168.163.133 (192.168.163.133)
    Version: 4
    Header length: 20 bytes
    Differentiated Services Field: 0x00 (DSCP 0x00: Default; ECN: 0x00: Not-ECT (Not ECN-Capable Transport))
        0000 00.. = Differentiated Services Codepoint: Default (0x00)
        .... ..00 = Explicit Congestion Notification: Not-ECT (Not ECN-Capable Transport) (0x00)
    Total Length: 40
    Identification: 0x270f (9999)
    Flags: 0x00
        0... .... = Reserved bit: Not set
        .0.. .... = Don't fragment: Not set
        ..0. .... = More fragments: Not set
    Fragment offset: 0
    Time to live: 225
    Protocol: TCP (6)
    Header checksum: 0x4c91 [correct]
    Source: 1.1.1.1 (1.1.1.1)
    Destination: 192.168.163.133 (192.168.163.133)
Transmission Control Protocol, Src Port: 24613 (24613), Dst Port: epmap (135), Seq: 0, Len: 0
    Source port: 24613 (24613)
    Destination port: epmap (135)
    [Stream index: 57]
    Sequence number: 0    (relative sequence number)
    Header length: 20 bytes
    Flags: 0x002 (SYN)
        000. .... .... = Reserved: Not set
        ...0 .... .... = Nonce: Not set
        .... 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
        .... .... ..1. = Syn: Set
            [Expert Info (Chat/Sequence): Connection establish request (SYN): server port epmap]
                [Message: Connection establish request (SYN): server port epmap]
                [Severity level: Chat]
                [Group: Sequence]
        .... .... ...0 = Fin: Not set
    Window size value: 1480
    [Calculated window size: 1480]
    Checksum: 0x8604 [validation disabled]

0000  00 0c 29 8b 6f f8 00 50 56 c0 00 08 08 00 45 00   ..).o..PV.....E.
0010  00 28 27 0f 00 00 e1 06 4c 91 01 01 01 01 c0 a8   .('.....L.......
0020  a3 85 60 25 00 87 20 7c 3c be 00 00 00 00 50 02   ..`%.. |<.....P.
0030  05 c8 86 04 00 00 00 00 00 00 00 00               ............

6. ARP 패킷 전송 


# nping 192.168.163.135 -c 2 --arp

Starting Nping 0.6.01 ( http://nmap.org/nping ) at 2012-11-23 08:13 KST
SENT (0.0630s) ARP who has 192.168.163.135? Tell 192.168.163.1
RCVD (0.0634s) ARP reply 192.168.163.135 is at 00:0C:29:8B:XX:XX
SENT (1.0636s) ARP who has 192.168.163.135? Tell 192.168.163.1
RCVD (1.0640s) ARP reply 192.168.163.135 is at 00:0C:29:8B:XX:XX

7. ECHO 클라이언트/서버

1) --echo-server 로 동작시킨다. passphrase 로 public 을 사용하였다.

# nping --echo-server "public" -vvv

Starting Nping 0.6.01 ( http://nmap.org/nping ) at 2012-11-23 08:16 KST
Packet capture will be performed using network interface eth0.
Waiting for connections...
Server bound to 0.0.0.0:9929
[1353626220] Connection received from 192.168.163.135:49275
[1353626220] Good packet specification received from client #0 (Specs=9,IP=4,Proto=6,Cnt=5)
[1353626220] NEP handshake with client #0 (192.168.163.135:49275) was performed successfully
[1353626225] Client #0 (192.168.163.135:49275) disconnected

2) 이후 클라이언트에서 --echo-client 로 TCP RST 패킷을 전달하였다. 위 에코서버 로그에서 접속상태를 확인할 수 있다.

C:\play>nping --echo-client "public" 192.168.163.1 --tcp --flags rst

Starting Nping 0.6.01 ( http://nmap.org/nping ) at 2012-11-23 08:16 대한민국 표
준시
SENT (0.6870s) TCP 192.168.163.135:50411 > 192.168.163.1:80 SR ttl=64 id=41968 i
plen=40  seq=133370060 win=1480
SENT (1.7030s) TCP 192.168.163.135:50411 > 192.168.163.1:80 SR ttl=64 id=41968 i
plen=40  seq=133370060 win=1480
SENT (2.7190s) TCP 192.168.163.135:50411 > 192.168.163.1:80 SR ttl=64 id=41968 i
plen=40  seq=133370060 win=1480
SENT (3.7340s) TCP 192.168.163.135:50411 > 192.168.163.1:80 SR ttl=64 id=41968 i
plen=40  seq=133370060 win=1480
SENT (4.7500s) TCP 192.168.163.135:50411 > 192.168.163.1:80 SR ttl=64 id=41968 i
plen=40  seq=133370060 win=1480

참고로 윈도우 사용자는 NMAP 을 설치하면 해당 프로그램 경로안에 NPING 을 찾을 수 있다.

2012년 11월 16일 금요일

Capstats 로 네트워크 인터페이스 통계 정보 수집하기

Capstats 는 Bro-IDS 에서 배포하는 작은 인터페이스 상태 정보 수집 도구이다. libpcap 을 이용한 것으로 네트워크 인터페이스에서 발생하는 트래픽 정보를 간단히 보여준다. 다운로드는 다음의 경로에서 할 수 있다.

http://www.bro-ids.org/downloads/release/capstats-0.18.tar.gz

컴파일을 하기 위해서는 cmake 가 설치되어 있어야 한다.  우분투 계열이면 apt-get 으로 쉽게 설치 가능하다.

# apt-get install cmake

그리고, 컴파일을 다음과정을 거치면 어려움 없이 쉽게 컴파일이 완료된다.

# ./configure
# make
# make install

사용방법 또한 아주 간단하다. 인터페이스를 지정하고 -I 로 얼마 주기로 정보를 출력할 것인지 시간만 정해주면 된다. -f 를 이용하면 BPF 스타일의 필터를 사용할 수 있고 -n 은 지정한 값 만큼만 출력해주고 중단한다. -w 를 사용하면 패킷을 파일로도 저장할 수 있어, 간단히 패킷 덤프용으로도 사용가능하다.

# capstats -i eth0 -I 1

1352159800.380532 pkts=14 kpps=0.0 kbytes=6 mbps=0.1 nic_pkts=2906 nic_drops=0 u=0 t=14 i=0 o=0 nonip=0
1352159801.380637 pkts=2 kpps=0.0 kbytes=0 mbps=0.0 nic_pkts=2908 nic_drops=0 u=0 t=2 i=0 o=0 nonip=0
1352159802.380823 pkts=10 kpps=0.0 kbytes=0 mbps=0.0 nic_pkts=2918 nic_drops=0 u=2 t=8 i=0 o=0 nonip=0
^C1352159803.374389 pkts=3 kpps=0.0 kbytes=0 mbps=0.0 nic_pkts=2921 nic_drops=0 u=0 t=2 i=0 o=0 nonip=1
1352159803.374402
=== Total

1352159803.374442 pkts=2921 kpps=0.0 kbytes=984 mbps=0.0 nic_pkts=2921 nic_drops=0 u=398 t=2299 i=0 o=14 nonip=210


위 예는 인터페이스 eth0 을 모니터링 하고 -I 로 1초마다 정보를 출력하도록 설정한 것이다. 라인별 각 필드 정보는 다음과 같다:

pkts: Interval 기간에 capstats 가 본 패킷 개수
kpps: 초당 패킷 개수
kbytes: 지정된 Interval 동안 발생한 KBytes
mbps: 초당 Mbits
nic_pkts: libcap 의 pcap_stats() 에 보고된 패킷 개수
nic_drops:libpcap 의  pcap_stats() 에 보고된 Drop 패킷 개수
u: UDP 패킷 개수
t: TCP 패킷 개수
i: ICMP 패킷 개수
nonip: non-IP 패킷 개수


간단하게 네트워크 인터페이스 상황을 모니터링할때 유용하다.

[참고]
1. Capstats 추가 정보

http://www.bro-ids.org/documentation/components/capstats/README.html

2012년 11월 9일 금요일

MS사의 새로운 네트워크 분석기, Message Analyzer

오늘은 마이크로소프트사의 새로운 네트워크 분석기 Message Analyzer 를 소개하고자 한다. 이미 블로그에서 MS 에서 만든 Network Monitor 3.x 를 소개한 적이 있다. 이 것의 연속선상으로 네트워크 트래픽이라는 것에만 초점을 두지 않고 메시지 분석이라는 영역으로 넓혀 만들어진 것이 Message Analyzer 이다.

2012년9월에 퍼블릭하게 베타로 공개되었는데, 이제서야 공유한다. 9월 베타로 공개되었을때 공유해야지 하고 생각만 하고 있다가 필자의 게으름으로 이제서야 이 글을 쓰고 있다.

주요한 기능으로는,
- 프로토콜 메시지에 대한 검증과 파싱 기능
- 다양한 시스템과 엔드포인트 레벨의 메시지 캡쳐
- 그리드 형태의 요약 출력
- 메시지의 그룹핑
- 다양한 타입 로그를 브라우징 할 수 있는 기능 (.cap, etl, .txt)
- 페이로드의 자동 리어셈블리
- 텍스트로그의 임포트를 통해 키/값 형태로 파싱
- "추적 시나리오" 형태 기능 제공

무엇보다 직접 사용해 보는것이 기능을 익히는데 가장 빠른 방법이다. 다운로드는 다음의 경로에서 가능하다.

https://connect.microsoft.com/site216

다운로드 받기 위해서는 connect 에 가입해야 한다. 왼쪽 메뉴에 보면 Download 를 선택하면 다운로드 받을 수 있는 파일 리스트들이 나타난다. Network Monitor 도 보인다. 하지만 이번에 우리가 설치할 파일은 Message Analyzer 이므로 해당 파일을 다운로드 받아 설치하면 된다. 참고로 "Message Analyzer Intro PPT" 도 받아 보면 이해하는데 더욱 도움이 될것 같다.

처음 설치하고 실행하면 다음과 같은 화면을 볼 수 있다. 몇 가지가 있는데 아래는 인터페이스를 선택하고 패킷캡쳐를 시작하도록 설정할 수 있다. 와이어샤크에서 패킷 캡쳐 전 인터페이스 선택하고 필터를 적용하는 화면하고 비슷한 역활이다.



다음은 패킷 캡쳐 메인화면이다. 상단의 메뉴는 아이콘이 크게 배치되어 있고 심플하다. 생각보다 메뉴는 많이 보이지 않는다. 중간쯤 패킷 하나를 세부적으로 보았고 거기서 스택을 선택하면 프로토콜 스택별로 나타난다. 그리고 이어지는 다른 패킷도 그룹핑되어 함께 보인다.
왼쪽 하단에는 각 필드의 길이와 타입, 비트 정보가 나열되어 있고 오른쪽 하단에는 HEX 값과 ASCII 값을 볼 수 있다. 다른 탭이 하단에 또 있는데 조합이 가능한 데이터는 직접 보여준다. 예를들어 사진 이미지 같은 정보는 바로 확인이 가능하다.

처음 사용시에는 다소 어렵게 느껴지기도 하였다. 와이어샤크에 익숙해져 있는 면이 있을수도 있겠지만, 정보형태가 개발자나 패킷을 좀더 세부적으로 분석하는 사용자들에게 어울릿듯한 느낌을 받았다.


눈에 띄는 기능으로는 좌측화면에서 오른쪽을 클릭하면 창을 하나 더 만들 수 있는데 아래 그림은 프로토콜 대쉬보드를 만든것이다. 프로토콜별 막대 그래프와 시간대별 사용량  그리고 원형 그래프 프로토콜 요약 정보도 보인다. 이거 하나는 깔끔해 보인다. 와이어샤크의 이쁘지 않은 그래프 정보에 비하면 이건 아주 깔끔해 보인다.


마지막으로 다른 창을 만들어 보았다. 시퀀스 하게 매치되는 뷰 형태로 보여주는 것으로, 앞서 설명한 기능중에 하나로 "추적 시나리오" 가 여기에 해당한다. 사전에 정의되어 있는 시나리오를 선택하여 동작시킨 것으로 연관된 정보가 나열된다.


지금은 주요 기능정도만 여러분들에게 설명을 드렸다. 아직 깊게 살펴보지 않아, 어떤 유용한 기능이 더 있는지는 살펴보아야 겠지만, 추적 시나리오 같은 기능은 유용하지 않을까 싶기도 한다.

사실 어떤 도구든 누가 사용하느냐에 따라 도구의 활용가치가 크게 달라진다. 나에겐 보잘것 없어 보이는 도구도 다른 누군가에는 아주 유용하기도 하다. 여러분이 사용하는 도구를 제대로 이해하고 활용하려면 살짝 드러나는 겉 기능만 이용할 것이 아니라 충분히 그 기능을 이해해야 하고 응용할 수 있어야 한다.

앞으로 Message Analyzer 의 발전을 기대해 본다.

/Rigel

[참고]
1. 마이크로소프트 네트워크 모니터의 프로세스별 통신 상태

2012년 11월 6일 화요일

안드로이드 폰에 리눅스(BackTrack5) 올리기

집에서 장난감 대용으로 사용하고 있는 소니에릭슨 X10 안드로이드 단말기에 리눅스를 올려보았다. 정확히 말하면 BackTrack5 를 올려 본 것이고 일단은 동작 한다. 설치는 어렵지 않게 진행할 수 있었다. 복잡한 방법으로 롬을 올리는 것이 아니라, 해당 이미지를 복사해 놓고   몇 가지 실행하는 것만으로 쉽게 된다. 그렇기 때문에 단말기에 있는 모든 파일도 그대로 유지할 수 있다. 루팅된 단말기를 가지고 있다면, 아래 참고에 적어놓은 주소를 통해서 어렵지 않게 해 볼 수 있을 것이다.

실행하면 옆 화면과 같이 BackTrack 실행화면이 나온다. 안드로이드 단말기에서 화면을 보니 나름 느낌이 다르다. 메뉴는 보는 것과 같이 여러가지 도구들이 보인다. 참고로, 이 BackTrack 이미지는 용량 이슈로 모든 것을 다 포함하고 있지는 않다.

일단 속도는 느렸다. 단말기가 오래되기도 하였고, 움직이면서 실행하는데 있어서는 끈기를 가지고 실행해야 한다 :-)

아래 화면은 패킷 스니핑을 해 본것이다. 패킷 블로그 답게 이 부분을 빼 먹어서는 안될것 같아 실행해 보았다. 블로그에서도 소개한 ettercap 을 이용한 것이다.


느려서 그렇지 일단은 실행이 된다. 단말기만 빠르다면 앞으로 이동하면서 패킷덤프를 손쉽게도 할 수 있을것이다. 자, 그럼 브라우징은 어떨까?  아래 화면과 같이 브라우징도 OK 다. 한글도 잘 표시되었고 패킷인사이드 페이지가 잘 나타난다.


이상 간략한 실행기였고 설치방법은 하단의 URL 을 참고하면 된다. 앞으로 재미있는 내용은 다시 한번 공유하도록 하겠다. :-)

[참고]
1. 소니에릭슨 X10 에서 BackTrack5 설치하기
http://forum.xda-developers.com/showthread.php?t=1074169

2012년 11월 4일 일요일

리눅스 패키지 포맷 다른 패키지 포맷으로 변환하기

이미지 출처: http://tenoch.scimexico.com

사용하고자 하는 프로그램이 특정 패키지로만 제공되는 경우 다른 패키지로 변환하여 설치가 가능한 방법이 있다. Alien 은 다른 리눅스 패키지 포맷 형태로 변환해 준다.

예를 들어, NMAP 의 경우 RPM 으로 패키지를 제공해 준다. 소스를 다운로드 받아 설치할 수도 있고, 기존 배포판을 이용하는 방법도 있을 수 있겠지만, 리눅스 배포판은 항상 최신의 버전을 제공하지는 못한다.
Alien 은 RPM, deb, slp, pkg, tgz 의 패키지 형식을 지원하며, 사용방법도 아주 간단하다.

데비안 계열이라면 우선 apt-get 를 이용해 쉽게 alien 을 설치할 수 있다.

#apt-get install alien

다운로드 받은 rpm 패키지를 deb 로 변경하는 경우 다음과 같이만 해 주면 된다. 옵션을 따로 지정하지 않은 이유는 deb 가 디폴트이기 때문이다.

#alien xxx.rpm

xxx.deb 가 만들어질 것이고 dpkg 를 통해 해당 패키지를 인스톨 해 주면 된다.

#dpkg -i xxx.deb

이제 패키지 포맷에 신경쓰지 말고 편하게 이용해 보자.

2012년 10월 30일 화요일

VMware 의 NAT 설정과 패킷캡쳐시 promiscuous 모드 설정

VMware 의 NAT 기능을 이용하면서 네트워크 설정에 문제를 겪는 분들이 있어 내용을 공유하고자 한다. NAT 설정을 있는 그대로 사용하면 크게 문제는 발생하지 않는데, 자체적으로 IP 를 설정하는 경우 네트워크 통신이 안되는 경우가 발생한다. 이런 경우는 가상 머신에 설정된 IP 대역과 호스트쪽 네트워크 인터페이스 내용이 일치 하지 않아 나타나는 경우가 많다. 즉, 가상머신 IP 는 바꾸었지만 호스트쪽은 이전에 설정된 내용 그대로 이용하면서 네트워크가 안되는 경우다.

리눅스 사용자라면 다음의 경로로 들어가 보자. 윈도우 사용자도 리눅스 경우와 크게 다르지 않다. (가상 머신에 설정된 IP 와 호스트에서 이용하는 NAT 어뎁터를 살펴보자)

# cd /etc/vmware

# ls -l
total 24
-rw-r--r-- 1 root root  226 2012-08-23 10:44 bootstrap
-rw-r--r-- 1 root root  526 2012-08-24 09:50 config
lrwxrwxrwx 1 root root   19 2012-08-23 10:44 icu -> /usr/lib/vmware/icu
lrwxrwxrwx 1 root root   56 2012-08-23 10:45 installer.sh -> /usr/lib/vmware-installer/2.0/vmware-uninstall-downgrade
-rw-r--r-- 1 root root   54 2012-08-23 10:45 locations
-rw-r--r-- 1 root root  462 2012-08-23 11:37 networking
drwxr-xr-x 3 root root 4096 2012-08-23 10:44 vmnet1
drwxr-xr-x 4 root root 4096 2012-08-23 10:44 vmnet8

vmnet8 이 보일 것이고 바로 기본 설정되는 이 vmnet8 이 NAT 로 이용되는 인터페이스 이다.
# cd vmnet8 
# ls -l
total 12
drwxr-xr-x 2 root root 4096 2012-08-24 11:00 dhcpd
drwxr-xr-x 2 root root 4096 2012-08-23 11:39 nat
-rw-r--r-- 1 root root   18 2012-08-24 11:10 nat.mac

nat 설정파일을 한번 들여다 보자.


# more nat

# VMware NAT configuration file

[host]

# NAT gateway address
ip = 192.168.70.1
netmask = 255.255.255.0

# VMnet device if not specified on command line
device = /dev/vmnet8

NAT gateway 주소 설정이 보인다. 여기에 설정된 IP 는 다를 것이고, 본인이 원하는 특정 IP 주소를 (여기서는 192.168.70.X 대역 이용) 기록해 주면 된다. 설정파일을 변경한다고 바로 적용되지는 않는다. VMware 네트워크를 재 시작해 주거나 또는  ifconfig 를 통해 vmnet8 의 IP 를 주소를 바꿔주면 된다. 다음은 ifconfig 로 IP 를 변경하고 ifconfig 로 살펴본 내용으로 vmnet8 의 주소가 192.168.70.1 이 되었다. 가상머신에서 192.168.70.X 로 설정하고 게이트웨이 주소를 192.168.70.1 로 잡아주면 네트워크는 잘 될 것이다.

# ifconfig vmnet8
vmnet8    Link encap:Ethernet  HWaddr 00:50:56:c0:xx:xx
          inet addr:192.168.70.1  Bcast:192.168.70.255  Mask:255.255.255.0
          inet6 addr: fe80::250:56ff:fexx:x/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:235 errors:0 dropped:0 overruns:0 frame:0
          TX packets:100 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

가상머신에서 와이어샤크를 이용해 패킷 덤프를 하는 경우 아래 그림과 같은 메시지가 나타날 수 있다. 보안상의 이유로 이더넷 인터페이스에 promiscuous 모드를 설정할 수 없다는 것이다.


이에 대한 해결책으로는 해당 디바이스의 퍼미션을 변경해 주면 된다.

# ls -l /dev/vmne*
crw------- 1 root root 119, 0 2012-08-24 10:13 /dev/vmnet0
crw------- 1 root root 119, 1 2012-08-24 10:13 /dev/vmnet1
crw------- 1 root root 119, 8 2012-08-24 10:13 /dev/vmnet8

/dev 밑에 vmnet* 이라는 문자열들을 볼 수 있고, NAT 에서 사용하는 /dev/vmnet8 에 rw 퍼미션을 추가해 주면 된다.

# chmod a+rw /dev/vmnet8
# ls -l /dev/vmne*
crw------- 1 root root 119, 0 2012-08-24 10:13 /dev/vmnet0
crw------- 1 root root 119, 1 2012-08-24 10:13 /dev/vmnet1
crw-rw-rw- 1 root root 119, 8 2012-08-24 10:13 /dev/vmnet8

rw 퍼미션이 추가된 후에는 패킷캡쳐 동작시 위와 같은 메시지는 다시 나타나지 않는다.


[참고]
1. Using Virtual Ethernet Adapters in Promiscuous Mode on a Linux Host
http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=287

2012년 10월 26일 금요일

패킷에서 추출해 낸 데이터 역으로 돌리기


패킷파일에서 추출해 낸 바이너리 데이터를 역(Reverse)으로 되돌릴 경우에는 어떤 방법을 사용할 수 있을까? 프로그램을 작성해서 역으로 만들수도 있다. 프로그램을 배우는 초반에 많이 언급되는 내용중에 하나이다. 이런 방법말고 간단히 도구만으로 쉽게 만들 수 없을까? 일단, 추출한 데이터가 1.bin 이라고 가정해 보자. xxd 나 hexdump 와 같은 프로그램을 이용해 HEX 값으로 출력을 할 수가 있다. 출력방법은 '00 00 00 00' 과 같이 한개의 HEX 값을 출력하고 공백 그리고 HEX 값이 이어지는 구조로 얻고 싶다. 이런 경우에는 hexdump 에서 아래와 같은 방법으로 포맷을 맞출수가 있다.

# hexdump -v -e '/1 "%02X "' 1.bin > 1.txt
52 75 6E 6E 69 6E 67 20 58 20 73 65 73 73 69 6F 6E 20 77 72 61 70 70 65 72 0A 4C
 6F 61 64 69 6E 67 20 70 72 6F 66 69 6C 65 20 66 72 6F 6D 20 2F 65 74 63 2F 70 7
2 6F 66 69 6C 65 0A 4C 6F 61 64 69 6E 67 20 70 72 6F 66 69

자, 그럼 이 데이터를 역으로 돌리면 되는데 쉽게 떠오르는 명령어로 rev 가 있다. 그런데 rev 를 사용하면 약간의 문제가 있다. 데이터가 역으로는 되는데 HEX 값 자체도 앞뒤가 뒤바뀌어 버린다.

# hexdump -v -e '/1 "%02X "' 1.bin | rev
 96 66 F6 27 07 02 76 E6 96 46 16 F6 C4 A0 56 C6 96 66 F6 27 07 F2 36 47 56 F2 02 D6 F6 27 66 02 56 C6 96 66 F6 27 07 02 76 E6 96 46 16 F6 C4 A0 27 56 07 07 16 27 77 02 E6 F6 96 37 37 56 37 02 85 02 76 E6 96 E6 E6 57 25

차이점을 알 수 있을 것이다. 끝 데이터인 6F 66 69 가 역으로 앞으로는 갔는데 96 66 F6 과 같이 이 값 자체도 앞뒤가 바뀐것이다. 이렇게 되면 전혀 엉뚱한 값이 된다. 이럴때 쉽게 사용할 수 있는 명령어로 tac 가 있다. *NIX 의 대표적인 명령어 cat 를 거꾸로 뒤짚어 보자. tac 가 된다. 그렇다 cat 과 같은 기능을 역으로 해주는 것이다. (필자도 tac 라는게 있는줄은 몰랐다. 쉽게 역으로 변환할 수 있는 도구가 무엇이 있을까 찾게되었다)

[TAC 도움말]

# tac --help

Usage: tac [OPTION]... [FILE]...
Write each FILE to standard output, last line first.
With no FILE, or when FILE is -, read standard input.

Mandatory arguments to long options are mandatory for short options too.
  -b, --before             attach the separator before instead of after
  -r, --regex              interpret the separator as a regular expression
  -s, --separator=STRING   use STRING as the separator instead of newline
      --help     display this help and exit
      --version  output version information and exit

Report tac bugs to bug-coreutils@gnu.org
GNU coreutils home page: <http://www.gnu.org/software/coreutils/>
General help using GNU software: <http://www.gnu.org/gethelp/>
For complete documentation, run: info coreutils 'tac invocation'

# tac -s ' ' 1.txt > 2.txt


-s 옵션은 구분자를 지정하는 것으로 우리가 만들어낸 데이터가 각 HEX 값 마다 공백을 가지고 있으므로 ' ' 로 구분해 주었다. 그러면 역으로 만들어진 데이터가 2.txt 에 저장되었다.

ASCII 로 만들어진 데이터를 바이너리로 만드는 방법은 여러가지가 있다. 입력 데이터가 무엇이냐에 따라 다르지만 앞서 언급한 경우는 다음과 같이 할 수 있다.

# xxd -r -plain 2.txt

xxd 의 -r 옵션은 hexdump 데이터를 바이너리로 컨버터 해주는 것이다.

패킷에서 추출해 낸 데이터가 어떤 형식이냐에 따라 그것을 어떻게 다뤄야 할지가 나눠진다. 오늘 소개한 것은 여러 경우중 일부에 속한다. 이런 방법도 있구나 하고 알아두면 좋을것 같다.

2012년 10월 22일 월요일

VMware Workstation 설치 컴파일 오류(SPIN_LOCK_UNLOCKED)

VMware 7.1.4 리눅스 버전을 설치하면서 발생하는 에러에 대해 공유하고자 한다. VMware Workstation 최신 버전은 9 이다. 그러나, 정식적으로 사용 가능한 라이센스는 7 버전을 보유하고 있기에 7.1.4 를 설치하였다. (물론, 많은 경우는 무료로 사용 가능한 VirtualBox 를 사용하지만..)

설치하는 도중에 아래 그림과 같이 Error 메시지를 출력한다.


자세한 에러 메시지를 보면

"Unable to build kernel module.
See log file /tmp/vmware-root/setup-29550.log for details"

와 같았다. 로그파일을 살펴보면 특정 파일을 컴파일 하는 과정에서 발생하는 것이고, 이것을 수동으로 컴파일 해보면 다음과 같은 과정이다.

root@:/tmp/vmware-root# /usr/bin/make -C /tmp/vmware-root/modules/vmmon-only auto-build SUPPORT_SMP=1 HEADER_DIR=/lib/modules/3.0.0-22-generic/build/include CC=/usr/bin/gcc GREP=/usr/bin/make IS_GCC_3=no VMCCVER=4.6.1
Using 2.6.x kernel build system.
make: Entering directory `/tmp/vmware-root/modules/vmmon-only'
make -C /lib/modules/3.0.0-22-generic/build/include/.. SUBDIRS=$PWD SRCROOT=$PWD/. \
 MODULEBUILDDIR= modules
make[1]: Entering directory `/usr/src/linux-headers-3.0.0-22-generic'
  CC [M]  /tmp/vmware-root/modules/vmmon-only/linux/driver.o
/tmp/vmware-root/modules/vmmon-only/linux/driver.c:783:59: error: ‘SPIN_LOCK_UNLOCKED’ undeclared here (not in a function)
make[2]: *** [/tmp/vmware-root/modules/vmmon-only/linux/driver.o] Error 1
make[1]: *** [_module_/tmp/vmware-root/modules/vmmon-only] Error 2
make[1]: Leaving directory `/usr/src/linux-headers-3.0.0-22-generic'
make: *** [vmmon.ko] Error 2
make: Leaving directory `/tmp/vmware-root/modules/vmmon-only'

SPIN_LOCK_UNLOCKED 가 선언되지 않았다고 계속 나타나는 문제였다. 관련 내용을 구글링 해보고 다음 패치파일을 찾을 수 있었다.

패치파일 다운로드 받기 : http://weltall.heliohost.org/wordpress/wp-content/uploads/2011/08/fullvmwarelinux310patch.tar.gz

패치를 실행해 보았다. 그러나 다음과 같은 메시지만 계속 출력된다.

# ./patch-modules_2.6.39.sh
Sorry, this script is only for VMWare WorkStation 7.1.5 or VMWare Player 3.1.5. Exiting

분명 패치파일에는 7.1.4 버전도 분명 명시되어 있었다. 스크립트 파일을 살펴보니

[ "$vmver" == "workstation$vmreqver2" ] && product="VMWare WorkStation"
[ "$vmver" == "player$plreqver2" ] && product="VMWare Player"

와 같이 vmreqver2 를 참고하는 변수가 있지만 실제 스크립트에는 없다. 아래와 같이 스크립트가 변경이 필요하다.

vmreqver=7.1.4
plreqver=3.1.4
vmreqver=7.1.5
plreqver=3.1.5

를 다음과 같이 변경하였다.

vmreqver=7.1.4
plreqver=3.1.4
vmreqver2=7.1.5
plreqver2=3.1.5

그리고 다시 패치 스크립트를 실행하면 깔끔하게 실행이 된다.

# ./patch-modules_2.6.39.sh
patching file vmblock-only/linux/dentry.c
patching file vmblock-only/linux/filesystem.c
patching file vmci-only/linux/driver.c
patching file vmmon-only/linux/driver.c
patching file vmmon-only/linux/hostif.c
patching file vmmon-only/linux/iommu.c
patching file vmnet-only/compat_netdevice.c
.
.
.
Built vsock module
Starting VMware services:
   VMware USB Arbitrator                                               done
   Virtual machine monitor                                             done
   Virtual machine communication interface                             done
   VM communication interface socket family                            done
   Blocking file system                                                done
   Virtual ethernet                                                    done
   Shared Memory Available                                             done


All done, you can now run VMWare WorkStation.
Modules sources backup can be found in the '/usr/lib/vmware/modules/source-workstation7.1.4-2012-10-09-15:04:41-backup' directory


자, 이제 패치가 완료되었으니 VMware 를 다시 재 설치 진행해 주면 에러 발생없이 깨끗하게 설치가 진행된다. 참고로 VMware 7.1.6.744570 버전도 해당 패치를 반영하여 사용이 가능하다. 패치 적용시 후반에 약간의 오류가 있긴 하지만 VMware 를 실행하면 커널 컴파일 하는 GUI 화면에서 제대로 진행이 계속된다.

참고로, VMWare 를 설치한 파일은 "VMware-Workstation-Full-7.1.4-385536.x86_64.bundle" 이며, 커널은 3.0.0-22 이었다. (64비트)

혹시, 같은 에러를 경험할 사용자를 위해 해결책을 공유한다.

2012년 10월 18일 목요일

크롬 브라우저에서 SSH 접속을 해보자!

SSH 를 통해서 시스템에 급하게 접근을 해야 하는데, SSH 클라이언트 프로그램이 없다면 구글 크롬 브라우저를 이용해 보는 것도 좋은 방법이다. 구글 크롬 웹 스토어에서 SSH 접속이 가능하게끔 해주는 클라이언트가 있기 때문이다.

우선, 아래의 크롬 웹 스토어에 접속을 한 후, SSH 로 검색해 본다.
https://chrome.google.com/webstore/category/home?hl=ko&utm_source=chrome-ntp-launcher

여러가지들이 나오는데 그 중에서는 필자는 다음 Secure Shell 이라는 것을 선택하였다.


크롬에 추가 한후, 실행하면 다음과 같이 접속 화면이 나온다.  세션을 저장할 이름을 기록하는 곳도 보이고 접속할 대상 시스템의 사용자 이름과 호스트명 (or IP) 을 적는 곳이 보인다.
접속 대상 정보를 입력하고 엔터를 눌러주면 SSH 접속이 이뤄진다.

그럼 일반적으로 사용해 오던 SSH 클라이언트 화면과 동일하게 사용할 수 있다. 크롬 브라우저 하나만 있으면 말이다.

2012년 10월 16일 화요일

[추천] '리버싱 핵심원리' 책을 소개합니다.

오늘 한권의 책을 소개하고자 한다. 필자와 친분이 있는 리버스코어 블로그 운영자님이 최근에 리버싱 이야기를 집대성한 책을 출간하였다.

이 책은 단순히 리버싱을 하기위한 것 보다 그 기본을 이해하는데 많은 내용을 할애하고 있다. 동작원리와 내부구조등을 이해하는데 중심을 두고 있다. 책 페이지는 1,029 페이지로 책 두께가 얼마나 노력하면서 써왔는지 말해주고 있다. 그간 옆에서 지켜보아오면서 책을 마무리 짓기 위해 고분분투하는 모습을 보아왔다. 그 노력의 결과가 바로 지금의 ' 리버싱 핵심원리 ' 라는 이야기로 책이 세상에 나온것이다.

패킷인사이드에서도 가끔 리버싱을 소개하는 경우도 있다. 패킷 그 자체를 분석하다 보면 그 안에서 바이너리 데이터를 얻기도 하고 그럼 그 데이터를 분석하기 위해 리버싱이 필요한 경우가 분명 있다.

여러분들이 분석가로서의 범위를 넓히고 싶다면 이 책을 추천하고자 한다. 절대 후회없는 선택이 될것이라 믿는다.


[패킷인사이드의 추천사]

지금 당신의 손에 이 책이 들려있다면, 당신은 리버싱이라는 단어가 주는 매력에 이끌렸을 것이다. 
 리버싱을 처음 접하는 사람들은 공부할 것이 많고 시작하기 전부터의 걱정에 사로잡혀 어려움을 느끼기도 한다. 하지만 모든것을 다 알고 시작할 필요는 없다. 배움의 과정에서 차근히 얻어갈 수 있는 지침을 이 책에서 제시해 줄 것이기 때문이다. 
 이 책은 리버싱 입문자의 마음자세를 중요하게 생각하고 있고, 다른 책들과 달리 단순 기법의 나열이 아닌 그 기법의 의미와 동작원리 그리고 내부구조를 이해하는데 초점을 맞추고 있다. 또한 풍부한 실습예제를 학습하면서 리버싱이 몸에 스며들도록 노력한 필자의 고민이 묻어난다. 
 리버서가 되기를 원하는가? 개발자인 나에게도 필요한가? 라는 질문을 가지고 있다면 이 책은 당신의 확실한 동반자가 될 것이다.

앞으로 패킷인사이드에서도 준비가 되면 한권의 책으로 여러분들을 만나뵙겠습니다. 그때가 언제될지는 모르겠지만요. ^^

2012년 10월 10일 수요일

내 시스템에 설치된 Libpcap 버전 확인하기

과연 내 시스템에는 어떤 버전의 Libpcap 이 설치되어 있는 것인가? 필요에 따라 PCAP 라이브러리 버전 확인이 필요한 경우가 있다. 이럴때 쉽게 확인할 수 있는 방법 몇 가지를 적어본다.

1) ls 명령어로 라이브러리 디렉토리 살펴보기 

$ ls -l /usr/lib/*pcap*
or
$ ls -l /usr/lib/i386*/*pcap*

/usr/lib/i386-linux-gnu/libpcap.so.0.8
/usr/lib/i386-linux-gnu/libpcap.so
/usr/lib/i386-linux-gnu/libpcap.a
/usr/lib/i386-linux-gnu/libpcap.so.1.1.1

이 상황은 시스템에 따라 많이 달라질 수 있으므로, find 를 이용해 검색해 보아도 된다. 여기 예에서는 1.1.1 버전과 0.8 버전이 있는 것으로 추정할 수 있다.

2) 패키지 프로그램을 이용해 확인하기 

rpm 을 사용한다면 다음과 같이 pcap 문자열로 확인해 본다.


$ rpm -qa | grep pcap

데비안 계열이라면

$ apt-cache pkgnames | grep pcap

를 통해 설치되어 있는 패키지를 확인하고 출력되는 패키지 이름을 보고

$ apt-cache showpkg libpcap-dev

와 같이 세부적으로 살펴볼 수 있다.

3) ldconfig 를 통해 라이브러리 링크 연결을 확인해 본다.

$ ldconfig -p | grep pcap

4) libpcap 라이브러리를 이용해 직접 버전을 출력해 본다.

다음과 같이 pcap_lib_version() 을 이용하면 버전이 확인가능하다. 아래와 같이 간단하게 코딩하여 실행해 볼 수 있다.


#include <pcap/pcap.h>

int main() {

        const char *pcap_v;
        pcap_v = pcap_lib_version();

        printf("Libpcap Version: %s \n", pcap_v);

}

# gcc libpcap_ver.c -lpcap
# ./a.out
Libpcap Version: libpcap version 1.1.1

1.1.1 버전을 사용하고 있음을 확인할 수 있다.