ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [HackCTF] Look at me Write-up
    표튜터와 함께하는 Pwnable/HackCTF Write-up 2019. 4. 26. 16:49

    이번 문제는 Look at me 이다.

    지금까지는 보통 dynamically linked 방식의 바이너리였다면




    이번 문제는 statically linked 방식의 바이너리였다.

    그래서 바이너리 내부에 많은 함수가 들어있었다.




    해당 바이너리에는 NX가 적용되어있어서 스택에

    Shellcode를 넣더라도 실행권한이 없어서 실행되지 않는다.




    코드는 굉장히 간단한 형태를 가지고 있었다.




    < Main >





    < look_at_me >

    gets함수를 이용해서 BOF를 일으키면 된다는 건 쉽게 알 수 있었다.





    음.. 어떤 방식으로 풀어야 할지 고민해보았는데

    일반적으로 쉘을 얻을 때 system함수를 이용하거나

    쉘코드를 사용해서 해결하는데 이 문제에 주어진

    함수에는 system이 없다. 듣기로는 execute함수를 사용하면

    된다는데 execute함수 마저도 없었다.. 쩝..



    하지만 이 때 머릿속에 떠오른 것이 있었다.

    1 ~ 2달전에 매주하는 스터디 모임 세미나에서 Py0zz1가

    발표했던 내용의 함수가 떠올랐다. 그 때 말했던

    상황이 바로 딱 지금 상황과 일치했다!!!



    바로 mprotect 함수를 사용하는 것이다. 이 함수를 이용하면

    우리는 실행권한을 부여할 수가 있다. 이 mprotect 함수는

    3개의 인자가 필요하다. 바로 권한을 줄 시작위치, 길이, 권한이다.

    사용 시에 한 가지 주의할 점은 시작위치로 주는 주소값이 4096

    즉, 0x1000의 배수여야 한다는 것이다. 이는 페이지의 경계에

    맞춰야 한다는 의미이다. 



    참고 : https://www.lazenca.net/display/TEC/03.ROP%28Return+Oriented+Programming%29+-+mmap%2C+mprotect#id-03.ROP(ReturnOrientedProgramming)-mmap,mprotect-Examplecode.1




    마침 mprotect 함수는 존재하고 있었다. 그러므로 우리는

    고정주소값 영역에 Shellcode를 저장하고 mprotect를 이용하여

    해당 영역에 실행권한을 부여하는 식으로 ROP를 진행하면

    쉘을 딸 수 있을 것이다. 그럼 이제 필요한 것들을 찾아보자.




    우선 pr gadget과 pppr gadget이다.

    pr gadget은 gets함수를 사용할 때 필요한 것이고

    pppr gadget은 mprotect함수를 사용할 때 필요할 것이다.


    < PR gadget >

    gets함수를 사용하는 이유는 Bss영역에 shellcode를

    입력할 때 사용할 것이기 때문이다.



    < PPPR gadget>

    아주 쉽게 두 개의 gadget을 구할 수 있었다.




    다음으로는 gets 함수와 mprotect 함수의 주소이다.

    IDA에는 함수가 너무 많이 보여서 그냥 gdb로 찾았다. (자신이 편한걸 사용하자)




    이번에는 고정주소인 Bss영역을 찾아보자!!

    스택영역에 Shellcode를 넣지 않는 이유는 ASLR 때문에

    정확한 스택의 주소를 알 수 없기 때문에 Bss 같이 고정주소를

    가진 영역에 Shellcode를 넣는 것이다.



    마지막으로 ret의 위치를 구해보도록 하자!!

    0x18만큼 ebp에서 떨어져있으니까 0x18+0x4 = 28 뒤에

    ret가 존재하는 걸 알 수 있었다. 이제 Payload를 구성해보자





    < Payload >

    bss_start가 있는 이유는 별 건 아니다.

    그저 mprotect함수의 첫 번째 인자로 쓰일 주소가 0x1000의

    배수여야하기 때문에 그 부분을 맞춰준 것이다. 이렇게 인자를

    bss_start 처럼 맞춰서 우리가 Shellcode를 넣어놓은 Bss영역을 포함시킬 만큼의

    크기로 두 번째 인자(길이)를 주게되면 쉽게 권한을 줄 수 있기 때문이다.

    혹시나 mprotect 함수의 첫 번째 인자를 맞춰주기 위해

    0x1000 배수 계산을 하는 사람이 있을 까봐 적어보았다! 

    세 번째 인자는 권한이고 나는 그냥 7(RWX)를 주었다.


    결론은 ROP를 이용해서 gets함수를 호출했고 gets함수의 인자로

    bss영역을 주었다. 그 영역에 shellcode를 입력하였고 mprotect를

    호출하여 Shellcode가 저장된 영역에 실행권한을 부여한 뒤

    Shellcode가 저장된 영역으로 ret하게 하였다~ 그러므로

    Shellcode가 작동하면서 쉘이 따지는 원리이다~




    역시 FLAG를 볼 수 있었다.



    반응형

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

    [HackCTF] 1996 Write-up  (0) 2019.04.29
    [HackCTF] Poet Write-up  (0) 2019.04.29
    [HackCTF] Gift Write-up  (0) 2019.04.25
    [HackCTF] ROP Write-up  (0) 2019.04.24
    [HackCTF] RTL_Core Write-up  (0) 2019.04.23

    댓글

Designed by Tistory.