FTZ level9 풀이
id: level8
pw: apple
level9의 디렉토리를 조사해보자
hint가 있다! hint를 읽어보자
/usr/bin에 존재하는 bof의 소스코드가 힌트로 들어있다.
소스코드를 먼저 분석해보면 다음과 같다.
//bof의 소스코드
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
main(){
char buf2[10]; //크기가 10인 char 배열 buf2 선언
char buf[10]; //크기가 10인 char 배열 buf 선언
printf("It can be overflow : "); //overflow를 이용해야함을 알려준다.
fgets(buf,40,stdin); //buf에 40만큼 입력받고 있다. overflow 발생 지점
if ( strncmp(buf2, "go", 2) == 0 ) //buf2의 첫 2글자가 go이면
{
printf("Good Skill!\n");
setreuid( 3010, 3010 ); // level10권한을 얻게된다.
system("/bin/bash"); //bash 쉘을 띄워준다.
}
}
우리가 주목해야 하는 부분은 fgets다.
buf는 사이즈가 10인데 최대 40만큼 입력받고 buf에 넣어주기 때문에 overflow가 발생해서
buf가 아닌 다른 지점에 값을 채울 수 있다.
(참고로 fgets가 원래 BOF에 취약한 함수는 아님!)
소스코드를 디스어셈블 하기 위해 /usr/bin으로 이동하고 gdb를 실행시켜주자
아무래도 디스어셈블 할 수 없게 권한이 설정되어있는 듯 하다.
그렇지만 우리는 소스코드를 알고 있기 때문에 똑같은 파일을 /tmp에 만들어서 컴파일 후 디스어셈블 할 수 있다!
/tmp로 이동해서 bof.c라는 파일을 만들어주자 (vi editor를 사용하자 vi bof.c)
그리고 hint의 소스코드를 복사 붙여넣기 해주자
이를 저장하고 컴파일 해주자! (gcc -o bof bof.c)
그리고 gdb로 bof 파일을 열어보자
set disas intel을 하면 intel문법을 적용할 수 있다.
그리고 main을 디스어셈블 해보자 (클릭하면 크게 볼 수 있음 ↓)
디스어셈블한 결과 ebp-40에서 fgets로 입력을 받아 저장하고 (=> ebp-40이 buf 위치)
ebp-24에서 strncmp로 값을 비교하는 것을 볼 수 있다. (=> ebp-24가 buf2 위치)
따라서 스택 구조는 그림의 오른쪽처럼 그려지게 된다.
우리는 buf에 10바이트 이상 입력해 overflow를 일으키고 buf2에 우리가 원하는 값을 넣을 것이다.
buf2의 첫 두글자는 "go"여야 하기 때문에 buf에서 buf2까지 거리인 16바이트는 아무거나 채워주고
(buf+dummy=10+6=16) go를 입력해줄 것이다!
다시 bof파일이 있는 곳으로 돌아가서 bof를 실행시켜주고 a를 16개 입력하고 go를 입력해보자!
(우리가 만든 bof에서는 level10의 권한을 얻을 수 없다. 꼭 /usr/bin에 있는 bof를 실행!)
권한이 level10으로 바뀌었다!
이제 my-pass를 입력해 level10의 비밀번호를 얻어내자!
level10의 pw: "interesting to hack!"