서론
커널 공간도 유저 공간과 마찬가지로 보호기법이 있다.
다행이라면 유저 공간의 보호기법과 대동소이한다는 점.
아직 각 보호기법에 따른 공격법을 공부하지 않았기에 느낌적인 느낌으로 써내려가본다.
보호기법 확인 방법
- checksec 먹힌다.
- /proc/cpuinfo와 /etc/default/grub 파일을 확인
- qemu script에 보통 설정되어있음.
제일 좋은건 두번째, 세번째 방법이고
cat /proc/cpuinfo | grep flags
로 smep, smap
/etc/default/grub
에서 kaslr을 확인하거나
qemu script에
-append nokaslr
-cpu smep, smap
와 같이 확인 가능하다.
KASLR
이름부터 ASLR이다. 말 그대로 주소 랜덤화.
qemu script에 적용 여부를 명시한다.
아래 nokaslr 부분이 그 부분.
qemu-system-x86_64 \
-m 512M \
-kernel ./bzImage \
-initrd ./rootfs.cpio \
-append "root=/dev/ram rw console=ttyS0 oops=panic panic=1 quiet nokaslr" \
-netdev user,id=t0, -device e1000,netdev=t0,id=nic0 \
-nographic \
-cpu qemu64,smep \
유저영역의 그것과 마찬가지로 아무 주소나 leak 하고 offset을 계산하여 해결할 수 있다.
특히, /proc/kallsyms 파일 내에 커널의 모든 심볼 주소를 담고 있기에 이를 토대로 계산하면 된다. (마치 libc 처럼)
더불어 해당 파일 내에 base address는 _text 심볼의 주소이다.
/ # cat /proc/kallsyms | grep _text
ffffffff81000000 T _text
...
SMEP
커널 공간에서 유저 공간의 실행 권한을 제한한다.
즉 ring 0 권한일 때 ring 3와 관련된 코드를 실행할 수 없게 한다.
결국은 유저 공간에서의 NX와 비슷하다.
cr4 레지스터에 SMEP를 제어하는 비트가 있으며, 이를 0으로 만들면 SMEP를 해제할 수 있다.
이는 유저 공간의 ROP과 같은 방법으로 파훼할 수 있으며, gadget은 vmlinux 이미지에서 구할 수 있다.
pwndbg> i r
rax 0x1a94000000000 467567319711744
rbx 0x0 0
rcx 0x0 0
...
cr0 0x80050033 [ PG AM WP NE ET MP PE ]
cr2 0x1b86fa8 28864424
cr3 0x1da70000 [ PDBR=121456 PCID=0 ]
cr4 0x6f0 [ OSXMMEXCPT OSFXSR PGE MCE PAE PSE ]
cr8 0x1 1
efer 0xd01 [ NXE LMA LME SCE ]
...
추가로 커널 공간에서 유저 공간의 실행권한을 제한한다면,
애초에 커널 공간에 페이로드를 넣어놓고 이를 실행하면 되지 않을까.
스택 피봇팅을 통해 이를 해결할 수 있다.
즉, 커널 영역에서 특정 주소에 접근할 수 있을 때, 유저 영역에서 mmap을 통해 해당 영역을 할당하고
페이로드를 미리 작성해둔 다음 그 곳으로 return 해버리는 것이다.
2023.09.07 - [Kernel Exploit] - Kernel - SMEP 우회, krop
Kernel - SMEP 우회, krop
서론 이제 보호기법을 하나씩 추가해보자. 우선은 SMEP이다. 2023.08.20 - [Kernel Exploit] - Kernel 보호기법 및 우회법 Kernel 보호기법 및 우회법 서론 커널 공간도 유저 공간과 마찬가지로 보호기법이 있
wyv3rn.tistory.com
2023.09.08 - [Kernel Exploit] - Kernel - SMEP 우회, cr4 overwrite #2
Kernel - SMEP 우회, cr4 overwrite #2
서론 cr4 overwrite 2차전이다. 문제 환경 첨부 환경을 기준으로 한다. 1. 환경설정 1.1. vmlinux 추출하기 앞과 동일하다. ┌[root🐲 Wyv3rn]-(~/kernel/cr4) └> extract-vmlinux bzImage > vmlinux ┌[root🐲 Wyv3rn]-(~/kernel
wyv3rn.tistory.com
SMAP
smep + 읽기/쓰기 권한도 제한한다.
마찬가지로 cr4 레지스터에서 이를 제어하며, 이를 0으로 만들면 해제할 수 있다.
(즉 cr4의 값에 따라 SMEP인지 SMAP인지 결정되는 것)
SMEP와 같이 stack based BOF가 발생하는 경우 단순히 ROP으로 파훼할 수 있다.
하지만 이런 경우에는 굳이 SMAP를 설정할 필요가 없어지니 일반적이지 않다.
다른 방법으로 slab 객체 크기의 커널 힙 할당 및 use after free가 가능한 경우
유저 공간에서 fork() 호출 시 커널 힙에 할당되는 cred 구조체의 멤버를 수정하여 권한 상승을 일으킬 수 있다.
KADR
로컬 유저가 커널의 심볼을 볼 수 없도록 제한한다.
stripped 같은 느낌?
/ $ cat /proc/kallsyms | grep text
0000000000000000 T _stext
0000000000000000 T _text
...
rootfs 파일의 init 파일 내에
echo 2 > /proc/sys/kernel/kptr_restrict
와 같이 설정되어있다.
2는 모두 표시하지않음.
1은 권한이 있으면 표시
0은 모두 표시이다.
#!/bin/sh
mount -t proc none /proc
mount -t sysfs none /sys
mount -t devtmpfs devtmpfs /dev
exec 0</dev/console
exec 1>/dev/console
exec 2>/dev/console
echo 0 > /proc/sys/kernel/kptr_restrict
insmod test.ko
chmod 777 /dev/test
setsid cttyhack setuidgid 0 sh
umount /proc
umount /sys
poweroff -d 0 -f
더불어 위와 같이 실행되는 쉘 권한도 0으로 수정해주면 이제 읽을 수 있다.
/ # cat /proc/kallsyms | grep _text
ffffffff81000000 T _text
ffffffff81025000 t __text_poke
...
다만, 커널 힙과 관련된 취약점에서는 user 권한과 root 권한일때의 heap 할당 방식이 조금 다르기에
offset을 계산하고 난 뒤 user 권한으로 다시 실행하여 디버깅하자.
SSP
= canary
leak 하면 되지.
KPTI
조금 특이한 부분인데, 커널 공간과 유저 공간의 전환이 일어날 때, 각각의 페이지 테이블을 사용한다.
이 때 최소한의 커널 주소만 포함되도록 하는 보호기법이다.
qemu start.sh에서 -cpu kvm64가 적용되어있는 경우에 해당한다. (아니면 qemu64 cpu를 사용함)
기본적으로는 ROP으로 페이로드를 작성한다.
앞선 다른 보호기법에서는 ROP 페이로드 내에 swapgs와 iretq 가젯을 사용하는데,
여기서는 swapgs_restore_regs_and_return_to_usermod 함수가 추가된다.
해당 함수는 커널공간에서 유저공간으로 전환될 때 호출되는 함수인데, 페이지 테이블을 분리하는 역할을 하며,
함수 내에서 페이지 테이블을 분리하고난 뒤 (or rdi,0x1000 부분에서 분리됨.) swapgs, iretq를 자동으로 호출한다.
2023.09.10 - [Kernel Exploit] - Kernel - KPTI 우회
Kernel - KPTI 우회
서론 KPTI는 유저 영역에서의 보호기법에는 없는 보호기법이다. 요약하자면, 커널 - 유저공간 간의 전환 시 최소한의 커널 주소만 포함하는 것이다. 이에 커널에서 유저공간으로 넘어갈때는 상관
wyv3rn.tistory.com
'Kernel Exploit' 카테고리의 다른 글
kernel debuging with pwndbg - pwndbg 설치 (0) | 2023.08.27 |
---|---|
rootfs.cpio 파일 추가 shell script (0) | 2023.08.21 |
exploit binary를 커널 이미지에 삽입하기. (0) | 2023.08.20 |
vmlinux 추출하기 (0) | 2023.08.20 |
qemu 및 gdb setting (0) | 2023.08.20 |