Advanced Return Address Discovery using Context-Aware Machine Code Emulation
description
Transcript of Advanced Return Address Discovery using Context-Aware Machine Code Emulation
eEye
Dig
ital S
ecur
ity Advanced Return Address Discovery using Context-Aware Machine Code Emulation
Presented byDerek Soeder,
Ryan Permeh, & Yuji Ukai
eEye
Dig
ital S
ecur
ityWhat is a Return Address?
• Subverting a function pointer• So you have EIP, now what?• Redirecting flow of execution
Stack buffer Caller’s EIP …Our EIP Our payloadOVERFLOW
eEye
Dig
ital S
ecur
ityReturn Addresses in the Past
• Static address of a stack buffer
• Unix versus Windows stacks
• Problems with dynamic stacks and heap buffers
eEye
Dig
ital S
ecur
ityReturn Addresses: Present
• Simple one- or two-instruction redirects (e.g., CALL/JMP reg)
• Scanning for byte sequences
• Change across image versions
CALL reg:FF/D0 .. FF/D7
JMP reg: FF/E0 .. FF/E7
PUSH reg / RET: 50/C2 .. 57/C2 or 50/C3 .. 57/C3
eEye
Dig
ital S
ecur
ityEnter EEREAP
• Similarities to current solutions– Finds viable points to execution– Examines process snapshot
Exhaustive Return Address Discovery using Machine Code Emulation
eEye
Dig
ital S
ecur
ityEEREAP
• Differences from current solutions– Emulates machine code at each candidate
address to see if it will reach payload– EEREAP doesn't search for byte
sequences – it actually emulates at each address to see if that code can get execution to a specified target
Exhaustive Return Address Discovery using Machine Code Emulation
eEye
Dig
ital S
ecur
ityEEREAP Continued
• Benefits of this approach– Finds more than simple instructions– Potentially every viable path will be
uncovered– More possible addresses to match across
various revisions of victim code – more universal or ASCII return addresses?
Exhaustive Return Address Discovery using Machine Code Emulation
eEye
Dig
ital S
ecur
ityEEREAP Concluded
• The execution flow beginning when a candidate address is loaded is the real-world determinant of its effectiveness.
• Emulating at each candidate is a theoretically-ideal solution, limited only by the amount of context information and engine capabilities.
Exhaustive Return Address Discovery using Machine Code Emulation
eEye
Dig
ital S
ecur
ityHow It Works
Welcome to the EEREAP Magical Mystery Tour
eEye
Dig
ital S
ecur
ityOverview
• EEREAP is an Intel 32-bit machine code emulation engine that supports nondeterminism (undefined values) and abstract address spaces
• Accepts a “state” and emulates at each candidate address to determine which will cause execution to reach a target memory region
eEye
Dig
ital S
ecur
ityEEREAP – State
• A path from the registers to a target buffer must exist
• Requires user observation to construct• If there is a way from the initial state
to the target buffer, EEREAP is designed to find it
State is given as a process memory snapshot and a context stating any available information on registers and memory contents.
eEye
Dig
ital S
ecur
ityEEREAP – Memory Regions
Memory regions are expressed abstractly because their locations shift between instances of a vulnerable process
Example:ESP EDI (pointer to payload in heap)
Run 1: 0012FEC4 025470A8
Run 2: 0032FEC4 0252F308
Run 3: 0022FEC4 025206A0
“Stack” and “heap block” are both identifiable memory regions whose addresses shift between runs, due to the dynamic nature of thread creation and heap memory allocation.
eEye
Dig
ital S
ecur
ityEEREAP – Context
Supplies register and memory values (integers or pointers) and defines memory regions
• Integers are tracked on the bit level (each bit is maintained as 0, 1, or X) – especially important for EFLAGS
• Pointers are a memory region ('virt' – the 4GB virtual address space – or a user-defined region) plus an integer offset
eEye
Dig
ital S
ecur
ityEEREAP – Context 2
Memory regions must be given a size, and can be defined with certain attributes as appropriate
• Size is usually just a guess, because an exact size often cannot be determined
• Attributes:– Read-Only – emulation fails on write
access; useful for protecting payload– Target – region contains a payload;
emulation ends successfully for return address candidate if execution reaches it
eEye
Dig
ital S
ecur
ityEEREAP – Context 3
• Memory regions can be “mapped” by specifying that one region starts at a relative offset within another
• For instance, a target buffer could be located in the stack, or a data area could be assigned a virtual address
• On dereference, attributes of all regions overlapping at address apply
eEye
Dig
ital S
ecur
ityEEREAP – Context Example
# defines STACK as a 64KB writable address spaceSTACK = 00XXXXXXh : 65536, RW# ESP is a pointer to offset E000h within ‘STACK’ESP = STACK + E000h# BUFFER maps into STACK at offset E09ChBUFFER @ STACK + E09Ch : 128, TARGET, RO# memory at STACK + E004h contains a pointer into BUFFER[STACK+E004h] = BUFFER + 8EAX = 0ECX = 3FFXXXXXhEBP = STACK + E134h[EBP] = STACK + E180hESI = STACK + E01ChTIB = 7FFXX000h : 4096, RWFS = TIBEFLAGS = 0010000X0X1Xb
eEye
Dig
ital S
ecur
ityEEREAP – Emulation
• For each return address candidate, emulation is started fresh:– EIP points to that address– Other registers and memory are initialized
according to the context• These runs will be referred to as
“emulation threads,” although only one is really performed at a time
eEye
Dig
ital S
ecur
ityEEREAP – Emulation 2
• Arithmetic attempts to preserve the destination as a pointer (if possible), then as an integer
• Takes unknown bits into account, erring on the side of nondeterminism
• EFLAGS are also modified and may be partially undefined
Each instruction is emulated as faithfully as possible…
eEye
Dig
ital S
ecur
ityEEREAP – Emulation 3
• The thread dies if anything occurs that could affect execution unpredictably:– A pointer dereference exceeds the bounds
of its memory region– A write occurs on read-only memory– A 'virt' pointer accesses invalid memory– An invalid opcode, privileged instruction,
potential divide-by-zero, etc., occurs
But sometimes faith just isn’t enough
eEye
Dig
ital S
ecur
ityEEREAP – Emulation 4
• An instruction execution countdown is used to prevent infinite loops
• If a Jcc or LOOPcc is reached with EFLAGS/ECX undefined, we follow both possible execution paths– Parent succeeds if both children “threads”
reach a target buffer– Each child gets a copy of parent's context
with the instruction countdown halved
Loops and Branches
eEye
Dig
ital S
ecur
ityEEREAP – Emulation 5
Success!
If an emulation thread (or both of its children, if it forked) reaches a memory region marked as Target, the return address candidate at which it started is considered a success and is logged.
eEye
Dig
ital S
ecur
ityHow to Use It / Demonstration
Don’t Fear the EEREAPer
eEye
Dig
ital S
ecur
ityEEREAP – How-To
• Crash the target process using the vulnerability to be exploited– Should put the process as close as
possible to the state that will be in effect when execution is hijacked
– e.g., a finished exploit with an invalid return address (0x41414141, anyone?)
– Process should definitely have a debugger on it with first-chance exceptions caught
eEye
Dig
ital S
ecur
ityEEREAP – How-To 2
• Use 'psnap' to grab a process memory snapshot
C:\>psnap.exe --priority --suspend -a:r -c:w 260 lsass.ees
* Record: micdhstp ---* Write: --c----- ---
[#] 00010000..00010FFF .................................. Recorded [#] 00020000..00020FFF .................................. Recorded [ ] 00030000..00065FFF ................................... Ignored [G] 00066000..00066FFF ................................... Ignored [#] 00067000..0006FFFF .................................. Recorded [#] 00070000..00120FFF Heap .............................. Recorded [ ] 00121000..0016FFFF Heap ............................... Ignored... [#] 00CAA000..00CAFFFF Stack ............................. Recorded [#] 01000000..01000FFF Image - lsass.exe ................ Recorded [#] 01001000..01001FFF Code - lsass.exe:.text ........... Written [#] 01002000..01002FFF Data - lsass.exe:.data .......... Recorded [#] 01003000..01009FFF Data - lsass.exe:.rsrc .......... Recorded [ ] 01090000..010C8FFF Stack .............................. Ignored [G] 010C9000..010C9FFF Stack .............................. Ignored...Saved process 260 snapshot to "lsass.ees" (12795328 bytes).
eEye
Dig
ital S
ecur
ityEEREAP – How-To 3
• Create the context– Study the environment at crash time:
consistent pointers and integers; memory regions of interest
– Reverse engineer as desired
– Context and snapshot are both specific to one version of the vulnerable process
eEye
Dig
ital S
ecur
ityEEREAP – How-To 4
STACK = 0XXXA000H:6000H,RW
EAX=00000000HEBX=00000000HECX=STACK+5D38HEDX=785B2C60HESI=00000004HEDI=STACK+5A58HESP=STACK+5A14HEBP=XXXXXXXXHEFLAGS=0296H
BUFFER@STACK+5A14H:10H,RO,TARGET
• Context for exploiting LSASS (SP4)
eEye
Dig
ital S
ecur
ityEEREAP – How-To 5
• Run EEREAP!
• Windows 2000 Advanced Server (English) No SP/Patch• Windows 2000 Advanced Server (English) SP3 No Patch• Windows 2000 Advanced Server (English) SP4 No Patch
LSASS.EXE (MS04-011)
Tested Platform :
Tested Process :
eEye
Dig
ital S
ecur
ity
• Result - Performance
Windows 2000 SP4
Windows 2000 SP3
Windows 2000 SP0
824
796
542126
143
167
0 200 400 600 800
EEREAPSimple Search
Comparison with common used return address finder - (jmp esp, call esp, push esp/ret)
EEREAP – Result 1
eEye
Dig
ital S
ecur
ity
• Distribution: number of instructions to target buffer
EEREAP – Result 2
# Instructions Addresses1 572 683 564 585 626 457 368 219 21
10 1311 1512 1513 2314 2
15 or more 50Total 542
Maximum # of instructions = 80
- Windows 2000 SP0
eEye
Dig
ital S
ecur
ity
Maximum # of instructions = 79
EEREAP – Result 3
# Instructions Addresses1 672 653 854 1095 946 897 558 529 30
10 2211 2212 1613 2214 2
15 or more 66Total 796
- Windows 2000 SP3• Distribution: number of instructions to target buffer
eEye
Dig
ital S
ecur
ityEEREAP – Result 4
• Distribution: number of instructions to target buffer- Windows 2000 SP4
Maximum # of instructions = 91
# Instructions Addresses1 592 633 904 905 1066 1007 578 549 30
10 2011 2212 1313 1114 5
15 or more 104Total 824
eEye
Dig
ital S
ecur
ityEEREAP – Result 5
• Return addresses exist onWindows 2000 SP0, SP3, and SP4
750231e2H
751c255eH
7732c167H
773e661fH
77836305H
77836307H
77836309H
eEye
Dig
ital S
ecur
ity
• Example return address for SP4 with 27 instructions
78599354 push esp78599355 and al,0Ch78599357 push edi78599358 push 77859935A xor eax,eax7859935C pop ecx7859935D mov edi,edx7859935F rep stosd78599361 mov eax,[esp+0Ch]78599365 xor ecx,ecx78599367 mov [edx],eax78599369 mov eax, [esp+8]7859936D cmp eax,ecx7859936F mov [edx+0Ch],cl
78599372 je 78599384
78599374 mov [edx+4],eax78599377 mov [edx+8],10h7859937E xor eax,eax78599380 pop edi78599381 ret 0Ch
78599384 mov [edx+4],ecx78599387 mov [edx+8],ecx7859937E xor eax,eax78599380 pop edi78599381 ret 0Ch
EEREAP – Result 6
eEye
Dig
ital S
ecur
ityEEREAP – Demonstration
• Plug in a suitable return address and try it out…
eEye
Dig
ital S
ecur
ityTo-Do
You Can’t Always Get What You Want
eEye
Dig
ital S
ecur
ityEEREAP – To Do
• Use EEREAP to find a completely universal offset (all languages/versions)
• Maintain results of pointer arithmetic as expressions (e.g., ~((~ptr)+1) = ptr-1, rather than ~ptr = X, X+1 = X, ~X = X)
• Automated context reconnaissance? (could be done third-party *hint*)
• Emulate exception handlers?
eEye
Dig
ital S
ecur
ityQuestions?!
Ask an eEye EngineerPrice $1.00
Questions? Comments? Email <[email protected]> today!