저번에 소개해 드렸던 집에서 네트워크 Passive Tap 만들기 기억나시나요? 그때 댓글에 누가 남겨주셨던 곳을 통해 잭을 구매했습니다. 이름을 무엇이라고 부르는지 몰라서 못 찾고 있었는데, KeyStone 잭 이라고 하네요. 이걸로 검색해 보시면 쉽게 찾아보실 수 있습니다.
잭 4개를 이용해 다음과 같이 케이블을 연결해 주었습니다. 실제로 데이터 전송에는 8개중 4개의 선만 이용이 됩니다. 그래서 오렌지 색깔과 녹색 색깔 라인을 따로 분리하여 만들어 준 것입니다.
선만 연결하고 마무리 정리를 안해 놓아서 상당히 지저분해 보이네요. 연결은 어렵지 않아서 이전 포스팅에 있는 그림만 참고하시면 쉽게 연결이 가능합니다. 연결이 되면 한쪽은 IN 다른 한쪽은 OUT 방향의 데이터를 덤프할수가 있습니다.
컴퓨터에 연결해서 쉽게 사용할 수 있지만, Tapping 을 하고자 하는 대상이 컴퓨터와 거리가 떨어져 있어서 라즈베리 파이를 이용했습니다. 라즈베리파이가 Tapping 용도로서 한 역할을 하더군요. 사실 간단하게는 노트북을 이용하는게 더 편리합니다 ^^ 라즈베리 이더넷에 연결만 하고 tcpdump 등을 이용해 저장하면 됩니다. 저번에 소개한 것과 같이 X 환경을 이용하기에는 너무 느리므로 콘솔 기반으로 데이터 저장형태로 이용하면 될것 같습니다.
기회 되면 Tapping 으로 패킷 덤프한 이야기도 소개하겠습니다. IPTV 가 그 첫번째 대상인데요, 이 이야기는 다음번에 할께요 ;-)
/Rigel
[참고]
1. 집에서 Passive 네트워크 탭(Tapping) 장비 만들기
2013년 5월 21일 화요일
2013년 4월 22일 월요일
집에서 Passive 네트워크 탭(Tapping) 장비 만들기
네트워크 트래픽 데이터를 덤프할때 기업에서 많이 사용하는 방법중의 하나가 Tapping 하는 것입니다. Tapping 전용 장비를 이용해 흐르는 트래픽 데이터를 Transparent 하게 중간에서 엿 볼수가 있는 것이죠. 트래픽 양이 큰 경우에는 더 큰 대역폭이 필요해 지므로 가격은 계속 비싸지겠죠. 전용장비 이외는 시스템에서 여러개의 네트워크 인터페이스를 설치해 사용할 수 있는 방법도 있습니다. 즉, 자기가 게이트웨이인양 모든 트래픽이 자기를 거쳐서 나가게 되므로 해당 인터페이스에서 덤프를 뜨게 되면 모두 관찰할 수 있습니다. 여러 작업을 거쳐야 하므로 조금 귀챦은 일이 되겠죠.
이보다 더 쉬운 방법은 과거에 사용하던 더미허브를 이용하는 것이죠. 더미허브 어디다 꼽아도 해당 허브의 모든 트래픽을 관찰할 수 있습니다. 요새는 더미허브 자체도 잘 나오지도 않아서 오히려 구하기도 힘듭니다 :-)
집에서 한번 시도해 볼 수 있는 Tapping 을 만들어 놓은게 있더군요. 스노트 팀에서 비슷한 다이아그램을 그려서 공개해 놓은게 있었는데, 막상 누가 만들어 찍어 놓은 사진을 보니 그럴싸합니다. 아래는 전체적인 그림 입니다.
4개의 RJ-45 잭을 이용해 2개의 포트는 트래픽 입력, 출력으로 이용되고 나머지는 2개는 입력데이터가 다른 포트로 나가고 출력 데이터는 다시 다른 포트를 지나 흐르는 것입니다. 아래 그림이 실제로 만들어 놓은 것입니다.
혹시, 아래 그림과 같은 잭을 어디서 살 수 있나요? 아시는 분은 댓글좀 ^^ (우리가 흔히 쓰는 RJ-45 잭 하고는 형태가 조금 다르네요)
이렇게 해서 인바운드나 아웃바운드를 따로 모니터링을 할 수도 있습니다. TAP 1, 2 에 연결된 포트가 컴퓨터에 연결되고 각 인터페이스에 덤프를 뜨면 따로 볼 수 있게 됩니다. 함께 같이 본다면 다음과 같이
shell> ifconfig bridge create
shell> ifconfig bridge0 addm ed0 addm ed1 monitor up
shell> tcpdump -i bridge0
브릿지를 만들어 하면 됩니다. 조금 더 세부적인 내용은 아래 URL 을 참고하세요.
저도 시간되면 집에서 한번 만들어 봐야 겠네요 :-)
그러나 요새는 글 한번 쓰기도 쉽지 않아지네요. ㅋㅋㅋ
[참고]
1. http://thnetos.wordpress.com/2008/02/22/create-a-passive-network-tap-for-your-home-network/
이보다 더 쉬운 방법은 과거에 사용하던 더미허브를 이용하는 것이죠. 더미허브 어디다 꼽아도 해당 허브의 모든 트래픽을 관찰할 수 있습니다. 요새는 더미허브 자체도 잘 나오지도 않아서 오히려 구하기도 힘듭니다 :-)
집에서 한번 시도해 볼 수 있는 Tapping 을 만들어 놓은게 있더군요. 스노트 팀에서 비슷한 다이아그램을 그려서 공개해 놓은게 있었는데, 막상 누가 만들어 찍어 놓은 사진을 보니 그럴싸합니다. 아래는 전체적인 그림 입니다.
4개의 RJ-45 잭을 이용해 2개의 포트는 트래픽 입력, 출력으로 이용되고 나머지는 2개는 입력데이터가 다른 포트로 나가고 출력 데이터는 다시 다른 포트를 지나 흐르는 것입니다. 아래 그림이 실제로 만들어 놓은 것입니다.
혹시, 아래 그림과 같은 잭을 어디서 살 수 있나요? 아시는 분은 댓글좀 ^^ (우리가 흔히 쓰는 RJ-45 잭 하고는 형태가 조금 다르네요)
이렇게 해서 인바운드나 아웃바운드를 따로 모니터링을 할 수도 있습니다. TAP 1, 2 에 연결된 포트가 컴퓨터에 연결되고 각 인터페이스에 덤프를 뜨면 따로 볼 수 있게 됩니다. 함께 같이 본다면 다음과 같이
shell> ifconfig bridge create
shell> ifconfig bridge0 addm ed0 addm ed1 monitor up
shell> tcpdump -i bridge0
브릿지를 만들어 하면 됩니다. 조금 더 세부적인 내용은 아래 URL 을 참고하세요.
저도 시간되면 집에서 한번 만들어 봐야 겠네요 :-)
그러나 요새는 글 한번 쓰기도 쉽지 않아지네요. ㅋㅋㅋ
[참고]
1. http://thnetos.wordpress.com/2008/02/22/create-a-passive-network-tap-for-your-home-network/
2. 직접 만들어 본 Tapping 장비와 라즈베리파이 연결
라즈베리파이(Raspberry PI)가 네트워크 탭(Tapping) 장비로 변신한 이유
라즈베리파이(Raspberry PI)가 네트워크 탭(Tapping) 장비로 변신한 이유
2013년 3월 6일 수요일
패킷인사이드, 라즈베리파이(Raspberry Pi)군 영입하다.
얼마전에 가지고 놀 장난감을 추가로 또 영입했습니다. 소형 컴퓨터 라즈베리파이 입니다. 이전에도 이래저래 하도 사 놓은게 많아서, 이건 미루고 있었는데 결국 또 구매했네요.
센서도 사 보고 연결해서 다양하게 테스트 해 볼까 하는데, 시간적 여유가 될지는 모르겠네요. 일단 박스는 이렇습니다. 랜케이블 연결되어 있고, HDMI 로 모니터 연결하고 SDCARD 가 연결되어있습니다.
리눅스가 설치되어 있으니 해 보면 다양하게 할건 많을거 같습니다.
물론, 패킷 덤프도 잘 되죠. tcpdump(apt-get install tcpdump) 도 잘 되고요, 와이어샤크도 설치해 보았더니 그림과 같이 잘 동작합니다.
사실 동작 안할 이유는 없죠 :-)
재미난것을 하게되면 다시 공유해 드릴께요 ^^
/Rigel
센서도 사 보고 연결해서 다양하게 테스트 해 볼까 하는데, 시간적 여유가 될지는 모르겠네요. 일단 박스는 이렇습니다. 랜케이블 연결되어 있고, HDMI 로 모니터 연결하고 SDCARD 가 연결되어있습니다.
리눅스가 설치되어 있으니 해 보면 다양하게 할건 많을거 같습니다.
물론, 패킷 덤프도 잘 되죠. tcpdump(apt-get install tcpdump) 도 잘 되고요, 와이어샤크도 설치해 보았더니 그림과 같이 잘 동작합니다.
사실 동작 안할 이유는 없죠 :-)
재미난것을 하게되면 다시 공유해 드릴께요 ^^
/Rigel
2012년 1월 11일 수요일
필요한 내용만 패킷파일로 저장하기
패킷덤프를 하는 과정에서는 통상
1) 네트워크 디바이스 전체를 대상으로 덤프를 하거나
2) 또는 캡처필터를 적용하여 저장하는 것이 일반적이다.
하지만 트래픽이 많은 경우라면 이 또한 여기서 원하는 데이터로 한정하여
필요한 데이터만 저장하기에는 사용자 수고가 따른다.
쉬운 방법으로 이용할 수 있는 것이 ngrep 이 있다. 간단하지만 잘 이용되지 않는것 같아 다시 소개해 본다.
-O 옵션을 이용하면 ngrep 에서 지정한 스트링이 검출된 패킷에 한해서만 PCAP 포맷형태로
저장되므로 필요한 패킷 데이터만을 저장할 수가 있다.
# ngrep -d eth0 -O extracted.pcap GET
or
# tcpdump -i eth0 | ngrep -I - -O extracted.pcap GET
ngrep 을 통해 바로 지정하여 사용하거나 또는 tcpdump 를 통해 입력을 ngrep 에
전달하여 사용할 수도있다. 매칭할 패턴만 잘 정의하고 사용한다면 아주 유용할 것이다.
이전에 ngrep 을 활용한 패킷데이터 추출에 대해 설명한 글이 있으므로 참고하길 바란다.
[링크] Ngrep 을 활용한 패킷 데이터 추출
1) 네트워크 디바이스 전체를 대상으로 덤프를 하거나
2) 또는 캡처필터를 적용하여 저장하는 것이 일반적이다.
하지만 트래픽이 많은 경우라면 이 또한 여기서 원하는 데이터로 한정하여
필요한 데이터만 저장하기에는 사용자 수고가 따른다.
쉬운 방법으로 이용할 수 있는 것이 ngrep 이 있다. 간단하지만 잘 이용되지 않는것 같아 다시 소개해 본다.
-O 옵션을 이용하면 ngrep 에서 지정한 스트링이 검출된 패킷에 한해서만 PCAP 포맷형태로
저장되므로 필요한 패킷 데이터만을 저장할 수가 있다.
# ngrep -d eth0 -O extracted.pcap GET
or
# tcpdump -i eth0 | ngrep -I - -O extracted.pcap GET
ngrep 을 통해 바로 지정하여 사용하거나 또는 tcpdump 를 통해 입력을 ngrep 에
전달하여 사용할 수도있다. 매칭할 패턴만 잘 정의하고 사용한다면 아주 유용할 것이다.
이전에 ngrep 을 활용한 패킷데이터 추출에 대해 설명한 글이 있으므로 참고하길 바란다.
[링크] Ngrep 을 활용한 패킷 데이터 추출
2011년 7월 28일 목요일
Libpcap 1.2, Tcpdump 4.2 베타 버전 릴리즈
Libpcap 이 2010년 8월 1.1.2 버전을 나온이후로 오랜만에 새로운 버전이 릴리즈가 되었다.
앞 버전 번호를 크게 바꾼 1.2 버전으로 나타났다. 이번 버전에는 1.1.1 과 1.1.2 에서 변경된 모든 코드들이 다 포함되어 있고, pcap_findalldevs() 에 대한 에러핸들링도 변경되었다. 이에 몇가지 링크 레이어 타입이 추가되고 memory-mapped 캡쳐의 프레임 사이즈 계산도 수정되었다.
이외 tcpdump 버전도 4.2 로 릴리즈 되었으니, 이번기회에 libpcap 과 tcpdump 가 오래된 버전이라면 한번 업데이트 하는 것도 좋을것 같다. 다만, 아직 libpcap 1.2 , tcpdump 4.2 는 베타 릴리즈 상태이다.
앞 버전 번호를 크게 바꾼 1.2 버전으로 나타났다. 이번 버전에는 1.1.1 과 1.1.2 에서 변경된 모든 코드들이 다 포함되어 있고, pcap_findalldevs() 에 대한 에러핸들링도 변경되었다. 이에 몇가지 링크 레이어 타입이 추가되고 memory-mapped 캡쳐의 프레임 사이즈 계산도 수정되었다.
이외 tcpdump 버전도 4.2 로 릴리즈 되었으니, 이번기회에 libpcap 과 tcpdump 가 오래된 버전이라면 한번 업데이트 하는 것도 좋을것 같다. 다만, 아직 libpcap 1.2 , tcpdump 4.2 는 베타 릴리즈 상태이다.
[다운로드]
라벨:
libpcap,
Packet Analysis,
tcpdump
2011년 7월 12일 화요일
Tcpdump 의 출력내용을 내가 원하는 형태로 바꾸어 보자.
예전에 검색하다 Tcpdump 필터를 하나 발견한 것이 있다. AWK 로 제작한 간단한 스크립트로 Tcpdump 의 출력내용을 awk 로 파싱하여 좀더 보기 쉽게 출력한 것이다. 다음은 일반적으로 tcpdump 를 통해 출력한 내용의 일부분이다.
# tcpdump -i eth0 -s1550 -x
09:26:19.571231 IP 202.131.29.71.www > 192.168.15.11.60478: . 1:1461(1460) ack 658 win 6570
0x0000: 4500 05dc 89d8 4000 3406 ffc5 ca83 1d47
0x0010: c0a8 0f0b 0050 ec3e b64f e2ba e85c e4e9
0x0020: 5010 19aa 1b94 0000 4854 5450 2f31 2e31
0x0030: 2032 3030 204f 4b0d 0a44 6174 653a 204d
0x0040: 6f6e 2c20 3131 204a 756c 2032 3031 3120
0x0050: 3133 3a32 363a 3137 2047 4d54 0d0a 5365
0x0060: 7276 6572 3a20 4170 6163 6865 0d0a 4c61
물론 -X 옵션과 같은 몇 가지를 조합하면 ASCII 값도 출력시키면서 조금은 더 보기 좋게 볼 수 있다. 여기서 소개하는 것을 이용하면 아래 화면과 같은 형태로 출력된다.
상단에 헤더정보가 요약되어 보이고 다음에 스트링 문자열을 보여준다. 사용방법은 아래 경로에서 스크립트를 다운로드 받고,
# tcpdump -i eth0 -l -s 65535 -x | fil
과 같이 사용하면 된다. 그냥 간단히 덤프하는 출력 내용을 fil 로 전달하는 것 뿐이다.
http://www.ishiboo.com/~danny/Projects/tcpdump.awkfilter/fil
요새는 워낙 좋은 도구들이 많이 나와있다보니 이런 필터가 큰 의미가 있을까 하는 분들도 있을 것이다. 나또한 이 필터의 직접 적인 출력 내용보다도 이런 방식으로 활용할 수 있다는 것을 여러분들에게 소개해 주고 싶은 것이다. Awk 로 만들어져 있지만, 이외에도 다양한 스크립트를 이용할 수 있다. 업무에 따라, 필요로 하는 정보가 조금씩 달라진다. 그럴때 나에게 맞는 도구를 간단히 만들어 응용해 보면, 더욱 효과적인 패킷 분석이 가능해 진다. 꼭, 어렵게 생각할 필요는 없다. 기존에 나와있는 도구를 잘 응용하면 여러분이 원하는 도구로 쉽게 만들어 버릴 수 있다는 사실을 잊지말자!
P.S 처음 받아서 실행해 보면, 출력이 제대로 되지 않아 살펴보았다. fil 필터를 열어보면 다음과 같은 시작부분에서 startip 를 0 에서 1로 변경하였다. 그냥 실행시 제대로 정보가 출력되지 않아, 프로토콜 번호를 찍어보니 엉뚱한 것이 찍히고 있었고, 코드를 확인결과 startip 만 살짝 바꾸면 위와 같이 출력이 된다.
BEGIN {
BIGENDIAN = 0
margin=" "
startip=1
FS = " "
}
# tcpdump -i eth0 -s1550 -x
09:26:19.571231 IP 202.131.29.71.www > 192.168.15.11.60478: . 1:1461(1460) ack 658 win 6570
0x0000: 4500 05dc 89d8 4000 3406 ffc5 ca83 1d47
0x0010: c0a8 0f0b 0050 ec3e b64f e2ba e85c e4e9
0x0020: 5010 19aa 1b94 0000 4854 5450 2f31 2e31
0x0030: 2032 3030 204f 4b0d 0a44 6174 653a 204d
0x0040: 6f6e 2c20 3131 204a 756c 2032 3031 3120
0x0050: 3133 3a32 363a 3137 2047 4d54 0d0a 5365
0x0060: 7276 6572 3a20 4170 6163 6865 0d0a 4c61
물론 -X 옵션과 같은 몇 가지를 조합하면 ASCII 값도 출력시키면서 조금은 더 보기 좋게 볼 수 있다. 여기서 소개하는 것을 이용하면 아래 화면과 같은 형태로 출력된다.
상단에 헤더정보가 요약되어 보이고 다음에 스트링 문자열을 보여준다. 사용방법은 아래 경로에서 스크립트를 다운로드 받고,
# tcpdump -i eth0 -l -s 65535 -x | fil
과 같이 사용하면 된다. 그냥 간단히 덤프하는 출력 내용을 fil 로 전달하는 것 뿐이다.
http://www.ishiboo.com/~danny/Projects/tcpdump.awkfilter/fil
요새는 워낙 좋은 도구들이 많이 나와있다보니 이런 필터가 큰 의미가 있을까 하는 분들도 있을 것이다. 나또한 이 필터의 직접 적인 출력 내용보다도 이런 방식으로 활용할 수 있다는 것을 여러분들에게 소개해 주고 싶은 것이다. Awk 로 만들어져 있지만, 이외에도 다양한 스크립트를 이용할 수 있다. 업무에 따라, 필요로 하는 정보가 조금씩 달라진다. 그럴때 나에게 맞는 도구를 간단히 만들어 응용해 보면, 더욱 효과적인 패킷 분석이 가능해 진다. 꼭, 어렵게 생각할 필요는 없다. 기존에 나와있는 도구를 잘 응용하면 여러분이 원하는 도구로 쉽게 만들어 버릴 수 있다는 사실을 잊지말자!
P.S 처음 받아서 실행해 보면, 출력이 제대로 되지 않아 살펴보았다. fil 필터를 열어보면 다음과 같은 시작부분에서 startip 를 0 에서 1로 변경하였다. 그냥 실행시 제대로 정보가 출력되지 않아, 프로토콜 번호를 찍어보니 엉뚱한 것이 찍히고 있었고, 코드를 확인결과 startip 만 살짝 바꾸면 위와 같이 출력이 된다.
BEGIN {
BIGENDIAN = 0
margin=" "
startip=1
FS = " "
}
2011년 4월 14일 목요일
윈도우 패킷스니퍼 WinDump 에 컬러 Hightlighting 기능을 입혀보자
커맨드라인의 패킷덤프 프로그램으로는 tcpdump 를 많이 사용하는 편이다. 윈도우에는 이와 유사한 Windump 라는 것이 있다. tcpdump 와 같은 형태로 윈도우에서 실행가능한 커맨드라인의 패킷 스니퍼이다. 와이어샤크와 같은 GUI 에 익숙해져 있다면, 커맨드라인의 출력되는 화면은 보잘것 없어 보인다.
어느 블로그에 Windump 와 관련한 괜챦은 스크립트 소개를 보았다. 윈덤프의 출력에 컬러를 입혀 보여주는 것으로 그나마 컬러를 입혀서 보면 보기에는 더욱 좋을 것이다. 방법은 윈도우의 파워셀(PowerShell)을 이용하는 것으로 이것이 설치되어 있어야 한다. 윈도우 7 의 경우는 기본적으로 포함되어 있고 그렇지 않은 경우라면 사이트에서 다운받아 설치하면 된다.
일단 파워쉘 스크립트인 Sniff.ps1 을 다음의 경로에서 다운로드 받는다:
http://blogs.sans.org/windows-security/files/Sniff.zip
압축을 풀고 실행해 보자
.\Sniff.ps1
이걸 그냥 도스창에서 실행하면 실행되지가 않는다. 파워쉘로 실행되어야 하므로 도스창에서 powershell 이라고 치면 파워쉘로 들어간다. 나의 경우는 파워쉘을 관리자 권한으로 실행시켰다. 실행 정책 때문에 관리자 권한이 필요하기 때문이다.
일단 아래와 같이 실행해 보니 권한이 부족하다고 나온다.
현재 실행 정책을 살펴보니 '제한적' 이다.
그래서 임시적으로 실행하기 위해 아래와 같이 제한을 풀었다.
실행정책을 변경한 다음에는 Sniff.ps1 을 정상적으로 실행할 수 있게 된다.
사용할 네트워크 어뎁터를 묻는 명령을 실행할 경우는 아래와 같이 실행하면, 네트워크 카드를 선택한 후 패킷 덤프를 할 수 있다.
* 참고로, Windump.exe 가 설치되어 있어야 한다. Windump 는 윈도우 패스에 잡혀 있으면 실행하는데 전혀 문제 없다. Windump 는 아래 참고 URL 에서 구할 수 있다.
다음 이미지는 아래와 같은 명령을 통해 실행한 화면으로 tcp 트래픽 중 80 번 포트를 덤프하도록 지정한 것이다.

[참고]
1. 윈덤프 컬러 사용 관련 블로그 글
http://blogs.sans.org/windows-security/2009/10/22/windump-color-highlighting/
2. 윈덤프 다운로드
http://www.winpcap.org/windump/
3. 마이크로소프트 윈도우 파워쉘
http://technet.microsoft.com/en-us/powershell
어느 블로그에 Windump 와 관련한 괜챦은 스크립트 소개를 보았다. 윈덤프의 출력에 컬러를 입혀 보여주는 것으로 그나마 컬러를 입혀서 보면 보기에는 더욱 좋을 것이다. 방법은 윈도우의 파워셀(PowerShell)을 이용하는 것으로 이것이 설치되어 있어야 한다. 윈도우 7 의 경우는 기본적으로 포함되어 있고 그렇지 않은 경우라면 사이트에서 다운받아 설치하면 된다.
일단 파워쉘 스크립트인 Sniff.ps1 을 다음의 경로에서 다운로드 받는다:
http://blogs.sans.org/windows-security/files/Sniff.zip
압축을 풀고 실행해 보자
.\Sniff.ps1
이걸 그냥 도스창에서 실행하면 실행되지가 않는다. 파워쉘로 실행되어야 하므로 도스창에서 powershell 이라고 치면 파워쉘로 들어간다. 나의 경우는 파워쉘을 관리자 권한으로 실행시켰다. 실행 정책 때문에 관리자 권한이 필요하기 때문이다.
일단 아래와 같이 실행해 보니 권한이 부족하다고 나온다.
PS C:\PlayGround\Sniff> .\Sniff.ps1
이 시스템에서 스크립트를 실행할 수 없으므로 C:\PlayGround\Sniff\Sniff.ps1 파일을 로드할 수 없습니다. 자세한 내용은 "get
-help about_signing"을 참조하십시오.
위치 줄:1 문자:12
+ .\Sniff.ps1 <<<<
+ CategoryInfo : NotSpecified: (:) [], PSSecurityException
+ FullyQualifiedErrorId : RuntimeException
이 시스템에서 스크립트를 실행할 수 없으므로 C:\PlayGround\Sniff\Sniff.ps1 파일을 로드할 수 없습니다. 자세한 내용은 "get
-help about_signing"을 참조하십시오.
위치 줄:1 문자:12
+ .\Sniff.ps1 <<<<
+ CategoryInfo : NotSpecified: (:) [], PSSecurityException
+ FullyQualifiedErrorId : RuntimeException
현재 실행 정책을 살펴보니 '제한적' 이다.
PS C:\PlayGround\Sniff> Get-ExecutionPolicy
Restricted
Restricted
그래서 임시적으로 실행하기 위해 아래와 같이 제한을 풀었다.
PS C:\PlayGround\Sniff> Set-ExecutionPolicy unrestricted
실행 규칙 변경
실행 정책은 신뢰하지 않는 스크립트로부터 사용자를 보호해 줍니다. 실행 정책을 변경하면 about_Execution_Policies 도움말
항목에 설명된 보안 위험에 노출될 수 있습니다. 실행 정책을 변경하시겠습니까?
[Y] 예(Y) [N] 아니요(N) [S] 일시 중단(S) [?] 도움말 (기본값은 "Y"임): y
실행 규칙 변경
실행 정책은 신뢰하지 않는 스크립트로부터 사용자를 보호해 줍니다. 실행 정책을 변경하면 about_Execution_Policies 도움말
항목에 설명된 보안 위험에 노출될 수 있습니다. 실행 정책을 변경하시겠습니까?
[Y] 예(Y) [N] 아니요(N) [S] 일시 중단(S) [?] 도움말 (기본값은 "Y"임): y
실행정책을 변경한 다음에는 Sniff.ps1 을 정상적으로 실행할 수 있게 된다.
사용할 네트워크 어뎁터를 묻는 명령을 실행할 경우는 아래와 같이 실행하면, 네트워크 카드를 선택한 후 패킷 덤프를 할 수 있다.
PS C:\PlayGround\Sniff> .\Sniff.ps1 -ask
1.\Device\NPF_{8B751B[삭제]-95BF-F2FB6F703EE6} (3Com EtherLink PCI)
2.\Device\NPF_{E849DA[삭제]-BD12-157CFC55BD8B} (NVIDIA nForce MCP Networking Adapter
3.\Device\NPF_{DE78577C-[삭제]9B-E46B98062A8F} (Sun)
Which adapter number? :
1.\Device\NPF_{8B751B[삭제]-95BF-F2FB6F703EE6} (3Com EtherLink PCI)
2.\Device\NPF_{E849DA[삭제]-BD12-157CFC55BD8B} (NVIDIA nForce MCP Networking Adapter
3.\Device\NPF_{DE78577C-[삭제]9B-E46B98062A8F} (Sun)
Which adapter number? :
* 참고로, Windump.exe 가 설치되어 있어야 한다. Windump 는 윈도우 패스에 잡혀 있으면 실행하는데 전혀 문제 없다. Windump 는 아래 참고 URL 에서 구할 수 있다.
다음 이미지는 아래와 같은 명령을 통해 실행한 화면으로 tcp 트래픽 중 80 번 포트를 덤프하도록 지정한 것이다.
PS C:\PlayGround\Sniff> .\Sniff.ps1 "tcp and port 80" -ask

[참고]
1. 윈덤프 컬러 사용 관련 블로그 글
http://blogs.sans.org/windows-security/2009/10/22/windump-color-highlighting/
2. 윈덤프 다운로드
http://www.winpcap.org/windump/
3. 마이크로소프트 윈도우 파워쉘
http://technet.microsoft.com/en-us/powershell
2011년 4월 4일 월요일
와이어샤크로 USB 디바이스를 모니터링 할 수 있다는 사실!
컴퓨터와 USB 사이의 통신 내용도 패킷을 캡쳐하는 것과 같이 볼 수 없을까? 이에 대한 대답은 '있다' 이다. 그것도 우리가 블로그에서 많이 언급하고 친근한 프로그램 중에 하나인 와이어샤크로 할 수 있다.
자, 그럼 어떻게 USB 트래픽 정보를 볼 수 있을까? 우선 운영체제에서 볼 수 있도록 지원해 주어야 하는데, USB 로우 트래픽 데이터를 패킷 형태로 변환하여 일반적인 네트워크 인터페이스와 같이 인식되어 볼 수 있다. 여기서는 리눅스를 기반으로 하여 설명을 할 것이다. 우선 커널 상에서 DEBUG 파일 시스템이라든지, USB 모니터링 모듈등을 지원해 주어야 한다. 그러므로, 다음과 같은 옵션이 설정되어 커널이 컴파일 되어 있어야 한다.
CONFIG_DEBUG_KERNEL=y
CONFIG_DEBUG_FS=y
CONFIG_USB_MON=y
CONFIG_DEBUG_FS=y
CONFIG_USB_MON=y
USBMON 모듈은 커널 2.6.11 이후에 포함되어 있으며, 최근의 배포판 리눅스에서는 크게 다른 설정 없이 아래의 명령어를 사용할 수 있을 것이다. 일단, lsmod 명령어를 통해 usb 관련한 모듈은 무엇이 올라가 있는지 살펴보았다.
# lsmod | grep usb
rt2800usb 28691 0
rt2x00usb 6829 1 rt2800usb
rt2x00lib 21810 2 rt2800usb,rt2x00usb
mac80211 137340 2 rt2x00usb,rt2x00lib
crc_ccitt 1323 2 rt2870sta,rt2800usb
usb_storage 39625 1
scsi_mod 122149 5 usb_storage,sg,sr_mod,sd_mod,libata
usbcore 122034 6 rt2870sta,rt2800usb,rt2x00usb,usb_storage,ehci_hcd
nls_base 6377 11 isofs,udf,hfsplus,hfs,ntfs,jfs,nls_utf8,nls_cp437,vfat,fat,usbcore
usbmon 은 보이지 않는다. usbmon 모듈은 modprobe 를 통해서 쉽게 모듈을 로드할 수 있다.
# modprobe usbmon
모듈을 올린 후 살펴보니 usbmon 모듈이 올라가 있는 것이 보인다.
# lsmod | grep usb
usbmon 15322 0
rt2800usb 28691 0
rt2x00usb 6829 1 rt2800usb
rt2x00lib 21810 2 rt2800usb,rt2x00usb
mac80211 137340 2 rt2x00usb,rt2x00lib
crc_ccitt 1323 2 rt2870sta,rt2800usb
usb_storage 39625 1
scsi_mod 122149 5 usb_storage,sg,sr_mod,sd_mod,libata
usbcore 122034 7 usbmon,rt2870sta,rt2800usb,rt2x00usb,usb_storage,ehci_hcd
nls_base 6377 11 isofs,udf,hfsplus,hfs,ntfs,jfs,nls_utf8,nls_cp437,vfat,fat,usbcore
그 다음 DebugFS 파일시스템 타입으로 아래와 같이 마운트 해 주면 된다.
# mount -t debugfs / /sys/kernel/debug
# mount
[생략]
/dev/sdb1 on /media/usb0 type vfat (rw,noexec,nosuid,nodev)
fusectl on /sys/fs/fuse/connections type fusectl (rw)
/ on /sys/kernel/debug type debugfs (rw)
# mount
[생략]
/dev/sdb1 on /media/usb0 type vfat (rw,noexec,nosuid,nodev)
fusectl on /sys/fs/fuse/connections type fusectl (rw)
/ on /sys/kernel/debug type debugfs (rw)
앞서 설명한 것과 같이 네트워크 인터페이스로 인식을 시켜준다고 하였다. 그럼, tshark 의 -D 옵션을 통해 사용가능한 인터페이스 리스트를 확인할 수 있다.
# tshark -D
1. eth0
2. usbmon1 (USB bus number 1)
3. usbmon2 (USB bus number 2)
4. any (Pseudo-device that captures on all interfaces)
5. lo
1. eth0
2. usbmon1 (USB bus number 1)
3. usbmon2 (USB bus number 2)
4. any (Pseudo-device that captures on all interfaces)
5. lo
기존에는 보이지 않던 usbmon1 과 usbmon2 이 보인다. 그렇다 그럼 이제 이 인터페이스로만 지정해서 패킷 덤프를 해 보면 USB 트래픽을 볼 수 있다는 것이된다. 그런데, 2번과 3번중 어떤것이 올바른 인터페이스일까? 그냥 쉽게는 2번,3번 한번씩 패킷덤프도 해 볼 수 있지만, lsusb 명령어로 usb 정보를 들여다 보자.
# lsusb
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 002: ID 8087:0020 Intel Corp. Integrated Rate Matching Hub
Bus 002 Device 002: ID 8087:0020 Intel Corp. Integrated Rate Matching Hub
Bus 002 Device 026: ID 0424:2514 Standard Microsystems Corp. USB 2.0 Hub
위 화면은 USB 를 연결하기 전이고 다음은 USB 를 연결한 후의 화면이다. 보는 것과 같이 Bus 002 에 새로운 디바이스가 잡혀있는것을 볼 수 있다.
# lsusb
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 002: ID 8087:0020 Intel Corp. Integrated Rate Matching Hub
Bus 002 Device 002: ID 8087:0020 Intel Corp. Integrated Rate Matching Hub
Bus 002 Device 026: ID 0424:2514 Standard Microsystems Corp. USB 2.0 Hub
Bus 002 Device 028: ID 090c:1000 Feiya Technology Corp. Flash Drive
그러면, USB 버스 2번이니 위에서 살펴본 인터페이스중 3번인 usbmon2 를 관찰하면 되겠다는 것을 알 수 있다. lsusb 외 usb-devices 명령어를 이용해서도 확인할 수 있다.
# usb-devices
T: Bus=02 Lev=03 Prnt=26 Port=02 Cnt=01 Dev#= 28 Spd=480 MxCh= 0
D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1
P: Vendor=090c ProdID=1000 Rev=11.00
S: Manufacturer=LG Electronics
S: Product=XTICK
S: SerialNumber=AA04012700015188
C: #Ifs= 1 Cfg#= 1 Atr=80 MxPwr=300mA
I: If#= 0 Alt= 0 #EPs= 2 Cls=08(stor.) Sub=06 Prot=50 Driver=usb-storage
tshark 를 통해서 USB 패킷 데이터를 덤프해 보자. -i 옵션을 통해 인터페이스 번호를 지정해 주었다. 와, USB 트래픽 정보가 잡힌다. 참고로, 와이어샤크 1.2.X 버전 이상을 사용하여야 한다.
# tshark -i 3
Running as user "root" and group "root". This could be dangerous.
Capturing on USB bus number 2
0.000000 host -> 28.0 USB GET DESCRIPTOR Request DEVICE
0.000407 28.0 -> host USB GET DESCRIPTOR Response DEVICE
0.000422 host -> 26.0 USB GET DESCRIPTOR Request DEVICE
0.000575 26.0 -> host USB GET DESCRIPTOR Response DEVICE
0.000615 host -> 2.0 USB GET DESCRIPTOR Request DEVICE
0.000658 2.0 -> host USB GET DESCRIPTOR Response DEVICE
0.000677 host -> 1.0 USB GET DESCRIPTOR Request DEVICE
0.000677 1.0 -> host USB GET DESCRIPTOR Response DEVICE
GUI 버전의 와이어샤크에서는 어떻게 나올까? 다음 그림과 같이 GUI 화면에서도 문제없이 깔끔하게 트래픽 정보가 출력된다. 데이터 영역부분도 보인다.

그러면, 여기서 살짝 의문이 생긴다. 와이어샤크로만 데이터를 덤프할 수 있는 것인가 ? 그렇지는 않다. 네트워크 인터페이스로 잡힌 것이기 때문에 tcpdump 프로그램을 통해서도 볼 수 있다. USB 트래픽 데이터를 파싱해서 보여줄 수 있는 것이면 된다.
# tcpdump -i 3
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on usbmon2, link-type USB_LINUX_MMAPPED (USB with padded Linux header), capture size 65535 bytes
09:11:09.835197 CONTROL SUBMIT to 2:28:0
09:11:09.835623 CONTROL COMPLETE from 2:28:0
09:11:09.835647 CONTROL SUBMIT to 2:26:0
09:11:09.835720 CONTROL COMPLETE from 2:26:0
09:11:09.835740 CONTROL SUBMIT to 2:2:0
09:11:09.835845 CONTROL COMPLETE from 2:2:0
09:11:09.835859 CONTROL SUBMIT to 2:1:0
09:11:09.835859 CONTROL COMPLETE from 2:1:0
09:11:12.002810 BULK SUBMIT to 2:28:2
09:11:12.002955 BULK COMPLETE from 2:28:2
09:11:12.002963 BULK SUBMIT to 2:28:1
이 외에도 더 로우 방법으로 확인할 수 있는 방법이 있는데, 직접 디버그파일 시스템을 cat 를 통해 볼 수도 있다. 아래와 같이 말이다.
# cat /sys/kernel/debug/usb/usbmon/2u
ffff88021d618540 1982035431 S Bo:2:028:2 -115 31 = 55534243 a8010000 00000000 00000600 00000000 00000000 00000000 000000
ffff88021d618540 1982035468 C Bo:2:028:2 0 31 >
ffff88021d618540 1982035549 S Bi:2:028:1 -115 13 <
ffff88021d618540 1982035856 C Bi:2:028:1 0 13 = 55534253 a8010000 00000000 00
ffff88021d618540 1982035895 S Bo:2:028:2 -115 31 = 55534243 a9010000 00000000 00000600 00000000 00000000 00000000 000000
ffff88021d618540 1982035963 C Bo:2:028:2 0 31 >
ffff88021d618540 1982035969 S Bi:2:028:1 -115 13 <
ffff88021d618540 1982036213 C Bi:2:028:1 0 13 = 55534253 a9010000 00000000 00
ffff88021d618540 1984037715 S Bo:2:028:2 -115 31 = 55534243 aa010000 00000000 00000600 00000000 00000000 00000000 000000
ffff88021d618540 1984037787 C Bo:2:028:2 0 31 >
ffff88021d618540 1984037793 S Bi:2:028:1 -115 13 <
ffff88021d618540 1984038035 C Bi:2:028:1 0 13 = 55534253 aa010000 00000000 00
ffff88021d618540 1984038056 S Bo:2:028:2 -115 31 = 55534243 ab010000 00000000 00000600 00000000 00000000 00000000 000000
ffff88021d618540 1984038192 C Bo:2:028:2 0 31 >
ffff88021d618540 1984038195 S Bi:2:028:1 -115 13 <
ffff88021d618540 1984038410 C Bi:2:028:1 0 13 = 55534253 ab010000 00000000 00
USB 트래픽을 관찰할 일이 있다면, 와이어샤크를 통한 이 방법이 좋은 방법중에 하나가 될 것이다. 윈도우에서는 와이어샤크를 통해 바로 USB 트래픽을 관찰할 수 없다. 리눅스의 가상 머신에 윈도우를 올려서 사용될 수 있는 방법이 아래 [참고] 를 보면 소개되어 있긴 하다.
추후 시간적 여유가 된다면 윈도우 기반에서도 테스트 해 본 후 결과를 공유하도록 하겠다.
[참고]
1. 와이어샤크 USB 캡쳐
http://wiki.wireshark.org/CaptureSetup/USB
2011년 4월 1일 금요일
와이어샤크의 또 다른 유틸리티, Rawshark 의 사용을 알아보자
와이어샤크를 설치하면 같이 배포되는 프로그램으로 Rawshark 가 있다. 주로 GUI 기반에서 사용한다면, wireshark 만을 실행해서 사용하기 때문 다른 유틸리티는 그냥 지나치는 경우가 많다.
Rawshark 이름만으로 추정해 보면, 로우 데이터를 본다는 의미로 추정된다. 이름과 같이 그 의미가 맞다. 로우 libpcap 데이터를 덤프 및 간단한 분석을 수행할 수 있는 기능을 가지고 있다.
우선, Rawshark 의 도움말을 살펴보면 아래와 같은 옵션 사용이 가능하다:
Rawshark 는 Tshark 와 달리 입력되는 데이터에 대한 정의가 필요하다. 그래서 무작정 실행해 보면 아래와 같은 로그를 보게된다.
# cat test.pcap | rawshark
rawshark: No valid payload dissector specified.
일반적인 형태의 사용과 약간 다르다 보니 혼돈이 오기도 하는데, 정상적으로 실행하기 위해서는 -d 와 -r 옵션을 사용해서 지정해 주어야 한다. 그리고 출력을 원하는 데이터가 있다면 -F 옵션으로 지정해 주어야 한다. Rawshark 는 기본적으로 다음과 같은 입력 레코드가 들어오는 것으로 판단한다. 많이 보던 레코드 형태일텐데, libpcap 에서 사용하는 pcap_pkthdr 구조와 데이터이다.
struct rawshark_rec_s {
uint32_t ts_sec; /* Time stamp (seconds) */
uint32_t ts_usec; /* Time stamp (microseconds) */
uint32_t caplen; /* Length of the packet buffer */
uint32_t len; /* "On the wire" length of the packet */
uint8_t data[caplen]; /* Packet data */
};
libpcap 구조 관련해서는 다음 글을 읽어 보면 도움이 된다.
1) PCAP 파일을 파헤쳐 보자 - 그 첫번째 이야기
2) PCAP 파일을 파헤쳐 보자 - 그 두번째 이야기
일단 실행해보면 다음과 같은 형태로 출력이 가능하다.
일반적인 tcpdump 나 tshark 와 달리 실행방법이 약간은 복잡해 보인다. rawshark 는 입력을 스트림으로 받아 들이기 때문에 앞에서, cat 을 이용했다. 즉, test.pcap 의 내용이 cat 을 통해 읽어 들이고 이 출력을 rawshark 로 넘긴 것이다. 그러므로 -r 옵션으로 - 를 사용하였다. 앞서 rawshark 를 제대로 사용하기 위해서는 -d 와 -r 을 옵션을 사용한다고 하였는데, -d 를 통해 이 데이터가 어떤 것인지 지정해 주었다. 앞에 encap 이라고 되어 있는것은 캡슐화를 뜻하는 것으로 뒤에 EN10MB 는 이더넷 데이터를 뜻한다. 즉, 이 패킷 데이터는 우리가 흔히 사용하는 이더넷 데이터 이라는 것을 지정해 준 것이다. 이런 데이터로는 PPP, FDDI, IEEE802_11 등이 있다. 데이터 타입은 아래 참고의 URL 을 살펴보기 바란다.
여기서 캡슐화라는 것이 나왔는데, 이 캡슐화에 대한 설명은 이미 앞서 포스팅을 해 놓았으므로 읽어보길 바란다.
[링크] 패킷을 보다 자주 접하는 캡슐화(Encapsulation)는 무엇이지?
그리고 -s 는 입력으로 표준 pcap 파일임을 뜻하고, -F 옵션으로 출력할 내용을 지정할 수 있는데, 와이어샤크에서 사용하던 필터를 그대로 사용하면 되므로 어렵지 않게 쓸수 있다. 출력 되어 나오는 것을 보면 아주 심플하다. 다양한 분석기능이 갖춰진 wireshark 와는 다르게 말이다. 말 그대로 로우 데이터를 덤프해서 분석하기 위한 용도이므로 이점은 기억해 두자. 맨앞에 숫자는 패킷의 넘버를 뜻하는 것이고, 그 뒤로 숫자 1 또는 0 이 보인다. 출력 필터로 지정한 것에 대한 필드의 매치 여부를 나타내는 것으로 1이면 매치가 되었다는 것이다. 11번을 보면 HTTP 호스트 정보가 매칭되어서 1 로 표시된것을 볼 수 있다.
마지막으로 앞서 cat 을 통해 출력 시켰는데, 이외에도 tcpdump 를 통해서도 할 수 있고, wireshark 를 통해서도 할 수 있다. 출력을 rawshark 로 넘겨줄수만 있으면 된다.
# tcpdump -r test.pcap -n -w - | rawshark -d encap:EN10MB -r- -s -F ip.dst -F http.host
다음은 eth1 인터페이스를 실시간으로 rawshark 로 넘기는 것이다. 이때 rawshark 옵션으로 -l 옵션을 추가로 사용하였다. 바로바로 실시간으로 데이터가 넘어오기 때문에 바로 Flush 시키도록 한 것이다.
# tcpdump -i eth1 -s 1514 -w - | rawshark -d encap:EN10MB -l -r- -s -F ip.dst -F http.host
[참고]
1. Libpcap 데이터 링크레이어 타입
http://www.tcpdump.org/pcap3_man.html
2. Rawshark 공식 메뉴얼
http://www.wireshark.org/docs/man-pages/rawshark.html
3. 패킷인사이드 libpcap 관련 태그 보기
http://www.packetinside.com/search/label/libpcap
Rawshark 이름만으로 추정해 보면, 로우 데이터를 본다는 의미로 추정된다. 이름과 같이 그 의미가 맞다. 로우 libpcap 데이터를 덤프 및 간단한 분석을 수행할 수 있는 기능을 가지고 있다.
우선, Rawshark 의 도움말을 살펴보면 아래와 같은 옵션 사용이 가능하다:
# rawshark -h
Rawshark 1.2.11
Dump and analyze network traffic.
See http://www.wireshark.org for more information.
Copyright 1998-2010 Gerald Combs <gerald@wireshark.org> and contributors.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Usage: rawshark [options] ...
Input file:
-r <infile> set the pipe or file name to read from
Processing:
-R <read filter> packet filter in Wireshark display filter syntax
-F <field> field to display
-s skip PCAP header on input
-n disable all name resolution (def: all enabled)
-N <name resolve flags> enable specific name resolution(s): "mntC"
-d <encap:dlt>|<proto:protoname>
packet encapsulation or protocol
Output:
-S format string for fields (%D - name, %S - stringval, %N numval)
-t ad|a|r|d|dd|e output format of time stamps (def: r: rel. to first)
-l flush output after each packet
Miscellaneous:
-h display this help and exit
-v display version info and exit
-o <name>:<value> ... override preference setting
Rawshark 1.2.11
Dump and analyze network traffic.
See http://www.wireshark.org for more information.
Copyright 1998-2010 Gerald Combs <gerald@wireshark.org> and contributors.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Usage: rawshark [options] ...
Input file:
-r <infile> set the pipe or file name to read from
Processing:
-R <read filter> packet filter in Wireshark display filter syntax
-F <field> field to display
-s skip PCAP header on input
-n disable all name resolution (def: all enabled)
-N <name resolve flags> enable specific name resolution(s): "mntC"
-d <encap:dlt>|<proto:protoname>
packet encapsulation or protocol
Output:
-S format string for fields (%D - name, %S - stringval, %N numval)
-t ad|a|r|d|dd|e output format of time stamps (def: r: rel. to first)
-l flush output after each packet
Miscellaneous:
-h display this help and exit
-v display version info and exit
-o <name>:<value> ... override preference setting
Rawshark 는 Tshark 와 달리 입력되는 데이터에 대한 정의가 필요하다. 그래서 무작정 실행해 보면 아래와 같은 로그를 보게된다.
# cat test.pcap | rawshark
rawshark: No valid payload dissector specified.
일반적인 형태의 사용과 약간 다르다 보니 혼돈이 오기도 하는데, 정상적으로 실행하기 위해서는 -d 와 -r 옵션을 사용해서 지정해 주어야 한다. 그리고 출력을 원하는 데이터가 있다면 -F 옵션으로 지정해 주어야 한다. Rawshark 는 기본적으로 다음과 같은 입력 레코드가 들어오는 것으로 판단한다. 많이 보던 레코드 형태일텐데, libpcap 에서 사용하는 pcap_pkthdr 구조와 데이터이다.
struct rawshark_rec_s {
uint32_t ts_sec; /* Time stamp (seconds) */
uint32_t ts_usec; /* Time stamp (microseconds) */
uint32_t caplen; /* Length of the packet buffer */
uint32_t len; /* "On the wire" length of the packet */
uint8_t data[caplen]; /* Packet data */
};
libpcap 구조 관련해서는 다음 글을 읽어 보면 도움이 된다.
1) PCAP 파일을 파헤쳐 보자 - 그 첫번째 이야기
2) PCAP 파일을 파헤쳐 보자 - 그 두번째 이야기
일단 실행해보면 다음과 같은 형태로 출력이 가능하다.
# cat test.pcap | rawshark -d encap:EN10MB -r- -s -F ip.dst -F http.host
0 FT_IPv4 BASE_NONE - 1 FT_STRING BASE_NONE -
1 1="[FF02::C" -
2 -
3 -
4 0="168.126.63.1" -
5 0="192.168.0.240" -
6 0="168.126.63.1" -
7 0="192.168.0.240" -
8 0="72.14.213.99" -
9 0="192.168.0.240" -
10 0="72.14.213.99" -
11 1="www.goog" 0="72.14.213.99" -
12 0="192.168.0.240" -
0 FT_IPv4 BASE_NONE - 1 FT_STRING BASE_NONE -
1 1="[FF02::C" -
2 -
3 -
4 0="168.126.63.1" -
5 0="192.168.0.240" -
6 0="168.126.63.1" -
7 0="192.168.0.240" -
8 0="72.14.213.99" -
9 0="192.168.0.240" -
10 0="72.14.213.99" -
11 1="www.goog" 0="72.14.213.99" -
12 0="192.168.0.240" -
일반적인 tcpdump 나 tshark 와 달리 실행방법이 약간은 복잡해 보인다. rawshark 는 입력을 스트림으로 받아 들이기 때문에 앞에서, cat 을 이용했다. 즉, test.pcap 의 내용이 cat 을 통해 읽어 들이고 이 출력을 rawshark 로 넘긴 것이다. 그러므로 -r 옵션으로 - 를 사용하였다. 앞서 rawshark 를 제대로 사용하기 위해서는 -d 와 -r 을 옵션을 사용한다고 하였는데, -d 를 통해 이 데이터가 어떤 것인지 지정해 주었다. 앞에 encap 이라고 되어 있는것은 캡슐화를 뜻하는 것으로 뒤에 EN10MB 는 이더넷 데이터를 뜻한다. 즉, 이 패킷 데이터는 우리가 흔히 사용하는 이더넷 데이터 이라는 것을 지정해 준 것이다. 이런 데이터로는 PPP, FDDI, IEEE802_11 등이 있다. 데이터 타입은 아래 참고의 URL 을 살펴보기 바란다.
여기서 캡슐화라는 것이 나왔는데, 이 캡슐화에 대한 설명은 이미 앞서 포스팅을 해 놓았으므로 읽어보길 바란다.
[링크] 패킷을 보다 자주 접하는 캡슐화(Encapsulation)는 무엇이지?
그리고 -s 는 입력으로 표준 pcap 파일임을 뜻하고, -F 옵션으로 출력할 내용을 지정할 수 있는데, 와이어샤크에서 사용하던 필터를 그대로 사용하면 되므로 어렵지 않게 쓸수 있다. 출력 되어 나오는 것을 보면 아주 심플하다. 다양한 분석기능이 갖춰진 wireshark 와는 다르게 말이다. 말 그대로 로우 데이터를 덤프해서 분석하기 위한 용도이므로 이점은 기억해 두자. 맨앞에 숫자는 패킷의 넘버를 뜻하는 것이고, 그 뒤로 숫자 1 또는 0 이 보인다. 출력 필터로 지정한 것에 대한 필드의 매치 여부를 나타내는 것으로 1이면 매치가 되었다는 것이다. 11번을 보면 HTTP 호스트 정보가 매칭되어서 1 로 표시된것을 볼 수 있다.
마지막으로 앞서 cat 을 통해 출력 시켰는데, 이외에도 tcpdump 를 통해서도 할 수 있고, wireshark 를 통해서도 할 수 있다. 출력을 rawshark 로 넘겨줄수만 있으면 된다.
# tcpdump -r test.pcap -n -w - | rawshark -d encap:EN10MB -r- -s -F ip.dst -F http.host
다음은 eth1 인터페이스를 실시간으로 rawshark 로 넘기는 것이다. 이때 rawshark 옵션으로 -l 옵션을 추가로 사용하였다. 바로바로 실시간으로 데이터가 넘어오기 때문에 바로 Flush 시키도록 한 것이다.
# tcpdump -i eth1 -s 1514 -w - | rawshark -d encap:EN10MB -l -r- -s -F ip.dst -F http.host
[참고]
1. Libpcap 데이터 링크레이어 타입
http://www.tcpdump.org/pcap3_man.html
2. Rawshark 공식 메뉴얼
http://www.wireshark.org/docs/man-pages/rawshark.html
3. 패킷인사이드 libpcap 관련 태그 보기
http://www.packetinside.com/search/label/libpcap
2011년 1월 6일 목요일
패킷파일의 민감한 정보를 지우고 전달하고자 하는 경우에는 이 방법을!
패킷파일을 전달하여야 하는데, 사내 IP 정보들이 알려지기는 싫고 할때 어떤 방법을 써야 할까? 패킷인사이드를 꾸준히 방문한 분들이라면 앞서 몇번 언급했던 패킷조작 프로그램을 이용해 IP 등을 변경할 수 있다. 또는 지금 필자가 소개하고자 하는 tcpdpriv 를 이용하면 간단히 해결된다. tcpdpriv 는 프로그램 이름에서도 살짝 느껴지는 것과 같이 패킷파일에서 private 한 정보를 제거해 주는 기능을 갖고 있다.
프로그램 정보 및 다운로드는 다음의 경로를 방문하면 된다 :
http://fly.isti.cnr.it/software/tcpdpriv/
다운 받은 파일은 컴파일 과정을 거쳐야 한다. 제작 된지 오래된 소스이기도 해서 첫 버전은 FreeBSD 와 같이 몇몇 시스템에서만 테스트 되었고 configure 옵션도 csh 로 지정되어 있었다.
지금 버전은 그래도 리눅스에서도 컴파일이 가능하다.
# ./configure
cat: VERSION: No such file or directory
./configure 를 통해 Makefile 이 만들어 지면 make 를 수행하자
debian:~/# make
gcc -g -Wall -c -o tcpdpriv.o tcpdpriv.c
tcpdpriv.c: In function ‘verify_and_print_args’:
tcpdpriv.c:1504: error: invalid storage class for function ‘usage’
tcpdpriv.c:1570: warning: implicit declaration of function ‘usage’
tcpdpriv.c: At top level:
tcpdpriv.c:1749: warning: conflicting types for ‘usage’
tcpdpriv.c:1749: error: static declaration of ‘usage’ follows non-static declaration
tcpdpriv.c:1570: error: previous implicit declaration of ‘usage’ was here
make: *** [tcpdpriv.o] Error 1
그런데 컴파일 하는 과정에서 에러가 발생한다. 이 에러는 다음과 같이 수정하면 된다
# vi tcpdpriv.c
tcpdpriv 소스파일을 오픈하고 두군데를 수정하면 된다.
1) 1504 라인에서 static void usage(char *cmd); => 를 void usage 로 변경
2) 1749 라인에서 static 을 삭제
그리고 다시 컴파일을 하면 된다.
# make
gcc -g -Wall -c -o tcpdpriv.o tcpdpriv.c
tcpdpriv.c:33: warning: ‘rcsid’ defined but not used
gcc -g -Wall -c -o tcpdutil.o tcpdutil.c
tcpdutil.c:24: warning: ‘rcsid’ defined but not used
gcc -g -Wall -o tcpdpriv tcpdpriv.o tcpdutil.o -lpcap
컴파일이 완료되면 다음과 실행하여 옵션들을 살펴볼 수 있다.
간단하게 옵션 몇개를 살펴보자.
-A : IP 주소를 어떤식으로 표현할지를 결정한다. 레벨이 99인 경우 IP 주소는 변하지 않는다.
-c : 지정한 패킷 카운트 후에 종료한다.
-F : 사용할 필터를 지정
-i : 네트워크 인터페이스
-p : TCP, UDP 포트주소를 매핑한다.
-r : 읽어들일 패킷 파일을 지정
-w : 출력할 파일을 지정
위 옵션들을 보면 각 옵션마다 특정 값을 지정하는 것이 있어, 얼핏보면 복잡해 보인다.
간단하게 생각하면 0은 가장 안전한 옵션이라 생각하면 된다. 즉, 가급적 Private 한 정보는
제거하게 되고 , 99 는 많은 정보를 보여주는 것이라 볼 수 있다. 이런 개념으로 옵션에 사용되는 값을 이해하면 될것 같다.
직접 사용해 보는 것이 이해가 가능 빠르므로 한번 예를 살펴보자. 다음은 정상적인 일반 패킷 파일을 tcpdump 로 본 것이다.
11:11:33.480941 IP6 fe80::f95c:91a7:8bd8:6216.49403 > ff02::c.1900: UDP, length 146
11:11:34.532638 arp who-has 192.168.0.200 tell 192.168.0.240
11:11:34.534733 arp reply 192.168.0.200 is-at 00:01:36:2e:0b:a7 (oui Unknown)
11:11:34.534756 IP 192.168.0.240.48603 > kns.kornet.net.domain: 34133+ AAAA? www
.google.co.kr. (34)
11:11:34.545974 IP kns.kornet.net.domain > 192.168.0.240.48603: 34133 2/1/0 CNAM
E[|domain]
11:11:34.546180 IP 192.168.0.240.60837 > kns.kornet.net.domain: 30670+ A? www.go
ogle.co.kr. (34)
11:11:34.554454 IP kns.kornet.net.domain > 192.168.0.240.60837: 30670 8/4/4 CNAM
E[|domain]
11:11:34.555094 IP 192.168.0.240.45918 > pv-in-f99.1e100.net.www: S 2001641216:2
001641216(0) win 5840 <mss 1460,sackOK,timestamp 1127508 0,nop,wscale 4>
특별한 옵션을 사용하지 않고 -r 옵션을 통해 읽어들일 파일과 새로 저장할 파일을 지정하였다. 기본 옵션은 최대한 정보를 제거하는 것으로 설정되어 있다. (즉, 0 이다)
# ./tcpdpriv -w test2.pcap -r test.pcap
# map 32-bit addresses into sequential integers
# multicast addresses cloaked per -A and -C flags
# map 16-bit TCP port numbers into sequential integer
# map 16-bit UDP port numbers into sequential integer
# pktsin 138 pktsout 134 tooshort 0 uncoded 4
새롭게 저장된 test2.pcap 파일을 열어보면 IP 주소가 변경된걸 알 수 있다. 처음에 보였던 IPv6 와 ARP 정보도 보이지 않는다. 또한, 헤더 정보에 nop 이 많이 보여진다.
# tcpdump -r test2.pcap
11:11:34.534756 IP 1.0.0.1.1 > 1.0.0.2.2: UDP, length 34
11:11:34.545974 IP 1.0.0.2.2 > 1.0.0.1.1: UDP, length 132
11:11:34.546180 IP 1.0.0.1.3 > 1.0.0.2.2: UDP, length 34
11:11:34.554454 IP 1.0.0.2.2 > 1.0.0.1.3: UDP, length 314
11:11:34.555094 IP 1.0.0.1.tcpmux > 1.0.0.3.2: S 2001641216:2001641216(0) win 5840 <nop,no
p,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop>
11:11:34.685957 IP 1.0.0.3.2 > 1.0.0.1.tcpmux: S 959091973:959091973(0) ack 2001641217 win
5672 <nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop>
11:11:34.686035 IP 1.0.0.1.tcpmux > 1.0.0.3.2: . ack 1 win 365 <nop,nop,nop,nop,nop,nop,no
p,nop,nop,nop,nop,nop>
11:11:34.686326 IP 1.0.0.1.tcpmux > 1.0.0.3.2: P 1:614(613) ack 1 win 365 <nop,nop,nop,nop
,nop,nop,nop,nop,nop,nop,nop,nop>
11:11:34.816891 IP 1.0.0.3.2 > 1.0.0.1.tcpmux: . ack 614 win 108 <nop,nop,nop,nop,nop,nop,
nop,nop,nop,nop,nop,nop>
11:11:34.833127 IP 1.0.0.3.2 > 1.0.0.1.tcpmux: . 1:1419(1418) ack 614 win 108 <nop,nop,nop
,nop,nop,nop,nop,nop,nop,nop,nop,nop>
11:11:34.833160 IP 1.0.0.1.tcpmux > 1.0.0.3.2: . ack 1419 win 546 <nop,nop,nop,nop,nop,nop
,nop,nop,nop,nop,nop,nop>
그럼 다른 옵션을 한번 사용해 보자. IP 주소의 변화를 좀 주고, -P 를 통해 포트번호가 바뀌지 않도록 99 를 주었다.
# ./tcpdpriv -A 50 -P 99 -w test2.pcap -r test.pcap
# tcpdump -r test2.pcap | more
11:11:34.534756 IP 16.76.127.170.48603 > 92.36.179.36.domain: [|domain]
11:11:34.545974 IP 92.36.179.36.domain > 16.76.127.170.48603: [|domain]
11:11:34.546180 IP 16.76.127.170.60837 > 92.36.179.36.domain: [|domain]
11:11:34.554454 IP 92.36.179.36.domain > 16.76.127.170.60837: [|domain]
11:11:34.555094 IP 16.76.127.170.45918 > 136.110.214.97.www: S 2001641216:2001641216(0) wi
n 5840 <nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop>
11:11:34.685957 IP 136.110.214.97.www > 16.76.127.170.45918: S 959091973:959091973(0) ack
2001641217 win 5672 <nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,n
op,nop,nop>
11:11:34.686035 IP 16.76.127.170.45918 > 136.110.214.97.www: . ack 1 win 365 <nop,nop,nop,
nop,nop,nop,nop,nop,nop,nop,nop,nop>
11:11:34.686326 IP 16.76.127.170.45918 > 136.110.214.97.www: P 1:614(613) ack 1 win 365 <n
op,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop>
11:11:34.816891 IP 136.110.214.97.www > 16.76.127.170.45918: . ack 614 win 108 <nop,nop,no
p,nop,nop,nop,nop,nop,nop,nop,nop,nop>
그러면, 위와 같이 IP 는 좀더 랜덤하게 변했지만, 포트번호는 그대로 유지하고 있다. 포트번호는 유지하면서 IP 주소만 변경하여 패킷파일을 전달하는 경우 사용될 수 있다.
tcpdpriv 는 간단하게도 사용할 수 있는 만큼, 패킷파일 에서 민감한 내용을 제거할 때 유용하게 사용할 수 있을것이다.
프로그램 정보 및 다운로드는 다음의 경로를 방문하면 된다 :
http://fly.isti.cnr.it/software/tcpdpriv/
다운 받은 파일은 컴파일 과정을 거쳐야 한다. 제작 된지 오래된 소스이기도 해서 첫 버전은 FreeBSD 와 같이 몇몇 시스템에서만 테스트 되었고 configure 옵션도 csh 로 지정되어 있었다.
지금 버전은 그래도 리눅스에서도 컴파일이 가능하다.
# ./configure
cat: VERSION: No such file or directory
./configure 를 통해 Makefile 이 만들어 지면 make 를 수행하자
debian:~/# make
gcc -g -Wall -c -o tcpdpriv.o tcpdpriv.c
tcpdpriv.c: In function ‘verify_and_print_args’:
tcpdpriv.c:1504: error: invalid storage class for function ‘usage’
tcpdpriv.c:1570: warning: implicit declaration of function ‘usage’
tcpdpriv.c: At top level:
tcpdpriv.c:1749: warning: conflicting types for ‘usage’
tcpdpriv.c:1749: error: static declaration of ‘usage’ follows non-static declaration
tcpdpriv.c:1570: error: previous implicit declaration of ‘usage’ was here
make: *** [tcpdpriv.o] Error 1
그런데 컴파일 하는 과정에서 에러가 발생한다. 이 에러는 다음과 같이 수정하면 된다
# vi tcpdpriv.c
tcpdpriv 소스파일을 오픈하고 두군데를 수정하면 된다.
1) 1504 라인에서 static void usage(char *cmd); => 를 void usage 로 변경
2) 1749 라인에서 static 을 삭제
그리고 다시 컴파일을 하면 된다.
# make
gcc -g -Wall -c -o tcpdpriv.o tcpdpriv.c
tcpdpriv.c:33: warning: ‘rcsid’ defined but not used
gcc -g -Wall -c -o tcpdutil.o tcpdutil.c
tcpdutil.c:24: warning: ‘rcsid’ defined but not used
gcc -g -Wall -o tcpdpriv tcpdpriv.o tcpdutil.o -lpcap
컴파일이 완료되면 다음과 실행하여 옵션들을 살펴볼 수 있다.
# ./tcpdpriv
attempt to write binary dump file to tty
usage:
./tcpdpriv [-Opq] [-a [[hh:]mm:]ss] [-A {0|1|2|50|99}] [-c count]
[-C {0|1|2|3|4|...|32|99}] [-F file] [-i interface]
[-M {0|10|20|70|80|90|99}] [-{P|T|U} {0|1|99}] [-r file]
[-s snaplen] [-w outputfile] [expression]
(one reasonable choice: ./tcpdpriv -P99 -C4 -M20 ...)
attempt to write binary dump file to tty
usage:
./tcpdpriv [-Opq] [-a [[hh:]mm:]ss] [-A {0|1|2|50|99}] [-c count]
[-C {0|1|2|3|4|...|32|99}] [-F file] [-i interface]
[-M {0|10|20|70|80|90|99}] [-{P|T|U} {0|1|99}] [-r file]
[-s snaplen] [-w outputfile] [expression]
(one reasonable choice: ./tcpdpriv -P99 -C4 -M20 ...)
간단하게 옵션 몇개를 살펴보자.
-A : IP 주소를 어떤식으로 표현할지를 결정한다. 레벨이 99인 경우 IP 주소는 변하지 않는다.
-c : 지정한 패킷 카운트 후에 종료한다.
-F : 사용할 필터를 지정
-i : 네트워크 인터페이스
-p : TCP, UDP 포트주소를 매핑한다.
-r : 읽어들일 패킷 파일을 지정
-w : 출력할 파일을 지정
위 옵션들을 보면 각 옵션마다 특정 값을 지정하는 것이 있어, 얼핏보면 복잡해 보인다.
간단하게 생각하면 0은 가장 안전한 옵션이라 생각하면 된다. 즉, 가급적 Private 한 정보는
제거하게 되고 , 99 는 많은 정보를 보여주는 것이라 볼 수 있다. 이런 개념으로 옵션에 사용되는 값을 이해하면 될것 같다.
직접 사용해 보는 것이 이해가 가능 빠르므로 한번 예를 살펴보자. 다음은 정상적인 일반 패킷 파일을 tcpdump 로 본 것이다.
11:11:33.480941 IP6 fe80::f95c:91a7:8bd8:6216.49403 > ff02::c.1900: UDP, length 146
11:11:34.532638 arp who-has 192.168.0.200 tell 192.168.0.240
11:11:34.534733 arp reply 192.168.0.200 is-at 00:01:36:2e:0b:a7 (oui Unknown)
11:11:34.534756 IP 192.168.0.240.48603 > kns.kornet.net.domain: 34133+ AAAA? www
.google.co.kr. (34)
11:11:34.545974 IP kns.kornet.net.domain > 192.168.0.240.48603: 34133 2/1/0 CNAM
E[|domain]
11:11:34.546180 IP 192.168.0.240.60837 > kns.kornet.net.domain: 30670+ A? www.go
ogle.co.kr. (34)
11:11:34.554454 IP kns.kornet.net.domain > 192.168.0.240.60837: 30670 8/4/4 CNAM
E[|domain]
11:11:34.555094 IP 192.168.0.240.45918 > pv-in-f99.1e100.net.www: S 2001641216:2
001641216(0) win 5840 <mss 1460,sackOK,timestamp 1127508 0,nop,wscale 4>
특별한 옵션을 사용하지 않고 -r 옵션을 통해 읽어들일 파일과 새로 저장할 파일을 지정하였다. 기본 옵션은 최대한 정보를 제거하는 것으로 설정되어 있다. (즉, 0 이다)
# ./tcpdpriv -w test2.pcap -r test.pcap
# map 32-bit addresses into sequential integers
# multicast addresses cloaked per -A and -C flags
# map 16-bit TCP port numbers into sequential integer
# map 16-bit UDP port numbers into sequential integer
# pktsin 138 pktsout 134 tooshort 0 uncoded 4
새롭게 저장된 test2.pcap 파일을 열어보면 IP 주소가 변경된걸 알 수 있다. 처음에 보였던 IPv6 와 ARP 정보도 보이지 않는다. 또한, 헤더 정보에 nop 이 많이 보여진다.
# tcpdump -r test2.pcap
11:11:34.534756 IP 1.0.0.1.1 > 1.0.0.2.2: UDP, length 34
11:11:34.545974 IP 1.0.0.2.2 > 1.0.0.1.1: UDP, length 132
11:11:34.546180 IP 1.0.0.1.3 > 1.0.0.2.2: UDP, length 34
11:11:34.554454 IP 1.0.0.2.2 > 1.0.0.1.3: UDP, length 314
11:11:34.555094 IP 1.0.0.1.tcpmux > 1.0.0.3.2: S 2001641216:2001641216(0) win 5840 <nop,no
p,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop>
11:11:34.685957 IP 1.0.0.3.2 > 1.0.0.1.tcpmux: S 959091973:959091973(0) ack 2001641217 win
5672 <nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop>
11:11:34.686035 IP 1.0.0.1.tcpmux > 1.0.0.3.2: . ack 1 win 365 <nop,nop,nop,nop,nop,nop,no
p,nop,nop,nop,nop,nop>
11:11:34.686326 IP 1.0.0.1.tcpmux > 1.0.0.3.2: P 1:614(613) ack 1 win 365 <nop,nop,nop,nop
,nop,nop,nop,nop,nop,nop,nop,nop>
11:11:34.816891 IP 1.0.0.3.2 > 1.0.0.1.tcpmux: . ack 614 win 108 <nop,nop,nop,nop,nop,nop,
nop,nop,nop,nop,nop,nop>
11:11:34.833127 IP 1.0.0.3.2 > 1.0.0.1.tcpmux: . 1:1419(1418) ack 614 win 108 <nop,nop,nop
,nop,nop,nop,nop,nop,nop,nop,nop,nop>
11:11:34.833160 IP 1.0.0.1.tcpmux > 1.0.0.3.2: . ack 1419 win 546 <nop,nop,nop,nop,nop,nop
,nop,nop,nop,nop,nop,nop>
그럼 다른 옵션을 한번 사용해 보자. IP 주소의 변화를 좀 주고, -P 를 통해 포트번호가 바뀌지 않도록 99 를 주었다.
# ./tcpdpriv -A 50 -P 99 -w test2.pcap -r test.pcap
# tcpdump -r test2.pcap | more
11:11:34.534756 IP 16.76.127.170.48603 > 92.36.179.36.domain: [|domain]
11:11:34.545974 IP 92.36.179.36.domain > 16.76.127.170.48603: [|domain]
11:11:34.546180 IP 16.76.127.170.60837 > 92.36.179.36.domain: [|domain]
11:11:34.554454 IP 92.36.179.36.domain > 16.76.127.170.60837: [|domain]
11:11:34.555094 IP 16.76.127.170.45918 > 136.110.214.97.www: S 2001641216:2001641216(0) wi
n 5840 <nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop>
11:11:34.685957 IP 136.110.214.97.www > 16.76.127.170.45918: S 959091973:959091973(0) ack
2001641217 win 5672 <nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,n
op,nop,nop>
11:11:34.686035 IP 16.76.127.170.45918 > 136.110.214.97.www: . ack 1 win 365 <nop,nop,nop,
nop,nop,nop,nop,nop,nop,nop,nop,nop>
11:11:34.686326 IP 16.76.127.170.45918 > 136.110.214.97.www: P 1:614(613) ack 1 win 365 <n
op,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop>
11:11:34.816891 IP 136.110.214.97.www > 16.76.127.170.45918: . ack 614 win 108 <nop,nop,no
p,nop,nop,nop,nop,nop,nop,nop,nop,nop>
그러면, 위와 같이 IP 는 좀더 랜덤하게 변했지만, 포트번호는 그대로 유지하고 있다. 포트번호는 유지하면서 IP 주소만 변경하여 패킷파일을 전달하는 경우 사용될 수 있다.
tcpdpriv 는 간단하게도 사용할 수 있는 만큼, 패킷파일 에서 민감한 내용을 제거할 때 유용하게 사용할 수 있을것이다.
2011년 1월 4일 화요일
패킷정보를 요약하여 통신내용을 한눈에 살펴보자!
패킷파일 안의 내용이 간단하면 분석가가 직접 눈으로 살피는 것 만으로도 어느정도 파악이 쉽게 된다. 그런데, 패킷파일이 수십메가 이상이 되어버리면 분석은 쉽지 않아진다. 더군다나, 아주 다양한 내용으로 까지 구성되어 있다면 더욱 힘들다.
그렇기 때문에 패킷분석기의 도움을 받는 것이다. 하지만, 때로는 간단히 대략 살펴보고 싶기도 하다. 이럴때 유용하게 사용할 수 있는 것이 있다. 패킷파일안에서의 통신과정을 대략 요약하여 정리해 보여주는 'nstreams' 라는 것이 있다. tcpdump 형태를 분석해 줄 수 있는 도구로 보면 된다. 일단, 다운로드는 다음의 경로에서 할 수 있다.
그렇기 때문에 패킷분석기의 도움을 받는 것이다. 하지만, 때로는 간단히 대략 살펴보고 싶기도 하다. 이럴때 유용하게 사용할 수 있는 것이 있다. 패킷파일안에서의 통신과정을 대략 요약하여 정리해 보여주는 'nstreams' 라는 것이 있다. tcpdump 형태를 분석해 줄 수 있는 도구로 보면 된다. 일단, 다운로드는 다음의 경로에서 할 수 있다.
http://www.hsc.fr/ressources/outils/nstreams/
다운받은 후 컴파일은 아래와 같은 순서로 진행하면 된다.
# tar -zxvf nstream-1.0.0.tar.gz
# cd nstreams
# ./configure
# make
# make install
이외 APT 패키지 사용자는
# apt-get install nstreams 로 간단히 설치할 수 있다.
관련파일이 2가지가 있는데, 없어도 사용하는데는 문제없다. 다만, 본인의 네트워크를 정의하거나 또는 사용 서비스를 정의해 놓으면 출력 내용을 볼 때 편리한 점은 있다.
1) 서비스 정의
nstreams-services 라는 파일이 있다. 여기에 프로토콜의 이름 같은 것을 정의할 수 있는데 형태는 아래와 같다 :
protocol_name:server_port(s)/{udp,tcp}:client_ports(s)
또는
protocol_name:type(s)/icmp:code(s)
# vi /etc/nstreams-services
telnet:23/tcp:any
bsd-passive-ftp:49152-65535/tcp:1024-65535
icmp-echo-request:8/icmp:0
bootps:67/udp:68
2) 네트워크 정보
네트워크의 영역을 정의해 놓을 수 있다.
internal-network:192.168.1.0/24
test-network:212.198.0.0/16
internet:0.0.0.0/0
다운받은 후 컴파일은 아래와 같은 순서로 진행하면 된다.
# tar -zxvf nstream-1.0.0.tar.gz
# cd nstreams
# ./configure
# make
# make install
이외 APT 패키지 사용자는
# apt-get install nstreams 로 간단히 설치할 수 있다.
관련파일이 2가지가 있는데, 없어도 사용하는데는 문제없다. 다만, 본인의 네트워크를 정의하거나 또는 사용 서비스를 정의해 놓으면 출력 내용을 볼 때 편리한 점은 있다.
1) 서비스 정의
nstreams-services 라는 파일이 있다. 여기에 프로토콜의 이름 같은 것을 정의할 수 있는데 형태는 아래와 같다 :
protocol_name:server_port(s)/{udp,tcp}:client_ports(s)
또는
protocol_name:type(s)/icmp:code(s)
제일 앞에 프로토콜의 이름이 온다. 그리고 서버의 포트 그리고 클라이언트 포트 정보가 오는데 대략 봐도 어떤 형태의 구성인지 쉽게 이해가 될 것이다.
# vi /etc/nstreams-services
telnet:23/tcp:any
bsd-passive-ftp:49152-65535/tcp:1024-65535
icmp-echo-request:8/icmp:0
bootps:67/udp:68
2) 네트워크 정보
네트워크의 영역을 정의해 놓을 수 있다.
internal-network:192.168.1.0/24
test-network:212.198.0.0/16
internet:0.0.0.0/0
정의해 놓으면 화면 출력시 좀더 이해하기 쉬워지는데, 이것은 아래 출력 예제를 보는
것으로 쉽게 이해가 될 것이다.
# nstreams -f test.pcap
dns traffic between 192.168.0.240 and 168.126.63.1
http traffic between 192.168.0.240 and 72.14.213.99
http traffic between 192.168.0.240 and 74.125.127.102
http traffic between 192.168.0.240 and 72.14.213.103
http traffic between 192.168.0.240 and 72.14.213.100
아래서는 해당 네트워크 대역이 정의해 놓은 것으로 치환되어 나타난다.
# nstreams -n /etc/nstreams/nstreams-networks -f test.pcap
dns traffic between private-network and internet
http traffic between private-network and internet
또 파일 외에 -l 로 인터페이스를 지정하면 실시간으로 볼 수도 있다.
# nstreams -l eth1
http traffic between private-network and internethttp traffic between 192.168.15.11 and 219.94.214.228
http traffic between 192.168.15.11 and 74.125.53.132
http traffic between 192.168.15.11 and 210.171.226.45
icmp-unreach traffic between 192.168.15.11 and 168.126.63.1
http traffic between 192.168.15.11 and 74.125.127.113
http traffic between 192.168.15.11 and 128.31.0.36
http traffic between 192.168.15.11 and 35.9.37.225
telnet traffic between 192.168.15.11 and 74.125.127.105
icmp-unreach traffic between 192.168.15.11 and 168.126.63.2
http traffic between 192.168.15.11 and 86.59.118.153
http traffic between 192.168.15.10 and 72.14.213.191
출력되는 형태가 간단하여 분석할 패킷파일의 용량이 큰 경우에는 대략적인 형태를
파악하는데 도움이 될 것이다. 또 오픈소스 이므로, 본인이 원하는 형태로도 수정하여
사용가능하다. 예를 들어, 출력되는 부분을 약간 바꿔보고자 한다.
그럼, output.c 소스파일을 열어 살펴보자. 목적지 포트가 1024 인 경우에 조금
다르게 출력해 본다면, printf 로 출력되는 부분을 살짝 변경해 더 쉽게 볼 수 있게 한다든지
원하는 형태로 할 수 있다.
void
standard_output(output, status)
struct output * output;
int status;
{
if(status)return;
if(!strcmp(output->serv_name, "unknown"))
{
if(!opt_u)
{
if(output->dport > 1024) {
printf("[* Suspicious > 1024] Unknown %s traffic between %s:%d and %s:%d \n",
output->asc_proto,
output->src, output->sport,
output->dst, output->dport);
} else {
printf("Unknown %s traffic between %s:%d and %s:%d\n",
output->asc_proto,
output->src, output->sport,
output->dst, output->dport);
}
}
}
오픈소스이기 때문에 내 상황에 맞게 적절히 수정하여 사용한다면 내 입맛에 맞는
최고의 분석도구가 될 것이다. 이게 바로 오픈소스의 맛 아닐까?
2010년 12월 20일 월요일
트래픽 흐름에 따라 사운드를 출력해 보자!
재미있는 유틸리티 하나를 소개해 본다. 일전에 트래픽 흐름 상태를 키보드의 LED 표시를 통해
깜빡 거리는 것을 소개한적 있다. 이와 같이 조금은 재미있는 형태의 프로그램이라 보면 된다.
키보드 LED 정보를 이용한 블로그 글은 다음을 참고한다.
-> 2010/04/26 Rigel 키보드 LED 를 이용한 패킷 송신/수신 표시하기
오늘 소개하고자 하는것은, 트래픽 흐름의 형태에 따라 사운드를 출력시키는 것이다. 트래픽 종류에 따라
지정된 사운드가 스피커를 통해 흘러나온다. 이름하여 Tcpsound 이다. 파일은 아래 URL 에서 받을 수 있다.
컴파일 하기 위해서는 libsdl 와 libmba 라이브러리가 필요하다. libmba 는 아래 경로를 참고한다.
APT 패키지 사용자는 sdl 패키지를 아래와 같이 설치할 수 있다.
# apt-cache search libsdl-sound
libsdl-sound1.2-dev - Development files for SDL_sound
libsdl-sound1.2 - Decoder of several sound file formats for SDL
# apt-get install libsdl-sound1.2-dev
이후 다운받은 tcpsound 패키지의 압축을 풀고 'make' 를 해 주면 된다.
컴파일 된 tcpsound 를 실행하면 아래와 같은 메시지가 발생된다.
$ ./tcpsound
searchpath: /usr/share/sounds:/usr/local/share/sounds
proto src dst wav path
src/sound.c:64:path_search: No such file or directory: generic.wav
src/sound.c:154:sound_load_cfg: Rule will be ignored.
src/sound.c:64:path_search: No such file or directory: sonar.wav
src/sound.c:154:sound_load_cfg: Rule will be ignored.
src/sound.c:64:path_search: No such file or directory: warning.wav
src/sound.c:154:sound_load_cfg: Rule will be ignored.
src/sound.c:64:path_search: No such file or directory: pop.wav
src/sound.c:154:sound_load_cfg: Rule will be ignored.
src/sound.c:64:path_search: No such file or directory: info.wav
src/sound.c:154:sound_load_cfg: Rule will be ignored.
src/sound.c:64:path_search: No such file or directory: cuckoo.wav
src/sound.c:154:sound_load_cfg: Rule will be ignored.
사운드 파일을 찾지 못해서 발생하는 것이다. 이럴 경우 따로 파일의 경로를 지정해 주거나 또는, make install 하게 되면 적절한 위치에 다 복사가 된다.
# make install
./mktool -i -m 0755 tcpsound /usr/local/bin
./mktool -i wavs/*.wav /usr/local/share/sounds
./mktool -i docs/man/*.1.gz /usr/local/man/man1
installation successful
tcpsound 를 실행하면 각 프로토콜 또는 포트번호 별로 지정된 사운드가 있는 것을 알 수 있다.
# tcpsound
searchpath: /usr/share/sounds:/usr/local/share/sounds
proto src dst wav path
ARP 0 0 /usr/local/share/sounds/generic.wav
ICMP 0 0 /usr/local/share/sounds/sonar.wav
IP 53 53 /usr/local/share/sounds/warning.wav
IP 0 80 /usr/local/share/sounds/pop.wav
IP 80 0 /usr/local/share/sounds/info.wav
IP 137 137 /usr/local/share/sounds/cuckoo.wav
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth1, link-type EN10MB (Ethernet), capture size 96 bytes
02:55:06.019559 IP 204.152.191.39.80 > 192.168.15.11.38248: . 2697887135:2697888583(1448) ack 4005699112 win 88 <nop,nop,timestamp 1513910257 322740>
02:55:06.044274 IP 204.152.191.39.80 > 192.168.15.11.38248: . 1448:2896(1448) ack 1 win 88 <nop,nop,timestamp 1513910257 322740>
실행되면 스피커에서 뽁,뽀,뽁 과 같은 사운드가 발생되는 들을 수 있다. 이외 -r 옵션을 이용하면
원격지로 로그인하여 실행도 가능하다. 원격지 로그인은 SSH 접속으로 이루어진다.
이 tcpsound 를 보면 그냥 단순히 재미있는 프로그램이기도 하지만, 특별한 목적으로 만들어 사용하는 것도
나름 의미가 있을것 같다. 특정한 포트를 임의의 사운드 파일로 지정하여,
트래픽이 발생될 경우 알람음 형태로 이용이 가능할 수도 있다. 평소에 접근이 이루어지지 않는 포트인데
외부에서 접근이 이뤄지면 음성으로 알려준다면, 나름 좋은 아이디어 아닐까.
특히나 관제 및 서비스 운영 팀 같은데서는 유용하게 이용될 수도 있을것 같다.
참고로, tcpdump 를 기본으로 이용하므로 tcpdump 가 설치되어 있어야 한다.
2010년 12월 7일 화요일
패킷 정보가 제대로 안보인다고 ?
패킷 덤프를 하다보면 정보가 제대로 출력이 되지 않는 경우가 있다. 이런 경우는,
해당 프로토콜을 알 수 없거나 또는 출력할 정보가 없는 것이다.
tcpdump 로 덤프하다 보면 아래와 같이 빈 공백으로 나오는 것이 있다. 이것은 단지 하나의 예이다.
# tcpdump -r test.pcap | more
reading from file test.pcap, link-type EN10MB (Ethernet)
17:24:22.251252
17:24:32.255374
17:24:32.953486 IP 192.3.3.14.netbios-dgm > 192.3.255.255.netbios-dgm: NBT UDP PACKET(138)
보통은 간단한 요약 정보가 표시되는데 상위 2줄은 공백으로 비워 있다. 아니, 왜 정보가 제대로 출력되지
않는 것일까? 좀더 세부적으로 보기 위해 -X 옵션을 사용해 보자!
# tcpdump -r test.pcap -X | more
reading from file test.pcap, link-type EN10MB (Ethernet)
17:24:22.251252
0x0000: 0000 0100 0000 0000 0000 0000 0000 0000 ................
0x0010: 0000 0000 0000 0000 0000 0000 0000 0000 ................
0x0020: 0000 0000 0000 0000 0000 0000 0000 ..............
17:24:32.255374
0x0000: 0000 0100 0000 0000 0000 0000 0000 0000 ................
0x0010: 0000 0000 0000 0000 0000 0000 0000 0000 ................
0x0020: 0000 0000 0000 0000 0000 0000 0000 ..............
보이는 것이라고는 0x00 만이 반복된다. 도대체 이것이 무엇이던가?
-XX 옵션을 사용해 링크레이어 정보까지 확인해 보자.
17:24:22.251252
0x0000: 0009 xx3f 1b8f 0009 xx3f 1b8f 9000 0000 ..|?....|?......
0x0010: 0100 0000 0000 0000 0000 0000 0000 0000 ................
0x0020: 0000 0000 0000 0000 0000 0000 0000 0000 ................
0x0030: 0000 0000 0000 0000 0000 0000 ............
17:24:32.255374
0x0000: 0009 xx3f 1b8f 0009 xx3f 1b8f 9000 0000 ..|?....|?......
0x0010: 0100 0000 0000 0000 0000 0000 0000 0000 ................
0x0020: 0000 0000 0000 0000 0000 0000 0000 0000 ................
0x0030: 0000 0000 0000 0000 0000 0000 ............
이더넷 헤더에 익숙한 사용자라면 딱 보고 알 수 있겠지만, 일단 이더넷 헤더 구조를 보면 아래와 같다:
Destination MAC address | Source MAC address | Type/Length | User Data |
MAC 주소는 각각 6 바이트 이다. 그럼 타입을 보면 0x9000 인걸 알 수 있다. 0x9000 타입은 무엇일까?
이더넷 타입은 미리 정의된 것이 있으며, 아래 주소에서 각 타입을 살펴볼 수 있다.
36864 9000 - - Loopback [XEROX]
9000 은 루프백으로 표시되어 있다. 좀더 쉽게 보기위해서는 와이어샤크를 통해 보면
쉽게 알 수 있다. 즉, 루프 프로토콜이었는데, 와이어샤크에서는 파싱하여 보여줄 수 있었지만,
tcpdump 에서는 나타나지 않은 것이다.

또는 tshark 로 아래와 같이도 확인해 볼 수 있다.
# tshark -r test.pcap -V | more
Frame 1 (60 bytes on wire, 60 bytes captured)
Arrival Time: Dec 3, 2010 17:24:22.251252000
[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: 60 bytes
Capture Length: 60 bytes
[Frame is marked: False]
[Protocols in frame: eth:loop:data]
Ethernet II, Src:
(생략...)
Type: Loopback (0x9000)
Configuration Test Protocol (loopback)
skipCount: 0
Relevant function:
Function: Reply (1)
Receipt number: 0
Data (40 bytes)
0000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0020 00 00 00 00 00 00 00 00 ........
Data: 000000000000000000000000000000000000000000000000...
패킷 분석 프로그램에 따라 처리하여 보여줄 수 있는 것도 있고, 아닌것도 있다. 여기 예에서는
이더넷 타입이 루프 타입인걸 소개한 것으로, 이 루프 타입은 Layer 2 상에서 'ping' 과 같은
형태로 보면 된다.
패킷 분석을 진행하다 보면 모르는 프로토콜 형태, 타입을 보다 이게 무엇이지 하고
분석 시간이 지연되는 경우가 크다. 그 만큼 분석에는 많은 경험이 있어야 정확히 무엇을 분석해 내야 할지
판단할 수도 있다. 물론, 상황에 따라 다 다르다.
어찌되었든 이런 경우도 있다는 것을 참고하기 바란다.
2010년 11월 17일 수요일
커널에서 drop 되는 패킷 수가 많다면...
tcpdump 와 같은 패킷 덤프 프로그램을 사용하면 몇 건의 패킷덤프가 되었는지 확인할 수 있다. 그런데, 캡쳐된 상태를 관심있게 살펴 보았다면, 의외로 drop 된 패킷 건수가 크게 나타나는 경우를 경험해 보았을지도 모른다.
다음의 경우를 보자:
16 packets captured
351742 packets received by filter
351655 packets dropped by kernel
tcpdump 를 이용해 패킷 덤프를 하다 Ctrl+C 를 통해 중지 하였는데, 16개의 패킷이 캡쳐되었다. 그런데 packets dropped by kernel 을 보면 그 카운터가 꽤 높다. 필터에서 받은 패킷 건수가 351,742 건인데 drop된 건수가 351,655 라는 것이다. 이러한 것은 다양한 원인이 있겠지만, 사용하는 패킷덤프 프로그램에 의한 영향이거나, 네트워크적인 영향, 하드웨어, 패킷필터, 운영체제와 관련한 것등이 있을 것이다.
이런 경우 IP 주소등을 이름으로 변경하는 작업등이 이뤄지지 않도록 하는 것 만으로도 큰 효과를 볼 수 있다.
tcpdump 에서는 '-n' 옵션을 사용하면 된다.
# tcpdump -i eth0 -n
51119 packets captured
51612 packets received by filter
493 packets dropped by kernel
같은 조건의 환경인데, -n 만을 사용하는 것만으로도 큰 차이가 나타난다. 패킷덤프시에는 이점을 참고하기 바란다. 이외, 커널 상에서 네트워크 관련 파라미터를 수정하는 것도 도움이 될 것이다. 패킷 덤프만이 아니라, 네트워크 관련된 서비스를 하는 시스템이라면 한번쯤은 검토해 보아야 한다.
sysctl 을 통해 관련 파라미터 정보를 확인할 수 있는데, 예를 들어 backlog 를 확인해 보면 아래와 같다.
# sysctl -a | grep backlog
error: permission denied on key 'net.ipv4.route.flush'
net.ipv4.tcp_max_syn_backlog = 1024
net.core.netdev_max_backlog = 5000
backlog 는 새로운 연결을 맺는데 관련하여 영향을 주는 파라미터중 하나다. 이외 여러가지 값 들이 있는데, 네트워크 연결이 많다면 다음과 같은 설정이 권장된다.
net.core.wmem_max = 8388608
net.core.rmem_max = 8388608
net.ipv4.tcp_wmem = 4096 65536 8388608
net.ipv4.tcp_rmem = 4096 87380 8388608
net.ipv4.tcp_default_win_scale = 7
net.ipv4.tcp_moderate_rcvbuf = 1
# sysctl -w net.core.rmem_max=8388608
와 같다. 참고로 리눅스 2.6.17 이후에는 오토튜닝이라는 기능이 있는데, 이것은 각 연결에 따라 버퍼 사이즈등이 동적으로 업데이트 되는 것이다. 이 값은 /proc/sys/net/ipv4/tcp_moderate_rcvbuf 를 통해 확인해 볼 수 있는데,
# cat /proc/sys/net/ipv4/tcp_moderate_rcvbuf
1 의 값이 셋팅되어 있다면 autotuning 이 설정되어 있는 것이다. 이런, 네트워크 관련 파라미터 설정외에도
현재 네트워크 관련한 상태를 확인해 보는 것도 원인 파악에 도움이 된다. 네트워크 상태를 파악하는데 기본적으로 많이 사용되는 netstat 를 사용하는 것만으로도 많은 정보를 얻을 수 있다.
# netstat -s
Ip:
2987551774 total packets received
480 with invalid headers
4288 with invalid addresses
139108843 forwarded
0 incoming packets discarded
2804683209 incoming packets delivered
1904276683 requests sent out
1832 outgoing packets dropped
1344 dropped because of missing route
169 fragments dropped after timeout
1551222 reassemblies required
38285 packets reassembled ok
230 packet reassembles failed
31867 fragments received ok
5222 fragments failed
1377531 fragments created
Icmp:
331800 ICMP messages received
26 input ICMP message failed.
ICMP input histogram:
destination unreachable: 331772
echo requests: 4
echo replies: 24
345417 ICMP messages sent
0 ICMP messages failed
ICMP output histogram:
destination unreachable: 340488
time exceeded: 451
redirect: 1831
echo request: 2647
IcmpMsg:
InType0: 24
InType3: 331772
InType8: 4
OutType3: 340488
OutType5: 1831
OutType8: 2647
OutType11: 451
Tcp:
7723898 active connections openings
13569062 passive connection openings
1469362 failed connection attempts
2505823 connection resets received
64 connections established
2794594182 segments received
1750284379 segments send out
4751200 segments retransmited
0 bad segments received.
1074943 resets sent
Udp:
9438290 packets received
323420 packets to unknown port received.
0 packet receive errors
9784976 packets sent
UdpLite:
TcpExt:
879602 resets received for embryonic SYN_RECV sockets
552 packets pruned from receive queue because of socket buffer overrun
21 ICMP packets dropped because they were out-of-window
...(생략)
그리고 다음 도표는 IBM 에서 정리된 파라미터 정보인데, 각 파라미터를 이해하는데 도움이 될거 같아 첨부하였다.
| Tunable parameter | Default value | Option description |
|---|---|---|
/proc/sys/net/core/rmem_default | "110592" | Defines the default receive window size; for a large BDP, the size should be larger. |
/proc/sys/net/core/rmem_max | "110592" | Defines the maximum receive window size; for a large BDP, the size should be larger. |
/proc/sys/net/core/wmem_default | "110592" | Defines the default send window size; for a large BDP, the size should be larger. |
/proc/sys/net/core/wmem_max | "110592" | Defines the maximum send window size; for a large BDP, the size should be larger. |
/proc/sys/net/ipv4/tcp_window_scaling | "1" | Enables window scaling as defined by RFC 1323; must be enabled to support windows larger than 64KB. |
/proc/sys/net/ipv4/tcp_sack | "1" | Enables selective acknowledgment, which improves performance by selectively acknowledging packets received out of order (causing the sender to retransmit only the missing segments); should be enabled (for wide area network communication), but it can increase CPU utilization. |
/proc/sys/net/ipv4/tcp_fack | "1" | Enables Forward Acknowledgment, which operates with Selective Acknowledgment (SACK) to reduce congestion; should be enabled. |
/proc/sys/net/ipv4/tcp_timestamps | "1" | Enables calculation of RTT in a more accurate way (see RFC 1323) than the retransmission timeout; should be enabled for performance. |
/proc/sys/net/ipv4/tcp_mem | "24576 32768 49152" | Determines how the TCP stack should behave for memory usage; each count is in memory pages (typically 4KB). The first value is the low threshold for memory usage. The second value is the threshold for a memory pressure mode to begin to apply pressure to buffer usage. The third value is the maximum threshold. At this level, packets can be dropped to reduce memory usage. Increase the count for large BDP (but remember, it's memory pages, not bytes). |
/proc/sys/net/ipv4/tcp_wmem | "4096 16384 131072" | Defines per-socket memory usage for auto-tuning. The first value is the minimum number of bytes allocated for the socket's send buffer. The second value is the default (overridden by wmem_default) to which the buffer can grow under non-heavy system loads. The third value is the maximum send buffer space (overridden by wmem_max). |
/proc/sys/net/ipv4/tcp_rmem | "4096 87380 174760" | Same as tcp_wmem except that it refers to receive buffers for auto-tuning. |
/proc/sys/net/ipv4/tcp_low_latency | "0" | Allows the TCP/IP stack to give deference to low latency over higher throughput; should be disabled. |
/proc/sys/net/ipv4/tcp_westwood | "0" | Enables a sender-side congestion control algorithm that maintains estimates of throughput and tries to optimize the overall utilization of bandwidth; should be enabled for WAN communication. This option is also useful for wireless interfaces, as packet loss may not be caused by congestion. |
/proc/sys/net/ipv4/tcp_bic | "1" | Enables Binary Increase Congestion for fast long-distance networks; permits better utilization of links operating at gigabit speeds; should be enabled for WAN communication. |
2010년 10월 20일 수요일
강력한 패킷 조작 프로그램 Scapy 를 소개한다 - 첫번째
Scapy
지금까지 패킷분석과 관련한 많은 도구들을 언급하였는데, 이 도구를 미처 소개하지 못했다.
강력한 기능과 프로그램적인 면에서도 뛰어난 도구인데말이다. 필자가 오늘 소개하고자 하는 도구는
Scapy 라는 것이다. Scapy 는 인터렉티브하게 패킷을 조작할 수 있는 강력한 기능을 제공하며,
수 많은 프로토콜의 디코딩 기능과 수정된 패킷을 전송할 수 있는 기능등을 포함하고 있다.
이 도구의 큰 장점은 다양한 기능을 수행할 수 있는 것인데, 우리가 흔히 스캐닝을 하거나, 패킷덤프를
하거나, 원격 시스템의 Alive 유무를 점검 또는 공격 패킷등을 만들고자 할때 사용하는 도구들이
다 달라진다. 예를 들면, hping, nmap, arpsoof, tcpdump, tshark, p0f 등의 여러 도구의 기능들 말이다
하지만 Scapy 는 이 도구 하나로 가능하다. 너무 강력한 도구인양 소개한 것일까?
사용용도에 따라 달라지겠지만 무척이나 편리한 기능을 갖고 있는 것은 사실이다. 다만 사용하는데 있어서는
일반적인 도구에 비해서는 사용방법이 처음에는 힘들 수도 있다. Scapy 는 파이썬을 기반으로
작성되어 있는데, 사용형태가 파이썬에서 코드를 사용하는 것과 같이 사용할 수 있으므로
파이썬에 익숙해져 있는 사용자라면 더 없이 편할 것이다. 또한, Scapy 모듈을 이용하여,
파이썬에서 패킷을 핸들링 하는 프로그램을 작성한다면 간단하게 그 기능을 이용할 수 있어
개발자 관점에서도 유용하다.
뛰어나다는 설명보다도 일단 직접 경험해 보는 것이 빠르다. 바로 설치해 보고 각 기능을
사용해 보면 앞서 얘기한 것들이 이해가 될 것이다.
1. 설치
Scapy 2.x 이상의 버전에서는 파이썬 2.5 이상이 필요하다. 그리고 libpcap, libdnet 이 필요하다.
보통 많은 경우에는 이런것들이 이미 설치되어 있으므로 사용하는데 큰 문제는 없을 것이다.
다음의 경로에서 파일을 다운로드 받을 수 있다:
$ unzip scapy-latest.zip
$ cd scapy-2.*
$ sudo python setup.py install
하는 것으로 쉽게 설치가 된다. 파이썬에 익숙한 사용자라면 어렵지 않을 것이다. 또는,
각 시스템에서 제공하는 패키지가 있다면 그것을 이용해도 좋다.
# apt-get install scapy
* 참고로 윈도우 기반에서 사용하고자 한다면, 다음의 문서를 참고하여 실행해 보길 바란다.
http://www.secdev.org/projects/scapy/doc/installation.html#platform-specific-instructions
2. 간단한 사용 예
실행하게 되면 다음과 같은 화면을 볼 수 있다.
# scapy
WARNING: No route found for IPv6 destination :: (no default route?)
Welcome to Scapy (2.1.0)
>>>
(설치되어 있는 모듈 및 환경에 따라, 경고 메시지가 뜰 수 있는데 무시하고 사용 가능하다.단, 해당 모듈 기능을 사용하지 않는 한)
몇 가지 간단한 기능을 살펴보자!
>>> ls()
ARP : ARP
BOOTP : BOOTP
CookedLinux : cooked linux
DHCP : DHCP options
DNS : DNS
DNSQR : DNS Question Record
DNSRR : DNS Resource Record
....
현재 지원하는 레이어 형태를 볼 수 있다. 쉽게 보면 프로토콜 이다.
다음은 존재하는 PCAP 파일을 오픈하는 것이다. 오픈할 파일을 " 없이 사용하는 경우는 다른 형태로 이해한다.
오픈 후에는 파싱되어 메모리 상에 다 들어가 있으므로 바로 바로 필요한 내용을 꺼내 사용할 수 있다.
>>> a=rdpcap(test.pcap)
Traceback (most recent call last):
File "<console>", line 1, in <module>
NameError: name 'test' is not defined
>>> a=rdpcap("test.pcap")
>>> a
<test.pcap: TCP:2040 UDP:0 ICMP:0 Other:0>
>>>
파일 전송도 할 수 있는데, 원하는 형태로 마음대로 수정하여 전송이 가능하다. 각 프로토콜 레이어 별로 정보를 기록하고 헤더를 붙일 수 있다. 아래의 경우는 IP 헤더에서 목적지를 1.2.3.4 로 설정하고, ICMP 헤더를 붙인 것이다.
>>> send(IP(dst="1.2.3.4")/ICMP())
.
Sent 1 packets.
전송하기 전 tcpdump 로 확인한 내용을 보면, 목적지 1.2.3.4 로 ICMP 패킷이 전송된걸 확인할 수 있다.
# tcpdump -v icmp
tcpdump: listening on eth0, link-type EN10MB (Ethernet), capture size 96 bytes
09:07:36.479199 IP (tos 0x0, ttl 64, id 1, offset 0, flags [none], proto ICMP (1), length 28) packet > 1.2.3.4: ICMP echo request, id 0, seq 0, length 8
이 정도에서 간단한 맛보기를 언급하고 다음 이어지는 두번째 편에서 좀더 세부적으로 Scapy 기능을 알아보도록 하겠다. 계속 이것저것 소개할 것이 많은데, 정리하고 쓰자니 시간이 꽤 걸리는 거 같다. 이래서 정리는 인내가 필요해지는 것 같다 :-)
2010년 10월 15일 금요일
TCP/IP 헤더 내 맘대로...tcp[13] == 2 의 의미는 무엇일까?
tcpdump 를 이용해 패킷을 덤프하다 보면 다양한 표현식을 이용해 필터를 표현하는 경우가 많다. 많은 경우는
대략 사용되는 문자만 보더라도 의미가 파악되는 경우가 많다. 예를 들어, src 라 하면 하면 source 인 출발지가 연상되고 host 는 말 그대로 호스트를 뜻한다. 그럼 이걸 다 연결해서 보면 src host 192.168.0.0 필터의 의미를 금방 추측해 볼 수 있다. tcpdump 에서 이용되는 필터 표현방식은 큰 어려움이 없다. 그런데 아래와 같은 경우는 무엇일까?
tcp[13] == 2
얼핏 봐서는 의미가 잘 파악이 안된다. 어렵게 느껴질 수도 있는데 TCP 헤더를 생각해 보면 의외로 쉽게 풀린다.
일단 다음의 TCP 헤더 포맷을 살펴보자.

[출처 : nmap.org]
TCP 헤더 포맷은 Options 을 제외하고는 20 바이트로 구성되어 있다. 오프셋은 0 부터 시작하고, Octet 형태로 보면 첫 라인은 0 - 3 까지이고, 두번째 라인은 4-7 이다. 그렇다 바로 위에서 13 이라는 것은 바로 이 위치인 것이다. TCP 라고 하였으니 TCP 헤더를 뜻한 것이고 뒤에 들어가는 것은 헤더의 위치 값이다.
자, 그럼 두번째 라인은 4-7 까지이고, 3번째는 8-11 까지가 된다. 네번째 라인은 12-15 가 되는데 13 위치를 보면 TCP Flags 라고 되어 있다. 그렇다 바로 플래그 값을 뜻하는 것으로 대표적인 몇 가지 값을 보면 아래와 같다:
F : FIN
S : SYN
R : RESET
P : PUSH
A : ACK
TCP 3-way Handshake 라는 것을 들어보았다면 위의 용어가 익숙할 것이다. 13 위치가 플래그 라는 것은 알았는데 TCP[13] 의 '== 2' 은 무었일까? == 는 같다는 의미로 쉽게 알 수 있고, 2는 설정된 비트 값이다. 좀더 자세히 알아보도록 하겠다. 1바이트는 8 비트로 구성되어 있다. 그래서 위 헤더의 한 라인씩은 4바이트로 이루어져 있고 13 번째 위치 부분도 1바이트 구성이다. 그럼 8비트 구성일텐데, 위 플래그들을 보면 8개이다. 즉, 각 플래그는 한 비트씩 차지하고 있는 것이다. 좀더 자세하게 표현하면 아래와 같다 :
|C|E|U|A|P|R|S|F|
|---------------|
|0 0 0 0 0 0 1 0|
|---------------|
|7 6 5 4 3 2 1 0|제일 아래 부분은 0-7 까지 비트를 표현한 것이고 그 윗 부분은 Set 된 비트를 의미한다. S 부분이 Set 되어 있는 상태이다. 그럼 이걸 다시 십진수로 변환해 보면 나머지는 다 0 이고 한 군데만 1 이므로 1*2 인 2가 되는 것이다. 차례로 각 계산을 세부적으로 표현하면 다음과 같아진다.
7 6 5 4 3 2 1 0
0*2 + 0*2 + 0*2 + 0*2 + 0*2 + 0*2 + 1*2 + 0*2 = 2
이제 느낌이 팍 오는가? SYN 값이 0x02 가 되는 것이다. 그럼 TCP[13] == 2 의 의미를 다시 정리해 보면,TCP 헤더의 13번째 Octet 위치는 TCP Flags 를 나타내는 것이고 2 는 SYN 를 표현한 것이다.
바로 TCP 패킷중 SYN 패킷만 해당하는 것을 탐지하고자 할때 사용할 수 있는 필터가 되는 것이다.
만약 PUSH 플래그를 잡고자 한다면 8 이 된다. 알고보면 어렵지 않은 부분인데, 이런 것을 모르고 해당
문법을 보게 되면 복잡함 부터 느껴지는 것은 당연하다. 이제 각 헤더의 어떤 부분도 여러분 스스로가 탐지해 낼 수 있게 된것이다.
다음번에는 패킷분석에 기본이 되는 TCP/IP 헤더 부분을 좀더 면밀히 살펴보고자 한다. 패킷분석의 기본이 되는 부분이지만, 의외로 처음 접하는 분들에겐 힘들어 보이는 부분이다. 헤더의 구성을 알게되면 패킷이라는 것에 대해 좀더 명확히 알 수 있으며, 이해가 훨씬 빨라진다. 한 패킷을 예로들어, OSI Layer 단계부터 시작해 TCP, IP 헤더까지 껴 맞춰보며 여러분들에게 명확한 이해를 제시하고자 한다.
패킷이 무엇이고, 통신이 어떻게 이뤄지며 패킷의 구성은 어떻게 이뤄지는지 이해가 잘 안된다면 꼭 보아야 할 내용이 될 것이다. 그럼 시작되는 그 날을 기약하며...
2010년 10월 5일 화요일
오래 간만에 접속해본 tcpdump 사이트 바뀌었네..
오래간만에 tcpdump 사이트를 방문하였더니 홈페이지가 새롭게 리뉴얼 되었다. 근 몇년간 한번도
바뀐적 없이 운영된 것으로 기억하는데, 새로운 화면이 머랄까 신선하게 다가온다. ;-)
패킷 분석을 하는 분들에겐 tcpdump 와 libpcap 을 빼 놓을 수 없을 것이다.
앞으로도 꾸준히 발전하는 모습을 기대하며....

I love libpcap :-)
2010년 9월 18일 토요일
패킷파일이 깨진 경우는 언제? 65535 보다 큰 값의 헤더가 있다면...
capinfo, tshak 등을 실행하다 아래와 같은 에러를 얻은 경우가 있다.
[Error] (pcap: File has 1279743227-byte packet, bigger than maximum of 65535)
[Error] (pcap: File has 1174099712-byte packet, bigger than maximum of 65535)
[Error] (pcap: File has 808345964-byte packet, bigger than maximum of 65535)
패킷 사이즈만 보면 엄청난 크기이다. 그런데 잘 생각해 보면 이상하다고 생각되는 부분이 있을 것이다.
아래 관련한 소스를 찾아보면 한번 살펴보자.
wireshark1.2.9/wiretap/libpcap.c 를 한번 들여다 본 것이다.
if (hdr->hdr.incl_len > WTAP_MAX_PACKET_SIZE) {
/*
* Probably a corrupt capture file; return an error,
* so that our caller doesn't blow up trying to allocate
* space for an immensely-large packet, and so that
* the code to try to guess what type of libpcap file
* this is can tell when it's not the type we're guessing
* it is.
*/
*err = WTAP_ERR_BAD_RECORD;
if (err_info != NULL) {
*err_info = g_strdup_printf("pcap: File has %u-byte packet, bigger than maximum of %u",
hdr->hdr.incl_len, WTAP_MAX_PACKET_SIZE);
}
return -1;
}
일단, 위에서 발생한 에러의 문구를 볼 수 있다. hdr->hdr.incl_len 이 WTAP_MAX_PACKET_SIZE 보다 큰 경우에 발생한 것인데 WTAP_MAX_PACKET_SIZE 값 또한 찾아보자.
이 값은 wtap.h 에 아래와 같이 정의되어 있다.
/*
* Maximum packet size we'll support.
* It must be at least 65535.
*/
#define WTAP_MAX_PACKET_SIZE 65535
최대 패킷 사이즈라고 정의되어 있다. 즉 헤더의 패킷 사이즈를 생각해보면 2 바이트로 최대 65535 까지
가능한 것이다. 그러므로 이론적으로 이 값을 초과할수는 없는 것이기에 패킷 파일이 깨졌을 가능성이 높은 것이다.
한번 테스트용 파일을 tcpdump 를 통해서 오픈 해 봤다. bogus savefile header 라는 문구가 보인다.
# tcpdump -n -r test.cap | wc -l
reading from file test.cap, link-type EN10MB (Ethernet)
tcpdump: pcap_loop: bogus savefile header
1407
이번에는 tshark 를 통해 파일을 읽어 보겠다.
tshark: "test.cap" appears to be damaged or corrupt.
(pcap: File has 781876-byte packet, bigger than maximum of 65535)
781876 바이트를 가지고 있다고 에러가 발생한다. 그리하여 781876 을 HEX 로 변환하여 해당 값을
찾아보니 나타난다.
# hexdump -C test.cap | grep "34 ee 0b"
00072eb0 34 ee 0b 00 66 00 00 00 66 00 00 00 01 00 5e 00 |4...f...f.....^.|
결국은 헤더파일에 잘못된 값이 들어가 있었기 때문에 발생한 것이다. 이렇게 파일이 깨지는 경우도 있으니, 이와 같은 메시지를 얻는 다면 참고하기 바란다.
피드 구독하기:
글 (Atom)






