본문 바로가기
시스템 해킹/드림핵

[Dreamhack] memory_leakage

by L3m0n S0ju 2021. 7. 19.


#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <string.h>

FILE *fp;

struct my_page {
char name[16];
int age;
};

void alarm_handler() {
    puts("TIME OUT");
    exit(-1);
}

void initialize() {
    setvbuf(stdin, NULL, _IONBF, 0);
    setvbuf(stdout, NULL, _IONBF, 0);

    signal(SIGALRM, alarm_handler);
    alarm(30);
}

int main()
{
    struct my_page my_page;
    char flag_buf[56];
    int idx;

    memset(flag_buf, 0, sizeof(flag_buf));
    initialize();

 

    while(1)

    {
        printf("1. Join\n");
        printf("2. Print information\n");
        printf("3. GIVE ME FLAG!\n");
        printf("> ");
        scanf("%d", &idx);
        switch(idx) {
            case 1:
                printf("Name: ");
                read(0, my_page.name, sizeof(my_page.name));
                printf("Age: ");
                scanf("%d", &my_page.age);
                break;
            case 2:
                printf("Name: %s\n", my_page.name);
                printf("Age: %d\n", my_page.age);
                break;
            case 3:
                fp = fopen("/flag", "r");
                fread(flag_buf, 1, 56, fp);
                break;
            default:
                break;
        }
    }
}

 


이번 문제는 memory_leakage를 사용하여 플래그를 획득하는 문제입니다. case 1에서는 my_page.name에 최대 16바이트 크기의 입력값을 입력하고 my_page.age에 정수를 입력합니다. case 2에서는 저장된 변수를 출력합니다. case 3에서는 flag 값을 flag_buf에 저장합니다.

 

문제 풀이 동작은 다음과 같습니다. case 2의 printf("Name: %s\n", my_page.name);에서 %s는 널 바이트가 나올 때 까지 문자를 출력합니다. 하지만 case 1의 read(0, my_page.name, sizeof(my_page.name));에서는 16바이트 만큼의 문자를 입력받을 수 있으므로 my_page.name의 마지막 문자에 0이 아닌 다른 문자가 존재하면 널 바이트가 나올 때 까지 쓰레기 값을 출력하게 됩니다. gdb를 이용하여 변수들의 주소를 확인하면 아래와 같습니다.

 

mypage.name : 0xffffd4b0
mypage.age : 0xffffd4c0 
flag_buf : 0xffffd4c4

mypage.name와 mypage.age의 차이가 16바이트 이므로 mypage.name의 마지막 문자열이 널 바이트가 아닌 경우 바로 뒤에 있는 mypage.age 값도 출력하게 됩니다. 그리고 mypage.age의 값은 최대 4바이트 크기로 널 바이트가 없을 경우 flag_buf에 있는 값까지 출력하게 됩니다. 따라서 아래와 같이 입력 값을 순서대로 입력하면 플래그가 출력됩니다. 286331153은 16진수로 0x11111111이고 널 바이트인 0x00이 아닌 값으로 4바이트를 모두 채우기 위함입니다.

 


 

플래그

 

 

'시스템 해킹 > 드림핵' 카테고리의 다른 글

[Dreamhack] basic_heap_overflow  (0) 2021.07.20
[Dreamhack] out_of_bound  (0) 2021.07.18
[Dreamhack] basic_exploitation_002  (0) 2021.07.17
[Dreamhack] sint  (0) 2021.07.15
[Dreamhack] basic_exploitation_003  (0) 2021.05.22

댓글