ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [LOB] Skeleton -> Golem Write-up
    표튜터와 함께하는 Pwnable/The Lord Of the BOF Write-up 2019. 2. 27. 18:11

    혹시나 이상하거나 잘못된 것이 있다면 댓글 부탁드립니다.


    Skeleton에서 Golem으로 가보도록 하자!!

    우선 코드를 보자~

    코드를 보면 stack destroyer라는 코드가 생겼다.

    stack에 우리가 넣을 수 있는 거의 모든 공간을 0으로 초기화해버린다. 물론 ret는 빼고!


    그렇다면 어떤식으로 문제를 풀어야할까??

    무언가 초기화 되지 않는 부분이 필요하다는 의미이다.

    하지만 현재 가진 바이너리에서는 방법이 없다.

    그렇다면 조금만 더 깊게 생각해보자. 프로그램이 실행될 때

    실행 파일만 가지고 실행되지 않는다는 점을 생각하면 이 문제를 해결 할 수 있다.

    메모리에는 실행시킨 실행파일만이 로드되는 것이 아니라는 것이다.



    해당 바이너리는 ldd와 file 명령어를 통해 확인한 결과 외부 라이브러리를 사용하고 있었다.



    프로그램 시작 전과 후의 함수 호출주소가 달라진 것을 확인할 수 있었다.

    그러므로 여기서 사용하고 있는 memset이나 strcpy들이 바로 위에서 보이는 libc라는

    외부 라이브러리에서 가져다가 사용된다는 것을 알 수 있었다.


    하지만 만약에 여기 등록되어있지 않은 어떠한 임의의 함수를 추가할 때는 어떤식으로 작업을 하게될까??

    메모리에 로드해야 실행이 가능하므로 프로그램이 실행되기 전에 메모리에 로드해야하는데

    그걸 가능하게 해주는 환경변수를 이용하면 된다.

    그러한 역할을 하는 환경변수가 바로 LD_PRELOAD이다.


    예를 들어 환경변수에 등록된 libc와 기존에 존재하던 libc에 중복되는 함수(printf)가 존재한다면

    환경변수에 등록된 libc에서 해당 함수의 정보를 알아오게 된다.

    이러한 시스템 취약점을 이용하면 printf 함수를 공격자가 설정한 방식으로 동작하게 만들 수 있다.

    이러한 공격을 함수 후킹이라고 한다.


    LD_PRELOAD 환경변수에 파일을 등록하게되면

    프로그램이 메모리에 로드되기전에 등록된 파일을 메모리에 먼저 업로드하게 된다.

    LD_PRELOAD로 메모리에 로드한 영역은 

    이 문제의 제약조건인 buffer부터 0xbfffffff까지 0으로 초기화하는 영역에

     해당되지 않음으로 우회가 가능하게된다.


    이제 생각했던 공격이 되는지를 확인해보자!!


    < test.c >

    우선 아무런 동작을 하지 않은 파일을 만들고 


    test.so라는 이름의 공유라이브러리로 컴파일해주었다.



    컴파일된 공유라이브러리를 LD_PRELOAD에 등록을 시켜주고 등록된 것을 확인하였다.



    ldd 명령어를 통해 공유라이브러리에 test.so가 제대로 올라간 것도 확인할 수 있었다.



    모든 초기화나 제약조건이 끝난 부분에 breakpoint를 걸고 실행을 시켜주었다.

    하지만 보다시피 우리가 LD_PRELOAD에 등록해놓은 

    libc파일은 초기화 되지않았다는 것을 확인할 수 있었다.



    그렇기 때문에 우리는 test.so라는 파일명 대신 nop과 쉘코드를 넣은 파일명으로 위의 절차를

    진행해주면 초기화되지않은 영역에 쉘코드를 올릴 수 있게 되는 것이다.



    이제 진짜 공격을 시작해보자!



    이름에 쉘코드와 nop을 넣어서 공유 라이브러리로 컴파일 해주었다.



    위의 파일을 공유라이브러리로 컴파일 한뒤 LD_PRELOAD를 등록했다.

    * 만약에 실수로 잘못 등록하거나 초기화를 원한다면 unset LD_PRELOAD 명령어를 입력하면 된다. *



    제대로 등록이 되었는지 확인해보았다.



    ldd로 바이너리의 libc정보를 확인해보니

    LD_PRELOAD에 등록했던 libc파일이 공유라이브러리로 올라간 것을 확인할 수 있었다.



    이제 공유라이브러리의 파일 경로가 저장된 스택의 주소를 찾아보도록 하겠다.

    넉넉하게 esp-5000부터 찾아보았다.


    Nop sled가 보이기 시작했고 그 뒤에 쉘코드가 보였다.

    그러므로 저 부분의 주소를 주면 된다.


    나는 0xbfffeb94를 Ret주었다. 당연히 쉘이 따졌다.



    이번에는 복사본이 아닌 원래의 바이너리 파일에서 실행하였고 당연히 쉘을 딸 수 있었다.


    다음 단계로 ~

    반응형

    댓글

Designed by Tistory.