What is heap?
A heap is a memory used by programming languages to store global variables. All global variable are stored in heap memory space.
As much as vulnerabilities of stack , heap also has some critical vulnerabilities. When a programmer doesn’t manage heap memory carefully, then it will cause memory leak which can be a critical issue in program.
Main Point with Heap Memory
- The data stored in heap memory can be read by all thread, so it is not safe as stack memory.
- Processing time of heap memory is much more slower than stack memory.
- Heap memory doesn’t free itself automatically, so programmer should free it.
- Heap memory space is larger than stack memory
Three typical vulnerabilities of heap
A heap overflow is buffer overflow that occurs in the heap data area
Memory on the heap is dynamically allocated at runtime and typically contains program data. Heap Overflow Exploitation is performed by corrupting specific data using overwriting internal structure techniques. Basic skills for Heap Overflow is overwriting dynamic memory allocation linkage and exchanging resulting pointer to overwrite program function pointer
Use-After-Free occurs after freeing a memory location. Using after freeing the memory location can cause pointer issue within memory
Since the dynamic memory is allocated iteratively, program persistingly needs to check section of heap whether it is free or occupied. There are helps with referencing allocated memory areas called headers. This headers contain starting address of corresponding block. When programs don’t supervise this headers correctly, then the UAF occurs
3)Double Free Bug(DFB)
Double Free Bug occurs when programmer frees same heap memory space twice
Simple Structure Of Heap
Chunks are areas of memory in heap that are dynamically allocated via commands such as malloc(memory allocation)
if previous chunk has been freed, then the size of heap chunk is stored in prev_size.
the size of this chunk is stored in size(8bit) and 3 bit is for bit flag.
when previous chunk has been freed
when present chunk has been allocated using mmap
when present chunk is not being managed by main_arena
iv)fd(Forward Pointer) & bk(Backward pointer):
fd and bk is used to manage list of chunks and each of these point to address of previous and next chunk. These are used when present chunk is freed
Kali Linux is Debian-derived Linux distribution designed for digital forensics and penetration testing
I will use Kali Linux to conduct a heap exploit. Kali has many pre-installed tools such as Burp Suite, John the Ripper, Nmap, Wireshark. Therefore many security experts use this Linux.
GDB stands for GNU Debugger which is a portable debugger that runs on many Unix-like systems and works on many programming languages
GDB offers extensive facilities for tracing and altering the execution of computer programs. I use GDB to get into some vulnerable code. And I will find some vulnerabilities inside the code so that I can think of some exploit methods.
i)Analyze of this code
First, to pass this level, I need to execute function ‘void winner()’ instead of function ‘void nowinner()’. In this code, structure data, fp is declared and memory is allocated with size of structure data, fp in d, f. This code copies value in argv to member variable ‘name’ in data structure. By using strcpy to copy values, this can be vulnerability of heap overflow. Then if I can use heap overflow attack in this code, I might manipulate pointer in fp structure.
I need to unactivate ASLR(Address Space Randomization). If I don’t unactivate this option, then loaded address will be changed every time is execute process.
so, I unactivated ASLR to prevent randomization of address using
sudo sysctl -w kernel.randomize_va_space=0
gcc -z execstack -w -no-pie -o heap0 heap0.c
I will use gcc compiler to compile heap0.c. In gcc, I used -no-pie option not to make a position independent executable(PIE). PIE is a precodition to enable ASLR(address space layout randomization).
iii) disassemble heap0.c
I opened GDB debugger to see vulnerability in heap0.c
To get the assembly code of main function, I conducted ‘disas main’.
I made a breakpoint at main+25 which is 0x401191.
Since 0x40118c is where ‘d = malloc(sizeof(struct data))’ is executed,
RAX in this point has data of ‘d = malloc(sizeof(struct data));’.
Since *main+106 was function ‘strcpy(d->name, argv)’, I thought that strcpy might cause heap overflow issue.
So, I made a breakpoint on *main+111 and continued process to that point to see assembly information after the function strcpy done.
In this point, to see the data of ‘d = malloc(sizeof(struct data))’,
I used ‘x/80xw’.
In GDB, ‘x/80xw’ means
x = checking memory | 80 = amount of values
x = in hexadecimal | w = unit is 4 byte (word)
Since 1 = 0x31 in ASCII, there are 0x31313131 which I input is in 0x4052a0.
To pass the level, I need to change the pointer function nowinner() to winner(). 0x00401165 is the address of function nowinner(), so I have to put 4*4*5 = 80 byte of trash value and add the address of winner() on it.
To get the address of function winner(), I disassembled winner().
iv)Result with execute code
./heap0 $(python -c “print ‘F * 80 + ‘\x52\x11\x40’”)
By executing this command, I put 80 ‘F’s + 0x00401152 as input