> 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-0-easy.md).

# heap 0 (Easy)

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

***

The source code is linked:

```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, "bico") != 0) {
        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 heap0!\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();
        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);
        }
    }
}
```

The jist of this code is that we would want to overwrite the save\_var. Since to print out the flag we need to set save\_var to something else other than bico, we need to overflow it. This is done by a need function provided by the code itself.&#x20;

Let's first describe some functions of the code.&#x20;

## C strcmp()

strcmp() is a built in library that compares 2 strings lexicographically (alphabet). From the comparsion it returns a result. Basically it adds the the value associated with each character, and subtracts them from the other total that is being compared.  &#x20;

## Dynamic Memory Allocation in C

It should be known that Memory is located on the Heap, not on the stack. "Memory persists even after the function that allocated it finishes, allowing functions to return pointers to it. This is different from stack allocated variables as it is not safe to return address of those variable." The malloc() command is used to allocate a single block of contiguous memory on the heap at runtime. Assume we want to store like 5 integers into an array. You would call malloc(20) since it would need to store 20 bytes.

## strncpy()

strncpy() takes 3 parameters. Source, Destination, and n (number of characters).&#x20;

* **dest:** A pointer to the destination array where the content is to be copied.
* **src:** A pointer to the source string to be copied.
* **n:** The number of characters to be copied from the source string.

This copies the amount of characters (n) from the src string into the dest string. If the n is bigger than the src, then it copies over nulls.&#x20;

### Solving It

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

If we want to override it, we need to replace "pico" with a input greater than the differences between the memory addresses. Since scanf() doesn't filter your input, this is easily achievable. &#x20;

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

To override the memory addresses, we needed a string that is over 32 bytes long. We can pretty put anything like a 1 or the letter A and it'll work.&#x20;

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

So after writing a bunch of As in the input, we managed to get the flag.&#x20;

picoCTF{my\_first\_heap\_overflow\_76775c7c}
