[Hack.lu 2018] Baby_Kernel_1

배경지식

  • 권한 상승 
  • Return_to_user

권한 상승

권한 상승 코드

commit_creds(prepare_kernel_cred(0))

commit_creds , prepare_kernel_cred 함수는 커널에서는 굉장히 필수적인 함수이다.

간단히 요약하면

prepare_kernel_cred : 권한들에 대한 구조체를 생성하는 함수

commit_creds : 권한을 적용시키는 함수

prepare_kernel_cred 에는 uid , gid 등등 여러 내용들이 포함되는데, prepare_kernel_cred(0) 을 하게 되면 그 모든 값들이 다 0으로 들어가기 때문에 uid 가 0 , 즉, root 권한으로 바꾸는 구조체를 만들 수 있다.

그 구조체를 commit_creds의 매개변수로 넣어주게 되면 그 권한들이 적용되어 root권한을 얻을 수 있다.

Return_to_user

Return to user는 위에서 언급한 권한 상승을 이용한 익스플로잇 기법으로,

스택에서 Return_to_library(RTL) 랑 비슷하게 기초적인 익스플로잇 기법이다.

Exploit 순서는 다음과 같다.
  1. prepare_kernel_cred(0)을 호출하고 그 반환값인 구조체 포인터를 알아낸다.
  2. commit_creds 함수를 호출하여 매개변수로 위에서 얻은 포인터를 넣어줌
  3. root 권한 획득 !__!

커널 문제 초기 설정

qemu 설치

 

sudo apt-get install qemu

 

qemu는 리눅스에서 사용하는 하나의 가상머신이다.

문제에서 원하는 조건에 맞게 환경을 구축해야 하기 때문에 이를 이용하여 문제 환경을 구축

run.sh에는 qemu 실행 옵션들에 대한 쉘 스크립트이다.

cat run.sh 로 파일을 읽어보면, 다음과 같이 되어있다.

 

qemu-system-x86_64 -monitor /dev/null -m 64 -nographic -kernel "bzImage" -initrd initrd.cpio -append "console=ttyS0 init='/init'"

 

위 옵션들이 문제에서 원하는 환경을 구축하기 위한 명령어라고 생각하면 된다.

여기서 qemu를 사용하기 위해서는 특정 설정이 필요하다.

VMware에서 설정 => Processors & Memory 에 들어가서 '하이버바이저 애플리케이션 사용' 체크를 해주어야 한다.

 

문제 파일 분석

우선 안에 들어있는 파일들을 살펴보자

 
 
문제 파일 구성 - bzImage , initrd.cpio , run.sh , vmlinux

 

bzImage : 커널 이미지 파일

initrd.cpio: 파일 시스템

run.sh: 부팅을 위한 쉘 스크립트

vmlinux: 디버깅용 심볼

(아직 잘 모르겠음)

initrd.cpio 압축을 풀어보면 initrd라는 파일이 생성되고, 그 안에는 하나의 시스템에 대한 파일들이 존재

(bin lib usr etc ... 문제 실행파일 등등 )

initrd 폴더에 들어가보면 client_kernel_baby 라는 ELF파일이 존재

또 /initrd/lib/modules/4.18.0 폴더에는 kernal_baby.ko 라는 ELF파일이 존재

위의 파일이 일반적으로 우리가 분석하던 실행파일인 것 같고, 아래의 파일이 커널과 관련된 코드로 예상됨

문제 분석(IDA)

실행을 시켜 보면 총 5가지 메뉴가 존재한다.

 

1. call

read_num 함수로 입력을 2번 받는데, 설명에 따르면 함수 주소 (GOT) 하나와 매개변수 하나를 입력하는 것 같다.

그리고 입력 받은 것들을 ioctl_call 함수로 넘겨준다.

 

2. Show me my uid

uid / gid / groups (현재 권한) 을 출력해준다.

 

3. Read file

파일 이름을 입력하고, 그 파일을 열 수 있으면 내용을 출력해주는 것 같다.

 

4. Any hintz?

힌트들을 알려주고 있다. 힌트들을 다 출력해보니 다음과 같다.

 

- You do not really need to exploit anything here

 

- The flag file is not readable by your current user

 

- You will need to become root to solve the challenge

 

- There is a specific combination of kernel functions you

   will want to be using to escalate your privileges

 

- We disabled Kernel ASLR in this case

 

번역해보면,

여기서 익스플로잇을 할 게 없다고 하며 flag는 현재 우리의 권한으로는 읽을 수 없다고 한다.

root권한을 따야하며, 권한을 상승시키기위한 특정 함수들이 있다고 하며, KASLR은 꺼져있다고 한다.

여기서 권한을 상승시키기 위한 특정 함수들이 commit_creds , prepare_kernel_cred 임을 눈치챘을 것이다.

가장 의심스러운 함수는 call 함수의 ioctl_call이다.

ioctl은 유저 영역과 커널 영역을 연결하는 인터페이스라고 한다.

그렇다면 이 ioctl 함수에서 이제 커널 영역으로 들어가서 무언가 동작을 하는 것이다.

Kernel_baby.ko 도 IDA로 분석을 해보자

 

call 함수

마침 Kernel_baby.ko 안에 call이라는 함수가 있다.

코드를 하나씩 분석해보자.

 

copy_from_user(&call.args , call_arg_ptr , 24LL);

 

copy_from_user 은 커널의 명령어로 memcpy와 동일하다고 보면 된다.

call_arg_ptr이라는 이름으로 유저 영역에서 값들을 받아와서, 그 값들을 call.args로 옮겨 받는 함수이다.

call_args는 하나의 구조체로 그 안에 fn_ptr , arg , out 3개의 값이 존재한다.

 

v1 = call_args.fn_ptr;
v2 = call_args.arg;

우리가 유저 영역에서 받아온 데이터는 함수의 GOT , 그리고 그 매개변수 값이다.

그 함수의 GOT를 v1 , 매개변수를 v2에 저장한다.

call_args.fn_ptr(call_args.arg , v1)

 

이제 입력한 함수와 매개변수를 이용하여 함수를 실행하고 그 결과값은 call_args.out 에 저장된다.

 

result = _put_user_8(v2, v1, v3, call_args.out)

 

_put_user_8 은 커널의 명령어로 put과 동일하다고 보면 된다.

요약하면, 우리가 유저 영역에서 call함수를 호출하여 GOT 와 매개변수를 입력하면,

function(매개변수)를 실행한 결과값을 출력해준다는 의미이다.

Vector

call을 이용하여 prepare_kernel_cred(0) 을 실행 => 반환값 받아옴

다시 call을 이용하여 commit_creds(prepare_kernel_cred(0)) 을 실행함 => uid = 0 ( root )

read 권한이 없던 flag를 이제 root가 되었으니 읽을 수 있음

Exploit

prepare_kernel_cred와 commit_creds 의 GOT 주소만 있으면 익스가 가능하다.

 

cat /proc/kallsyms

 

원래는 /proc/kallsyms 파일안에 주소값들이 다 저장되어 있지만,

이유는 모르겠지만 주소값이 0으로 되어있다.

그래서 vmlinux를 통헤 직접 알아내자.

prepare_kernel_cred 주소 : 0xffffffff8104ee50

commit_creds 주소 : 0xffffffff8104e9d0

이를 이용하여 권한을 root로 상승시킨 뒤, flag를 읽으면 된다.

'CTF > CTF_writeup' 카테고리의 다른 글

[SCTF 2020] Eat the pie  (0) 2020.08.19
[SCTF 2020] T express  (0) 2020.08.19
[zer0pts] dirty laundry  (0) 2020.03.12
[zer0pts] nibelung  (0) 2020.03.12
[zer0pts] diysig  (0) 2020.03.12
  Comments,     Trackbacks