admin 发表于 2020-5-4 11:34:55

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


主要记录一下学习muhe师傅的系列教程,记录其中的坑点。muhe师傅的教程是在32位ubuntu环境下测试的,本文是在64位环境下测试,有很多地方需要修改,故记录本文,以供后来者学习。附件在文末下载。环境说明:内核版本2.6.32.1busybox版本1.19.4gcc版本4.7实验环境ubuntu16.04 64位1.更新gcc内核2.6.x只支持gcc 3.x和4.x.y,可能是较高版本的gcc不支持老版本kernel的某些语法格式。gcc下降:sudo apt-get install -y gcc-4.7
  sudo apt-get install -y g++-4.7
  # 重新建立软连接
  cd /usr/bin    #进入/usr/bin文件夹下
  sudo rm -r gcc#移除之前的软连接
  sudo ln -sf gcc-4.7 gcc #建立gcc4.7的软连接
  sudo rm -r g++#同gcc
  sudo ln -sf g++-4.7 g++
  
安装依赖:$ 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
  
2.下载源码官网:https://mirrors.edge.kernel.org/pub/linux/kernel/国内镜像(速度超快):https://mirrors.tuna.tsinghua.edu.cn/kernel/# 最好还是从国内镜像上下载
  $ wget https://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.32.1.tar.gz -O linux-2.6.32.1.tar.gz
  $ tar -xvf linux-2.6.32.1.tar.gz
  
3.编译过程$ cd linux-2.6.32.1/
  $ make menuconfig
  $ make
  $ make all
  $ make modules
  
问题1:include/linux/compiler-gcc.h:86:30: fatal error: linux/compiler-gcc5.h: No such file or directoryinclude/linux/compiler-gcc.h:86:1: fatal error: linux/compiler-gcc9.h: No such file or directory解决1-1:https://blog.csdn.net/u014525494/article/details/53573298把当前linux系统/usr/src的compiler-gcc.h拷贝到要编译的linux源码目录中。$ 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-2:原因:编译的内核版本比较低,而gcc版本比较高。gcc下降到4.7。貌似没有问题了。问题2:遇到文中所说的4个问题,可能是老版本内核代码有问题,对照以下一一解决即可。(除了第2个问题)https://www.anquanke.com/post/id/858374.增加syscallhttps://o0xmuhe.github.io/2017/02/08/Adding-your-own-syscall-in-linux-kernel/https://arvindsraj.wordpress.com/2012/10/05/adding-hello-world-system-call-to-linux/(1)在syscall table中添加信息文件arch/x86/kernel/syscall_table_32.S中添加自己的调用.long sys_muhe_test .long sys_hello(2)定义syscall的宏32位文件arch/x86/include/asm/unistd_32.h中添加#define __NR_hello 337 #define __NR_muhe_test 338 #ifdef __KERNEL__ #define NR_syscalls 339要注意NR_syscalls要修改成现有的调用数目,比如原来有0~336一共337个调用,现在增加了两个,那就改成339。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)添加函数定义文件include/linux/syscalls.hasmlinkage long sys_muhe_test(int arg0); asmlinkage long sys_hello(void);(4)编写syscall代码新建目录放自定义syscall的代码,./linux-2.6.32.1/muhe_test# muhe @ ubuntu in ~/linux_kernel/linux-2.6.32.1/linux-2.6.32.1/muhe_test
  $ cat 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 worldn");
  return0;
  }
  # muhe @ ubuntu in ~/linux_kernel/linux-2.6.32.1/linux-2.6.32.1/muhe_test
  $ cat Makefile
  obj-y := muhe_test.o
  
(5)修改Makefile# muhe @ ubuntu in ~/linux_kernel/linux-2.6.32.1/linux-2.6.32.1
  $ cat Makefile| grep muhe
  ifeq ($(KBUILD_EXTMOD),)
  core-y      += kernel/ mm/ fs/ ipc/ security/ crypto/ block/ muhe_test/
  
!!!!!!注意:这一句一定要修改原句“core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/”。(6)编译$ make -j2
  
5.busybox编译配置(1)编译步骤大坑:make menuconfig时一定要选择静态编译。$ make menuconfig
  $ make
  $ make install
  
(2)报错busybox1.19版本会出错,修改两处即可;用最新的1.31没报错。(2-1)问题:linux/ext2_fs.h: 没有那个文件或目录make menuconfig时 Linux System Utilities ---> 选空[ ] mkfs_ext2 和 [ ] mkfs_vfat(2-2)问题:‘RLIMIT_FSIZE’ undeclared$ vim include/libbb.h 添加#include <sys/resource.h>(3)配置(3-1)方案1$ cd _install
  $ mkdir -pv {bin,sbin,etc,proc,sys,usr/{bin,sbin}}
  $ cat init
  #!/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 # We need this to find /dev/sda later
  echo -e "nBoot took $(cut -d' ' -f1 /proc/uptime) secondsn"
  exec/bin/sh
  $ chmod +x init
  $ find . | cpio -o --format=newc > ../rootfs.cpio
  $ qemu-system-x86_64 -kernel ./arch/x86/boot/bzImage -initrd ../rootfs.cpio
  
问题:总是报错——kernel panic - not syncing no init found. try passing init= option to kernel解决:用ctf题中的clio文件就能正常运行,应该是busy box的问题。只要make menuconfig的时候选择静态编译就行(Busybox Settings -> Build Options -> Build BusyBox as a static binary),因为在这里我们希望生成的文件不对当先主机系统的共享目录产生依赖,我们希望生成的文件是静态库文件而非是动态库文件。参考http://www.dataguru.cn/thread-475271-1-1.html(3-2)方案2目录结构和之前差不多,添加inittab文件:$ cat 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
  
添加rcS文件$ cat etc/init.d/rcS
  #!/bin/sh
  #!/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
  $ chmod +x ./etc/init.d/rcS
  
配置下dev目录$ mkdir dev
  $ sudo mknod dev/ttyAMA0 c 20464
  $ sudo mknod dev/null c 13
  $ sudo mknod dev/console c 51
  $ find . | cpio -o --format=newc > ../rootfs2-1.img
  $ qemu-system-x86_64 -kernel ./arch/x86/boot/bzImage -initrd ../rootfs2-1.img-append "root=/dev/ram rdinit=/sbin/init"
  
6.测试系统调用$ cat muhe_test_syscall_lib.c
  #include<stdio.h>
  #include<linux/unistd.h>
  #include<sys/syscall.h>
  int main(int argc,char**argv)
  {
  printf("n Diving to kernel levelnn");
  syscall(300,1337);
  return0;
  }
  $ gcc muhe_test_syscall_lib.c -o muhe -static
  
一定要静态链接,因为你进busybox链接库那些是没有的。$ cp muhe_test_syscall_lib/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"
  
报错:/bin/shcan't access tty job control turned off
  
解决:https://blog.csdn.net/qq_26093511/article/details/53464468加上这一句:console::askfirst:-/bin/sh (注意:我之前写的是console::askfirst:/bin/sh,缺少了-,所以才报错)。因为,uboot的启动参数指定了console = ttySAC0 ,也就是串口控制台。所以要在/bin/sh 前加 - 。!!!注意鼠标退出QEMU界面:ctl+alt+鼠标点击保护机制关闭方法:mmap_min_addr:$ sysctl -w vm.mmap_min_addr="0"kernel canary:编辑.config文件,注释掉CONFIG_CC_STACKPROTECTOR这一行,再重新编译内核。编译driver:1.为了能够加载自己写的driver编译内核时make menuconfig -> Enable loadable module support ->Forced module loading 关闭Source checksum for all modules$ make2.编译driver时的Makefile本机编译时指向/usr/src/linux-headers-4.4.0-103-generic测试qemu时指向下载的kernel源码目录,如~/Desktop/kernel/linux-2.6.32.1/参考:https://www.anquanke.com/post/id/85837https://www.anquanke.com/post/id/85840https://www.anquanke.com/post/id/85848本文首发于先知-linux内核漏洞利用初探(1):环境配置,里面有我编译的文件。内核安全相关项目见git仓库。欢迎扫描下方二维码加入平凡路上知识星球平凡路上是二进制技术交流的圈子,致力于二进制逆向与漏洞分析的经验交流与分享。References 先知-linux内核漏洞利用初探(1):环境配置: https://xz.aliyun.com/t/6009 git仓库: https://github.com/bsauce/kernel-security-learning  往期推荐
  IO FILE之fread详解
  IO FILE之fwrite详解
  IO FILE 之fclose 详解
  IO FILE 之劫持vtable及FSOP
欢迎扫描下方二维码加入平凡路上知识星球平凡路上是二进制技术交流的圈子,致力于二进制逆向与漏洞分析的经验交流与分享。

monkeyman 发表于 2020-5-5 19:38:46

非常不错啊,感谢楼主无私的共享精神!

monkeyman 发表于 2020-5-6 16:03:02

感谢分享,我会认真学习的!
页: [1]
查看完整版本: linux内核漏洞利用初探(1):环境配置