linux内核漏洞利用初探(1):环境配置
字数 1206 2025-08-03 16:49:27

Linux内核漏洞利用初探(1):环境配置

1. 环境准备

1.1 系统要求

  • 实验环境:Ubuntu 16.04 64位
  • 内核版本:2.6.32.1
  • BusyBox版本:1.19.4
  • GCC版本:4.7

1.2 依赖安装

sudo apt-get install -y gcc-4.7 g++-4.7
sudo apt-get install git fakeroot build-essential ncurses-dev xz-utils libssl-dev bc qemu qemu-system
sudo apt-get install bison flex libncurses5-dev

1.3 GCC降级

cd /usr/bin
sudo rm -r gcc
sudo ln -sf gcc-4.7 gcc
sudo rm -r g++
sudo ln -sf g++-4.7 g++

2. 内核源码获取与编译

2.1 下载源码

wget https://mirrors.tuna.tsinghua.edu.cn/kernel/v2.6/linux-2.6.32.1.tar.gz
tar -xvf linux-2.6.32.1.tar.gz

2.2 编译内核

cd linux-2.6.32.1/
make menuconfig
make
make all
make modules

2.3 常见编译问题解决

问题1: fatal error: linux/compiler-gcc5.h: No such file or directory

解决方案:

  1. 将当前系统的compiler-gcc.h拷贝到内核源码目录
cp /usr/src/linux-headers-4.4.0-103-generic/include/linux/compiler-gcc.h ./linux-2.6.32.1/include/linux/compiler-gcc5.h
  1. 确保使用GCC 4.7版本

3. 添加自定义系统调用

3.1 修改系统调用表

32位系统修改arch/x86/kernel/syscall_table_32.S:

.long sys_muhe_test
.long sys_hello

64位系统修改arch/x86/include/asm/unistd_64.h:

#define __NR_hello 299
__SYSCALL(__NR_hello,sys_hello)
#define __NR_muhe_test 300
__SYSCALL(__NR_muhe_test,sys_muhe_test)

3.2 定义系统调用宏

修改arch/x86/include/asm/unistd_32.h:

#define __NR_hello 337
#define __NR_muhe_test 338
#define NR_syscalls 339  # 注意更新总数

3.3 添加函数声明

修改include/linux/syscalls.h:

asmlinkage long sys_muhe_test(int arg0);
asmlinkage long sys_hello(void);

3.4 实现系统调用

创建muhe_test/muhe_test.c:

#include <linux/kernel.h>

asmlinkage long sys_muhe_test(int arg0) {
    printk("I am syscall");
    printk("syscall arg %d", arg0);
    return ((long)arg0);
}

asmlinkage long sys_hello(void) {
    printk("hello my kernel world\n");
    return 0;
}

创建muhe_test/Makefile:

obj-y := muhe_test.o

3.5 修改顶层Makefile

修改Makefile:

core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/ muhe_test/

4. BusyBox配置与编译

4.1 编译步骤

make menuconfig  # 确保选择静态编译
make
make install

4.2 常见问题解决

问题1: linux/ext2_fs.h: 没有那个文件或目录

解决方案:
make menuconfig时:

Linux System Utilities ---> 
    取消选择[ ] mkfs_ext2 和 [ ] mkfs_vfat

问题2: 'RLIMIT_FSIZE' undeclared

解决方案:
修改include/libbb.h:

#include <sys/resource.h>

4.3 文件系统配置

方案1:

cd _install
mkdir -pv {bin,sbin,etc,proc,sys,usr/{bin,sbin}}

cat > init <<EOF
#!/bin/sh
echo "INIT SCRIPT"
mount -t proc none /proc
mount -t sysfs none /sys
mount -t debugfs none /sys/kernel/debug
mkdir /tmp
mount -t tmpfs none /tmp
mdev -s
echo -e "\nBoot took $(cut -d' ' -f1 /proc/uptime) seconds\n"
exec /bin/sh
EOF

chmod +x init
find . | cpio -o --format=newc > ../rootfs.cpio

方案2:
创建etc/inittab:

::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

配置设备节点:

mkdir dev
sudo mknod dev/ttyAMA0 c 204 64
sudo mknod dev/null c 1 3
sudo mknod dev/console c 5 1

5. 测试环境启动

5.1 启动QEMU

qemu-system-x86_64 -kernel ./arch/x86/boot/bzImage -initrd ../rootfs.cpio
# 或
qemu-system-x86_64 -kernel ./arch/x86/boot/bzImage -initrd ../rootfs2-1.img -append "root=/dev/ram rdinit=/sbin/init"

5.2 测试系统调用

创建测试程序muhe_test_syscall_lib.c:

#include <stdio.h>
#include <linux/unistd.h>
#include <sys/syscall.h>

int main(int argc, char **argv) {
    printf("\nDiving to kernel level\n\n");
    syscall(300, 1337);
    return 0;
}

编译并测试:

gcc muhe_test_syscall_lib.c -o muhe -static
cp muhe ../busybox-1.19.4/_install/usr/muhe
find . | cpio -o --format=newc > ../rootfs_test_syscall.img
qemu-system-x86_64 -kernel ./arch/x86/boot/bzImage -initrd ../rootfs_test_syscall.img -append "root=/dev/ram rdinit=/sbin/init"

6. 其他注意事项

  1. QEMU退出: 使用Ctrl+Alt组合键点击鼠标退出QEMU界面

  2. 保护机制关闭方法:

    • mmap_min_addr: sysctl -w vm.mmap_min_addr="0"
    • 内核Canary: 编辑.config文件,注释掉CONFIG_CC_STACKPROTECTOR并重新编译
  3. 驱动编译:

    • 启用可加载模块支持: make menuconfig -> Enable loadable module support -> Forced module loading
    • 关闭模块校验: 取消Source checksum for all modules
    • Makefile指向正确的内核源码目录
Linux内核漏洞利用初探(1):环境配置 1. 环境准备 1.1 系统要求 实验环境:Ubuntu 16.04 64位 内核版本:2.6.32.1 BusyBox版本:1.19.4 GCC版本:4.7 1.2 依赖安装 1.3 GCC降级 2. 内核源码获取与编译 2.1 下载源码 2.2 编译内核 2.3 常见编译问题解决 问题1 : fatal error: linux/compiler-gcc5.h: No such file or directory 解决方案 : 将当前系统的 compiler-gcc.h 拷贝到内核源码目录 确保使用GCC 4.7版本 3. 添加自定义系统调用 3.1 修改系统调用表 32位系统修改 arch/x86/kernel/syscall_table_32.S : 64位系统修改 arch/x86/include/asm/unistd_64.h : 3.2 定义系统调用宏 修改 arch/x86/include/asm/unistd_32.h : 3.3 添加函数声明 修改 include/linux/syscalls.h : 3.4 实现系统调用 创建 muhe_test/muhe_test.c : 创建 muhe_test/Makefile : 3.5 修改顶层Makefile 修改 Makefile : 4. BusyBox配置与编译 4.1 编译步骤 4.2 常见问题解决 问题1 : linux/ext2_fs.h: 没有那个文件或目录 解决方案 : 在 make menuconfig 时: 问题2 : 'RLIMIT_FSIZE' undeclared 解决方案 : 修改 include/libbb.h : 4.3 文件系统配置 方案1 : 方案2 : 创建 etc/inittab : 创建 etc/init.d/rcS : 配置设备节点: 5. 测试环境启动 5.1 启动QEMU 5.2 测试系统调用 创建测试程序 muhe_test_syscall_lib.c : 编译并测试: 6. 其他注意事项 QEMU退出 : 使用 Ctrl+Alt 组合键点击鼠标退出QEMU界面 保护机制关闭方法 : mmap_ min_ addr: sysctl -w vm.mmap_min_addr="0" 内核Canary: 编辑 .config 文件,注释掉 CONFIG_CC_STACKPROTECTOR 并重新编译 驱动编译 : 启用可加载模块支持: make menuconfig -> Enable loadable module support -> Forced module loading 关闭模块校验: 取消 Source checksum for all modules Makefile指向正确的内核源码目录