> For the complete documentation index, see [llms.txt](https://simon-6.gitbook.io/simoncyber/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://simon-6.gitbook.io/simoncyber/ctf-writeups/picoctf-2024/binary-exploitation/heap-1-medium.md).

# heap 1 (Medium)

<figure><img src="/files/xFO1m60I29Rcnva09n8k" alt=""><figcaption></figcaption></figure>

wget [**https://artifacts.picoctf.net/c\_tethys/32/chall.c**](https://artifacts.picoctf.net/c_tethys/32/chall.c)

***

```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define FLAGSIZE_MAX 64
// amount of memory allocated for input_data
#define INPUT_DATA_SIZE 5
// amount of memory allocated for safe_var
#define SAFE_VAR_SIZE 5

int num_allocs;
char *safe_var;
char *input_data;

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);
    }
}

void print_menu() {
    printf("\n1. Print Heap:\t\t(print the current state of the heap)"
           "\n2. Write to buffer:\t(write to your own personal block of data "
           "on the heap)"
           "\n3. Print safe_var:\t(I'll even let you look at my variable on "
           "the heap, "
           "I'm confident it can't be modified)"
           "\n4. Print Flag:\t\t(Try to print the flag, good luck)"
           "\n5. Exit\n\nEnter your choice: ");
    fflush(stdout);
}

void init() {
    printf("\nWelcome to heap1!\n");
    printf(
        "I put my data on the heap so it should be safe from any tampering.\n");
    printf("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.\n\n");
    fflush(stdout);
    input_data = malloc(INPUT_DATA_SIZE);
    strncpy(input_data, "pico", INPUT_DATA_SIZE);
    safe_var = malloc(SAFE_VAR_SIZE);
    strncpy(safe_var, "bico", SAFE_VAR_SIZE);
}

void write_buffer() {
    printf("Data for buffer: ");
    fflush(stdout);
    scanf("%s", input_data);
}

void print_heap() {
    printf("Heap State:\n");
    printf("+-------------+----------------+\n");
    printf("[*] Address   ->   Heap Data   \n");
    printf("+-------------+----------------+\n");
    printf("[*]   %p  ->   %s\n", input_data, input_data);
    printf("+-------------+----------------+\n");
    printf("[*]   %p  ->   %s\n", safe_var, safe_var);
    printf("+-------------+----------------+\n");
    fflush(stdout);
}

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);
        }
    }
}
```

Let's try the same method we did as heap 0.

<figure><img src="/files/gy6tnLeEyuOK5wCoebb4" alt=""><figcaption></figcaption></figure>

The distance is the same, so what if we write a length bigger than 32?&#x20;

<figure><img src="/files/oH1iBr4J9Zxsbmd90xub" alt=""><figcaption></figcaption></figure>

This time, they didn't let us get the flag. What's different?&#x20;

```
if (!strcmp(safe_var, "pico"))
```

This is the essential part of the source code. Basically strcmp is commonly used to compare if a string is equal to another string. it returns 0 if safe\_var equals to pico. But in C, a false of 0 is considered to be False and everything else is considered to be True that why we need a ! inverse operator.  Essentially we need to overwrite safe\_var to equal pico instead of bico. Should be pretty easy!

<figure><img src="/files/hcpGRjOoozZvrH5gIAzD" alt=""><figcaption></figcaption></figure>

Surprisingly this worked well enough. What I did was to write 32 bytes of information, but since at 32 I want to overwrite bico, I just wrote pico.&#x20;

&#x20;
