Loading... 一直对 kernel pwn 挺感兴趣的,再加上 libc 那里也没什么新东西可学了,简单题没什么做的意义,难题也不会做,所以准备开始学习 kernel pwn。不过可能最近也没办法太深入的学习,总之先把环境搭起来再说。 首先说一下这里的环境到底指的是什么,我们希望能够有一个沙盒环境,可以做到 * 启动速度快。kernel pwn 的过程中很容易造成 kernel panic,如果每次启动要几十秒,体验肯定是很差的 * 可以用 gdb 之类的调试器调试。脑调是很痛苦的 * 可复用。每次启动环境的时候初始状态都应该相同,即便上一次把内核搞炸了下一次重启应该也可以解决全部问题 满足上述要求的解决方案就是 qemu + gdb 的调试方法。 以一台全新的 Ubuntu 20.04 LTS Desktop 虚拟机为例,虚拟机的安装使用 VMware 快速安装模式安装。 首先运行一个 kernel 的环境需要有一个 kernel 的镜像,镜像的获取手段有 * 手动编译一个内核出来 * 直接从软件源里面下 * 直接用本机的镜像 ### 从软件源下载 首先搜索镜像,下面这句话会把源里有的所有镜像都显示出来,可以配合 grep 来查找特定版本的镜像 ```shell sudo apt search linux-image ``` 找出镜像后就可以下载,这里以 linux-image-5.8.0-23-generic 为例 ```shell sudo apt download linux-image-5.8.0-23-generic ``` 下载下来后解压,在文件夹 `data/boot/` 中的以 vmlinux 开头的即为镜像文件 ### 使用本机镜像 在 `/boot` 文件夹中即可找到 ### 内核镜像编译 使用前两种方法比较快速,但是往往没有符号,为了调试方便,还是需要手动编译。 首先安装一些依赖 ```shell sudo apt install git fakeroot build-essential ncurses-dev xz-utils libssl-dev bc libelf-dev flex bison ``` 然后下载 kernel 源码,在[官网](https://mirrors.edge.kernel.org/pub/linux/kernel/v5.x/)可以下载,我下载的是 5.8 版本(版本应该可以随便选,我选择和系统版本一致)。 解压后先进行编译设置 ```shell make menuconfig ``` 进入内核编译设置,进入 kernel hacking 子目录,检查一下 debug 相关的选项有没有打开(其实默认都是打开的,进去看看确定一下就可以了)。 然后编译安装 ```shell make bzImage -j$(nproc) ``` `-j$(nproc)` 是使用所有的核心编译,可以加快编译速度。 编译的过程中可能会碰到报错 `*** No rule to make target 'debian/canonical-certs.pem', needed by 'certs/x509_certificate_list'. Stop.`,对于该错误只要注释掉编译目录下的 .config 中的`CONFIG_SYSTEM_TRUSTED_KEYS="debian/certs/benh@debian.org.cert.pem"` 一行即可。 我两次编译安装过程中都只碰到了这一个问题,如果出现别的问题通过搜索引擎应该也都可以解决。 编译出来的 bzImage 是不带符号的压缩映像,如果想要源码级调试,需要编译 vmlinux,也就是 ```shell make vmlinux -j$(nproc) ``` vmlinux 就是带符号的。 ### qemu 安装 qemu 可以模拟各个架构,基本是唯一的选择了。图省事的话可以直接用包管理器安装 ```shell sudo apt install git libglib2.0-dev libfdt-dev libpixman-1-dev zlib1g-dev sudo apt install qemu-user ``` 安装好后敲下 qemu 之后按 tab 有大量回显就算安装好了(可能需要重启终端)。 但是就我在调 ARM 过程中使用包管理安装的 qemu 时不怎么美好的经历,也建议自己手动编译安装一个最新版,可以参考[这篇文章](https://www.cjovi.icu/pwnreview/1353.html)。 ### busybox 安装 busybox 提供了一个 Linux 虚拟环境需要的大量程序,如 ls,cat 等。 首先到 [官网](https://busybox.net/downloads/) 中下载,下下来之后解压,进行配置 ```shell make menuconfig ``` 注意勾选 Settings ---> Build static binary file (no shared lib),避免之后还要配置 lib。 然后 ```shell make -j$(nproc) make install ``` 既可,默认是安装在当前目录下的 _install 文件夹中的,把这个文件夹移到你想移的位置即可,为了方便,我直接放在了准备运行 qemu 的目录下。 然后进入 _install 文件夹中,先建立一些必要的文件夹 ```shell mkdir sys mkdir proc ``` 然后写一下 init 脚本 ```shell #!/bin/sh mount -t proc none /proc mount -t sysfs none /sys exec 0</dev/console exec 1>/dev/console exec 2>/dev/console echo -e "{==DBG==} Boot took $(cut -d' ' -f1 /proc/uptime) seconds" setsid /bin/cttyhack setuidgid 1000 /bin/sh #normal user umount /proc umount /sys poweroff -d 0 -f ``` 给予可执行权限 ```shell chmod +x ./init ``` 然后把这里的文件都打包 ```shell find . | cpio -o --format=newc > ../rootfs.cpio ``` 到上层文件夹中就会有 rootfs.cpio 文件了,然后把 bzImage 也放到这里,就可以启动 qemu 了。由于参数较多,所以写成一个 shell 脚本来启动 ```shell qemu-system-x86_64 \ -m 128M \ -kernel bzImage \ -initrd rootfs.cpio \ -append 'root=/dev/ram console=ttyS0 oops=panic panic=1' \ -monitor /dev/null \ -cpu kvm64,+smep \ -smp cores=1,threads=1 \ -netdev user,id=t0, -device e1000,netdev=t0,id=nic0 \ -nographic ``` 执行脚本后就会调用 qemu 来启动虚拟机 <div style="text-align:center"><img src="https://www.cjovi.icu/usr/uploads/2021/06/269383429.png "></div> 这里会报错,我也不知道是什么原因,但是好像没什么影响,所以暂且不管了。 可见,有 boot.sh bzImage rootfs.cpio 即可启动一个虚拟内核环境,所以大多数的题目都会给出这几个文件。 对于 rootfs.cpio 的解压可以通过 ```shell cpio -idmv < rootfs.cpio ``` 这会把 rootfs.cpio 中的文件都解压到当前目录中。 最后修改:2022 年 03 月 10 日 © 允许规范转载 打赏 赞赏作者 支付宝微信 赞 1 如果觉得我的文章对你有用,那听听上面我喜欢的歌吧