More Vulnerabilities�(buffer overreads, format string, integer overflow, heap overflows)
Chester Rebeiro
Indian Institute of Technology Madras
CR
2
CR
Buffer Overreads
3
CR
4
Buffer Overread Example
CR
Buffer Overread Example
5
len read from command line
len used to specify how much�needs to be read.
Can lead to an overread
CR
Buffer Overreads
we are not executing any code
not moving out of the segment
6
CR
Heartbleed : A buffer overread malware
7
CR
Heartbeat
8
Hello World; 12
Hello World; 12
Heartbeat Message
type
length
payload
padding
CR
Heartbeat
9
Hello World; 12
Hello World; 12
Heartbeat Message
type
length
payload
padding
CR
SSL3 struct and Heartbeat
length : length of the heartbeat message
data : pointer to the entire heartbeat message
10
struct ssl3_record_st
{
unsigned int D_length; /* How many bytes available */
[...]
unsigned char *data; /* pointer to the record data */
[...]
} SSL3_RECORD;
type
Length (pl)
payload
Format of data (Heartbeat Message)
CR
Payload and Heartbeat length
11
type
Length (pl)
payload
Heartbeat Message
payload length (pl)
D_length (pl)
CR
Overread Example
12
Attacker sends a heartbeat message with�a single byte payload to the server.
However, the pl_length is set to 65535�(the max permissible pl_length)
Victim ignores the SSL3 length (of 4 bytes),
Looks only at the pl_length and returns �a payload of 65535 bytes. In the payload, only
1 byte is victim’s data remaining 65534 from�its own memory space.
CR
Broken OpenSSL �code@victim
13
p points to the attackers heart
beat packet which the victim�just received.
get the heartbeat type;�fill payload with size of payload�(pl in our notation)
This is picked up from the
attackers payload and contains�65535
Allocate buffer of 3 + 65535 + 16 bytes
memcpy grossly overreads from the victim’s heap
1
2
3
4
CR
Broken OpenSSL �code@victim
14
Add padding and send the�response heartbeat message�back to the attacker
5
CR
65534 byte return payload may contain sensitive data
15
Further, invocations of similar false heartbleed will result in another 64KB of the�heap to be read.
In this way, the attacker can scrape through the victim’s heap.
CR
The patch in OpenSSL
16
Discard the heartbeat response if it happens to be greater than �the length in the SSL3 structure (i.e. D_length)
CR
Format String Vulnerabilities
17
CR
Format Strings
18
printf ("The magic number is: %d\n", 1911);
format string
Format specifier
arguments
void printf (char **fmt, . . .);
variable arguments
Function declaration of printf
CR
printf invocation
19
void main(){
printf (“%d %d %d\n", a, b, c);
}
b
return Address
Locals of function
prev frame pointer
stack
a
ptr to fmt string
c
CR
20
void printf(char *fmt, ...){
va_list ap; /* points to each unnamed arg in turn */
char *p, *sval;
int ival;
double dval;
va_start(ap, fmt); /*make ap point to 1st unnamed arg */
for (p = fmt; *p; p++) {
if (*p != '%’) {
putchar(*p);
continue;
}
switch (*++p) {
case 'd':
ival = va_arg(ap, int);
print_int(ival);
break;
| | | | |
case 's':
for (sval = va_arg(ap, char *); *sval; sval++)
putchar(*sval);
break;
default:
putchar(*p);
break;
}
}
va_end(ap); /* clean up when done */
}
b
return Address
Locals of function
prev frame pointer
stack
a
ptr to fmt string
c
CR
Insufficient Arguments to printf
21
void main(){
printf (“%d %d %d\n", a, b);
}
b
return Address
Locals of function
prev frame pointer
stack
a
ptr to fmt string
Can the compiler detect this inconsistency
3 format�specifiers
But only 2�arguments
Can the printf function detect this inconsistency
CR
Exploiting inconsistent printf
22
printf ("%s%s%s%s%s%s%s%s%s%s%s%s");
printf ("%x %x %x %x");
CR
Exploiting inconsistent printf
23
This should have the contents of s
user_string has to be local
CR
Exploiting inconsistent printf
24
This should have the contents of s
user_string has to be local
contents of the stack printed�by the 6 %x
string pointed to by 0x080496c0.�this happens to be ‘s’
%s, picks pointer�from the stack
and prints from the
pointer till \0
CR
Digging deeper
25
0x0000001a
0xbffe72d8
b776a54
0
0xb7fe1b48
0x08096c0
%x
%x
0x8048566
%x
%x
%x
%x
%s
user_string
stack
esp
printf(user_string);
CR
More Format Specifiers
26
Pick the 7th argument from the stack.
0x0000001a
0xbffe72d8
b776a54
0
0xb7fe1b48
0x08096c0
%7$s
0x8048566
user_string
stack
esp
+7
CR
Overwrite �an arbitrary location
%n format specifier : returns the number of characters printed so far.
Using the same approach to read data from any location, printf can be used to modify a location as well
Can be used to change function pointers as well as return addresses
27
int i;
printf(“12345%n”, &i);
CR
Overwrite Arbitrary Location�with some number
28
CR
Overwrite Arbitrary Location with Arbitrary Number
29
An arbitrary number
CR
Another useful format specifier
30
address of�s to store the�lower 16bits
address of�s to store the�higher 16bits
Store the number�of characters printed.
Both 16 bit lower and�16 bit higher will be�stored separately
CR
Integer Overflow Vulnerability
31
CR
What’s wrong with this code?
32
Expected behavior
CR
What’s wrong with this code?
33
Defined as short. Can hold
a max value of 65535
If i > 65535, s overflows, therefore is truncated. So, the condition check is likely to be bypassed.
Will result in an overflow of buf, �which can be used to perform nefarious activities
CR
Integer Overflow Vulnerability
34
CR
Widthness Overflows
Occurs when code tries to store a value in a variable that is too small (in the number of bits) to handle it.
For example: a cast from int to short
35
int a1 = 0x11223344;
char a2;�short a3;��a2 = (char) a1;
a3 = (short) a1;
a1 = 0x11223344
a2 = 0x44
a3 = 0x3344
CR
Arithmetic Overflows
36
CR
Exploit 1�(manipulate space allocated by malloc)
37
Space allocated by malloc�depends on len. If we choose a suitable value of len such that len*sizeof(int) overflows,
then,
CR
(Un)signed Integers
38
l is initialized with the highest positive value that a signed 32 bit integer can take.
When incremented, the MSB is set, and the number is interpreted as negative.
CR
Sign Interpretations in compare
39
This test is with signed numbers.
Therefore a negative len will pass the�‘if’ test.
In memcpy, len is interpreted as unsigned.
Therefore a negative len will be treated
as positive.
This could be used to overflow kbuf.
void *memcpy(void *restrict dst, const void *restrict src, size_t n);
From the man pages
CR
Sign interpretations in arithmetic
40
table + pos is expected to be a value greater than table.
If pos is negative, this is not the case.
Causing val to be written to a location beyond the table
This arithmetic done considering unsigned
CR
exploiting overflow due to sign�in a network deamon
41
if size1 and size2 are large enough,
size may end up being negative.
size1 and size2 are unsigned
Size is signed.
Size is returned, which may�cause an out to overflow in the�callee function
CR
Sign could lead to �memory overreads.
42
#define MAX_BUF_SIZE 64 * 1024
void store_into_buffer(const void *src, int num)
{
char global_buffer[MAX_BUF_SIZE];
if (num > MAX_BUF_SIZE)
return;
memcpy(global_buffer, src, num);
[...]
}
CR
Stagefright Bug
43
CR
MPEG4 Format
44
CR
tx3g exploit
45
status_t MPEG4Source::parseChunk(off64_t *offset) {
[...]
uint64_t chunk_size = ntohl(hdr[0]);
uint32_t chunk_type = ntohl(hdr[1]);
off64_t data_offset = *offset + 8;
if (chunk_size == 1) {
if (mDataSource->readAt(*offset + 8, &chunk_size, 8) < 8) {
return ERROR_IO;
}
chunk_size = ntoh64(chunk_size);
[...]
switch(chunk_type) {
[...]
case FOURCC('t', 'x', '3', 'g'):
{
uint32_t type;
const void *data;
size_t size = 0;
if (!mLastTrack->meta->findData(
kKeyTextFormatData, &type, &data, &size)) {
size = 0;
}
uint8_t *buffer = new (std::nothrow) uint8_t[size + chunk_size];
if (buffer == NULL) {
return ERROR_MALFORMED;
}
if (size > 0) {
memcpy(buffer, data, size);
}
offset into file
int hdr[2] is the first two�words read from offset
chunksize of 1 has a �special meaning.
All ingredients for an integer overflow vulnerability
Buffer could be made to overflow here. Resulting in a heap based exploit.
This can be used to control …�... Size written
... What is written
... Predict where objects are allocated
CR
Integer Overflows
On 32 bit platforms
widthness overflow� (chunk_size + size) is uint64_t however new takes a 32 bit
value
On 64 bit platforms
arithmetic overflow� (chunk_size + size) can overflow by setting large values for
chunk_size
46
uint64_t chunk_size = ntohl(hdr[0]);
uint8_t *buffer = new (std::nothrow) uint8_t[size + chunk_size];
CR
Attack Vectors
47
CR
Heap exploits
48
CR
Heap
49
Text
Data
Heap
Stack
CR
Heap vs Stack
50
CR
Heap Management
tcmalloc (from Google)
jemalloc (used in Android)
51
CR
ptmalloc 2
52
https://sploitfun.wordpress.com/2015/02/10/understanding-glibc-malloc/
CR
Ptmalloc: the whole structure
53
CR
Creating the Arena and Heap
void* threadFunc(void* arg)
{
char* addr = (char*) malloc(1000);
free(addr);
}
int main()
{
pthread_t t1;
void* s;
int ret;
char* addr;
addr = (char*) malloc(1000);
free(addr);
ret = pthread_create(&t1, NULL,
threadFunc, NULL);
ret = pthread_join(t1, &s);
return 0;
}
54
Process starts with no heap segment
CR
Creating the Arena and Heap
void* threadFunc(void* arg)
{
char* addr = (char*) malloc(1000);
free(addr);
}
int main()
{
pthread_t t1;
void* s;
int ret;
char* addr;
addr = (char*) malloc(1000);
free(addr);
ret = pthread_create(&t1, NULL,
threadFunc, NULL);
ret = pthread_join(t1, &s);
return 0;
}
55
Heap of size 132 KB created on the first malloc invocation.
The arena is created by invoking the
system call brk.
Future allocations use this arena until it gets completely used up. In which case the arena can grow or shrink.
chester@optiplex:~$ cat /proc/1897/maps
00400000-00401000 r-xp 00000000 08:07 2490714 ..a.out
00600000-00601000 r--p 00000000 08:07 2490714 ..a.out
00601000-00602000 rw-p 00001000 08:07 2490714 ..a.out
00602000-00623000 rw-p 00000000 00:00 0 [heap]
7ffff77f3000-7ffff79b1000 r-xp 00000000 08:06 161656 /lib/x86_64-linux-gnu/libc-2.19.so
7ffff79b1000-7ffff7bb1000 ---p 001be000 08:06 161656 /lib/x86_64-linux-gnu/libc-2.19.so
7ffff7bb1000-7ffff7bb5000 r--p 001be000 08:06 161656 /lib/x86_64-linux-gnu/libc-2.19.so
7ffff7bb5000-7ffff7bb7000 rw-p 001c2000 08:06 161656 /lib/x86_64-linux-gnu/libc-2.19.so
CR
Creating the Arena and Heap
void* threadFunc(void* arg)
{
char* addr = (char*) malloc(1000);
free(addr);
}
int main()
{
pthread_t t1;
void* s;
int ret;
char* addr;
addr = (char*) malloc(1000);
free(addr);
ret = pthread_create(&t1, NULL,
threadFunc, NULL);
ret = pthread_join(t1, &s);
return 0;
}
56
Even after free, the arena will still exist.
chester@optiplex:~$ cat /proc/1897/maps
00400000-00401000 r-xp 00000000 08:07 2490714 ..a.out
00600000-00601000 r--p 00000000 08:07 2490714 ..a.out
00601000-00602000 rw-p 00001000 08:07 2490714 ..a.out
00602000-00623000 rw-p 00000000 00:00 0 [heap]
7ffff77f3000-7ffff79b1000 r-xp 00000000 08:06 161656 /lib/x86_64-linux-gnu/libc-2.19.so
7ffff79b1000-7ffff7bb1000 ---p 001be000 08:06 161656 /lib/x86_64-linux-gnu/libc-2.19.so
7ffff7bb1000-7ffff7bb5000 r--p 001be000 08:06 161656 /lib/x86_64-linux-gnu/libc-2.19.so
7ffff7bb5000-7ffff7bb7000 rw-p 001c2000 08:06 161656 /lib/x86_64-linux-gnu/libc-2.19.so
CR
Creating the Arena and Heap
void* threadFunc(void* arg)
{
char* addr = (char*) malloc(1000);
free(addr);
}
int main()
{
pthread_t t1;
void* s;
int ret;
char* addr;
addr = (char*) malloc(1000);
free(addr);
ret = pthread_create(&t1, NULL,
threadFunc, NULL);
ret = pthread_join(t1, &s);
return 0;
}
57
When threads are created, it may lead to new arenas being created. These new arenas are also of 132 KB and obtained by invoking mmap on the OS.
chester@optiplex:~$ cat /proc/2283/maps
00400000-00401000 r-xp 00000000 08:07 a.out
00600000-00601000 r--p 00000000 08:07 2490714 a.out
00601000-00602000 rw-p 00001000 08:07 2490714 a.out
00602000-00623000 rw-p 00000000 00:00 0 [heap]
7ffff0000000-7ffff0021000 rw-p 00000000 00:00 0
7ffff0021000-7ffff4000000 ---p 00000000 00:00 0
7ffff6ff2000-7ffff6ff3000 ---p 00000000 00:00 0
7ffff6ff3000-7ffff77f3000 rw-p 00000000 00:00 0 [stack:2330]
CR
The Whole Structure
58
CR
More about Arenas
59
CR
Allocated Chunk
60
P : previous chunk in use (PREV_INUSE bit)
If P=0, then the word before this contains�the size of the previous chunk.
The very first chunk always has this bit set
Preventing access to non-existent memory.
M : set if chunk was obtained with mmap
N : set if chunk belongs to thread arena
Allocated chunk
mem. Is the pointer returned by malloc.
chunk. Is the pointer to metadata for�malloc
User data size for malloc(n) is �N = 8 + (n/8)*8.
Total size of chunk is N+8 bytes
CR
Free Chunk
61
P : previous chunk in use (PREV_INUSE bit)
If P=0, then the word before this contains�the size of the previous chunk.
The very first chunk always has this bit set
Preventing access to non-existent memory.
M : set if chunk was obtained with mmap
N : set if chunk belongs to thread arena
Free chunk
mem. Is the pointer returned by malloc.
chunk. Is the pointer to metadata for�malloc
On 32 bit machine,
User data size for malloc(n) is �N = 8 + (n/8)*8.
Total size of chunk is N+8 bytes
CR
List of Free Chunks
Free chunks (blue) are maintained in a linked list.
The linked list is called bins and can vary in size and characteristic
62
Allocated Chunk
Free Chunk
CR
Binning
63
16
24
32.
…
512
576
640
---
231
sorted
Different list maintained to trade off between fragmentation
and speed of malloc / free.
CR
Types of Bins
64
Fast Bins
Unsorted Bins
Small Bins
Large Bins
Top Chunk
Last Reminder
Chunk
Single link list
8 byte chunks; defined by NFASTBINS in malloc.c (12 of them)
each list has one of these sizes: 16, 24, 32, …., 80
No coalescing (could result in fragmentation; but speeds up free)
LIFO
Pointer to list maintained in the arena (malloc_info)
CR
Fastbin Example
65
CR
Example of Fast Binning
66
x and y end up in the same bin.
x and y end up in different bins.
CR
Types of Bins
67
Fast Bins
Unsorted Bins
Small Bins
Large Bins
Top Chunk
Last Reminder
Chunk
127 bins
CR
Bins
68
CR
Types of Bins
69
Fast Bins
Unsorted Bins
Small Bins
Large Bins
Top Chunk
Last Reminder
Chunk
Single link list
8 byte chunks
(16, 24, 32, …., 128)
No coalescing (could result in fragmentation; but speeds up free)
LIFO
1 bin
Doubly link list
Chunks of any size
Helps reuse recently used chunks
62 bins ; less than 512 bytes
Chunks of 8 bytes : 16, 24, …. 504
Circular doubly linked list – because chunks are unlinked from�the middle of the list
Coalescing – join to free chunks which are adjacent to each �other
FIFO
CR
Types of Bins
70
Fast Bins
Unsorted Bins
Small Bins
Large Bins
Top Chunk
Last Reminder
Chunk
Single link list
8 byte chunks
(16, 24, 32, …., 128)
No coalescing (could result in fragmentation; but speeds up free)
LIFO
1 bin
Doubly link list
Chunks of any size
Helps reuse recently used chunks
62 bins ; less than 512 bytes
Chunks of 8 bytes
Circular doubly linked list – because chunks are unlinked from�the middle of the list
Coalescing – join to free chunks which are adjacent to each �other
FIFO
63 bins ;
First 32 bins are 64 bytes apart
Next 16 bins are 512 bytes apart
Next 8 bins are 4096 bytes apart
Next 4 bins are 32768 bytes apart
Next 2 bins are 262144 bytes apart
1 bin of remaining size
Each bin is circular doubly linked list
Since contents of bin are not of same size; they are stored in �decreasing order of size
Coalescing – join to free chunks which are adjacent to each �other
CR
Types of Bins
71
Fast Bins
Unsorted Bins
Small Bins
Large Bins
Top Chunk
Last Reminder
Chunk
Single link list
8 byte chunks
(16, 24, 32, …., 128)
No coalescing (could result in fragmentation; but speeds up free)
LIFO
1 bin
Doubly link list
Chunks of any size
Helps reuse recently used chunks
62 bins ; less than 512 bytes
Chunks of 8 bytes
Circular doubly linked list – because chunks are unlinked from�the middle of the list
Coalescing – join to free chunks which are adjacent to each �other
FIFO
63 bins ;
First 32 bins are 64 bytes apart
Next 16 bins are 512 bytes apart
Next 8 bins are 4096 bytes apart
Next 4 bins are 32768 bytes apart
Next 2 bins are 262144 bytes apart
1 bin of remaining size
Each bin is circular doubly linked list
Since contents of bin are not of same size; they are stored in �decreasing order of size
Coalescing – join to free chunks which are adjacent to each �other
CR
free(ptr)
72
00000000
ptr
prev_chunk
ptr_chunk
next_chunk
p
0
CR
free(ptr)
2. If the previous chunk is free then
Similar is done if the next chuck is free as well.
73
00000000
prev_chunk
next_chunk
p
is 0
CR
Unlinking from a free list
74
void unlink(malloc_chunk *P, malloc_chunk *BK, malloc_chunk *FD){
FD = P->fd;
BK = P->bk;
FD->bk = BK;
BK->fd = FD;
}
CR
Types of Bins
75
Fast Bins
Unsorted Bins
Small Bins
Large Bins
Top Chunk
Last Reminder
Chunk
Single link list
8 byte chunks
(16, 24, 32, …., 128)
No coalescing (could result in fragmentation; but speeds up free)
LIFO
1 bin
Doubly link list
Chunks of any size
Uses the first chunk that fits.
When a chunk is freed, it is first added here.
Helps reuse recently used chunks
CR
Glib’s first fit allocator
76
https://github.com/shellphish/how2heap (first_fit.c)
First Fit scheme used for allocating chunk
Allocating a memory chunk of 512 bytes
Now freeing it
Now allocating another chunk < 512 bytes.
The first free chunk available corresponds to the freed ‘a’. So, ‘c’ gets allocated the same address as ‘a’
CR
Types of Bins
77
Fast Bins
Unsorted Bins
Small Bins
Large Bins
Top Chunk
Last Reminder
Chunk
Single link list
8 byte chunks
(16, 24, 32, …., 128)
No coalescing (could result in fragmentation; but speeds up free)
LIFO
1 bin
Doubly link list
Chunks of any size
Helps reuse recently used chunks
62 bins ; less than 512 bytes
Chunks of 8 bytes
Circular doubly linked list – because chunks are unlinked from�the middle of the list
Coalescing – join to free chunks which are adjacent to each �other
FIFO
63 bins ;
First 32 bins are 64 bytes apart
Next 16 bins are 512 bytes apart
Next 8 bins are 4096 bytes apart
Next 4 bins are 32768 bytes apart
Next 2 bins are 262144 bytes apart
1 bin of remaining size
Each bin is circular doubly linked list
Since contents of bin are not of same size; they are stored in �decreasing order of size
Coalescing – join to free chunks which are adjacent to each �other
Top of the arena;
Does not belong to any bin;
Used to service requests when there is no free �chunk available.
If the top chunk is larger than the requested memory�it is split into two: user chunk (used for the requests�memory and last reminder chunk which becomes�the new top chunk)
If the top chunk is smaller than the requested chunk
It grows by invoking the brk() or sbrk() system call
Which defines the end of the process’ data segment
CR
Unlinking from a free list
78
void unlink(malloc_chunk *P, malloc_chunk *BK, malloc_chunk *FD){
FD = P->fd;
BK = P->bk;
FD->bk = BK;
BK->fd = FD;
}
CR
Unlinking in ptmalloc2
79
/* Take a chunk off a bin list */
void unlink(malloc_chunk *P, malloc_chunk *BK, malloc_chunk *FD)
{
FD = P->fd;
BK = P->bk;
if (__builtin_expect (FD->bk != P || BK->fd != P, 0)) malloc_printerr(check_action,"corrupted double-linked list",P);
else {
FD->bk = BK;
BK->fd = FD;
}
}
Detects cases such as these
FD pointer
BK pointer
void main()
{
char *a = malloc(10);
free(a);
free(a);
}
Causing programs like this to�crash
CR
Some double frees are detected
80
/* Take a chunk off a bin list */
void unlink(malloc_chunk *P, malloc_chunk *BK, malloc_chunk *FD)
{
FD = P->fd;
BK = P->bk;
if (__builtin_expect (FD->bk != P || BK->fd != P, 0)) malloc_printerr(check_action,"corrupted double-linked list",P);
else {
FD->bk = BK;
BK->fd = FD;
}
}
Detects cases such as these
FD pointer
BK pointer
FD pointer
BK pointer
void main()
{
char *a = malloc(10);
free(a);
free(a);
}
Causing programs like this to�crash
CR
Most double frees are not detected
81
void main()
{
char *a = malloc(10);
char *b = malloc(10);
free(a);
free(b);
free(a);
printf(“The end!\n”);
}
FD pointer
BK pointer
FD pointer
BK pointer
a
b
After the second free
CR
Most double frees are not detected
82
void main()
{
char *a = malloc(10);
char *b = malloc(10);
free(a);
free(b);
free(a);
printf(“The end!\n”);
}
FD pointer
BK pointer
FD pointer
BK pointer
a
b
After the third free
FD pointer
BK pointer
a
CR
Another malloc
83
void main()
{
char *a = malloc(10);
char *b = malloc(10);
char *c;
free(a);
free(b);
free(a);
c = malloc(10);
}
Another malloc�c gets allocated the same address as a
FD pointer (a)
BK pointer (a)
FD pointer (b)
BK pointer (b)
b
a
CR
Two views of the same chunk
84
prev chunk
size
data
prev chunk
size
unused�space
size
FD ptr
BK ptr
Allocated chunk
Free chunk
c
a
*c = 0xdeadbeef;
*(c+4) = 0xdeadbeef;
you can control the FD ptr and BK ptr contents using c
CR
Exploiting
85
char payload[] = “\x33\x56\x78\x12\xac\xb4\x67”;
Void fun1(){}
void main()
{
char *a = malloc(10);
char *b = malloc(10);
char *c;
fun1();
free(a);
free(b);
free(a);
c = malloc(10);
*(c + 0) = GOT entry – 12 for fun1;
*(c + 4) = payload;
some malloc(10);
fun1();
}
Need to lookout for programs that
have (something) like this structure
We hope to execute payload instead of�the 2nd invocation of fun1();
CR
Exploiting
86
char payload[] = “\x33\x56\x78\x12\xac\xb4\x67”;
Void fun1(){}
void main()
{
char *a = malloc(10);
char *b = malloc(10);
char *c;
fun1();
free(a);
free(b);
free(a);
c = malloc(10);
*(c + 0) = GOT entry for fun1;
*(c + 4) = payload;
some malloc(10);
fun1();
}
FD pointer (b)
BK pointer (a)
FD pointer (a)
BK pointer (a)
a
b
FD pointer
BK pointer
a
CR
Exploiting
87
char payload[] = “\x33\x56\x78\x12\xac\xb4\x67”;
Void fun1(){}
void main()
{
char *a = malloc(10);
char *b = malloc(10);
char *c;
fun1();
free(a);
free(b);
free(a);
c = malloc(10);
*(c + 0) = GOT entry for fun1;
*(c + 4) = payload;
some malloc(10);
fun1();
}
FD ptr (b)
BK pointer (b)
FD pointer (a)
BK pointer (a)
a alias c
b
CR
Exploiting
88
char payload[] = “\x33\x56\x78\x12\xac\xb4\x67”;
Void fun1(){}
void main()
{
char *a = malloc(10);
char *b = malloc(10);
char *c;
fun1();
free(a);
free(b);
free(a);
c = malloc(10);
*(c + 0) = GOT entry for fun1 - 12;
*(c + 4) = payload;
some malloc(10);
fun1();
}
GOT entry
ptr payload
FD pointer (a)
BK pointer (a)
a alias c
b
CR
Exploiting
89
char payload[] = “\x33\x56\x78\x12\xac\xb4\x67”;
Void fun1(){}
void main()
{
char *a = malloc(10);
char *b = malloc(10);
char *c;
fun1();
free(a);
free(b);
free(a);
c = malloc(10);
*(c + 0) = GOT entry for fun1 - 12;
*(c + 4) = payload;
some malloc(10);
fun1();
}
GOT entry - 12
ptr payload
FD pointer (a)
BK pointer (a)
a alias c
alias FD
alias BK
b
unlink(P){
FD = P->fd;
BK = P->bk;
FD->bk = BK;
BK->fd = FD;
}
CR
Exploiting Heap
90
char payload[] = “\x33\x56\x78\x12\xac\xb4\x67”;
Void fun1(){}
void main()
{
char *a = malloc(10);
char *b = malloc(10);
char *c;
fun1();
free(a);
free(b);
free(a);
c = malloc(10);
*(c + 0) = GOT entry for fun1 - 12;
*(c + 4) = payload;
some malloc(10);
fun1();
}
Payload executes
CR
Other heap based attacks
91
CR