ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • LEVEL 13
    WARGAME/FTZ 2018. 4. 27. 16:13
    level13

    FTZ LEVEL13


    [Summary]

    1. 소스코드의 10 행에서 strcpy 함수를 사용하므로 길이체크를 하지않아 Buffer Overflow 취약점이 발생한다.
    2. 소스코드의 12 행에서 메모리보호기법 중 canary 역할을하는 i 변수의 값이 변조되면 종료되어 버리기 때문에 i 변수의 값이 변조되지 않은것처럼 그대로 덮어준다.
    3. buf 배열의 길이가 (1024 + 12) 이며 canary 변수 i의 길이(4 + 8) 와 sfp 사이즈(4바이트)를 더한 1052바이트를 payload 로 전송하게되면 RET 값을 변조할 수 있다.
    4. aslr 보호기법으로 인해 buf 배열에 shellcode 를 삽입할 수 없어서 환경변수에 삽입하고 RET 를 쉘코드가 포함된 환경변수의 주소로 변조함으로써 결론적으로 프로그램의 흐름을 제어하고 level14(3094) 권한의 쉘을 획득하였다.

    [Sourcecode]

    1.  #include <stdlib.h>
    2.  
    3.  main(int argc, char *argv[])
    4.  {
    5.     long i=0x1234567;
    6.     char buf[1024];
    7.  
    8.     setreuid( 3094, 3094 );
    9.     if(argc > 1)
    10.          strcpy(buf,argv[1]);
    11.  
    12.     if(i != 0x1234567) {
    13.          printf(" Warnning: Buffer Overflow !!! \n");
    14.          kill(0,11);
    15.     }
    16.  }
    17.  
    18. // attackme.c
    

    [Analysis]

    • setuid 가 설정되어 있으면 gdb 가 동작하지 않기 떄문에 tmp 디렉토리에 cp 명령을 이용하여 복사한다.

    • attackme 소스코드 9~10행 보면 매개변수가 있을경우 buf 배열에 버퍼를 복사(strcpy)한다.
    • 소스코드 상에서는 buf 배열 크기가 1024 이지만 실제로 1024 이상의 버퍼가 할당되어 있을것이다.(자세한 내용 참조 : http://mdkstudy.tistory.com/41)
    • 또한, 소스코드 12~15 행을 보면 i 변수에 0x01234567 값이 아닐경우 즉, 변조되었을경우 프로그램을 종료 시켜버리는 루틴이 있다.
    • 이제 소스코드를 통해 전체적인 흐름은 파악했으니 gdb 를 이용해 실행시켜보면서 동적 분석을 진행한다.

    • gdb 에 실행파일을 로드한 뒤 main 함수의 ret 에 브레이크포인트를 걸고 실행한다.

    • buf 배열에 1024 사이즈만큼 "A" 문자열을 넣고 확인해봣더니 예상했던데로 시스템에서 1024 보다 12바이트 더 큰 공간을 할당했다.
    • 따라서, 1036(1024 + 12) 사이즈만큼 넣고 실행한다.

    • 하지만, SIGSEGV 시그널이 발생하면서 프로그램이 종료 되어버렸다.
    • 이유를 파악하기 위해 esp 레지스터 값을 통해 필자가 넣은 문자열을 확인해보니 사이즈는 1036 이 맞지만 문자열의 마지막을 뜻하는 NULL(0x00) 이 자동으로 "A" 문자열 뒤에 들어가버려서 canary 변수를 변조되었다.
    • 이를 우회하기 위해, canary 변수의 값과 동일하게 0x01234567 을 넣고 실행했다.

    • 실행결과, SIGSEGV 시그널이 발생하지 않고 정상실행되었다.
    • 메모리(스택 영역)를 확인해보니 canary 변수주소의 값이 변조되지 않은것처럼 보인다.
    • 따라서, 이 가설을 통해 canary 변수의 값을 그대로 덮어주면 우회된다는것이 증명되었고 payload 를 canary 변수 이후 12바이트를 더 덮으면 RET 주소도 변조할 수 있게 되었다.

    • gdb 를 통해 다시 paylaod 를 작성한 뒤, 실행시켜보면 RET 가 "CCCC" 문자열로 변조되었는것을 확인할 수 있다.

    • Shell 로 빠져나와 bash2 프로세스를 실행시키고(자세한 내용 참조 : http://mdkstudy.tistory.com/42) aslr 기법을 우회하기 위한 환경변수에 쉘코드를 로드한다.

    • findegg.c 를 통해 필자가 로딩한 환경변수의 주소를 찾고 gdb 에서 확인을 한다.
      (자세한 내용 참조 : http://mdkstudy.tistory.com/42)

    • findegg.c 에서 찾은 주소 0xbffffc1f 를 살펴보니 필자가 올린 쉘코드가 위치한 환경변수의 주소가 맞다.

    마지막으로, payload 는 (의미없는 값 * 1036) + canary(\x67\x45\x23\x01) + (의미없는 값 * 12) + 쉘코드가 위치한 환경변수 주소(\x1f\xfc\xff\xbf) 이렇게 작성하면 된다.

    [Exploit]

    ./attackme $(python -c 'print "A"*1036 + "\x67\x45\x23\x01" + "B"*12 + "\x1f\xfc\xff\xbf"')
    

    [References]


    'WARGAME > FTZ' 카테고리의 다른 글

    LEVEL 16  (0) 2018.05.06
    LEVEL 15  (0) 2018.05.05
    LEVEL 14  (0) 2018.04.29
    LEVEL 12  (0) 2018.04.26
    LEVEL 11  (0) 2018.04.24
Designed by Tistory.