https://dreamhack.io/lecture/roadmaps/2
System Hacking
시스템 해킹을 공부하기 위한 로드맵입니다.
dreamhack.io
[ RELocation Read-Only(RELRO) ]
: 프로세스의 데이터 세그먼트를 보호
: 쓰기 권한이 불필요한 데이터 세그먼트에 쓰기 권한을 제거
→ 1. Partial RELRO: RELRO를 부분적으로 적용
→ 2. Full RELRO: RELRO를 가장 넓은 영역에 적용
[ Partial RELRO ]
→ gcc는 Full RELRO를 기본 적용하며, PIE를 해제하면 Partial RELRO를 적용함
Ex) gcc -o prelro relro.c -no-pie fno-PIE
* “.got”와 “.got.plt”
: partial relro가 적용된 바이너리는 got와 관련된 섹션이 두 개가 존재하는데
→ 전역 변수 중에서 실행되는 시점에 바인딩(now binding)되는 변수는 .got에 위치함.
바이너리가 실행될 때는 이미 바인딩이 완료되어있으므로 이 영역에 쓰기 권한을 부여하지는 않음
→ 반면 실행 중에 바인딩(lazy binding)되는 변수는 .got.plt에 위치함. 이 영역은 실행 중에 값이 쓰여져야 하므로
쓰기 권한이 부여되며, partial relro가 적용된 바이너리에서 대부분 함수들의 got 엔트리는 .got.plt에 저장됨
[ Full RELRO ]
: got에 쓰기 권한 제거, 따라서 data와 bss에만 쓰기 권한이 있음
: full relro가 적용되면 라이브러리 함수들의 주소가 바이너리의 로딩 시점에 모두 바인딩됨
: 따라서 got에는 쓰기 권한이 부여되지 않음
[ RELRO 기법 우회 ]
1. Partial RELRO
- .init_array와 .fini_array에 대한 쓰기 권한이 제거되어 두 영역을 덮어쓰는 공격을 수행하기 어려움
- 그러나 .got.plt 영역에 대한 쓰기 권한이 존재하므로 GOT overwrite 공격 가능
2. Full RELRO
- .init_array, .fini_array 뿐만 아니라 .got 영역에도 쓰기 권한이 제거
→ 라이브러리에 위치한 hook을 통해 공격 가능
→ 라이브러리 함수의 대표적인 hook : malloc hook, free hook
- 원래 이 함수 포인터는 동적 메모리의 할당과 해제 과정에서 발생하는 버그를 쉽게 디버깅하기 위해 만들어짐
* Hook Overwrite 공격 (malloc 함수 코드)
1. 시작 부분에서 __malloc_hook이 존재하는지 검사
2. 존재하면 이를 호출
3. __malloc_hook은 libc.so에서 쓰기 가능한 영역에 위치하므로, 공격자는 libc가 매핑된 주소를 알 때,
이 변수를 조작하고 malloc을 호출하여 실행 흐름을 조작할 수 있음
[ Position-Independent Executable(PIE) ]
: ASLR이 코드 영역에도 적용되게 해주는 기술
: 보안성 향상을 위해 도입된 것이 아니라서 엄밀하게는 보호 기법은 아님
[ Position-Independent Code(PIC) ]
: 재배치(RELOCATION)가 가능하도록 설계되어 있는 코드
즉, 메모리의 어느 주소에 적재되어도 코드의 의미가 훼손되지 않는 코드
[ PIC 코드 분석 ]
pic.c 코드이다.
Pic가 적용된 바이너리와 아닌 바이너리의 차이를 알아보기 위해 각각 pic와 no_pic로 컴파일하였다.
두 바이너리는 printf에서 차이를 보인다고 한다.
먼저 no_pic의 main을 보면 0x4005a1이라는 절대 주소로 문자열을 참조하고 있다.
반면 pic의 main을 보면 문자열의 주소를 [rip+0xa2]로 참조하고 있다.
결론적으로 바이너리가 매핑되는 주소가 바뀌면 no_pic 코드의 0x4005a1에 있던 데이터도 함께 이동되어 제대로 실행되지 못하지만, pic의 코드는 rip를 기준으로 데이터를 상대 참조(relative addressing)하기 때문에 바이너리가 무작위 주소에 매핑되어도 제대로 실행될 수 있다.
[ PIE ]
: Position-Independent Executable은 무작위 주소에 매핑되어도 실행 가능한 실행 파일을 뜻한다.
: ASLR이 도입된 후, 실행 파일도 무작위 주소에 매핑될 수 있게 하고 싶었으나, 실행 파일의 형식을 변경하면 호환성
문제가 발생하기 때문에, 원래 재배치가 가능했던 공유 오브젝트를 실행 파일로 사용하기로 함
: 리눅스의 기본 실행 파일 중 하나인 /bin/ls는 공유 오브젝트 형식을 띠고 있음
→ PIE on ASLR
: PIE는 재배치가 가능하므로, ASLR이 적용된 시스템에서는 실행 파일도 무작위 주소에 적재됨
: PIE가 적용되면 main 함수의 주소가 매 실행마다 바뀜
→ 우회
1) 코드 베이스 구하기
- ASLR 환경에서 PIE가 적용된 바이너리는 실행될 때마다 다른 주소에 적재됨.
- 이러한 이유로 코드 영역의 가젯을 사용하거나, 데이터 영역에 접근하려면 바이너리가 적재된 주소를 알아야 함
- 이 주소를 PIE 베이스, 또는 코드 베이스라고 부름
- 코드 베이스를 구하려면 라이브러리의 베이스 주소를 구할 때처럼 코드 영역의 임의 주소를 읽고, 그 주소에서
오프셋을 빼야 함
2) Partial Overwrite
- 코드 베이스를 구하기 어렵다면 반환 주소의 일부 바이트만 덮는 공격을 고려할 수 있음
- 일반적으로 함수의 반환 주소는 호출 함수(caller)의 내부를 가리키는데, 특정 함수의 호출 관계는 정적 분석 또는
동적 분석으로 쉽게 확인할 수 있으므로, 공격자는 반환 주소를 예측할 수 있음
- ASLR의 특성상, 코드 영역의 주소도 하위 12비트 값은 항상 같다.
- 따라서 사용하려는 코드 가젯의 주소가 반환 주소와 하위 한 바이트만 다르다면, 이 값만 덮어서 원하는 코드 실행
가능
- 그러나 두 바이트 이상이 다른 주소로 실행 흐름을 옮기고자 한다면, ASLR로 뒤섞이는 주소를 맞춰야하므로
브루트포싱이 필요함
[ Hook Overwrite 실습 ]
: Hooking(후킹): 운영체제가 어떤 코드를 실행하려 할 때, 이를 낚아채어 다른 코드가 실행되게 하는 것
→ 함수에 훅을 심어 함수 호출 모니터링하기 / 함수에 기능 추가 / 실행 흐름 변조
- malloc과 free에 훅 설치: 소프트웨어에서 할당/해제하는 메모리 모니터링 가능
- 더 응용하면 모든 함수의 도입 부분에 모니터링 함수를 훅으로 설치하여 어떤 소프트웨어가 실행 중에
호출하는 함수를 모두 추적(tracing)할 수 있음
- Full RELRO가 적용되더라도 libc의 데이터 영역에는 쓰기가 가능하므로, Full RELRO를 우회할 수 있음
* 메모리 함수 훅_ malloc, free, realloc hook
- C언어에서 메모리의 동적 할당과 해제를 담당하는 함수 : malloc, free, realloc
→ 각 함수는 libc.so에 구현되어 있음
libc에는 이 함수들의 디버깅 편의를 위해 훅 변수가 저장되어 있는데,
예를 들어, malloc 함수는 __malloc_hook 변수의 값이 NULL이 아닌지 검사하고, 아니라면 malloc을 수행하기 전에 __malloc_hook이 가리키는 함수를 먼저 실행한다.
이때, malloc의 인자는 훅 함수에 전달된다.
Free와 realloc도 같은 방식으로 각각 __free_hook, __realloc_hook이라는 훅 변수를 사용함
→ 훅의 위치와 권한
: __malloc_hook, __free_hook, __realloc_hook도 마찬가지로 libc.so에 정의되어 있음
위의 사진을 보면
변수들의 오프셋은 각각 0x3ed8e8, 0x3ebc30, 0x3ebc28인데, 섹션 헤더 정보를 참조하면 libc.so의 bss 섹션에 포함됨을 알 수 있다.
또한 bss 섹션은 쓰기가 가능하므로 해당 변수들의 값을 조작될 수 있다.
'Pwnable > 개념' 카테고리의 다른 글
[Pwnable] Dreamhack STAGE 10 (0) | 2022.08.26 |
---|---|
[Pwnable] Dreamhack STAGE 8 (0) | 2022.08.26 |
[Pwnable] Dreamhack STAGE 7 (0) | 2022.08.26 |
[Pwnable] Dreamhack STAGE 6 (0) | 2022.08.25 |
[Pwnable] Dreamhack STAGE 5 (0) | 2022.08.25 |