Lec13 HeapAttacks
Lec13 HeapAttacks
Double-Free Attacks
Yan Huang
va_arg(ap,type) computes
Frame with
retrieves next
arg from offset
ap
location on the
stack past last
statically known
argument
Format Strings in C
◆ Proper use of printf format string:
… int foo=1234;
printf(“foo = %d in decimal, %X in hex”,foo,foo); … This will
print
foo = 1234 in decimal, 4D2 in hex
C has a concise way of printing multiple symbols: %Mx will print exactly 4M bytes (taking them
from the stack). Attack string should contain enough “%Mx” so that the number of characters
printed is equal to the most significant byte of the address of the attack code.
buf[256]
vtable
object T
buf[256]
vtable
object T
Problem?
<SCRIPT language="text/javascript">
shellcode = unescape("%u4343%u4343%...");
overflow-string = unescape(“%u2332%u4276%...”);
vtable
Where will the
buf[256] browser place the
shell shellcode on the
code
object T
Heap Spraying
◆ Force JavaScript JIT (“just-in-time” compiler) to fill
heap with executable shellcode, then point SFP or
vtable ptr anywhere in the spray area
hea
p
execute enabled execute enabled
Size
Last 4 bytes of user data
1
head 1
head 1
element Size
element Size
Size
Size 1
Forward pointer to next Forward Size
Size
pointer to next Forward pointer to Size
next Size
Forward pointer to next Forward
Forward pointer to next Back
pointer to prev. pointer to next Forward pointer to
1 pointer to prev.
Responding to Malloc
◆ Best-fit method
- An area with m bytes is selected, where m is the
smallest available chunk of contiguous memory equal
to or larger than n (requested allocation)
◆ First-fit method
- Returns the first chunk encountered containing n or
more bytes
◆ Prevention of fragmentation
- Memory manager may allocate chunks that are larger
than the requested size if the space remaining is too
small to be useful
To free()
#define link(bin, P) {
chk = bin->fd;
bin->fd = P;
P->fd = chk;
chk->bk = P;
P->bk = bin;
}
Add a chunk to the free list, bin.
Example of Unlink
Size
1
1
Forward pointer to
next
Forward pointer to
next Back pointer to
prev.
Back pointer to prev. Size
Unused space 1
Unused space 1
Forward pointer to
next
Forward pointer to Size
next Back pointer to Size
prev. :
Back pointer to prev. Size or last 4 bytes of
Size Unused space prev. Size or last 4
Size Unused space
: bytes of prev. Size
<-P
What if this
area
is
contaminated
with
untrusted user
Size
1
data?
1
Forward pointer to
: (4)
next
: (1) FD = P->fd;
Forward pointer to
<-BK (2)
next Back pointer to (2) BK = P->bk;
prev.
(3) FD->bk = BK;
Back pointer to prev. <-FD (1)
(4) BK->fd = FD;
Double-Free Vulnerabilities
◆ Freeing the same chunk of memory twice, without
it being reallocated in between
◆ Start with a simple case:
- The chunk to be freed is isolated in memory
- The bin (double-linked list) into which the chunk will be placed
is empty
P->
Size of chunk, :
in bytes P
User data
P->
Size of chunk, P
in bytes
Forward pointer to next chunk in list
Back pointer to previous chunk in list
Unused space (may be 0 bytes long)
Size of chunk
Call to free()
P->
Size of chunk, P
in bytes
Forward pointer to next chunk in list
Back pointer to previous chunk in list
Unused space (may be 0 bytes long)
Size of chunk
is
bin-> pointer to last chunk in how?
Forward pointer to first list
chunk in list Back unlinked from free list…
Size of previous chunk,
if unallocated
P->
Size of chunk, in bytes P
After malloc, user data
list Unused space (may be 0 bytes
will be written here
Forward pointer to next chunk in listlong) Size of chunk
Back pointer to previous chunk in
P->
Size of chunk, in bytes P
After another malloc,
in list Back pointer to previous
pointers will be read from here as
chunk in list Unused space (may be
if it pointed to a free chunk (why?)
0 bytes long) Size of chunk
Forward pointer
to next chunk
One will be
interpreted
as address, the other as value
(why?)