ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 메모리 보호기법 - PIE
    공부정리 2019. 1. 12. 22:43

    TU-CTF2018에서 출제된 lisa 라는 문제를 풀면서 PIE에 대해서 공부하게 되었다.


    바이너리에 PIE가 걸려있으면 주소값들이 해괴망측하게 변하는 걸 볼 수 있는데

    이 모습을 처음 보고 '아. 빡세다.' 라는 생각이 들어서 그런지 PIE라는 존재에 겁을 먹고 있었다.

    근데 막상 공부해보니까 'ASLR과 크게 다르지 않다'라는게 나의 결론이다.


    [ PIE란? ]

    Position Independent Executable의 약자로 바이너리 주소가 상대적인 주소로 랜덤하게 매핑시키는 기법이다.

    ASLR과 비슷하게 생각하되, 차이점은 PIE는 Code(Text)영역을 포함한 모든 영역(Data,Stack,Heap,Libc)을 

    랜덤하게 매핑시킨다는 것이다.


    [ Sample.c 소스코드 ]

    위 샘플코드로 확인해보도록 하자.

    foo변수가 전역으로 선언되어 data영역에 할당되게 될 것이고, func_foo( )에서 주소값을 출력해준다.


    [ 컴파일 ]

    PIE를 적용하기 위해서는 -fPIE와 -pie 두 개의 옵션으로 컴파일 하여야 한다.

    하나는 기본 컴파일을 하고, 다른 하나는 PIE를 적용하여 컴파일 하였다.


    [ Checksec ]

    non_PIE바이너리는 NX만 적용된 상태이며, PIE바이너리는 PIE가 추가로 적용되어 있는 상태이다.


     [ Data영역 주소확인 ]

    ASLR이 적용된 상태이며, PIE가 적용되지 않은 바이너리는 Data영역 주소가 고정된 것을 확인할 수 있으며

    PIE가 적용된 바이너리는 Data영역의 주소가 실행할 때마다 변하는 것을 확인할 수 있다.


    [ Code영역 주소확인 ]

    Code영역 또한 랜덤하게 매핑이 되는데, PIE가 적용된 바이너리는 어떠한 곳에 매핑되더라도 

    상대적으로 찾아가서 실행될 수 있게끔 설계되어 있다.


    쉽게 말하자면, 저 작은 주소값들은 offset의 개념으로 봐도 무방하다.

    주소값이 바뀌는 부분은 offset바이트를 제외한 Base부분이며, 저기 할당된 작은 주소값은 고정적이다.


    예를들면, 첫번째 실행했을 때 위의 인스트럭션 주소값이 [0x55555555554447de] 였다면

    두번째 실행했을 때는 [0x55555555553337de]로 할당된 0x7de는 고정적이고

    변하는 부분은 [0x5555555555444],[0x5555555555333] 이 Base부분인 것이다.


    따라서, RET를 핸들링할 수 있는 상황이라면 offset바이트만 바꿔서 Code Reuse Attack이 가능하다.

    물론, 인자가 필요한 함수를 재사용 할때는 인자값 또한 핸들링이 가능한 상황이어야 한다.



    [ 핵심 정리 ]

    1. PIE는 위치 독립 실행 파일이다.

    2. PIE는 바이너리의 모든 주소(Code,Data,Stack,Heap,Libc)를 랜덤 매핑한다.

    3. Code영역에 할당된 주소는 고정적인 값이며, 바뀌는 부분은 Base주소이다.



    '공부정리' 카테고리의 다른 글

    Syscall 가젯이 없을 때  (0) 2019.03.06
    Return-to-Csu 기법 정리  (8) 2019.03.05
    [02-14 공부정리(FSB 정리)]  (0) 2018.02.15
    [02-11 공부정리(Chaining RTL 정리)]  (0) 2018.02.11
    [02-10 공부정리]  (0) 2018.02.10

    댓글

Designed by Tistory.