ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Bugbear -> Giant Write-up
    표튜터와 함께하는 Pwnable/The Lord Of the BOF Write-up 2019.03.03 17:31

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



    생각보다 오래걸렸다.. 어떻게 풀어야 할지는 알았으나 삽질을 많이 했다.

    우선 코드를 보도록 하자!!

    코드를 보게되면 fopen을 통해서 어떠한 결과값을 버퍼에 저장한다.

    버퍼에 저장된 값을 lib_addr과 execve_offset에 넣어 더해 ret에 넣어준 뒤

    argv[1][44]와 비교해서 다르면 프로그램이 종료된다.




    그렇다면 우리는 execve 함수의 주소를 알아야 이 문제를 풀 수 있다는 것을 알 수 있었다.

    그럼 지금부터 하나씩 구해보자




    디버깅을 위해 우선 복사본을 만든다.


    코드를 보면 첫 번째 popen에서 구하려고 하는 것은 libc_base이고

    두 번째 popen에서 구하려고 하는 것은 execve함수의 offset이다.





    우선 나와있는 명령어를 그대로 입력해보았다.

    첫 번째의 명령어는 권한이 없기 때문에 찾을 수 없다고 나온다.

    두 번째의 명령어의 경우 정상 실행이 되어 execve함수의 offset을 구할 수 있었다.





    하지만 공유라이브러리 libc_base의 경우 파일이 다르더라도

    메모리에 올라가 있는 같은 공유라이브러리를 접근하기 때문에 주소값이 같다.

    그러므로 그냥 다른 파일에서 찾아도 상관이 없다.

    이렇게 아주 간단하기 libc_base를 구할 수 있었다.





    * 그 밖에 그냥 함수의 offset 구하는 방법이다 *


    < 방법 1 >




    < 방법 2 >

    구한 libc_base + execve_offset = ret이다.

    그러므로 ret = 0x400a9d48이 된다.


    결론적으로 strcpy함수의 취약점을 이용하여 buffer를 오버플로우 시켰을 때

    ret값을 execve함수의 시작주소로 덮어야 이 문제를 풀 수 있다는 것이며

    execve함수를 이용해서 문제를 풀어야함으로 execve함수의 인자로 사용될 것들을 구해야한다.



    execve함수의 인자는 3개이다.

    우리는 쉘을 따기위하여 "/bin/sh", {/bin/sh, NULL}, NULL 순으로 넣어 줄 것이다.

    하나씩 찾아보도록 하자.




    먼저 "/bin/sh"이다. 아주 간단한 명령어로 찾을 수 있었다.

    offset이 0xe3ff9이다. 그러므로 libc_base와 더하면 정확한 주소는 0x400fbff9가 된다.




    다음으로는 { "/bin/sh", NULL }을 구해야하는데 이를 어떻게 이용할지 고민이 됬다.

    이 부분을 해결하는 방법은 바로 심볼릭 링크를 이용한 방법을 사용하면 된다.

    해당 파일명 다음부분에 우리가 필요한 NULL이 있다. 

    execve의 두 번째 인자값이 배열로 진행되기 때문에 NULL 또한 4byte NULL을 가진 주소값이 필요할 것이다.



    그렇다면 심볼릭 링크를 걸어보도록하자!!

    심볼릭 링크로 만들파일이름은 당연히 "/bin/sh"이므로 위에서 구해놓은 "/bin/sh"의 주소를 전달해준다.

    심볼릭 링크가 제대로 걸린 것을 확인하였다.



    심볼릭 링크파일을 디버깅해보았다. 

    (권한이 없어서 제대로 내용을 못봄으로 공부를 위해 root 권한으로 보았음)




    "/bin/sh"이 제대로 들어가 있음을 볼 수 있었다.



    우리가 원하는 부분의 주소값은 "/home/bugbear"(14) 를 제외한

     "/bin/sh"이므로 0xbfffffe9 + 14(0xe) = 0xbffffff7



    두 번째 인자는 0xbffffff7가 된다!

    마지막 인자인 NULL은 위의 사진에서 파란색으로 표시된 것처럼 0xbffffffc를 사용하면 될 것 같다.




    이제 Payload를 작성해보겠다.

     A*44 + execve주소 + dummy(4) + "/bin/sh" + {"/bin/sh",NULL} + NULL

    짜잔~ 쉘이 따졌다.. 하지만 다 구해놓고 삽질을 하게되었는데

    그 이유는 바로 execve함수의 주소에 0x0a가 들어있었기 때문이다.

    0x0a를 개행문자로 인식해서 0x00으로 인식되어 제대로 payload가 작동하지 않았다.

    해결방법은 위의 그림처럼 " " 로 한 번 감싸주면된다!!


    * 참고 0x20은 space로 인식하기 때문에 0x00이 될 수 있으며 0x2f의 경우 이전에 푼 문제에서처럼 " / " 로 인식할 수 있음으로 주의 *


    다음 단계로~

    댓글 0

Designed by Tistory.