참고 강의: 드림핵(DreamHack) - System Hacking
System Hacking
dreamhack.io
STAGE 7. Bypass NX & ASLR
[ NX ]
No-eXecute(NX)
실행에 사용되는 메모리 영역과 쓰기에 사용되는 메모리 영역을 분리하는 보호 기법 (프로세스의 각 세그먼트에 필요한 권한만 부여)
→ 일반적으로 코드 영역에는 읽기 + 실행 / 나머지 영역에는 읽기 + 쓰기 권한 부여
Checksec 명령어를 이용하면 바이너리에 NX가 적용됐는지 확인 가능
✓ 다양한 명칭
∘ 인텔 → XD(eXecute Disable)
∘ 윈도우 → DEP(Data Execution Prevention)
∘ ARM → SN(eXecute Never)
[ ASLR ]
Address Space Layout Randomization(ASLR)
바이너리가 실행될 때마다 스택, 힙, 공유 라이브러리 등을 임의의 주소에 할당하는 보호 기법 (메모리를 무작위 주소에 할당)
→ 커널에서 지원하는 보호 기법 / 최신 커널들은 대부분 적용되어 있음
# ASLR 확인 방법
$ cat /proc/sys/kernel/randomize_va_space
2
ASLR이 적용되는 메모리 영역
→ 명령어를 통해 0, 1, 2 값 얻을 수 있음
∘ 0 (No ASLR): ASLR 적용 안함
∘ 1 (Conservative Randomizaion): 스택, 라이브러리, vdso 등등
∘ 2 (Conservative Randomization + brk): 1의 영역과 brk로 할당한 영역
ASLR의 특징
1. 코드 영역의 main 함수를 제외한 다른 영역의 주소들은 실행할 때마다 변경됨
→ 실행하기 전 해당 영역들의 주소 예측 불가
2. 바이너리를 반복 실행해도 libc_base 주소 하위 12비트 값과 printf 주소 하위 12비트 값은 변경되지 않음
→ 리눅스는 ASLR 적용 시 파일을 페이지(page) 단위로 임의 주소에 매핑. 따라서 페이지 크기인 12비트 이하로는 주소 변경 불가
3. libc_base 와 printf의 주소 차이는 항상 동일
→ ASLR 적용 시 라이브러리를 임의 주소에 매핑. 그러나 라이브러리 파일을 그대로 매핑하기에 해당 주소로부터 다른 심볼들까지의 거리는 항상 동일
⚲ NX와 ASLR 적용
스택, 힙, 데이터 영역에는 실행 권한 제거 + 할당되는 주소가 지속적으로 변경
바이너리의 코드가 존재하는 영역에는 실행 권한 존재 + 할당되는 주소도 고정
[ 라이브러리 ]
컴퓨터 시스템에서 프로그램들이 함수나 변수를 공유해서 사용할 수 있게 함
e.g.) printf, scanf, strlen, memcpy, malloc 등등
각 언어에서 범용적으로 많이 사용되는 함수들은 표준 라이브러리가 제작되어 있음
→ 해당 함수들을 쉽게 사용 가능
libc
우분투에 기본으로 탑재된 라이브러리
✓ 종류
∘ 동적 라이브러리
∘ 정적 라이브러리
[ 링크(Link) ]
프로그래밍 언어에서 컴파일의 마지막 단계
라이브러리의 함수 사용 → 호출된 함수와 실제 라이브러리의 함수가 링크 과정에서 연결됨
리눅스에서 C소스 코드는 전처리, 컴파일, 어셈블 과정을 거쳐 ELF형식을 갖춘 오브젝트 파일(Object file)로 변역됨
⚲ 오브젝트 파일
실행 가능한 형식이나, 라이브러리 함수들의 정의를 알지 못하므로 실행 불가 (심볼로는 기록되어 있음)
→ 심볼과 관련된 정보들을 찾아 최종 실행 파일에 기록하는 것이 링크 과정 중 하나임
✓ 종류
구분 | 내용 | 설명 |
동적 링크 (Dynamic Link) |
동적 라이브러리가 프로세스의 메모리에 매핑 실행 중 함수 호출 시 매핑된 라이브러리에서 해당 함수의 주소를 찾아 실행 |
동적 라이브러리를 링크 |
정적 링크 (Static Link) |
바이너리에 정적 라이브러리에 필요한 모든 함수가 포함 함수 호출 시 라이브러리 참조 X, 자신의 함수를 호출하는 것처럼 호출 가능 → 여러 바이너리에서 사용 시 라이브러리 복제로 인한 용랑 낭비 발생 有 |
정적 라이브러리를 링크 |
✓ 용량
# 동적링크와 정적링크 용량 비교
$ ls -lh ./static ./dynamic
-rwxrwxr-x 1 dreamhack dreamhack 16K May 22 02:01 ./dynamic
-rwxrwxr-x 1 dreamhack dreamhack 880K May 22 02:01 ./static
→ 정적 링크(Stacic)가 동적 링크(Dynamic)보다 50배 가까이 더 많은 용량 차지
✓ 호출 방법
∘ 동적 링크 → puts의 plt주소인 0x401040 호출
∘ 정적 링크 → put가 있는 0x40c140 직접 호출
※ 동적 링크된 바이너리를 함수의 주소를 라이브러리에서 찾아야 하기 때문
→ plt는 해당 과정에서 사용되는 테이블
[ PLT & GOT ]
PLT(Procedure Linkage Table), GOT(Global Offset Table)
라이브러리에서 동적 링크된 심볼의 주소를 찾을 때 사용하는 테이블
반복적으로 호출되는 함수의 정보를 매번 탐색 → 비효율적
따라서 ELF는 GOT라는 테이블을 두고 resolve된 함수의 주소를 해당 테이블에 저장
후에 다시 해당 함수 호출 시 저장된 주소를 꺼내서 사용
✓ 보안 약점
PLT에서 GOT를 참조해 실행 흐름을 옮길 시 GOT의 값 미검증 → 보안 취약
e.g.
puts의 GOT 엔트리에 저장된 값을 공격자가 임의로 변경
→ puts 호출 시 공격자가 원하는 코드 실행 가능
✓ GOT OverWirte
GOT 엔트리에 임의의 값을 오버라이트(OverWrite)하여 실행 흐름을 변조하는 공격 기법
(어떤 함수의 GOT 엔트리를 덮고, 해당 함수를 재호출해 원하는 코드를 실행시키는 공격 기법)
→ 임의 주소에 임의의 값을 오버라이트하는 수단을 가지고 있을 때 수행
[ RTL(Return To Library) ]
NX를 우회하는 공격 기법 (실행권한이 남아있는 코드 영역으로 반환 주소를 덮는 공격 기법)
→ 실행권한 존재 영역: 바이너리의 코드 영역, 라이브러리의 코드 영역
Return to PLT
PLT에 라이브러리 함수가 등록되어 있을 경우 해당 함수의 PLT 엔트리 실행 → 함수 실행 가능
ASLR이 걸려 있어도 PLE가 미적용되어 있을 경우 PLT의 주소는 고정
∴ 라이브러리의 베이스 주소를 몰라도 라이브러리 함수 실행 가능
⚲ Return gadget(리턴 가젯)
ret 명령어로 끝나는 어셈블리 코드 조각
→ 셸을 획득할 수 있는 단서
ROPgadget 명령어 사용
[ ROP(Return Oriented Programming) ]
다수의 리턴 가젯을 연결해 복잡한 실행 흐름을 구현하는 기법
→ 문제 상황에 맞춰 RTL, return to dl-resolve, GOT overwrite 등의 페이로드 구성 가능
✓ ROP 페이로드
리턴 가젯으로 구성
ret 단위로 여러 코드가 연쇄적으로 실행 → ROP chain 이라고도 불림
✓ ret2main
system 함수의 주소를 페이로드에 사용하고자 하는 경우 main 함수로 돌아가서 버퍼 오버플로우를 일으키는 공격 패턴
→ system 함수의 주소를 알았을 시점에는 이미 ROP 페이로드가 전송된 이후이기 때문
∴ 알아낸 system 함수의 주소를 어떤 함수의 GOT에 작성 후 해당 함수를 재호출 하도록(GOT OverWrite) ROP 체인 구성
STAGE 8. Bypass PIE & RELRO
[ PIC(Position-Independent Code) ]
리눅스에서 ELF는 실행파일(Executable) / 공유 프로젝트(Shared Object, SO) 존재
공유 오브젝트(SO)는 기본적으로 재배치(Relocation)이 가능하도록 설계되어 있음
→ 이는 어느 주소에 적재되어도 의미가 훼손되지 않음을 의미
해당 성질을 만족하는 코드 = PIC
→ 어느 주소에 매핑되어도 실행 가능한 코드
절대주소 사용 X, rip를 기준으로 한 상대주소 사용
[ PIE(Position-Independent Executable) ]
무작위 주소에 매핑돼도 실행 가능한 실행 파일
→ 재배치가 가능하므로 ASLR이 적용된 시스템에서도 실행 파일이 무작위 주소에 적재됨
(ASLR이 미적용된 시스템에서는 PIE가 적용되더라도 무작위 주소에 적재되지 않음)
PIE의 코드는 모두 PIC임
ASLR이 적용된 환경에서는 시스템을 더욱 안전하게 만드는 효과가 있음 (보호 기법은 X)
→ 최신 gcc는 기본적으로 PIE 컴파일함
[ PIE 우회 ]
✓ 코드 베이스 구하기
코드 베이스(PIE 베이스)
ASLR 환경에서 PIE가 적용된 바이너리는 실행될 때 마다 다른 주소에 적재됨
따라서 코드 영역의 가젯 사용 or 데이터 영역 접근 시 바이너리가 적재된 주소(코드 베이스)를 알아야 함 (ROP 과정과 유사)
✓ Partial Overwrite
코드 베이스를 구하기 어려울 시 반환 주소의 일부 바이트만 덮는 공격
[ RELRO ]
RELocation Read-Only(RELRO)
쓰기 권한이 불필요한 데이터 세그먼트에 해당 권한 제거
→ 프로세스의 데이터 영역 보호 목적
No RELRO
어떠한 RELRO 보호 기법도 적용되지 않은 상태
✓ Partial RELRO
RELRO를 부분적으로 적용
여러 섹션에 쓰기 권한 제거
e.g.) .got.plt, .data, .bss → 쓰기 권한 有 / .init_array, .fini_array → 쓰기 권한 無
GOT 엔트리 쓰기 및 GOT Overwrite 공격으로 우회 가능
✓ Full RELRO
RELRO를 가장 넓은 영역에 적용
e.g.) .data, .bss → 쓰기 권한 有 / .init_array, .fini_array, .got → 쓰기 권한 無
→ 라이브러리 함수들의 주소가 바이너리의 로딩 시점에 모두 바인딩되기 때문
∴ libc의 malloc hook, free hook과 같은 함수 포인터를 조작하는 공격으로 우회 가능 (Hook Overwrite 공격)
[ Hook Overwrite ]
후킹(Hooking)
어떤 코드 실행를 실행하려고 할 때, 낚아채서 다른 코드로 실행되게 하는 것
훅(Hook)
후킹으로 인해 실행되는 코드
Hook Overwrite
바이너리에 존재하는 훅을 덮어서 특정 함수를 실행할 때 원하는 코드(악의적인 코드)를 실행하는 공격 기법
e.g.
malloc, free, realloc 등의 함수
→ 라이브러리에 쓰기가 가능한 훅 포인터를 보유하고 있어 공격에 사용됨 (Full RELRO를 우회하는데 사용 가능)
[ OOB(Out Of Bounds) ]
요소를 참조할 때 인덱스 값이 음수이거나 배열의 길이를 벗어날 때 발생
배열의 길이를 벗어나는 경우?
개발자가 인덱스 범위에 대한 검사를 명시적으로 프로그래밍하지 않음
이는 계산한 주소가 배열의 범위 안에 있는지 검사하지 않는다는 의미
→ gcc도 아무런 경고창을 띄워주지 않음
사용자가 배열 참조에 사용하는 인덱스를 임의의 값으로 설정이 가능하다면
→ 배열의 주소로부터 특정 오프셋에 있는 메모리의 값 참조 가능
(이를 배열에 벗어나는 참조라 하고 Out Of Bounds라고 부름)
✓ 배열의 속성
내용 | 설명 |
배열 | 연속된 메모리 공간 점유 같은 자료형의 요소(Element)로 이루어짐 |
인덱스 | 각 요소의 위치 |
배열이 점유하는 공간의 크기 | (요소의 개수) X (요소 자료형의 크기) |
배열의 길이 | 배열이 포함하는 요소의 개수 |
배열의 각 요소 주소 | 배열의 주소, 요소의 인덱스, 요소 자료형의 크기를 이용해 계산 |
※ C언어는 기본적으로 인덱스에 대한 검사 진행 X → Out Of Bounds 취약점이 발생하지 않게 하기 위해 인덱스 검사를 미리 진행해야 함
✓ 임의 주소 읽기
OOB로 임의 주소 값 읽기 가능
→ 읽으려는 변수와 배열의 오프셋을 알아야 함
e.g.
if 배열과 변수가 같은 세그먼트에 할당되어 있다면?
→ 둘 사이의 오프셋은 항상 일정하기에, 디버깅을 통해 쉽게 알아낼 수 있음
e.g.
if 배열과 변수가 같은 세그먼트에 할당되어 있지 않다면?
→ 다른 취약점을 통해 두 변수의 주소를 구해 차이를 계산해야 함
✓ 임의 주소 쓰기
OOB로 임의 주소 값 쓰기 가능
'3. Pwnable (포너블) > 2) 개념 정리' 카테고리의 다른 글
[2025.04.04] 3주차 활동_Pwnabless (0) | 2025.04.04 |
---|---|
[2025.03.28] 2주차 활동 _ Pwnabless (0) | 2025.03.29 |
[2025.03.21] 1주차 활동 _ Pwnabless (0) | 2025.03.21 |
[24.05.18] 7주차 활동- 포너블 개념 (0) | 2024.05.18 |
[24.05.11] 6주차 활동- 포너블 개념 (0) | 2024.05.11 |