0% found this document useful (0 votes)
119 views

Using Immunity Debugger To Write Exploits PDF

Using Immunity Debugger to Write Exploits discusses how Immunity Debugger can help with writing exploits by providing better interfaces, integration with existing Python tools, and capabilities for analyzing binaries. Recent advances in defenses like ASLR, DEP, and improved heap protections have made exploitation more difficult. Immunity Debugger aims to give attackers an advantage through improved debugging and analysis tools that help overcome these protections. The document provides examples of how it could aid in exploiting SQL injection bugs and heap overflows despite increased heap protections in modern operating systems.

Uploaded by

nudo
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
119 views

Using Immunity Debugger To Write Exploits PDF

Using Immunity Debugger to Write Exploits discusses how Immunity Debugger can help with writing exploits by providing better interfaces, integration with existing Python tools, and capabilities for analyzing binaries. Recent advances in defenses like ASLR, DEP, and improved heap protections have made exploitation more difficult. Immunity Debugger aims to give attackers an advantage through improved debugging and analysis tools that help overcome these protections. The document provides examples of how it could aid in exploiting SQL injection bugs and heap overflows despite increased heap protections in modern operating systems.

Uploaded by

nudo
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 78

Using Immunity Debugger

to Write Exploits

Dave Aitel, Nicolas Waisman


dave@immunityinc.com
nicolas.waisman@immunityinc
.com

Security Research
1
Who am I?

z CTO, Immunity Inc.


z Responsible for new product development
− Immunity Debugger
− SILICA
− Immunity CANVAS

2
Software companies now
understand the value of security
z Over the past few years regular users have
become more aware of security problems
z As a result 'security' has become a valuable
and marketable asset
z Recognizing this, the computer industry has
invested in both hardware and software
security improvements

3
Immunity Debugger is a
strategic answer to defensive
advances
z ASLR, NX, /gS and high levels of automated
and manual code auditing have raised the
bar significantly
z Attackers operate at a distinct disadvantage
− No source code or internal documentation on
structures and protocols
− Vulnerabilities must be created into reliable
exploits
4
But attackers have their own
resources
z Used to working in small teams
z Broad range of knowledge (Unix hackers
that know Win32, etc)
z Exploit development knowledge is often not
fed back to defensive teams, allowing for
knowledge leadership over a long time
period
− i.e. new bug classes and attack surfaces

5
Attackers will defeat the current
generation through profound
and rapid tool innovation

z Interfaces
z Analysis engines
z Integration into existing tool-sets
z Teamwork and coordination

6
Better interfaces save valuable time

Pure-
Python
Graphi Usable
ng GUI

WinDBG-
like
command
line

7
Python integration offers
useful analysis

z safeseh discovery
z stack/heap variable sizing
z most importantly – custom automated binary
analysis can be written cheaply and easily!
z Static and runtime analysis

8
Existing toolsets are also in
Python
z Python x86 emulators
z Python exploit frameworks
z Python web application analysis
z PEID
z Non-python toolkits can be accessed easily
via Sockets or XML-RPC

9
Hackers already work in teams...
z But their tools don't – yet
z Ongoing efforts include
− SVN + Debugger
− Portable function fingerprints
− Global RE database
z While previous efforts have broken ground
in team binary analysis, in a year, this will
be the default mode of operation

10
Two examples of how Immunity
Debugger changes assessment
and exploitation

z File Include/SQL Injection bugs


z Heap Overflows

11
SQL Injection/File Include
z Traditionally web applications are looked at
via code review or remote blind assessment
− But complexity is rising and closed source modules are
common

z With ID's sql_hooker.py and sqllistener.py


− All SQL Queries get sent to the attacker via XML-RPC
− Python lets you filter on only interesting results at server
side

12
Heap overflows are dead,
long live heap overflows
z Common technique for reliable exploitation
of heap overflows is the write4 primitive

z OS Vendors are well aware of this

13
And so... heap protection has been introduced

z Windows XP SP2, Windows 2003 SP1 and Vista


introduced different heap validity checks to
prevent unlink() write4 primitives
z Similar technologies are in place in glibc in
Linux
z There are no generic ways to bypass the new
heap protection mechanisms
− The current approaches have a lot of requirements: How do we
meet these requirements?

14
XP SP2 makes our work hard
z Windows XP SP2 introduced the first
obvious protection mechanism
− unlinking checks:

blink = chunk->blink
flink = chunk->flink

if blink->flink == flink->blink
and blink->flink == chunk

15
and harder...
z Windows XP SP2 introduced the first
obvious protection mechanism
− unlinking checks:

-BL Chunk- -FL Chunk-


Flink Flink
??? ?
Blink Blink
??
??

-Chunk-
Flink Chunk been
unlinked
Blink
16
XP SP2 ( and Vista) introduced more
heap protections

− Low Fragmentation Heap Chunks:


metadata semi-encryption

subsegment = chunk->subsegmentcode
subsegment ^= RtlpLFHKey
subsegment ^= Heap
subsegment ^= chunk >> 3

17
Vista heap algorithm changes make
unlink() unlikely
− Vista Heap Chunks:
metadata semi-encryption and integrity check

*(chunk) ^= HEAP->EncodingKey
checksum = (char) *( chunk + 1)
checksum ^= (char) *( chunk )
checksum ^= (char) *(chunk + 2)

if checksum == chunk->Checksum

18
Checksum makes it hard to predict
and control the header
− Vista Heap Chunks:
metadata semi-encryption and integrity check

0 1 2 3

SIZE Fl Checks

??
?? Xor against
HEAP->EncodingKey

19
Other protections in Vista are not
heap specific
− Other protection mechanisms:
z ASLR of pages
z DEP (Hardware NX)
z Safe Pointers
z SafeSEH (stack)
z etc.

20
A lot of excellent work has been
done to bypass heap protections

z Taking advantage of Freelist[0] split


mechanism (“Exploiting Freelist[0] on XP
SP2” by Brett Moore)
z Taking advantage of Single Linked List
unlink on the Lookaside ( Oded Horovitz and
Matt Connover)
z Heap Feng Shui in Javascript (Alexander
Sotirov)
21
We no longer use heap algorithms
to get write4 primitives
z Generic heap exploitation approaches are
obsolete. There is no more easy write4.
− Sinan: “I can make a strawberry pudding with so
many prerequisites”
z Application specific techniques are needed
− We use a methodology based on understanding and
controlling the algorithm to position data carefully
on the heap

22
We have been working on this
methodology for years
z All good heap overflow exploits have been in
careful control of the heap for years to reach the
maximum amount of reliability
z We now also attack not the heap metadata, but
the heap data itself
− Because our technique is specific to each program, generic heap
protections can not prevent it

z Immunity Debugger contains powerful new tools


to aid this process
23
Previous exploits already carefully
crafted the heap
z Spooler Exploit:
− Multiple Write4 with a combination of the
Lookaside and the FreeList
z MS05_025:
− Softmemleaks to craft the proper layout for two
Write4 in a row
z Any other reliable heap overflow
z These still used write4s from the heap
algorithms themselves!
24
To establish deterministic control
over the Heap you need

z Understanding of the allocation algorithm


z Understanding of the layout you are
exploiting
z A methodology to control the layout
z The proper tools to understand and control
the allocation pattern of a process

25
The heap, piece by piece
z Understanding the algorithm
− Structures where chunks are held:
z Lookaside
z FreeList
z Understanding Chunk Behaviour
− Coalescing of Chunks
− Splitting of Chunks

26
A quick look at the lookaside
z Lookaside
0 1 2 3 4 5

8 bytes 24 bytes

Note: 24 bytes
8 bytes is the total size.
The actual data
size is: 24 - 8 =
16 byes

27
A quick look at the FreeList
data structure
z FreeList
1600 bytes 2000 bytes

0 BL FL BL FL BL FL
1 BL FL
2 BL FL 24 bytes 24 bytes

3 BL FL BL FL BL FL
4 BL FL
5 BL FL n*8 bytes

n BL FL BL FL

Where n < 128


28
Chunk coalescing: contiguous
free chunks are joined to
minimize fragmentation
Back_chunk
Size

PrevSize
Flink/Blin
ptr k PSize= *(ptr+2)
Size Back_chunk = ptr-(PSize*8)
if Back_chunk is not BUSY:
PrevSize unlink(Back_chunk)
Flink/Blin
k 29
Chunks are split into two
chunks when necessary

z Chunk splitting happens when a chunk of a


specific size is requested and only larger
chunks are available
z After a chunk is split, part of the chunk is
returned to the process and part is inserted
back into the FreeList

30
The life-cycle of a heap overflow
z There are four distinct segments in a heap exploit's
life that you need to understand and control:
− Before the overflow

}
− Between the overflow and a “Write4” Might
− Between the “Write4” and the function be the
same
pointer trigger
− Hitting payload and onward (surviving)

31
Heaps do not all start in the
same layout
z With heap overflows it is not always easy to
control how an overwritten chunk will affect the
operation of the heap algorithm
z Understanding how the allocation algorithm
works, it becomes apparent that doing three
allocations in a row does not mean it will return
three bordering chunks
z Typically this problem is because of “Heap Holes”
32
Heap Holes
z Assume Chunk is part of
the FreeList[97]

Vulnerable(function)

A = Allocate(0x300);
B = Allocate(0x300);
[...]
Overwrite(A);
fn_ptr = B[4];
fn_ptr(“hello world”);

33
Heap Holes
z Assuming
A

Vulnerable(function)

A = Allocate(0x300);
B = Allocate(0x300);
[...]
Overwrite(A);
fn_ptr = B[4];
fn_ptr(“hello world”);

34
Heap Holes
z Suppose
A

Vulnerable(function)

A = Allocate(0x300);
B = Allocate(0x300);
[...]
Overwrite(A); B
fn_ptr = B[4];
fn_ptr(“hello world”);

35
Heap Holes
z Suppose
A

Vulnerable(function)

A = Allocate(0x300);
B = Allocate(0x300);
[...]
Overwrite(A); B
fn_ptr = B[4];
fn_ptr(“hello world”);

36
Heap Holes
z Suppose
A

Vulnerable(function)

A = Allocate(0x300);
B = Allocate(0x300);
[...]
Overwrite(A); B
fn_ptr = B[4];
fn_ptr(“hello world”);

37
Two types of memory leaks are
used in heap exploitation
z A memleak is a portion of memory that is
allocated but not deallocated throughout
the life of the target
z There are two types of memleaks:
− Hard: Memleaks that remain allocated
throughout the entire life of the target
− Soft: Memleaks that remain allocated only for a
set period of time (e.g. a memleak based on one
connection)
38
Several bad coding practises
lead to hard memleaks
z Allocations within a try-except block that forget to
free in the except block
z Use of RaiseException() within a function before
freeing locally bound allocations (RPC services do
this a lot)
z Losing track of a pointer to the allocated chunk or
overwriting the pointer. No sane reference is left
behind for a free
z A certain code flow might return without freeing the
locally bound allocation
39
Soft memory leaks are almost as
useful to exploit writers
z Soft Memleaks are much easier to find:
− Every connection to a server that is not disconnected,
allocates memory
− Variables that are set by a command and remain so until
they are unset

− Ex:
X-LINK2STATE CHUNK=A allocates
0x400 bytes.
X-LINK2STATE LAST CHUNK=A free
that chunk.

40
We correct our heap layout with
memory leaks
z In summary, memleaks will help us do
different things:

}
Both have the same
− Empty the Lookaside objective: to
allow us to have
− Empty the FreeList consecutive chunks

− Leaving Holes for a specific purpose

41
Heap Rule #1: Force and control
the layout
z Assume again

Vulnerable(function)

A = Allocate(0x300);
B = Allocate(0x300);
[...]
Overwrite(A);
fn_ptr = B[4];
fn_ptr(“hello world”);

42
Heap Rule #1: Force and control
the layout
z memleak(768)

Calculating size:
768 + 8 = 776
Vulnerable(function) 776/8 = entry 97

A = Allocate(0x300);
B = Allocate(0x300);
[...]
Overwrite(A);
fn_ptr = B[4];
fn_ptr(“hello world”);

43
Heap Rule #1: Force and control
the layout
z memleak(768)

Vulnerable(function)

A = Allocate(0x300);
B = Allocate(0x300);
[...]
Overwrite(A);
fn_ptr = B[4];
fn_ptr(“hello world”);

44
Heap Rule #1: Force and control
the layout
z memleak(768)

Vulnerable(function)

A = Allocate(0x300);
B = Allocate(0x300);
[...]
Overwrite(A);
fn_ptr = B[4];
fn_ptr(“hello world”);

45
Heap Rule #1: Force and control
the layout
z memleak(768)

Vulnerable(function)

A = Allocate(0x300);
B = Allocate(0x300);
[...]
Overwrite(A);
fn_ptr = B[4];
fn_ptr(“hello world”);

46
Heap Rule #1: Force and control
the layout
z memleak(768)

Vulnerable(function)

A = Allocate(0x300);
B = Allocate(0x300);
[...]
Overwrite(A);
fn_ptr = B[4];
fn_ptr(“hello world”);

47
Good exploits are the result
of Intelligent Debugging

z With the new requirements for maximum


deterministic control over the algorithm,
exploiting the Win32 heap relies on
intelligent debugging
z The need for a debugger that will fill these
requirements arises

48
Immunity Debugger is the first
debugger specifically for
vulnerability development

z Powerful GUI
z WinDBG compatible commandline
z Powerful Python based scripting engine

49
Immunity Debugger's specialized
heap analysis tools

z A series of scripts offering everything


needed for modern Win32 Heap exploitation
!heap !searchheap
!funsniff !heap_analyze_chunk
!hippie !modptr

50
Immunity Debugger
z Dumping the Heap:
− !heap -h ADDRESS
z Scripting example:
pheap = imm.getHeap( heap )
for chunk in pheap.chunks:
chunk.printchunk()

51
52
Searching the heap using Immlib
z Search the heap
− !searchheap
what (size,usize,psize,upsize,flags,address,next,prev)
action (=,>,<,>=,<=,&,not,!=)
value (value to search for)
heap (optional: filter the search by heap)

z Scripting example:
SearchHeap(imm, what, action, value, heap = heap)
53
Comparing a heap before and
after you break it

z Dumping a Broken Heap:


− Save state:
z!heap -h ADDRESS -s
− Restore State:
z !heap -h ADDRESS -r

54
Heap Fingerprinting

z To craft a correct Heap layout we need a


proper understanding of the allocation
pattern of different functions in the target
process
z This means there is a need for fingerprinting
the heap flow of a specific function

55
Heap Fingerprinting

z !funsniff <address>
− fingerprint the allocation pattern of the given
function
− find memleaks
− double free
− memory freed of a chunk not belonging to our
current heap flow (Important for soft memleaks)

56
57
Automated data type
discovery using Immlib
z As we now know overwriting the metadata
of chunks to get a unlink primitive is mostly
no longer viable
z The next step of heap exploitation is taking
advantage of the content of chunks
z We need straightforward runtime
recognition of chunk content

58
Immunity Debugger offers
simple runtime analysis of heap
data to find data types

z String/Unicode
z Pointers ( Function Pointer, Data pointer,
Stack Pointer)
z Double Linked lists
− Important because they have their own unlink()
write4 primitives!

59
Data Discovery
z !heap -h HEAP_ADDRESS -d
− See next slide for awesome screenshot of
this in action!

60
61
Data Discovery can be
scripted easily
import libdatatype
dt = libdatatype.DataTypes( imm )
ret = dt.Discover( memory, address, what)
memory memory to inspect
address address of the inspected memory
what (all, pointers, strings,
asciistrings, unicodestrings,
doublelinkedlists, exploitable)
for obj in ret:
print ret.Print()
62
Heap Fuzzing heaps you
discover a way to obtain the
correct layout

z Sometimes controlling the layout is not as


easy as you think, even though it sounds
straightforward in theory
z From this the concept of Fuzzing the Heap
arises, to help in discovering the correct
layout for your process (manually or
automatically)

63
Heap Fuzzing

z !chunkanalizehook
z Get the status of a given chunk at a specific
moment. Answers the common questions:
− What chunks are bordering your chunk?
− What is the data in those chunks?

64
Heap Fuzzing

z Run the script, Fuzz and get result...


z usage:
!chunkanalizehook (-d) -a ADDRES <exp>
-a ADDRESS address of the hook
-d find datatypes
<exp> how to find the chunk
ex: !chunkanalizehook -d -a 0x77fcb703 EBX - 8

65
66
Inject Hook
z One of the biggest problems when hooking
an allocation function is speed
z Allocations are so frequent in some
processes that a hook ends up slowing down
the process and as a result changing the
natural heap behaviour (thus changing the
layout)
− lsass
− iexplorer
67
Inject Hooks into the target
process speeds things up

z This means doing function redirection and


logging the result in the debugger itself
(Avoiding breakpoints, event handling, etc)
z Can be done automatically via Immlib

68
Inject Hook

mapped mem
process
VirtualAllocEx

69
Inject Hook

mapped mem
process
hook code
InjectHooks

70
Inject Hook

mapped mem
process
hook code
Redirect
Function
RtlAllocateHeap
RtlFreeHeap

71
Inject Hook

mapped mem
process
hook code
Run the program

RtlAllocateHeap log data


[...]
RtlFreeHeap

72
Inject Hook

mapped mem
process
hook code
Inspect the result
log data
[...]

73
Inject Hook
z Hooking redirection:
− !hippie -af -n tag_name
z Hooking redirection as script:
fast = immlib.STDCALLFastLogHook( imm )
fast.logFunction( rtlallocate, 3)
fast.logRegister( "EAX" )
fast.logFunction( rtlfree, 3 )
fast.Hook()

74
The future
z In the near future ID will have a heap
simulator that, when fed with heap flow
fingerprints, will tell you which function
calls are needed to get the correct heap
layout for your target process
z Simple modifications to existing scripts can
put memory access breakpoints at the end of
every chunk to find out exactly when a heap
overflow happens
− This is great for fuzzers
75
Automating exploitation

z Stack overflows
− Automation of simple exploitation techniques
(bad bytes, etc) will be built into VisualSploit+ID
z Anti-DEP scripts already working!
z Deep protocol analysis and fuzzer
integration on its way

76
Conclusions
z Exploiting heap vulnerabilities has become
much more costly
z Immunity Debugger offers tools to
drastically reduce the effort needed to write
reliable heap overflows
− On older Windows platforms getting a reliable
write4 the traditional way
− On newer Windows platforms by abusing
program-specific data structures

77
Thank you for your time

Contact us at:
dave@immunityinc.com
nicolas.waisman@immunityinc.com

Security Research Team


78

You might also like