본문 바로가기

System Hacking

[Dreamhack] basic_exploitation_002 풀이 - 티스토리

 

32비트 환경에 NX만 걸려있는 상황이다. 

 

 

#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 get_shell() {
    system("/bin/sh");
}

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

    char buf[0x80];

    initialize();

    read(0, buf, 0x80);
    printf(buf);

    exit(0);
}

 

개인적으로 FSB 드림핵 강의가 너무 어렵고 헷갈려서 가장 이해하는데 오래 걸린 파트인 것 같다

 

 

 

또 막상 이해하고 보니 크게 별거 없다..

 

 

 

코드 분석

 

1. 먼저 main에서 buf에 입력을 받고 printf로 변수를 바로 출력하므로 fsb가 발생한다

 

2. fsb를 이용해서 코드 내 함수인 get_shell로 코드흐름을 바꿔주면 될 것 같다

 

 

처음에 main의 ret를 get_shell로 바꿀 생각이었는데 

 

 

main을 까보니까 ret가 없다

 

 

코드를 다시 보니까 exit()함수가 있어서 ret가 없는 거 같다

 

 

exit함수의 got를 get_shell 주소로 바꿔서 exit 실행 시 get_shell이 실행 되도록 하면 쉘이 따인다

 

 

 

정보 수집

 

먼저 필요한 것들은 get_shell 주소, exit의 got주소 정도이다

 

 

기본적으로 pie가 꺼져 있으므로 코드 및 데이터 영역은 주소가 고정이다

 

get_shell : 0x08048609

 

 

 

exit_got : 0x0804a024

 

 

 

 

시나리오

 

 

필요한 것들을 구했으니 이것들을 잘 활용하면 된다

 

 

 

exit_got주소에 get_shell의 주소를 덮어야 하므로 %n 서식 지정자를 이용하면 된다

 

 

 

%n은 이전까지 나온 글자수 만큼 %n에 해당하는 인자에 바이트 수를 저장한다

 

즉 %100c%n이면 100바이트가 n에 저장 되는 것이다

 

 

ex) n에 해당되는 인자 주소가 0x1234이면 0x1234에 0x64 (100)이 저장되는 것이다

 

 

 

먼저 buf의 시작 위치를 구하자

 

 

 

첫 입력부터 바로 출력되는 걸 볼 수 있다

 

 

 

따라서 exit_got의 주소를 먼저 입력하고 %1$n을 이용해서 첫 번째 인자 (exit_got) 에 원하는 바이트 수를 저장할 수 있다

 

 

여기서 get_shell의 주소인 0x08048609를 저장해야 되는데 0x08048609는 너무 큰 값이므로 2바이트 씩 나눠서 저장해주어야 한다

 

 

*너무 큰값 ex) %21억c 이럴 경우 너무 커서 출력이 너무 오래 걸려서 time out 발생함

 

 

exit_got의 주소인 0x0804a024를 2바이트 씩 나누면

 

 

exit_got + 0 ~ exit_got + 1 : 0xa024

 

exit_got + 2 ~ exit_got + 3 : 0x0804 이다 

 

그러므로 exit_got 부분에는 0x8609를 넣어주고 exit_got+2 부분에는 0x0804를넣어주면 된다

 

0x0804 = 2052

 

0x8609 = 34313

 

 

최종 페이로드

 

 

 

2052 - 8을 해준 2044를 써 준다. 이유로는 앞의 주소 8 바이트가 들어가므로 빼준 것이다

 

 

마찬가지로 34313 - 2052 해준 값을 쓴다

 

 

 

여기서 %hn은 2바이트 값만 참조한다

 

 

 

 

 


fsb 힘들었다 하