ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Pwnkr] Bof Write-up
    표튜터와 함께하는 Pwnable/Pwnable.kr Write-up 2019. 3. 26. 01:15


    이번 문제의 이름은 bof이다. 

    다운로드 받은 bof의 소스코드를 보도록 하자.


    버퍼의 크기는 32개인데 우리가 입력할 수 있는 입력 수의 제한이 없다.

     그러므로 gets함수에서 bof를 일으킬 수 있다는 것을 알 수 있었다.


    이 때 key의 값이 0xcafebabe여야만 쉘을 딸 수 있는데 이 값을 우리가

     입력하는 값이 아닌 이미 인자로 넘겨진 값 0xdeadbeef가 존재했다. 




    < 대충 스택이 이런식으로 쌓여있을 것이다. >

    스택의 구조를 생각해보면 key가 버퍼인 overflowme보다 높은 곳에 존재한다.

    그러므로 버퍼를 오버플로우 시켜서 key값을 cafebabe로

    덮게되면 쉘을 따낼 수 있다는 것을 알게되었다.

    우리가 해야하는 것은 바로 이 key값의 위치를 알아야한다.


    func 함수의 어셈블리어 코드를 보자.

    첫 번째 상자는 overflowme라는 buffer의 값이고 두 번째 상자는 key라는 것을 알 수 있었다.


     

    gdb를 이용해서 디버깅도 진행해보았다. 입력값으로는 "aaaa"를 주었다

    overflowme의 버퍼에 저장된 "aaaa"에서 key에 저장된 0xdeadbeef까지

    0xffffd0d0 - 0xffffd09C = 0x34 = 52

    52byte의 거리차이가 났다. 그러므로 52byte를 dummy값으로 채우고

    0xcafebabe를 덮어씌워주면 쉘을 딸 수 있을 것이다.



    이런식으로 진행하면 된다.~



    깔끔하게 쉘이 따진 모습이다.





    < 번 외 >


    하지만.. 이 문제를 풀면서 또다른 것을 배우게됬다. 그것은 바로 Canary이다.

    하다보니 52대신 32이상의 값을 주게되었는데 아래와 같은 에러가 발생했다.

    또잉? 이건 SSP가 적용된 바이너리에서 Canary값이 변조되었을 때

    발생하는 에러메시지 인데???.. 라는 생각으로 접근해보게 되었다.


    여윽시나 Canary가 걸려있었다. PIE와 NX bit도 걸려있었지만 이번 문제에서는 신경쓸 필요는 없었다. 


    SSP가 걸려있는 문제를 처음 본 입장에서 내가 궁금했던 것은

    지금까지 알았던 Canary는 값이 변조되면 위의 에러메시지를 출력하는 것으로 알고있는데

    그렇다면 overflowme 버퍼 다음에 바로 Canary가 있는 건가? 하는 것이였고

    그렇다면 32개를 훌쩍넘은 52개를 dummy로 채울 때는 변조됬음에도 불구하고

    왜 에러메시지가 발생하지 않았느냐? 하는 궁금증이 생겼다.

    (나중에 알았지만.. 실수로 일어난 잘못된 궁금증이었다.. ㅎㅎ)


    우선 어셈블리어 코드를 보면서 설명해보도록 하겠다.

    우선 위의 그림에서 보이는 gs란 gs segment를 의미하며 커널영역에

    있는 값을 의미한다. 또한 DWORD PTR gs:0x14의 의미는

    "커널의 gs segment+0x14에 있는 값을 DWORD만큼 참조하겠다"

    라는 의미가 된다. 저 값은 랜덤으로 바뀌는 값이며 그 값과 eax에 있는 [ebp-0xc]의 값을

    비교하여 맞으면 정상작동되고 다르면 stack_chk_fail 함수를 call하게되는 것이다.



    즉, stack_chk_fail은 Canary값이 변조되었을 때 호출되며 이 함수가 있다면

    SSP(Stack Smashing Protector)가 적용되어있다고 봐도 무방하다. 이 함수는

    "stack smashing detected"라는 에러메시지와 함께 __fortify_fail 함수를 호출한다.

    이 함수는 backtrace정보와 memory map을 출력한 뒤 프로그램을 종료한다. 





    어쨌든 나는 overflowme 다음에 Canary값이 존재한다고 생각했고 확인해보았다.

    이번 Canary 값은 다음과 같았다.(참조하는 값이 랜덤이므로 실행 할때 마다 계속 바뀌는 것임)



    버퍼에는 32개의 "a"를 넣어주고 디버깅을 진행하였다.

    역시 overflowme 버퍼 다음에 Canary값이 존재했다. 이 말은 분명 위에서

    "a" 52개를 넣었을 때 Canary값이 변조되었다는 의미이다. 



    gdb를 이용해서 다시 디버깅 해보았다.

    디버깅 시 입력값을 주는 방법!!

    run <<< $(python -c 'print("a"*52 + "\xbe\xba\xfe\xca")')

    또잉? system함수로 "/bin/sh"이 실행되고나서 에러메시지가 뜬다??



    해당 에러메시지가 작동하지 않는다는 것은 잘못된 생각이었다.

    쉘을 따더라도 "stack smashing detected"는 떴다..

    알고보니 내가 맨날 Ctrl + Z나 Ctrl + C로 종료해서 그런것이였다..쩝..



    정상적으로 나가니 에러메시지가 있었다. 원리는 우리가 지금까지 본 것과 같다.

     func함수에서 Canary가 덮인 것을 확인하는 __stack_chk_fail함수는

    func함수가 끝날 때 호출하게된다. 그렇기 때문에 이전의 분기문 0xcafebabe를

    만족시겨서 system함수의 "/bin/sh"이 실행될 것이고 우리가 쉘을 종료하면

    다음 명령들이 실행되면서 Canary값이 변조된 것을 알고 __stack_chk_fail 함수도

    실행하게 되는 것이다. (당연한이야기지만...)


    주의하자 실행이 안되는 것이 아니라는것을!! 그리고 정상종료하자;;




    반응형

    '표튜터와 함께하는 Pwnable > Pwnable.kr Write-up' 카테고리의 다른 글

    [Pwnkr] Passcode Write-up  (0) 2019.03.31
    [Pwnkr] Horcruxes -> Write-up  (0) 2019.03.29
    [Pwnkr] Flag Write-up  (0) 2019.03.28
    [Pwnkr] Collision Write-up  (0) 2019.03.26
    [Pwnkr] Fd Write-up  (0) 2019.03.25

    댓글

Designed by Tistory.