
USB 대용량 저장장치 트래픽을 블록 및 파일 수준에서 가로채고 분석하며, USB 장치를 에뮬레이션하고, 보안 연구, 포렌식 및 TOCTOU 취약점 테스트를 위한 맞춤형 Python 스텁을 지원합니다.

usb-spy는 WiFi 또는 Ethernet 지원 마이크로컨트롤러를 기반으로 구축된 USB Mass Storage 트래픽 분석기입니다.
이 보드는 대상 시스템에 가짜 USB Mass Storage 장치로 디스크 이미지(FAT 또는 모든 파일시스템)를 노출하는 반면, 실제 저장 데이터는 WiFi 또는 Ethernet을 통해 원격 서버에서 제공됩니다. 이 구조를 통해 usb-spy는 대상이 수행하는 모든 블록 액세스를 가로채고 분석할 수 있습니다.
usb-spy는 원시 블록 수준 추적 외에도 파일시스템을 이해하고 액세스된 각 블록을 해당 파일 및 디렉터리에 매핑하여 원시 섹터 번호 대신 읽거나 쓰고 있는 파일을 즉시 확인할 수 있게 해줍니다.
또한 usb-spy는 JSON 구성 파일을 통해 공급업체 ID, 제품 ID, 일련번호, 제조업체 및 제품 이름과 같은 장치 속성을 사용자 정의하여 모든 USB 장치를 에뮬레이션할 수 있습니다. 이를 통해 테스트 및 분석 목적으로 특정 USB 장치를 가장할 수 있습니다.
이 도구는 사용자가 작성한 Python 스텁을 통해 쉽게 확장 가능하며, USB 읽기/쓰기 이벤트 및 블록 수준 작업 처리를 위한 사용자 정의 로직을 구현할 수 있습니다.

지원되는 파일시스템이 감지되면 usb-spy는:
현재 지원되는 파일시스템:
향후 추가 파일시스템에 대한 지원이 추가될 예정입니다.
파일시스템이 지원되지 않는 경우에도 usb-spy를 사용할 수 있습니다:
이를 통해 usb-spy는 알 수 없거나, 사용자 정의 또는 독점 파일시스템에서도 유용합니다.

각 지원 보드에 대한 펌웨어 빌드 지침은 여기에 설명되어 있습니다:
소스 코드는 src 디렉터리에 있습니다. FAT 이미지를 로드하고, TCP 포트를 통해 노출하며, 이미지에 대한 모든 액세스를 기록합니다. 파일 및 디렉터리 정보를 출력하기 위해 이 도구는 TheSleuthKit 라이브러리를 사용합니다.
빌드하려면 루트 디렉터리에서 다음 명령을 실행하세요.
모든 서브모듈 가져오기
git submodule update --init --recursive
그런 다음 waf configure 명령을 실행합니다.
./waf configure
필요한 모든 종속성을 확인하고 빌드한 후, 실제 프로젝트 빌드를 위해 다음을 실행합니다.
./waf build
바이너리는 wbuild 디렉터리에 생성됩니다.
mtools 유틸리티 패키지를 사용하면 쉽게 할 수 있습니다.
2MB 파일 생성
dd if=/dev/zero of=disk.img bs=1M count=2
FAT 파일시스템 적용 (-F는 FAT32, 기본값은 자동)
mformat -i disk.img ::
파일 추가
mcopy -i disk.img example.txt ::
파일 목록 보기
mdir -i disk.img ::
파일 추출
mcopy -i disk.img ::/example.txt extracted.txt
새로 생성한 이미지로 spy 실행
./usb-spy -v disk.img
보드를 대상 USB 포트에 연결하세요.
특정 USB 장치를 에뮬레이션하려면 JSON 구성 파일을 통해 매개변수를 재정의할 수 있습니다:
다음 JSON 파일은 Kingston DataTraveler USB 장치를 에뮬레이션합니다:
{
"vendor_id": 2385,
"product_id": 5734,
"bcd_device": 272,
"product_rev": "3.0",
"manufacturer": "Kingston",
"product_name": "DataTraveler",
"serial": "509C4BBFACCDE742880C026B",
"language": 1033
}
이 구성 파일로 spy 실행
./usb-spy -c config/kingston.json disk.img
이 장치의 dmesg 출력:
usb 1-8: New USB device found, idVendor=0951, idProduct=1666, bcdDevice= 1.10
usb 1-8: New USB device strings: Mfr=1, Product=2, SerialNumber=3
usb 1-8: Product: DataTraveler
usb 1-8: Manufacturer: Kingston
usb 1-8: SerialNumber: 509C4BBFACCDE742880C026B
usb-storage 1-8:1.0: USB Mass Storage device detected
scsi host6: usb-storage 1-8:1.0
scsi 6:0:0:0: Direct-Access Kingston DataTraveler 3.0 PQ: 0 ANSI: 2
모든 읽기/쓰기 이벤트에 대해 자신만의 로직을 구현하고 싶다면 Python으로 쉽게 할 수 있습니다.
다음 더미 이미지와 같이 Python에서 USBImage 클래스를 구현하세요:
class USBImage:
def __init__(self, *args, **kwargs):
"""
USBImage를 초기화합니다.
:param args: 다음을 포함해야 합니다:
- filename: 관리할 파일의 이름.
:param kwargs: c++ 명령줄에서 전달되는 임의의 인수. 다음을 포함합니다:
readOnly: 인터페이스가 읽기 전용인지 여부.
verbose: 상세 로깅 활성화 여부.
block: 블록 모드 활성화 여부.
"""
pass
def getBlockNumber(self):
"""블록 번호 가져오기"""
return 100
def getBlockSize(self):
"""블록 크기 가져오기"""
return 512
def read(self, lba, buffer, size):
"""블록 읽기"""
print(f"read block={lba} size={size}")
for i in range(size):
buffer[i] = (lba + i) % 256 # 데이터 읽기 시뮬레이션
return size
def write(self, lba, buffer, size):
"""블록 쓰기"""
print(f"write block={lba} size={size}")
print(buffer)
return size
def flush(self):
"""블록 플러시"""
print("flush data")
그리고 Python 모듈로 spy를 실행하세요.
./usb-spy --py python/dummy.py disk.img
명령줄에서 Python 클래스에 임의의 인수를 전달할 수도 있습니다. 인수는 kwargs에서 사용할 수 있습니다.
./usb-spy --py python/dummy.py --py-args arg1=2 --py-args arg2=Hello disk.img
또한 usb-spy 바이너리에서 기본적으로 구현된 기능의 완전한 구현(약 100줄 코드)을 제공하는 rawimage 예제에서 시작할 수도 있습니다.
이 프로젝트는 "있는 그대로" 제공됩니다. 정확성, 보안 또는 특정 목적에의 적합성에 대한 보장이 없습니다.
도구 및 펌웨어는 사용자의 책임 하에 사용하십시오. 저자 및 기여자는 이 소프트웨어 또는 하드웨어 사용으로 인해 발생할 수 있는 손해, 데이터 손실 또는 법적 결과에 대해 책임을 지지 않습니다.
기여를 환영합니다! 다음 단계를 따라주세요:
이 프로젝트는 GNU General Public License v3.0에 따라 라이선스가 부여됩니다. 자세한 내용은 LICENSE 파일을 참조하세요.