컴퓨터와 USB 사이의 통신 내용도 패킷을 캡쳐하는 것과 같이 볼 수 없을까? 이에 대한 대답은 '있다' 이다. 그것도 우리가 블로그에서 많이 언급하고 친근한 프로그램 중에 하나인 와이어샤크로 할 수 있다.
자, 그럼 어떻게 USB 트래픽 정보를 볼 수 있을까? 우선 운영체제에서 볼 수 있도록 지원해 주어야 하는데, USB 로우 트래픽 데이터를 패킷 형태로 변환하여 일반적인 네트워크 인터페이스와 같이 인식되어 볼 수 있다. 여기서는 리눅스를 기반으로 하여 설명을 할 것이다. 우선 커널 상에서 DEBUG 파일 시스템이라든지, USB 모니터링 모듈등을 지원해 주어야 한다. 그러므로, 다음과 같은 옵션이 설정되어 커널이 컴파일 되어 있어야 한다.
CONFIG_DEBUG_KERNEL=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)
앞서 설명한 것과 같이 네트워크 인터페이스로 인식을 시켜준다고 하였다. 그럼, 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
기존에는 보이지 않던 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