-
메모리 보호기법 - 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 댓글