编辑
2023-03-08
Kernel Pwn
00
请注意,本文编写于 624 天前,最后修改于 624 天前,其中某些信息可能已经过时。

目录

安装依赖
获取系统镜像
下载现有内核文件
使用系统内核镜像
安装busybox
构建文件系统
后续向文件系统内添加文件
测试运行内核

离开Glibc的第一天 想他

安装依赖

首先建议直接新起一个虚拟机 以免环境污染

bash
sudo apt-get update sudo apt-get install git fakeroot build-essential ncurses-dev xz-utils qemu flex libncurses5-dev fakeroot build-essential ncurses-dev xz-utils libssl-dev bc bison libglib2.0-dev libfdt-dev libpixman-1-dev zlib1g-dev libelf-dev

获取系统镜像

自行编译内核源码

下载地址: https://www.kernel.org/

bash
wget https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.11.tar.xz tar -xvf linux-5.11.tar.xz

解压完成之后 修改编译配置 一般配置文件不需要怎么改动 直接保存即可

bash
make menuconfig make bzImage

编译过程非常非常非常漫长..可以先吃饭睡觉打豆豆...等到如下提示出现时即为编译完成

可能会遭遇的报错

make[1]: *** 没有规则可制作目标“debian/canonical-certs.pem”,由“certs/x509_certificate_list” 需求

尝试修改刚刚保存的配置文件.config中的CONFIG_SYSTEM_TRUSTED_KEYS属性值 将其清空

BTF: .tmp_vmlinux.btf: pahole (pahole) is not available

缺少依赖

sudo apt install dwarves

此时目录下的vmlinux即为原始内核文件

arch/x86/boot/bzImage为压缩过后的内核文件

下载现有内核文件

直接下载也是一种常用的方式 优点就是不用等待编译的时间 但是需要等待下载的时间 怎么取舍要看条件进行选择

bash
sudo apt search linux-image-

有很多 选一个喜欢的就行 下载下来之后是一个deb 解压即可得到和上面自行编译一样的目录结构

bash
sudo apt download linux-image-

使用系统内核镜像

/boot内可以直接拿出来用

安装busybox

下载地址: https://busybox.net/downloads/

bash
wget https://busybox.net/downloads/busybox-1.35.0.tar.bz2 tar -jxvf busybox-1.35.0.tar.bz2

老样子 解压之后进入对应目录保存编译配置文件

make menuconfig

注意 这里有个配置需要改一下 在Setting->Build static binary file (no shared lib)

修改完配置文件之后直接编译就行了 这个会比编译内核快一些

bash
make install

在编译完成之后 本目录下会有_install目录 这个将在下一步中打包成为文件系统

构建文件系统

基本以下操作都是固定的了 直接复制执行即可

一些初始化操作

bash
cd _install mkdir -pv {bin,sbin,etc,proc,sys,home,lib64,lib/x86_64-linux-gnu,usr/{bin,sbin}} touch etc/inittab mkdir etc/init.d touch etc/init.d/rcS chmod +x ./etc/init.d/rcS

配置初始化配置文件etc/inttab

bash
::sysinit:/etc/init.d/rcS ::askfirst:/bin/ash ::ctrlaltdel:/sbin/reboot ::shutdown:/sbin/swapoff -a ::shutdown:/bin/umount -a -r ::restart:/sbin/init

配置初始化脚本 etc/init.d/rcS 主要是各个目录的挂载

#!/bin/sh mount -t proc none /proc mount -t sys none /sys /bin/mount -n -t sysfs none /sys /bin/mount -t ramfs none /dev /sbin/mdev -s

配置用户组 新建了ctfroot两个组 ctfroot两个用户

bash
echo "root:x:0:0:root:/root:/bin/sh" > etc/passwd echo "ctf:x:1000:1000:ctf:/home/ctf:/bin/sh" >> etc/passwd echo "root:x:0:" > etc/group echo "ctf:x:1000:" >> etc/group echo "none /dev/pts devpts gid=5,mode=620 0 0" > etc/fstab

打包文件系统为镜像文件 输出路径可以自己选

bash
find . | cpio -o --format=newc > ../../rootfs.cpio

后续向文件系统内添加文件

不可避免的后续我们可能想向文件系统内添加各种东西 这个时候我们有两种选择 要么直接修改_install然后重新打包 这样简单但是容易造成环境污染 或者是我们解压刚刚打包的文件系统 然后添加新文件

解压文件系统 会将文件系统解压到当前目录内

bash
cpio -idv < ./rootfs.cpio

然后我们可以添加文件 再使用上面同样的打包命令打包

bash
find . | cpio -o --format=newc > ../../rootfs.cpio

测试运行内核

将之前的内核bzImage和文件系统rootfs.cpio放到同一级目录下 编写启动脚本

bash
#!/bin/sh qemu-system-x86_64 \ -m 128M \ -kernel ./bzImage \ -initrd ./rootfs.cpio \ -monitor /dev/null \ -append "root=/dev/ram rdinit=/sbin/init console=ttyS0 oops=panic panic=1 loglevel=3 quiet nokaslr" \ -cpu kvm64,+smep \ -smp cores=2,threads=1 \ -netdev user,id=t0, -device e1000,netdev=t0,id=nic0 \ -nographic \ -s

-m:虚拟机内存大小 -kernel:内存镜像路径 -initrd:磁盘镜像路径 -append:附加参数选项 nokalsr:关闭内核地址随机化,方便我们进行调试 loglevel=3& quiet:不输出log console=ttyS0:指定终端为/dev/ttyS0,这样一启动就能进入终端界面 -monitor:将监视器重定向到主机设备/dev/null -cpu:设置CPU安全选项,在这里开启了smep保护 -s:相当于-gdb tcp::1234的简写(也可以直接这么写),后续我们可以通过gdb连接本地端口进行调试

直接运行启动脚本即可启动刚刚我们编译好的内核

可能会遭遇的报错

qemu-system-x86_64 not found

bash
sudo apt-get install qemu-system-x86

本文作者:Du4t

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!