PIE
Position-Independent Executable(PIE)은 무작위 주소에 매핑돼도 실행 가능한 실행 파일을 뜻합니다.
PIC(Position-Independent Code)
공유 오브젝트는 기본적으로 재배치(Relocation)가 가능하도록 설계되어 있습니다.
재배치가 가능하다는 것은 메모리의 어느 주소에 적재되어도 코드의 의미가 훼손되지 않음을 의미하는데,
컴퓨터 과학에서는 이런 성질을 만족하는 코드를 Position-Independent Code(PIC)라고 부릅니다.
pic의 코드는 rip를 기준으로 데이터를 상대 참조(Relative Addressing)하기 때문에 바이너리가 무작위 주소에 매핑돼도 제대로 실행될 수
ASLR을 꺼도 PIE가 적용된 프로세스는 무작위 주소에 매핑되지 않음
PIE 우회
코드 베이스 구하기
코드 영역의 가젯을 사용하거나, 데이터 영역에 접근하려면 바이너리가 적재된 주소를 알아야 합니다. 이 주소를 PIE 베이스, 또는 코드 베이스라고 부릅니다.
코드 베이스를 구하려면 라이브러리의 베이스 주소를 구할 때 처럼 코드 영역의 임의 주소를 읽고, 그 주소에서 오프셋을 빼야합니다
Partial Overwrite
코드 베이스를 구하기 어렵다면 반환 주소의 일부 바이트만 덮는 공격
일반적으로 함수의 반환 주소는 호출 함수(Caller)의 내부를 가리킵니다. 특정 함수의 호출 관계는 정적 분석 또는 동적 분석으로 쉽게 확인할 수 있으므로, 공격자는 반환 주소를 예측할 수 있습니다.
ASLR의 특성 상, 코드 영역의 주소도 하위 12비트 값은 항상 같습니다.
따라서 사용하려는 코드 가젯의 주소가 반환 주소와 하위 한 바이트만 다르다면,
이 값만 덮어서 원하는 코드를 실행시킬 수 있습니다.
그러나 만약 두 바이트 이상이 다른 주소로 실행 흐름을 옮기고자 한다면,
ASLR로 뒤섞이는 주소를 맞춰야 하므로 브루트 포싱이 필요하며, 공격이 확률에 따라 성공하게 됩니다.
PIE 적용 확인방법
file 명령어로 확인 시, LSB Shared object 사용 시 PIE 적용된거임
/bin/ls: ELF 64-bit LSB shared object, x86-64
---------------------
RELocation Read-Only(RELRO)
함수가 처음 호출될 때 함수의 주소를 구하고, 이를 GOT에 적는 Lazy Binding을 소개했습니다.
이를 방어하고자 만듦
RELRO는 쓰기 권한이 불필요한 데이터 세그먼트에 쓰기 권한을 제거합니다.
1) RELRO를 부분적으로 적용하는 Partial RELRO
.got.plt , .data , .bss 섹션들에는 쓰기가 가능합니다
Partial RELRO, Full RELRO의 적용 방식과 효과를 확인해 보았습니다. Partial RELRO의 경우, .init_array와 .fini_array에 대한 쓰기 권한이 제거되어 두 영역을 덮어쓰는 공격을 수행하기 어려워집니다.
하지만, .got.plt 영역에 대한 쓰기 권한이 존재하므로 GOT overwrite 공격을 활용할 수 있습니다.
2) 가장 넓은 영역에 RELRO를 적용하는 Full RELRO
got에는 쓰기 권한이 제거되어 있으며 data와 bss에만 쓰기 권한이 있습니다.
Full RELRO의 경우, .init_array, .fini_array 뿐만 아니라 .got 영역에도 쓰기 권한이 제거되었습니다.
그래서 공격자들은 덮어쓸 수 있는 다른 함수 포인터를 찾다가 라이브러리에 위치한 hook을 찾아냈습니다.
라이브러리 함수의 대표적인 hook이 malloc hook과 free hook입니다
__malloc_hook은 libc.so에서 쓰기 가능한 영역에 위치합니다.
따라서 공격자는 libc가 매핑된 주소를 알 때, 이 변수를 조작하고 malloc을 호출하여 실행 흐름을 조작할 수 있습니다.
이와 같은 공격 기법을 통틀어 Hook Overwrite라고 부릅니다
---------------------------
Glibc 2.33 이하 버전에서 libc 데이터 영역에는 malloc()과 free()를 호출할 때
함께 호출되는 훅(Hook)이 함수 포인터 형태로 존재합니다.
이 함수 포인터를 임의의 함수 주소로 오버라이트(Overwrite)하여
악의적인 코드를 실행하는 기법을 배울 것입니다.
malloc 함수는 __malloc_hook
free, __free_hook,
realloc __realloc_hook
셋중에 되는 걸 해봐야함
도커 이미지 실행방법
IMAGE_NAME=ubuntu1804 CONTAINER_NAME=my_container;
docker build . -t $IMAGE_NAME;
docker run -d -t --privileged --name=$CONTAINER_NAME $IMAGE_NAME;
docker exec -it -u root $CONTAINER_NAME bash
-----------------------------------
readelf -s libc-2.27.so | grep " __libc_start_main@"
위 명령어로 라이브러리 main주소를 구함
'System (Pwnable)' 카테고리의 다른 글
Dreamhack basic_rop_x86 문제 풀이 방향 (0) | 2025.03.09 |
---|---|
basic_rop_x64 Writeup (0) | 2025.03.09 |
Dreamhack rop writeup (0) | 2025.03.08 |
Dreamhack Return to Library Writeup (0) | 2025.03.06 |
NX 및 ASLR 우회방안 - PLT GOT 설명 (0) | 2025.03.06 |