Private & Confidential Property of COSEINC Metafuzz 0.9 Deep Fuzzing MS Word / Office (With Ruby)...

29
Private & Confidential Property of COSEINC Metafuzz 0.9 Deep Fuzzing MS Word / Office (With Ruby) (rubyrubyrubypythonsucksyayruby!)

Transcript of Private & Confidential Property of COSEINC Metafuzz 0.9 Deep Fuzzing MS Word / Office (With Ruby)...

Page 1: Private & Confidential Property of COSEINC Metafuzz 0.9 Deep Fuzzing MS Word / Office (With Ruby) (rubyrubyrubypythonsucksyayruby!)

Private & Confidential Property of COSEINC

Metafuzz 0.9

Deep Fuzzing MS Word / Office

(With Ruby)(rubyrubyrubypythonsucksyayruby!)

Page 2: Private & Confidential Property of COSEINC Metafuzz 0.9 Deep Fuzzing MS Word / Office (With Ruby) (rubyrubyrubypythonsucksyayruby!)

Private & Confidential Property of COSEINC

Basic Fuzzer Problems for Word• Opening Word is SLOW• Success detection is harder than crash detection• Dr Watson, Dialog Boxes, Hangs, HDD Grind• Lots of internal exception handling• Hard to parse file formats• Massive Attack Surface means millions of tests

• My first fuzzer did a blistering 20-30 tests per minute.

Page 3: Private & Confidential Property of COSEINC Metafuzz 0.9 Deep Fuzzing MS Word / Office (With Ruby) (rubyrubyrubypythonsucksyayruby!)

Private & Confidential Property of COSEINC

omgwtfdoc? Each FKP can be viewed as a bucket or bin that contains the properties of a certain range of FCs in the Word file. In Word files, a PLC, the plcfbte (PLex of FCs containing Bin Table Entries) is maintained. It records the association between a particular range of FCs and the PN (Page Number) of the FKP that contains the properties for that FC range in the file. In a complex (fast-saved) Word document, FKP pages are intermingled with pages of text in a random pattern which reflects the history of past fast saves. In a complex document, a plcfbteChpx which records the location of every CHPX FKP must be stored and a plcfbtePapx which records the location of every PAPX FKP must be stored. In a non-complex, full-saved document, all of the CHPX FKPS are recorded in consecutive 512-byte pages with the FKPs recorded in ascending FC order, as are all of the PAPX FKPS. A plcfbteLvcx serves the same purpose for LVCX FKPS. In a full save document, the plcfbte‘s may not have been able to expand during the save process due to a lack of RAM. In this situation, the plcfbte‘s are interspersed with the property pages in a linked list of FBD pages.

Page 4: Private & Confidential Property of COSEINC Metafuzz 0.9 Deep Fuzzing MS Word / Office (With Ruby) (rubyrubyrubypythonsucksyayruby!)

Private & Confidential Property of COSEINC

General Approach• Distributed fuzzing will be essential for speed• Use OLE automation to detect success• Independent process to kill hung applications and

deal with dialog boxes• Write a few core parsers that abstract the scut work

of the binary format and focus on deep structures• Integrate with CDB to catch first chance exceptions

and gather information

Page 5: Private & Confidential Property of COSEINC Metafuzz 0.9 Deep Fuzzing MS Word / Office (With Ruby) (rubyrubyrubypythonsucksyayruby!)

Private & Confidential Property of COSEINC

Things to know about Word .dochttp://www.microsoft.com/interop/docs/OfficeBinaryFormats.mspx

• Also, check “Supporting Technologies” link for spec for “Compound Binary File Format Specification”

• Basically, .DOC, .PPT and .XLS are OLE Structured Storage files, which means they are more or less a FAT filesystem inside a file.

• This means that structures you want to fuzz may well be broken into bits and scattered at random throughout the file.

• ruby-ole gem by Charles Lowe helps a LOT here. Install it, then…require ‘ruby-ole’Ole::Storage.open('c:\tmp.doc','rb+') {|ole|ole.file.open("1Table","wb+") {|f| f.write( fuzz(f.read) )

}

• TSBrowse Demo

Page 6: Private & Confidential Property of COSEINC Metafuzz 0.9 Deep Fuzzing MS Word / Office (With Ruby) (rubyrubyrubypythonsucksyayruby!)

Private & Confidential Property of COSEINC

Things to know about Word .doc• Your guide to the file – the FIB (File Information

Block), a 1472 byte page turner.• Lots of general info, followed by a long list of

offset / length pairs describing structures in the Table Stream.

• FIBBrowse Demo• Parsing it – Binstruct• It’s little endian. That’s important.

Page 7: Private & Confidential Property of COSEINC Metafuzz 0.9 Deep Fuzzing MS Word / Office (With Ruby) (rubyrubyrubypythonsucksyayruby!)

Private & Confidential Property of COSEINC

Working with Word• Ruby’s Win32OLE gem can be used for the heavy lifting• The call to open below raises an exception if it fails, which may or

may not be a crash.

require ‘win32ole’word_app=WIN32OLE.new(‘Word.Application')word_app.DisplayAlerts=0word_app.Visible=falseword_app.Documents.Open({

"FileName"=>filename,"AddToRecentFiles"=>false,"OpenAndRepair"=>false

})

Page 8: Private & Confidential Property of COSEINC Metafuzz 0.9 Deep Fuzzing MS Word / Office (With Ruby) (rubyrubyrubypythonsucksyayruby!)

Private & Confidential Property of COSEINC

Working with Word

1. Open the Visual Basic Editor from inside Word ALT+F11

2. Press F2 for the Object Browser

3. Poke around.

Page 9: Private & Confidential Property of COSEINC Metafuzz 0.9 Deep Fuzzing MS Word / Office (With Ruby) (rubyrubyrubypythonsucksyayruby!)

Private & Confidential Property of COSEINC

Working with Word

require ‘win32/registry’Win32::Registry::HKEY_CURRENT_USER.open(

'SOFTWARE\Microsoft\Office\12.0\Word\Resiliency',

Win32::Registry::KEY_WRITE) do |reg|reg.delete_key "StartupItems" rescue

nilreg.delete_key "DisabledItems" rescue

nilend

Page 10: Private & Confidential Property of COSEINC Metafuzz 0.9 Deep Fuzzing MS Word / Office (With Ruby) (rubyrubyrubypythonsucksyayruby!)

Private & Confidential Property of COSEINC

Working with Word• Word has a massive, horrible array of dialog boxes with which

to hang your fuzzer.• Do I have dialog boxes to deal with?

GW_ENABLEDPOPUP=6FindWindow=Win32API.new("user32.dll", "FindWindow", 'PP','N')GetWindow=Win32API.new("user32.dll","GetWindow",'LI','I')

window_caption=rand(2**32).to_swin32ole_app.caption=window_captionwindow_id=FindWindow.call(0,window_caption)GetWindow.call(window_id,GW_ENABLEDPOPUP)!=0

Page 11: Private & Confidential Property of COSEINC Metafuzz 0.9 Deep Fuzzing MS Word / Office (With Ruby) (rubyrubyrubypythonsucksyayruby!)

Private & Confidential Property of COSEINC

Working with WordFindWindow=Win32API.new("user32.dll", "FindWindow", 'PP','N')GetWindow=Win32API.new("user32.dll", "GetWindow", 'LI','I')PostMessage=Win32API.new("user32.dll", "PostMessage", 'LILL','I')

def kill_dialog_boxes word_hwnd=FindWindow.call("OpusApp",0) # Get any descendant windows which are enabled - alerts, dialog boxes etc child_hwnd=GetWindow.call(word_hwnd, GW_ENABLEDPOPUP) # Get any toplevel dialog boxes that pop up during open before the main window toplevel_hwnd=FindWindow.call(0, "Microsoft Office Word") [toplevel_hwnd, child_hwnd].each {|hwnd| next if hwnd==0 PostMessage.call(hwnd,WM_COMMAND,IDCANCEL,0) PostMessage.call(hwnd,WM_COMMAND,IDNO,0) PostMessage.call(hwnd,WM_COMMAND,IDCLOSE,0) PostMessage.call(hwnd,WM_COMMAND,IDOK,0) PostMessage.call(hwnd,WM_DESTROY,0,0) }end

Page 12: Private & Confidential Property of COSEINC Metafuzz 0.9 Deep Fuzzing MS Word / Office (With Ruby) (rubyrubyrubypythonsucksyayruby!)

Private & Confidential Property of COSEINC

Working with Word• Word creates temp files all over the place• This fills up your client disk and fragments it• Best thing to do is create a RAMDisk (later)• ~$foo.doc gets created next to foo.doc• Other temp files may be created in %TMP% or %TEMP%• Still more in ...

Temporary Internet Files/Content.Word andTemporary Internet Files/Content.Office

• Those directories may be hidden even when “show hidden files” is turned on, so you may need to type the name into the File Browser.

Page 13: Private & Confidential Property of COSEINC Metafuzz 0.9 Deep Fuzzing MS Word / Office (With Ruby) (rubyrubyrubypythonsucksyayruby!)

Private & Confidential Property of COSEINC

Integrating the Debugger• I used CDB • Command line version of WinDbg, just as powerful• Instead of painfully wrapping a DLL, I cheated.• Take CDB, wrap its STDIN, STDOUT and STDERR• Some hoopy code required for Ruby 1.8 since popen

doesn’t work properly and had to be rewritten• Use a Connector class I had already, which manages a

read queue from the target and uses blocking writes

Page 14: Private & Confidential Property of COSEINC Metafuzz 0.9 Deep Fuzzing MS Word / Office (With Ruby) (rubyrubyrubypythonsucksyayruby!)

Private & Confidential Property of COSEINC

Integrating the DebuggerWhen done, it looks like this:

debugger=Connector.new(CONN_CDB,"-p #{word_pid}“)debugger.puts ‘!load winext\msec.dll’debugger.puts ‘sxe -c “r;!exploitable -m" av’debugger.puts ‘g’

Some syntax sugar:

debugger.registers.eaxdebugger.send_breakdebugger.target_running?debugger.crash?debugger.dequeue_all.join => all STDOUT, joined as a string.

Page 15: Private & Confidential Property of COSEINC Metafuzz 0.9 Deep Fuzzing MS Word / Office (With Ruby) (rubyrubyrubypythonsucksyayruby!)

Private & Confidential Property of COSEINC

Analysisfuzzadmin@coopers:/fuzzfiles$ grep -h CLASSIFICATION *.txt | sort |

uniq -c 9 CLASSIFICATION:PROBABLY_EXPLOITABLE 429 CLASSIFICATION:PROBABLY_NOT_EXPLOITABLE 64 CLASSIFICATION:UNKNOWNfuzzadmin@coopers:/fuzzfiles$ grep -h SHORT *.txt | sort | uniq -c 25 SHORT_DESCRIPTION:ReadAV 429 SHORT_DESCRIPTION:ReadAVNearNull 39 SHORT_DESCRIPTION:TaintedDataControlsBranchSelection 9 SHORT_DESCRIPTION:TaintedDataControlsCodeFlow

Page 16: Private & Confidential Property of COSEINC Metafuzz 0.9 Deep Fuzzing MS Word / Office (With Ruby) (rubyrubyrubypythonsucksyayruby!)

Private & Confidential Property of COSEINC

Analysisfuzzadmin@coopers:/fuzzfiles$ grep -h Hash= *.txt | sort | uniq -c | sed -e "s/\+\S*/+xxx/"

17 BUG_TITLE:Data from Faulting Address controls Branch Selection starting at mso!Ordinal1597+xxx (Hash=0x4e367722.0x35484e20)

2 BUG_TITLE:Data from Faulting Address controls Branch Selection starting at wwlib!DllGetClassObject+xxx (Hash=0x47357e23.0x6c7a2b24)

1 BUG_TITLE:Data from Faulting Address controls Branch Selection starting at wwlib!DllGetClassObject+xxx (Hash=0x5554064b.0x3a4b3b56)

17 BUG_TITLE:Data from Faulting Address controls Branch Selection starting at wwlib!DllGetClassObject+xxx (Hash=0x5554064b.0x3f763e6b)

2 BUG_TITLE:Data from Faulting Address controls Branch Selection starting at wwlib!DllGetClassObject+xxx (Hash=0x5554064b.0x703d0b32)

9 BUG_TITLE:Probably Exploitable - Data from Faulting Address controls Code Flow starting at wwlib!wdGetApplicationObject+xxx (Hash=0x6b6b3f1a.0x7037147e)

425 BUG_TITLE:Read Access Violation near NULL starting at mso!Ordinal8472+xxx (Hash=0x403f7b2c.0x4673930) 1 BUG_TITLE:Read Access Violation near NULL starting at wwlib!DllGetClassObject+xxx

(Hash=0x47357e23.0x553d3855) 3 BUG_TITLE:Read Access Violation near NULL starting at wwlib!DllGetClassObject+xxx

(Hash=0x47357e23.0x1e2b434c) 3 BUG_TITLE:Read Access Violation starting at kernel32!RaiseException+xxx (Hash=0x425b1536.0x72b5f4a) 3 BUG_TITLE:Read Access Violation starting at mso!Ordinal2669+xxx (Hash=0x537e727f.0x28425d2a) 10 BUG_TITLE:Read Access Violation starting at mso!Ordinal2669+xxx (Hash=0x537e727f.0x4227180d) 8 BUG_TITLE:Read Access Violation starting at mso!Ordinal2669+xxx (Hash=0x537e727f.0x42271a0d) 1 BUG_TITLE:Read Access Violation starting at mso!Ordinal8472+xxx (Hash=0x403f7b2c.0x4673930)

Page 17: Private & Confidential Property of COSEINC Metafuzz 0.9 Deep Fuzzing MS Word / Office (With Ruby) (rubyrubyrubypythonsucksyayruby!)

Private & Confidential Property of COSEINC

AnalysisINSTRUCTION_ADDRESS:0x327f72d7INSTRUCTION_STACK_FRAME:-1DESCRIPTION:Read Access Violation near NULLSHORT_DESCRIPTION:ReadAVNearNullCLASSIFICATION:PROBABLY_NOT_EXPLOITABLEBUG_TITLE:Read Access Violation near NULL starting at mso!Ordinal8472+0x1092

(Hash=0x403f7b2c.0x4673930)EXPLANATION:This is a user mode read access violation near null, and is probably

not exploitable.First chance exceptions are reported before any exception handling.

This exception may be expected and handled.eax=05969600 ebx=05969600 ecx=05969600 edx=05969650 esi=00000000 edi=0011d894eip=327f72d7 esp=0011d734 ebp=0011d8b8 iopl=0 nv up ei pl zr na pe nccs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010246mso!Ordinal8472+0x1092:327f72d7 a5 movs dword ptr es:[edi],dword ptr [esi]

es:0023:0011d894=00000000 ds:0023:00000000=????????0:000>

Page 18: Private & Confidential Property of COSEINC Metafuzz 0.9 Deep Fuzzing MS Word / Office (With Ruby) (rubyrubyrubypythonsucksyayruby!)

Private & Confidential Property of COSEINC

Analysisfuzzadmin@coopers:/fuzzfiles$ grep -h Hash=0x5554064b *.txt | sort |

uniq -c | sed -e "s/\+\S*/+xxx/" 1 BUG_TITLE:Data from Faulting Address controls Branch Selection

starting at wwlib!DllGetClassObject+xxx (Hash=0x5554064b.0x3a4b3b56) 17 BUG_TITLE:Data from Faulting Address controls Branch Selection

starting at wwlib!DllGetClassObject+xxx (Hash=0x5554064b.0x3f763e6b) 2 BUG_TITLE:Data from Faulting Address controls Branch Selection

starting at wwlib!DllGetClassObject+xxx (Hash=0x5554064b.0x703d0b32)fuzzadmin@coopers:/fuzzfiles$ grep -l Hash=0x5554064b *.txt | xargs

grep -h STACK_FRAME | sort | uniq -c | grep -v 20 | sed -e "s/\+\S*/+xxx/"

36 STACK_FRAME:mso!Ordinal5900+xxx 2 STACK_FRAME:mso!Ordinal5900+xxx 56 STACK_FRAME:mso!Ordinal5900+xxx

Page 19: Private & Confidential Property of COSEINC Metafuzz 0.9 Deep Fuzzing MS Word / Office (With Ruby) (rubyrubyrubypythonsucksyayruby!)

Private & Confidential Property of COSEINC

Production 1

Production 2

Production n

Fuzz Server

/dev/shm(sqlite)

/fuzzfilesdetail-n.txtcrash-n.doc

Delivery 1

Delivery 2

Delivery n

Metafuzz “Harness”

Page 20: Private & Confidential Property of COSEINC Metafuzz 0.9 Deep Fuzzing MS Word / Office (With Ruby) (rubyrubyrubypythonsucksyayruby!)

Private & Confidential Property of COSEINC

Metafuzz Harness• Almost all the code is generic, and could be used for any file fuzzing work (just

need to work out how to test for success etc)• All components auto-resume, so code can be upgraded on the fly without

restarting test streams• Very simple, home grown protocol using JSON-serialised hashes over DJB-

Netstrings• Could write production clients in any language• Network based on Ruby EventMachine, single threaded, using the Reactor pattern• DB SQLite for now, easy to upgrade• /dev/shm on Ubuntu is your friend for DB Writes• RESTful web interface (beta) to enable production clients to check results and full

debugger output for any test (adaptive fuzzing?)

Page 21: Private & Confidential Property of COSEINC Metafuzz 0.9 Deep Fuzzing MS Word / Office (With Ruby) (rubyrubyrubypythonsucksyayruby!)

Private & Confidential Property of COSEINC

Optimising Fuzzclients• The ideal client for Office fuzzing is– Stable – no disk bloat, no memory leaks etc– Fast – performs as well as Windows will let us– Managable without a GUI

(Thanks to #uncon / Ollie Whitehouse for some great tips here...)

Page 22: Private & Confidential Property of COSEINC Metafuzz 0.9 Deep Fuzzing MS Word / Office (With Ruby) (rubyrubyrubypythonsucksyayruby!)

Private & Confidential Property of COSEINC

Building an XP Fuzzclient for ESXi• (or any VMWare)• 1024MB RAM, or as much as you can spare• 8-10GB Disk, pre-allocated• Enhanced vmxnet NIC (just change the .vmx)• No background• No screensaver

Page 23: Private & Confidential Property of COSEINC Metafuzz 0.9 Deep Fuzzing MS Word / Office (With Ruby) (rubyrubyrubypythonsucksyayruby!)

Private & Confidential Property of COSEINC

Building an XP Fuzzclient for ESXi• My Computer->Properties->Advanced– Visual Effects -> Adjust for best performance– Processor Scheduling -> Programs– Memory Usage -> System Cache– Virtual Memory -> Change to 0MB

Page 24: Private & Confidential Property of COSEINC Metafuzz 0.9 Deep Fuzzing MS Word / Office (With Ruby) (rubyrubyrubypythonsucksyayruby!)

Private & Confidential Property of COSEINC

Building an XP Fuzzclient for ESXi• Install a RAMDisk. I got a free one at:

http://www.mydigitallife.info/2007/05/27/free-ramdisk-for-windows-vista-xp-2000-and-2003-server/

• 64MB should be enough, as long as you clear it often• Change Temporary Internet Files, and ALL temp files to point to R:\

Temp• Two User Environment Variables %TMP%, %TEMP% and two System

Environment Variables• Write your fuzzer tests to the RAMDisk• Check your work with Process Monitor

http://technet.microsoft.com/en-us/sysinternals/bb896645.aspx

(You’ll still have a little)

Page 25: Private & Confidential Property of COSEINC Metafuzz 0.9 Deep Fuzzing MS Word / Office (With Ruby) (rubyrubyrubypythonsucksyayruby!)

Private & Confidential Property of COSEINC

Building an XP Fuzzclient for ESXi• Last but definitely not least...• gflags /p /enable WINWORD.EXE /full• (not sure if that survives a reboot)• Full page heap kills performance, but greatly

increases the chance of crashing on heap corruption

Page 26: Private & Confidential Property of COSEINC Metafuzz 0.9 Deep Fuzzing MS Word / Office (With Ruby) (rubyrubyrubypythonsucksyayruby!)

Private & Confidential Property of COSEINC

Building an XP Fuzzclient for ESXi• Office Apps want to be logged on.• We don’t want to type passwords on 72 clients.• Disable user passwords when logging on:

http://support.microsoft.com/kb/315231

• We used an oldskool .bat in the startup folder:– copy /y all code from a share– (re)-enable gflags just in case– re-create required directories in RAMDisk– start the fuzzer

Page 27: Private & Confidential Property of COSEINC Metafuzz 0.9 Deep Fuzzing MS Word / Office (With Ruby) (rubyrubyrubypythonsucksyayruby!)

Private & Confidential Property of COSEINC

Our Fuzzpark• The Hardware:• 5 Servers, Dual Quad-Core Xeon, 16GB RAM, 4 x 300GB SATA disks, one

per SATA port• (actually not very high spec, these days)• GB Switch, MTU 9000, all clients with TSO enabled• The Logical Network:• 2 Quad Processor Ubuntu 8.10 64-bit servers running a Server and

several Production processes each• 72 XP Fuzzclients• Ghetto style shellscripts to restart all clients, power-on, power-off etc

from the ESXi command-line

Page 28: Private & Confidential Property of COSEINC Metafuzz 0.9 Deep Fuzzing MS Word / Office (With Ruby) (rubyrubyrubypythonsucksyayruby!)

Private & Confidential Property of COSEINC

Our Fuzzpark

• Peak performance ~50 tests/sec• Peak with Page Heap ~30 tests/sec• Average disk usage per Fuzzclient server

~150KB/sec (for all 16 clients)• Average CPU usage per Fuzzclient server 99.99%• Ubuntu Server guests ~30% CPU, could

probably handle another 32+ clients

Page 29: Private & Confidential Property of COSEINC Metafuzz 0.9 Deep Fuzzing MS Word / Office (With Ruby) (rubyrubyrubypythonsucksyayruby!)

Private & Confidential Property of COSEINC

Beer!But questions may be asked first.