制作基于ubuntu-base的文件系统,用于sudo,网络内核cve调试

内核编译环境搭建

主机是 ubuntu 20.04

macos 下使用 orbStack软件,耗能较低,能充分利用本地硬件资源

安装docker

参考 : https://blog.csdn.net/u012563853/article/details/125295985

执行docker命令免去sudo 命令

参考 :
https://www.cnblogs.com/faqbug/p/12484958.html
https://www.cnblogs.com/xyztank/articles/16919180.html

拉取docker镜像

docker pull ubuntu:14.04
docker pull ubuntu:16.04

# docker  ubuntu:14.04 可编译的版本 < linux 4.0
# docker  ubuntu:16.04 可编译的版本 linux 4.0 <= ~ < linux 5.0
# 主机     ubuntu 20.04 可编译的版本 linux 5.0 <= ~ 最新的linux版本

配置用于编译linux kernel的仓库

查看已拉取的images

$ docker images -a
REPOSITORY                 TAG       IMAGE ID       CREATED         SIZE
ubuntu                     16.04     b6f507652425   21 months ago   135MB
ubuntu                     14.04     13b66b487594   2 years ago     197MB

确定要编译内核的存放位置

比如,我这里有一块移动硬盘,路径为/media/showme/OneT

创建用于编译kernel的仓库

docker run -it \
	-v /media/showme/OneT:/media/showme/OneT \    # 将主机的目录映射到docker中(主要是为了方便源码调试,不增大仓库体积)
	--name="buildUbuntu1404" \                    # 给这个仓库取一个名字
	13b66b487594 \                                # ubuntu:14.04的 image id
	/bin/bash

在仓库内部配置编译环境

# 进入docker仓库
docker start -i buildUbuntu1404

# apt更新
apt update

# 安装编译内核需要的库及软件
apt-get install libncurses5-dev gcc make bc g++ vim git bc flex bison libssl-dev dwarves libelf-dev xz-utils wget

docker ubuntu:16.04 和 主机 ubuntu:20.04 安装与上相同的软件

由于调试环境是在主机中, 主机 ubuntu:20.04还需要安装qemu和配置gdb调试插件(我用的是pwndbg)

sudo apt-get install qemu qemu-system gdb

例子

比方说,现在要调试CVE-2016-9793

# 下载源码,进入 docker buildUbuntu1604
showme@showme:/media/showme/OneT/linux_kerenl_vulnerability/cve_recurrence/2016/CVE-2016-9793$ wget https://mirrors.edge.kernel.org/pub/linux/kernel/v4.x/linux-4.8.13.tar.xz
showme@showme:/media/showme/OneT/linux_kerenl_vulnerability/cve_recurrence/2016/CVE-2016-9793$ tar xvf linux-4.8.13.tar.xz
showme@showme:/media/showme/OneT/linux_kerenl_vulnerability/cve_recurrence/2016/CVE-2016-9793$ cd linux-4.8.13
showme@showme:/media/showme/OneT/linux_kerenl_vulnerability/cve_recurrence/2016/CVE-2016-9793/linux-4.8.13$ docker start -i buildUbuntu1604
root@5b0fb117b49f:/#

# 切换到源码目录
root@5b0fb117b49f:/# cd /media/showme/OneT/linux_kerenl_vulnerability/cve_recurrence/2016/CVE-2016-9793/linux-4.8.13

# 编译配置
root@5b0fb117b49f:/media/showme/OneT/linux_kerenl_vulnerability/cve_recurrence/2016/CVE-2016-9793/linux-4.8.13# make menuconfig  

# 用vim 打开.config文件,做必要的修改
# 1 搜索debian关键字,如果存在如下内容
CONFIG_SYSTEM_TRUSTED_KEYS="debian/canonical-certs.pem"
CONFIG_SYSTEM_REVOCATION_KEYS="debian/canonical-revoked-certs.pem"
# 将其清空
CONFIG_SYSTEM_TRUSTED_KEYS=""
CONFIG_SYSTEM_REVOCATION_KEYS=""

# 2 将如下3个配置修改为y
CONFIG_E100=m
CONFIG_E1000=m
CONFIG_E1000E=m
# 
CONFIG_E100=y
CONFIG_E1000=y
CONFIG_E1000E=y

# 进行编译, 编译完之后,先不管,等文件系统搭建完毕后,再进行验证
root@5b0fb117b49f:/media/showme/OneT/linux_kerenl_vulnerability/cve_recurrence/2016/CVE-2016-9793/linux-4.8.13# make bzImage vmlinux -j8

可复用文件系统搭建

通过该方式搭建的文件系统,从linux 4 到最新内核版本都可正常运行

对于个人来书,有如下有点

  • 方便在poc调试阶段,直接对poc进行修改编译,不必总是打包/解包文件系统
  • 便于调试类似sudo/cap/fuse这样的漏洞(轻量)
  • 可联网
  • 可安装任意软件(内部安装gdb,配置pwndbg等等)
  • 新增文件持久化,方便回顾调试老的CVE

根据 ubuntu-base 构建文件系统

获取 ubuntu-base

wget https://mirrors.tuna.tsinghua.edu.cn/ubuntu-cdimage/ubuntu-base/releases/20.04.4/release/ubuntu-base-20.04.1-base-amd64.tar.gz

wget https://mirrors.tuna.tsinghua.edu.cn/ubuntu-cdimage/ubuntu-base/releases/18.04.5/release/ubuntu-base-18.04.5-base-amd64.tar.gz

wget https://mirrors.tuna.tsinghua.edu.cn/ubuntu-cdimage/ubuntu-base/releases/16.04.6/release/ubuntu-base-16.04.6-base-amd64.tar.gz

wget https://mirrors.tuna.tsinghua.edu.cn/ubuntu-cdimage/ubuntu-base/releases/14.04.6/release/ubuntu-base-14.04.6-base-amd64.tar.gz

给文件系统镜像分配空间,并格式化为ext4

fallocate -l 3000M rootfs.img 
sudo mkfs.ext4 -F -L ROOTFS rootfs.img

创建挂载点,并挂载,同时将ubuntu-base基础文件解药到挂载点中

mkdir mnt
sudo mount rootfs.img mnt
sudo tar -xzvf ubuntu-base-20.04.1-base-amd64.tar.gz -C mnt/

(可选)将当前主机的配置文件拷贝到挂载点中

sudo cp /etc/resolv.conf mnt/etc/
sudo cp -R /etc/skel /mnt/etc/

挂载其他文件系统

sudo mount -t proc /proc mnt/proc && sudo mount -t sysfs /sys mnt/sys && sudo mount -o bind /dev mnt/dev && sudo mount -o bind /dev/pts mnt/dev/pts

切换根目录

sudo chroot mnt/
# 这之后就进入到 ubuntu-base中了

更新apt, 并安装基本的软件

apt-get update
apt-get install bash-completion udev sudo gdb gcc g++ ssh net-tools ethtool wireless-tools ifupdown network-manager iputils-ping rsyslog xterm htop vim wget alsa-utils --no-install-recommends

创建普通用户,并放置到sudo组中

我这里创建的用户名是 showme

useradd -G sudo -m -s /bin/bash showme

给普通用户和root用户设置密码

passwd showme
passwd root

设置主机名,并配置hosts文件

echo "showme" > /etc/hostname 
echo "127.0.0.1 localhost.localdomain localhost" > /etc/hosts 
echo "127.0.0.1 showme" >> /etc/hosts     # 注意:这里的showme需要和hostname中的内容一致

配置网络相关的内容

该文件中的内容,后续可能需要修改

echo "auto lo" > /etc/network/interfaces
echo "iface lo inet loopback" >> /etc/network/interfaces
echo "auto ens3" >> /etc/network/interfaces
echo "iface ens3 inet static" >> /etc/network/interfaces
echo "address 10.0.2.15" >> /etc/network/interfaces
echo "netmask 255.255.255.0" >> /etc/network/interfaces

配置DNS

这里面的内容后续可能修改

echo "nameserver 127.0.0.53" > /etc/resolv.conf
echo "options edns0 trust-ad" >> /etc/resolv.conf
echo "nameserver 8.8.8.8" >> /etc/resolv.conf
echo "nameserver 8.8.4.4" >> /etc/resolv.conf

退出根目录,进入到主机原先的目录

exit

卸载之前的挂载点

sudo umount mnt/proc/ && sudo umount mnt/sys/ && sudo umount mnt/dev/pts/ && sudo umount mnt/dev/ && sudo umount mnt/

配置启动脚本,并修正网络相关配置

创建一个start_kernel.sh文件,并赋予可执行权限chmod 777 start_kernel.sh

qemu-system-x86_64 \
	-m 4096M \
	-kernel arch/x86/boot/bzImage \                       # 编译linux生成的kernel的位置,根据实际情况修改
	-append "root=/dev/sda rw nokaslr console=ttyS0" \
	-drive format=raw,file=../../../rootfs.img  \         # 文件系统的位置,根据实际情况修改
	--nographic

执行start_kernel.sh登录系统

[  OK  ] Finished Daily man-db regeneration.
[  OK  ] Started Hostname Service.

Ubuntu 20.04.1 LTS showme ttyS0

showme login: showme
Password:
Welcome to Ubuntu 20.04.1 LTS (GNU/Linux 4.8.13 x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage


This system has been minimized by removing packages and content that are
not required on a system that users do not log into.

To restore this content, you can run the 'unminimize' command.
Last login: Tue May 30 20:10:05 UTC 2023 on ttyS0
showme@showme:~$

解决终端大小不适应的问题

sudo apt install xterm
resize

解决网络接口不为 ens3的问题

执行ifconfig -a查看接口

showme@showme:~$ ifconfig -a
enp0s3: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 10.0.2.15  netmask 255.255.255.0  broadcast 10.0.2.255
        inet6 fec0::5054:ff:fe12:3456  prefixlen 64  scopeid 0x40<site>
        inet6 fe80::5054:ff:fe12:3456  prefixlen 64  scopeid 0x20<link>
        ether 52:54:00:12:34:56  txqueuelen 1000  (Ethernet)
        RX packets 7  bytes 798 (798.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 13  bytes 1066 (1.0 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1  (Local Loopback)
        RX packets 66  bytes 5582 (5.5 KB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 66  bytes 5582 (5.5 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

可以看到我这里接口的名称是 enp0s3
修改/etc/network/interfaces文件,将其中的ens3替换为enp0s3

echo "auto lo" > /etc/network/interfaces
echo "iface lo inet loopback" >> /etc/network/interfaces
echo "auto enp0s3" >> /etc/network/interfaces
echo "iface enp0s3 inet static" >> /etc/network/interfaces
echo "address 10.0.2.15" >> /etc/network/interfaces
echo "netmask 255.255.255.0" >> /etc/network/interfaces

解决DNS配置开机重置的问题

sudo apt-get remove resolvconf 
sudo mv /etc/resolv.conf /etc/resolv.conf.link 
su root # 切换到root用户

# 将如下内容写入到 /etc/resolv.conf 中
echo "nameserver 127.0.0.53" > /etc/resolv.conf
echo "options edns0 trust-ad" >> /etc/resolv.conf
echo "nameserver 8.8.8.8" >> /etc/resolv.conf
echo "nameserver 8.8.4.4" >> /etc/resolv.conf

# 锁定 /etc/resolv.conf
chattr +i /etc/resolv.conf

配置路由开机生效

# 切换到 root用户

# 创建 /etc/rc.local 文件

# 将如下两行内容写入到 /etc/rc.local 中
#!/bin/sh
route add -net 0.0.0.0 netmask 0.0.0.0 gw 10.0.2.2 dev enp0s3

# 赋予可执行权限
chmod 777 /etc/rc.local

# 让 /etc/rc.local 配置开机生效
systemctl start rc-local.service 
# 或者 
systemctl enable rc-local.service

最后需要注意的

新增和修改的内容大部分是在内存缓存中的,还没有写进rootfs.img中
需要执行sync将文件缓存写入磁盘

效果

showme@showme:~$ uname -a
Linux showme 4.8.13 #4 SMP Thu May 25 06:15:26 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux


showme@showme:~$ ping www.baidu.com
PING www.a.shifen.com (36.152.44.96) 56(84) bytes of data.
64 bytes from 36.152.44.96 (36.152.44.96): icmp_seq=1 ttl=255 time=78.7 ms
64 bytes from 36.152.44.96 (36.152.44.96): icmp_seq=2 ttl=255 time=14.8 ms
^C
--- www.a.shifen.com ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1003ms
rtt min/avg/max/mdev = 14.836/46.752/78.669/31.916 ms


showme@showme:~$ sudo apt install sl
Reading package lists... Done
Building dependency tree
Reading state information... Done
sl is already the newest version (5.02-1).
0 upgraded, 0 newly installed, 0 to remove and 43 not upgraded.
showme@showme:~$

制作 KERNEL PWN 题文件系统

wget https://www.busybox.net/downloads/busybox-1.34.1.tar.bz2 --no-check-certificate



# 配置编译选项
make menuconfig

Linux System Utilities --->
        [ ] mkfs_ext2   取消
        [ ] mkfs_vfat   取消
        
 
Busybox Settings -> Build Options ->
选中 Build Busybox as a static binary

linux System Utilities ->
取消 Support mounting NFS file system 网络文件系统

Networking Utilities ->
取消 inetd (Internet超级服务器) 

# 编译busybox,最终会在busybox-1.19.4下生成 _install文件夹
make install -j4

配置文件系统启动脚本(最简化配置)

# 进入生成的 _install目录
cd _install

# 1、配置文件系统
mkdir proc sys dev etc etc/init.d

# 2、在启动脚本rcS中的代码为
vim etc/init.d/rcS

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

# 3、给启动脚本赋予可执行权限
chmod +x etc/init.d/rcS

# 4、生成文件系统镜像
find . | cpio -o --format=newc > ../rootfs.img

https://blog.csdn.net/thisinnocence/article/details/127931774

ubuntu18.04
sd.c:(.text.sd_revalidate_disk+0x16bc): relocation truncated to fit: R_MIPS_26 against `____ilog2_NaN’
make: *** [.tmp_vmlinux1] Error 1
解决方法:

  1. 去除 driver/scsi 的支持,这种是冶标不冶本的方法 (不予推荐)
  2. 在 .config 中添加 CONFIG_CC_OPTIMIZE_FOR_SIZE=y (推荐)
    出现此问题为gcc的bug:详见

你可能感兴趣的:(pwn_cve_kernel,linux,pwn)