Recent Posts
Recent Comments
Link
«   2025/02   »
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28
Tags
more
Archives
Today
Total
관리 메뉴

CIDY

[Linux Kernel] 0. Linux Kernel Exploit🐧 본문

Hack/Kernel

[Linux Kernel] 0. Linux Kernel Exploit🐧

CIDY 2023. 7. 25. 16:50

Kernel


커널은 핵심, 중심부라는 영어 단어로, 운영 체제의 주요 기능을 담당하는 시스템 프로그램이다. 운영체제가 부팅된 순간부터 종료 시 까지 커널은 메모리에 존재하며, 하드웨어 제어, 응용 프로그램 로딩과 같은 여러 중요한 기능들을 수행한다. 이러한 핵심 역할 수행을 위해 커널은 시스템 상에서 절대적인 권한을 가진다. 

 

 

운영 모드


시스템 상에는 파일, 장치, 프로세스 등 여러 자원이 존재하는데, 커널은 응용 프로그램이 시스템 자원을 요청할 때 권한에 맞춰 접근 제어를 한다. 즉 커널의 코드나 데이터를 조작해 접근 제어를 우회할 수 있다면, 주어진 권한을 넘어 공격할 수 있는 것이다. (ex: 일반 유저는 /etc/passwd와 같은 시스템 파일 수정 권한이 없지만, 커널을 공격해 root권한을 획득한 경우, 이 파일을 수정할 수 있게 된다.)

 

출처: dreamhack.io

이러한 상황을 방지하기 위해 커널은 메모리를 커널 공간(kernel space)과 사용자 공간(user space)로 구분한다. 커널 공간에는 커널의 데이터가, 사용자 공간에는 응용 프로그램의 데이터가 적재되는 것이다.

 

프로세서가 사용자 모드에 있을 때, 실행중인 프로세스는 사용자 공간에만 접근할 수 있다. 또한 각 프로세스는 서로 독립적인 메모리 공간을 가지며, 서로의 메모리에 접근할 수 없다. (프로세스간에 영향 미치지 못하도록)

 

각 프로세스가 사용하는 메모리 주소는 가상 주소(Virtual Address, VA)로, 이는 실제 주소가 아니다. 두 프로세스가 가상 주소상 같은 주소를 나타내어도 실제 물리 주소에서는 다른 주소인 것이다. 메모리 관리 장치(MMU)를 통해 가상 주소는 물리 주소로 번역된다. (실제 메모리 장치 접근 시에는 물리 주소를 이용한다.)

 

프로세서가 커널 모드에 있을 때, 사용자 공간과 커널 공간에 모두 접근 가능하다. 이 커널 모드에서 공격하는 것이 kernel exploit이다.

 

 

System Call


사용자 모드에서 입/출력 등의 외부 상호작용을 하려면 커널 권한이 필요하다. 사용자 모드는 마음대로 커널 모드에 진입할 수 없으므로 시스템 콜을 통해 운영 체제의 제약 조건 하에 커널에 도움을 요청한다.

 

출처: dreamhack.io

시스템 콜은 프로세서에 시스템 콜 명령어를 전달해 이루어진다. 프로세서가 이 명령어를 실행하면, 프로세서는 커널 모드로 전환되는 동시에 커널 개발자가 지정해 둔 entry point(진입 코드)를 수행한다. 진입 코드는 시스템 콜을 마친 이후에 원래의 코드로 돌아갈 수 있도록 프로세서의 상태를 저장하고 시스템 콜을 처리한다. (처리 후 저장해 둔 상태로 돌아간다.)

 

시스템 콜은 커널 모드와 유저 모드가 교차되는 지점이므로 주요 공격 대상이다.

 

 

커널 공격 표면


공격 벡터의 집합을 공격 표면(attack surface)이라고 한다. 리눅스(Linux 5.7.10)에는 약 431개의 시스템 콜이 존재한다. (macOS 10.15.3은 약 429개, Windows 10 2004는 약 1787개 정도) 리눅스의 경우 호환성 유지를 위해 유사한 기능의 시스템 콜을 여럿 제공하므로 중복되는 내용의 시스템 콜도 다수 존재한다.

 

출처: dreamhack.io

또한 리눅스는 단일형 커널(monolithic kernel)로, 장치 드라이버와 파일 시스템 등의 구성 요소가 모두 커널 모드에서 동작한다. 이러한 외부 구성 요소들을 고려하면 리눅스 커널의 공격 표면을 시스템 콜에서 네트워크와 주변 기기로까지 확장할 수 있다.

 

 

커널 보호기법


보편적으로 알고 있는 NX, ASLR, SSP등은 리눅스 커널 빌드 시에도 적용될 수 있다. (ASLR의 커널 ver를 KASLR이라고 한다.)

 

그 외에도 SMEP(Supervisor Mode Execution Prevention)이라는 보호 기법이 있는데, 이는 사용자 공간의 코드가 커널에서 실행되는 것을 막는 기법니다. (NX의 다른 ver 느낌이다.)

 

SMAP(Supervisor Mode Access Prevention)은 SMEP에서 더 발전된 보호 기법으로, 커널 프로그래머가 명시적으로 허용한 특정 케이스를 제외하고는 커널 모드에서 사용자 공간에 접근 자체를 불가하게 한다.

 

 

About Kernel Exploit..


사용자 영역에서 일반 바이너리를 대상으로 하는 공격의 목적은 주로 공격자가 의도한 임의 코드를 실행하여 쉘을 얻는 것이었다. 하지만 커널 익스플로잇의 주된 목표는 공격 대상에 침입하여 루트 권한 등 더 높은 권한을 얻는 것이다. (이것을 LPE, Local Privilege Escalation 이라고 한다.)

 

보통 커널 익스플로잇을 공격 대상은 1) Linux Kernel, 2) Kernel Module이다. 리눅스 커널과 Device Driver등의 커널 모듈은 모두 루트 권한으로 동작하기 때문에 LPE를 시도해볼 수 있다.

 

사용자 공간에서는 주로 파이썬의 pwntools모듈을 이용해 익스플로잇 코드를 작성하였을 것이다. 하지만 커널의 경우, 공격 대상이 운영체제나 드라이버이므로 C언어로 작성한 스크립트로 익스플로잇하여야 한다.

 

커널이나 디바이스 드라이버는 해당 운영체제를 이용하는 모든 프로세스에 공유된다. 시스템 콜은 어느 프로세스에서나 사용할 수 있고, 장치 드라이버도 언제 어떻게 조작될지 모르므로, 커널 영역에서 동작하는 코드를 작성할 때에는 멀티스레딩 환경에서 동작하는 코드라고 생각하고 짜야 할 것이다. 즉, 레이스 컨디션이 발생할 수 있는 자원(전역 변수 등)의 경우 mutex나 semaphore로 락을 걸어주어야 한다.

 

커널 영역이 사용자 영역과 다른 또다른 점은 heap의 공유 범위이다. 사용자 영역의 프로그램을 공격할 때에는 프로그램마다 할당된 가상 메모리에 힙 영역이 있고, 각 프로세스의 메모리는 다른 프로세스와 구분되므로 메모리가 어떻게 꼬이든 그 영향은 해당 프로세스로 한정된다. 

 

반면, 커널의 힙은 모든 드라이버와 커널에서 공유되므로 한 곳에서 발생한 취약점의 영향이 다른 드라이버나 커널에까지 미치게 된다. 사용자 영역에서 프로그램을 익스할때에는 힙 상태를 지속적으로 관찰하고 파악할 수 있기 때문에 이때까지 공부해 온 정교하고 복잡한 힙익스 기법들을 사용할 수 있지만, 커널의 경우 힙이 모든 태스크와 공유되고 영향을 받기 때문에 힙 공격을 하려면 힙 스프레이를 해야 한다.

 

 

Ref.


https://dreamhack.io/lecture/courses/36

 

Introduction: Linux Kernel Exploit🐧

-

dreamhack.io

 

'Hack > Kernel' 카테고리의 다른 글

[Linux Kernel] 4. prepare & commit  (1) 2023.07.25
[Linux Kernel] 3. KASLR  (0) 2023.07.25
[Linux Kernel] 2. Kernel Debugging  (0) 2023.07.25
[Linux Kernel] 1. QEMU  (0) 2023.07.25
[Linux Kernel] Kernel Debugging Environment setup  (0) 2023.07.24