准备开始搞 kernel pwn 了。

环境搭建

编译内核

首先下载 kernel 源码:https://mirrors.tuna.tsinghua.edu.cn/kernel/

需要什么版本就指定什么版本好了。

因为我现在想复现 Dirty Cred,所以我下载了 5.8.1 版本的内核,解压之后使用 make menuconfig 可以打开一个配置界面,这里一定要把调试符号勾选,方便我们调试。

具体在 kernel hacking->kernel debugging 勾选,kernel hacking->Compile-time checks and compiler options->Compile the kernel with debug info

因为我们还是使用 pwndbg 去调试,所以不勾选 kgdb 了,最后呢,使用命令 make -j3 bzImage 来编译内核。

这里我遇到一个错误,根据说法,安装开发环境即可,如图示命令安装。

这里遇到一个坑的地方,如果开 wsl 在 E 盘下面编译,不仅慢而且容易错,所以还是建议把源码移动到 home 目录下再去编译,几分钟就能搞定。

这里我修改了一点源码,因为之前编译遇到问题,具体修改参考这个:https://gitee.com/openeuler/kernel/pulls/141/files

关于 wsl 编译错误的问题,我也参考了这个 issue:https://github.com/microsoft/WSL/issues/8045

最后输出

我们的内核就编译完了。

编译文件系统

这里我们使用 busybox 制作根文件系统,下载地址 https://www.busybox.net/ ,这里我选用了 1.32 版本。

同样使用 make menuconfig 打开配置界面。

Setting-> (build option分页下)Build static binary (no shared libs) 勾选,编译为静态链接的文件。

Networking Utilities->inetd 取消勾选。

然后 make -j8 去编译,编译完成之后使用 make install 创建 _install 目录,完成之后进这个目录再创建一些文件夹 mkdir -p proc sys dev etc/init.d,那么这里就是我们要打包的文件系统了。当然还需要创建一个 init 启动脚本,主要是挂载那些目录。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#!/bin/sh
echo "INIT SCRIPT"
mkdir /tmp
mount -t proc none /proc
mount -t sysfs none /sys
mount -t devtmpfs none /dev
mount -t debugfs none /sys/kernel/debug
mount -t tmpfs none /tmp
echo -e "Boot took $(cut -d' ' -f1 /proc/uptime) seconds"
setsid /bin/cttyhack setuidgid 1000 /bin/sh
#如果不加下面三行,那么你退出qemu的时候会无限重启
umount /proc
umount /sys
poweroff -d 0 -f

然后建立系统的配置文件。

etc/passwd

1
2
root:x:0:0:root:/root:/bin/sh
ctf:x:1000:1000:ctf:/home/ctf:/bin/sh

etc/group

1
2
root:*:0:
ctf:*:1000:

之后可以用一个命令打包这个文件系统 find . | cpio -o --format=newc > ../rootfs.img

如果要重新解包文件系统可以使用这个命令 cpio -idmv < rootfs.img

qemu启动

然后把 bzImage 和 rootfs.img 放一起,新建一个启动脚本,输入以下命令:

1
2
3
4
5
6
7
8
9
#!/bin/sh
qemu-system-x86_64 \
-m 64M \
-nographic \
-kernel ./bzImage \
-initrd ./rootfs.img \
-append "root=/dev/ram rw console=ttyS0 oops=panic panic=1 kaslr" \
-smp cores=2,threads=1 \
-cpu kvm64

就可以启动 qemu 了。

OK,配置环境到这里也就差不多了。