Kernel exploit 기본 setting

2025. 5. 28. 10:19·Kernel Exploit/Exercise
728x90
반응형

서론

오랜만에 공부를 다시 시작하며, 죄다 까먹어서 정리를 위해 글을 쓴다.

 

System setting

Qemu 설치

sudo apt install qemu-utils qemu-system-x86

Kerner debugging tool 설치

gef addon을 통해 커널 디버깅을 원활히 하자.

wget -q https://raw.githubusercontent.com/bata24/gef/dev/install-uv.sh -O- | sudo sh

https://github.com/bata24/gef

 

GitHub - bata24/gef: GEF - GDB Enhanced Features for exploit devs & reversers

GEF - GDB Enhanced Features for exploit devs & reversers - bata24/gef

github.com

 

Kernel file

pwnyable을 기준으로 공부한다.

Holstein 모듈 분석 및 취약성 점화 | 포니터블!

 

Holsteinモジュールの解析と脆弱性の発火 | PAWNYABLE!

Holsteinモジュールの解析と脆弱性の発火 LK01(Holstein)の章ではKernel Exploitの基礎的な攻撃手法について学びます。導入の章でLK01をダウンロードしていない方は、まず練習問題LK01のファイルをダ

pawnyable.cafe

https://pawnyable.cafe/linux-kernel/LK01/distfiles/LK01.tar.gz

 

File system

통상적으로 파일은 아래 3개가 주어진다.

bzImage  rootfs.cpio  run.sh

bzImage는 커널의 이미지파일

rootfs.cpio는 파일 시스템

run.sh는 qemu를 커널 이미지 파일과 파일 시스템, 기타 옵션과 함께 실행하기 위한 명령을 담을 파일

이다.

여기서 vmlinux파일이 추가로 주어지거나, cpio 파일을 미리 압축 해제해놨다던가 하는 방식으로 주어질 것이다.

 

vmlinux 추출

가장 먼저 bzImage에서 vmlinux 파일을 추출하자.

vmlinux는 kernel을 elf 파일 즉, 커널 실행파일이라고 생각하면 된다.

해당 파일을 추출하기 위해서는 extract-vmlinux 소스파일이 필요하며, 아래와 같이 다운로드 가능하다.

wget https://raw.githubusercontent.com/torvalds/linux/master/scripts/extract-vmlinux && chmod +x extract-vmlinux

이후 아래와 같이 추출할 수 있다.

extract-vmlinux bzImage > vmlinux

이렇게 하면 vmlinux는 추출되지만 symbol이 없다.

따라서 아래를 설치하고

GitHub - marin-m/vmlinux-to-elf: A tool to recover a fully analyzable .ELF from a raw kernel, through extracting the kernel symbol table (kallsyms)

 

GitHub - marin-m/vmlinux-to-elf: A tool to recover a fully analyzable .ELF from a raw kernel, through extracting the kernel symb

A tool to recover a fully analyzable .ELF from a raw kernel, through extracting the kernel symbol table (kallsyms) - marin-m/vmlinux-to-elf

github.com

sudo apt install python3-pip liblzo2-dev
sudo pip3 install --upgrade lz4 zstandard git+https://github.com/clubby789/python-lzo@b4e39df
sudo pip3 install --upgrade git+https://github.com/marin-m/vmlinux-to-elf

이를 통해 symbol을 복구해주자.

vmlinux-to-elf vmlinux vmlinux_symbol

새로 생성된 vmlinux_symbol 파일을 통해 gdb로 심볼을 확인할 수 있다.

➜  gdb vmlinux_symbol
...
(No debugging symbols found in vmlinux_symbol) #하지만 심볼을 확인 가능함.
gef➤  p commit_creds
$1 = {<text variable, no debug info>} 0xffffffff8106e390 <commit_creds>

 

kernel 분석

이제 분석을 시작해보자.

qemu 실행 조건 분석

qemu 실행 조건은 run.sh에 포함되어있다.

예를 들면 아래와 같다.

qemu-system-x86_64 \
    -m 64M \
    -nographic \
    -kernel bzImage \
    -append "console=ttyS0 loglevel=3 oops=panic panic=-1 nopti nokaslr" \
    -no-reboot \
    -cpu qemu64 \
    -smp 1 \
    -monitor /dev/null \
    -initrd rootfs.cpio \
    -net nic,model=virtio \
    -net user

여기서는 nopti 및 nokaslr이 포함되어있기에 페이지를 분리하거나 주소를 랜덤화 하지 않는다.

애초에 cpu가 qemu64인 경우 pti 설정이 불가하다.

이외에 보호기법은 없다.

 

qemu-system-x86_64 \
    -snapshot \
    -kernel ./bzImage \
    -smp cores=1,threads=1 \
    -initrd ./initramfs.cpio.gz \
     -append "console=ttyS0 debug earlyprintk=serial oops=panic nokaslr smap smep selinux=0 tsc=unstable net.ifname
s=0 panic=1000 cgroup_disable=memory" \
    -net nic -net user,hostfwd=tcp::${SSH_PORT}-:22 \
    -nographic \
    -m 128M \
    -monitor none,server,nowait,nodelay,reconnect=-1 \
    -cpu kvm64,+smap,+smep \
     2>&1

여기서는 nokaslr이지만 smap, smep가 적용되어있음을 알 수 있다.

더불어 nopti가 적용되어있지 않기에 유저-커널 페이지를 분리함을 알 수 있다.

 

qemu 실행 조건 변경

통상적으로 nokaslr을 무조건 붙여준다. 이는 디버깅의 편리함을 위함이다.

더불어 gdb를 통한 분석을 위해서 무조건 마지막에 s는 붙여주자.

나머지 보호기법의 경우 상황에 따라 유동적으로 수정하자.

 

Init 파일 수정

cpio 압축 해제

init 파일은 커널이 실행될 때 가장 먼저 실행되는 파일이다.

이를 확인하기 위해서는 cpio 파일의 압축 해제가 필요하다.

아래와 같이 해제 가능한데 유의할 점은 해당 파일이 있는 위치에 그대로 모두 해제된다는 점이다.

그러므로 폴더를 하나 만든 뒤 그 안에 이 파일을 옮긴 다음 해제하자.

cpio -idv < rootfs.cpio

init 설정 변경

init 파일은 통상적으로 /etc/init.d 내에 있는 것으로 판단된다.

하지만 다른 위치에 있을 가능성도 있으니 유의하자.

예를 들면 pwnyable의 경우 /etc/init.d 내에 있었고, 한 ctf 문제에서는 최 상위 폴더에 그냥 있었다.

결국 문제 파일인 모듈을 로드해야하기 때문에 insmod 명령어가 있는 파일이면 그 파일이 맞다고 보면 된다.

만일 해당 파일에 kptr 관련 설정이라던지, 쉘 실행 시 권한을 제한하는 부분이 있으면 이를 수정해주자.

pwnyable의 경우 아래와 같이 수정하면 kptr을 누구나 읽을 수 있도록 하고, dmesg 명령어를 사용할 수 있게하며, root 권한으로 kernel이 실행된다.

echo 2 > /proc/sys/kernel/kptr_restrict
#echo 1 > /proc/sys/kernel/dmesg_restrict
setsid cttyhack setuidgid 1337 sh

-------------------------------------

#echo 2 > /proc/sys/kernel/kptr_restrict
echo 1 > /proc/sys/kernel/dmesg_restrict
setsid cttyhack setuidgid 0 sh

한 ctf 파일에서는 아래와 같았는데, 마지막 su user만 su root으로 바꿔줬고

#!/bin/sh

mount -t proc none /proc
mount -t sysfs none /sys
mount -t 9p -o trans=virtio,version=9p2000.L,nosuid hostshare /home/ctf
#for f in $(ls *.ko); do
#    insmod $f
#done
sysctl -w kernel.perf_event_paranoid=1

cat <<EOF

Boot took $(cut -d' ' -f1 /proc/uptime) seconds


Welcome to the lost and found store! Please look around to see if you can find the key to the flag.


EOF
mkdir /home/user
adduser user -D
chmod 600 /flag
chown 0.0 /flag
insmod thejumps.ko
su user
#exec su -l ctf

kptr과 dmesg는 애초에 0으로 설정되어있어서 별도로 건드리지 않았다.

/proc/sys/kernel # cat kptr_restrict
0
/proc/sys/kernel # cat dmesg_restrict
0

cpio 압축

해당 폴더 내에서 아래 명령어로 압축 가능하며, 생성 파일 경로는 지정 가능하다.

sudo find .| cpio -o --owner=root --format=newc > ../rootfs.cpio

gunzip

간혹 gunzip으로 추가 압축하여 배포하는 경우가 있다.

이때 압축 및 해제는 아래와 같다.

gunzip 파일명 #압축
gunzip -d 파일명 #해제

 

조금 편하게 setting하기

결국은 파일을 압축 해제하고, 파일을 수정하고, 재 압축하는 등 번거로운 작업이 반복되어야한다.

이를 아래와 같이 shell script를 통해 쉽게 할 수 있다.

#!/bin/bash

set -e

pushd cpio
sudo find .| cpio -o --owner=root --format=newc > ../rootfs.cpio
popd

qemu-system-x86_64 \
    -m 64M \
    -nographic \
    -kernel bzImage \
    -append "console=ttyS0 loglevel=3 oops=panic panic=-1 nopti nokaslr" \
    -no-reboot \
    -cpu qemu64 \
    -smp 1 \
    -monitor /dev/null \
    -initrd rootfs.cpio \
    -net nic,model=virtio \
    -net user

즉 주어진 cpio 파일을 한 폴더에 압축을 풀어놓고, 해당 폴더 내에서 익스코드를 짜던, 수정할 사항을 수정한 뒤 run.sh만 실행하면 해당 폴더를 압축하고 이를 바로 qemu 실행 시 사용하게된다.

gz 파일의 경우 아래와 같이 처리 가능하다.

find . -print0 | cpio --null -ov --format=newc | gzip -9 > ../initramfs.cpio.gz

(cpio 압축 시 옵션은 입맛대로)

추가로 컴파일도 추가해보면 아래와 같다.

#!/bin/bash
set -e

sudo gcc -o ./cpio/payload ./cpio/payload.c -static

pushd cpio
sudo find .| cpio -o --owner=root --format=newc > ../rootfs.cpio
#sudo find . -print0 | cpio --null -ov --format=newc | gzip -9 > ../rootfs.cpio.gz
popd
728x90
반응형
저작자표시 비영리 변경금지 (새창열림)

'Kernel Exploit > Exercise' 카테고리의 다른 글

kernel exploit / NahamCon 2025 CTF - The jumps  (0) 2025.05.30
kernel exploit payload - krop  (0) 2025.05.30
kernel exploit payload - kaslr  (0) 2025.05.30
kernel exploit payload - no mitigation  (0) 2025.05.30
'Kernel Exploit/Exercise' 카테고리의 다른 글
  • kernel exploit / NahamCon 2025 CTF - The jumps
  • kernel exploit payload - krop
  • kernel exploit payload - kaslr
  • kernel exploit payload - no mitigation
wyv3rn
wyv3rn
아저씨의 흔한 취미. wyv3rn#1249
  • wyv3rn
    think storage
    wyv3rn
  • 전체
    오늘
    어제
    • 분류 전체보기 (500)
      • To do list (7)
        • Doing (1)
        • Complete (6)
      • Diary (35)
      • Tips & theory (77)
      • Kernel Exploit (27)
        • Theory (15)
        • Exercise (5)
      • Wargame (313)
        • pwn.college (34)
        • Dreamhack (148)
        • pwnable.kr (15)
        • Lord of Sqlinjection (3)
        • Cryptohack (20)
        • Root me (27)
        • CodeEngn (4)
        • Exploit Education (22)
        • ROP Emporium (8)
        • H4C (10)
        • Hackerchool (22)
      • CTF (41)
        • Solved (39)
        • Unsolved (2)
      • Script (0)
      • RubiyaLap (0)
  • 블로그 메뉴

    • 홈
    • 방명록
  • 링크

  • 공지사항

    • PWN wargame 모음 (및 느낀점)
    • 비공개 글들에 대해.
    • 뭐라도 하나 얻어가시길...
  • 인기 글

  • 태그

    root
    exploit education
    64bit
    FSB
    rop
    Format String Bug
    phoenix
    root-me
    _IO_FILE
    lob
    x86
    la ctf
    ROOT ME
    BOF
    heap
    CANARY
    RTL
    hackerschool
    libc
    vtable
    cryptohack
    Me
    x64
    pwntools
    dreamhack
    tcache
    Buffer Overflow
    32bit
    docker
    pwnable.kr
  • 최근 댓글

  • 최근 글

  • 250x250
    반응형
  • hELLO· Designed By정상우.v4.10.3
wyv3rn
Kernel exploit 기본 setting
상단으로

티스토리툴바