massive scale usb device driver fuzz without ......the idea software hardware usb*hci.sys usbhub.sys...
TRANSCRIPT
MASSIVE SCALE USB
DEVICE DRIVER FUZZ
WITHOUT DEVICE
HC Ma @ Tencent’s XuanwuLab
whoami
• Security Researcher@
• Used to doing Chemistry;
• Interested in:• Console Hacking;
• Embedded Device Security;
• Firmware Reverse and Emulation;
• Unpacking and Un-virtualizing;
• Geek Stuff: RFID、lock-picking、Device hacking;
Agenda
•Attack On USB and Drivers
•Creating Hardwares
•The Massive Fuzzing
•Results and Demo
Attack On USB and Drivers
Features• Universal Serial Bus;
• Data Transfer;
• Multi Device Class;
• Quick Charge;
• Determined by VID and PID
Research• vUSBf;
• BadUSB;
• USB MITM Fuzzing;
• PS3 USB JailBreak;
• Nintendo Switch JailBreak;
The idea
Software
Hardware
USB*hci.sys USBHUB.sys Enumeration
Usbstor.sys usbport.sys usbhid.sys
Device Specific Driver
Plug to Code execution
The attacking scenairo
1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0
• Unpack Cab File;• Verify Binary Signature;• Install Driver into DriverStore;• Load Driver into Kernel Space;• Call Entry Point of Driver;• Initial PNP irp and call PNP IRP
handler in target driver
The Goal
• Find Bugs in auto installed device drivers;• Enumeration;
• Entry point Code in target driver;
• IRP handler in target driver;
• Other related code potion in target driver;
• IO Control Code Fuzzing;
• Achieve ‘Plug2Pwn’ attack;• Trigger and exploit driver bugs in a crafted USB device;
• Gain Kernel Code Execution directly;
Get the targets
•Where and How? • How many?• Drivers Stored on Windows update server;
• Search while a foreign USB device insert;
• VID and PID are submitted to server;
• Protocol is documented (WSUS);
• Create a fake client with Python and tiny bit reverse-engineering;
• Enumeration each combination of VID and PID;
win7x64
win10x64
win7x86
win10x86
RAW 5598 6735 5756 6843
After updateid
3066 3230 3261 3406
After URI 966 1047 951 1014
Total 3978
Trick
• VID and PID are WORD, max to 65535;
• 65536*65536=4294967296;
• www.catalog.update.microsoft.com/v7/site/Search.aspx?q=usb%5Cvid_
• Get VIDs first
• VID:65536->903 (1.3%)
Creating Hardwares
Hardware
• Need hardware to trigger the driver-loading;
• Prepare devices for thousands of drivers is impossible and costly;
• No way to make fuzzing automatically with real hardwares;
Firmware
Emulation
• USB Redirection Protocol: Redirect physical USB device into virtual machine;
• QEMU’s feature;
• While enabled, a socket is exposed to host from guest machine;
• Connect the socket normally, send the protocol packets, then a USB device shows in guest machine;
Emulation
• Based on vUSBf’s work, thank you Sergej Schumilo
• vUSBf’s way:• Use scapy to construct USB protocol in Python;
• Parse real USB device descriptor file;
• My work:• Pack the emulation code into a thread function;
• Use a common COM device as a base descriptor;
• Apply new VID and PID on each thread running;
• Extend code for other device classes;
• Add Microsoft specific descriptor support;
• Bulk transfer monitor and fuzzing;
Firmware
Emulation result
• Working for 90% drivers;
Let’s Fuzzing
VM Management
Initial
EnvOK
DrvInstalled
VMSnap
Alive
Plugin
Fuzzing
Restart
VMCrash
BSOD
DrvRdy
VMStuck
EndStage1 Stage2 Stage3
Stage 1
• Prepare environment for fuzzing;
• Pre-install target driver into Virtual Machine;
• Take Snapshot to speed up fuzzing;
• Task to achieve:• Execute program inside VM;
• Collect as much as possible information for target drivers;
Execute program inside VM
• QGA(Qemu Guest Agent),much like VMTools, but customizable;
• Run as service on Windows, expose Virtual COM device inside VM;
• Exposed as regular socket outside VM;
• Feature:• Probe VM status;
• Read/Write File;
• Execute Program;
• Etc.
Driver Installation System
• Pre-install drivers into OS before fuzzing;
• Dynamically parse CAB file depends on results of installation for each INF file;
• Information obtained:• List of valid INF file;
• INF dynamic behavior while installation;
• The actual copied/ installed sys file;
• Restore VM from Snapshot;
• Get Virtual USB device ready;
• Make sure target driver is running;
• Task to achieve:• Launch Virtual USB Device;
• Monitor Device Status to see if target driver is running;
Stage 2
Launch Virutal USB Device
• Running Virtual Device in a standalone thread;
• Accept VID and PID as arguments;
• Connect to the USB redir socket to indicate a USB device inserted;
• Once inserted, Waiting for packets from guest VM;
Device Status Monitor
• Device is accessible only when driver is properly installed and run;
• When driver is installed successfully, status code is 0; if (IsFound){
cr = CM_Get_DevNode_Status(&Status, &Problem,
DeviceInfoData.DevInst, 0);
printf("Device status : 0x%x\n",Status);
if(Status & DN_HAS_PROBLEM)
{
printf("\tERROR code : %d\n", Problem);
}
count++;
IsFound=FALSE;
}
}
• The IO Control Code Fuzzing Stage;
• Other Code potion fuzzing occur when virtual USB device inserted in stage2;
• Task to achieve:• Start IO Control Code Fuzzing;
• Monitor fuzzing and VM status: both VM and VM process;
• Collect Crashdump and fuzzing testcase;
Stage 3
IO Control Code Fuzzing
• Design a fuzzer running inside VM;
• Enumerate IoCtl Codes, and do random fuzzing;
• Record buffer Out data when fuzzing for further analysis; for aa in validinterfaces:
print "[*]Try to fuzz interface: %s"%aa['interface']
#if CurrentIoCTL in aa['validcode']:
ret=fuzzerdll.fuzzworker("\\\\.\\"+aa['interface'],CurrentIoCTL,seed,MAX_LE
N_TESTCASE,NUM_OF_EACH_ITERATION)
if ret!=0:
dict={}
dict['errorcode']=ret
dict['seed']=seed
dict['interface']=aa['interface']
dict['IOCTLCode']=CurrentIoCTL
xml['UIFRecord']['ErrorLog'].append(dict)
#print "Error Found while fuzzing, code: %d"%ret
CurrentIoCTL=int(xml['UIFRecord']['CurrentIoCTL']["@code"],16)
CurrentTestedCase=int(xml['UIFRecord']['CurrentTestedCase']["@num"])
TotalIoCTL=int(xml['UIFRecord']['TotalIoCTL']["@num"])
Monitor fuzzing
• Monitor IO Control Code fuzzing progress;
• Read, parse progress file and record the current progress;
• Monitor VM alive status;
• Monitor VM process alive status;
Collection
• Copy Crashdump and Testcase out of VM;
• Save crash evidence, and record in database;
• Restore VM back to snapshot;
• Re-apply progress file to VM and continue fuzzing;
Results and Demo
Demo1
Getting Results
• To get a reasonable result, you have to:• Reproduce the bug;• Scalable Crashdump automatically analysis;
• Binary level auto-analysis on target drivers;
Bug verification
• Launch two VMs, one for debugger, the other for debugee;
• Redirect guest virtual serial COM to host tcp/ip port;
• One-click Windows kernel debugging on Linux Host;
Really Slowwwww!!!!!!!!!
CrashDump Auto-analysis
• Hundreds of CrashDump to be analyzed
• Lots of duplication and time consuming ;
• python+pykd make life easier;
• Parse Crashdump and output basic information;
Driver Auto-Analysis
• Tons of drivers need to be analyzed;
• Time consuming and tedious;
• IDA plugin is made to make life easier;
Before After
Example
Result
Bonus-Exploit Demo
Summary• We propose a novel attack surface of Windows;
• We established a fuzzing system to fuzz USB device driver;
• 3rd party driver developer differs in code quality;
• Low quality of device drive may harm to Microsoft ecology;
• Virtual device make driver fuzzing possible, extensible, reliable and efficient;
Acknowledgement
• My leader: tkyu;
• WenqunWang for writing exploit
THANKS FOR ATTENTION