[Research] Linux Kernel Basic - (1) 유저모드와 커널모드

[Research] Linux Kernel Basic - (1) 유저모드와 커널모드

서론

리눅스 커널 공격(Linux Kernel Exploitation)을 진행하기 위해서는 리눅스 커널(Linux Kernel)에 대한 이해가 먼저 선행되어야 한다. 하지만 리눅스 커널(Linux Kernel)은 일반적으로 접근한다면 오픈소스의 특성인 집단지성의 결정체라고 할 수 있을만큼 매우 방대하며 모든 것을 학습을 할 수 없다. 그러므로 리눅스 커널 공격(Linux Kernel Exploitation)을 위한 기초적인 운영체제의 지식을 기반으로하여 프로세스의 메모리 구조, 유저모드(user mode)와 커널모드(kernel mode), 커널의 공격할 수 있는 부분(attack surface)가 될 수 있는 많은 부분 중 쉽게 구현할 수 있는 디바이스 드라이버(device driver)를 기반으로 연구를 진행했다.

커널(kernel)이란

공격할 대상은 리눅스 커널(linux kernel)이다. 그렇다면 커널(kernel)이 무엇인지 확인하고 넘어갈 필요가 있다. 컴퓨터(computer)는 흔히 알고 있는 전기적으로 제어할 수 있는 CPU, Memory, Devices들로 이루어진 일종의 기계장치(machine)으로 볼 수 있다. 기계란 어떠한 방식으로 동작되는 지 사람이 지정해주어야 하며 기계의 특성상 프로그램을 실행할 수 있도록 섬세하게 조정이 되어야 한다. 그렇지 않다면 단순한 실리콘 덩어리들의 불과하다. 다음과 같은 이유를 고려하면 어떻게 이러한 실리콘 덩어리를 잘 활용하여야 흔히 사용하는 프로그램을 돌리기 위해서는 어떠한 동작이 정의되어 있어야 한다. 커널(kernel)은 다음과 같은 역할을 하기에 중간계층이라고도 많이 불리운다.

메모리(memory)란

프로그램이 실행되기 위해서는 보조기억장치(HDD, SSD등)에서 주기억장치(RAM)에 로드 되어야 한다. 하나의 프로세스가 로드되면 32bit를 예시로 총 4GB의 가상메모리 공간에 위치하게 된다. 상단에 제시한 그림과 같은 형태를 나타낸다. 상위 주소(0xC0000000 ~ 0xFFFFFFFF)에는 커널의 위치한 주소가 되며 하위 주소(0x00000000~0xBFFFFFFFF)에는 흔히 알고 있는 유저 프로세스가 로드된다. 커널의 경우는 앞서 언급한 것과 같이 하드웨어의 직접적으로 접근할 수 있는 중요한 부분이며 이러한 이유로 스택 메모리를 확인하면 높은 주소에서 낮은 주소로 데이터가 쓰이는 것을 볼 수 있다.

커널의 권한

하늘아래 태양은 두개가 될 수 없는 법.

커널은 프로세스들을 관리하기도 하고 주요한 정보들이 위치하기에 일반적으로 높은 권한을 지니고 있다. 그럼 다른 이야기를 해보자! 서로 친해지기 위해서 술게임을 하며 왕게임을 하는 데 가학적 성격장애가 있는 친구에게 권력이 부여된다면 타겟들은 인생이 힘들어진다. 또한 아무나 왕이 될 수 있다고하면 배가 산으로 가게되며 시스템 상에서는 아주 큰 문제가 발생할 수 있다. 그러므로 시스템에서는 특권을 지닌 커널 모드와 제한된 권한인 유저 모드로 나누어져 있다.

커널에게 일을 시키고 싶어 - 시스템콜(syscall)

그렇다면 어떻게 하면 커널을 공격할 수 있을 지 고민해보아야 한다. 일반적으로 유저 권한을 지닌 사용자 어플리케이션을 생각해보면 입력값(Input)이 될 수 있는 부분에서 문제가 발생한다. 커널도 마찬가지이다. 커널에서의 입력값(Input)이 될 수 있는 부분에서 문제가 발생한다. 이를 공격 표면(attack surface)라고 불린다. 가장 손쉽게 접근이 가능한 부분은 시스템 콜(syscall)이라고 볼 수 있다. 유저 모드에서는 직접적으로 컴퓨터의 중요 자원에 접근할 수 없기 때문에 커널 모드로의 전환이 일어나야 한다. 흔히 사용하는 printf와 같이 화면에 출력을 하는 함수의 경우도 저수준 함수로 변환되어 커널에게 시스템 콜이라는 인터럽트(interrupt)를 발생시키게 된다.

커널의 공격 대상(attack vector)

커널의 주요한 자원에 접근하기 위해서는 직접적으로 접근할 수 없으며 시스템 콜과 같은 간접적인 형태로 접근할 수 있음을 언급하였다. 또한 정의된 시스템 콜 이외에도 리눅스의 경우 디바이스 드라이버 또는 파일 시스템이 모두 커널 모드에서 동작된다. 이러한 요소들까지 고려하면 리눅스의 attack surface의 경우는 시스템 콜 뿐만이 아닌 블루투스 디바이스 드라이버와 같은 많은 형태로 확장이 가능하다.