查看: 160|回复: 2

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

[复制链接]
发表于 2020-5-4 11:34:55 | 显示全部楼层 |阅读模式

主要记录一下学习muhe师傅的系列教程,记录其中的坑点。muhe师傅的教程是在32位ubuntu环境下测试的,本文是在64位环境下测试,有很多地方需要修改,故记录本文,以供后来者学习。
附件在文末下载。
环境说明:
内核版本2.6.32.1
busybox版本1.19.4
gcc版本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.tuna.tsinghua.edu.cn/kernel/
# 最好还是从国内镜像上下载
  $ wget [url]https://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.32.1.tar.gz[/url] -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 directory
include/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/85837
4.增加syscall
https://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中添加自己的调用
[size=1em].long sys_muhe_test .long sys_hello
(2)定义syscall的宏32位
文件arch/x86/include/asm/unistd_32.h中添加
[size=1em]#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
[size=1em]#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.h
[size=1em]asmlinkage 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 [2:43:06]
  $ 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 [2:43:12]
  $ cat Makefile
  obj-y := muhe_test.o
  

(5)修改Makefile
# muhe @ ubuntu in ~/linux_kernel/linux-2.6.32.1/linux-2.6.32.1 [2:44:59]
  $ 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),因为在这里我们希望生成的文件不对当先主机系统的共享目录产生依赖,我们希望生成的文件是静态库文件而非是动态库文件。
(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/sh  can'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
$ make
2.编译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/85837
https://www.anquanke.com/post/id/85840
https://www.anquanke.com/post/id/85848
本文首发于先知-linux内核漏洞利用初探(1):环境配置[1],里面有我编译的文件。内核安全相关项目见git仓库[2]。
欢迎扫描下方二维码加入平凡路上知识星球
平凡路上是二进制技术交流的圈子,致力于二进制逆向与漏洞分析的经验交流与分享。
References
[1] 先知-linux内核漏洞利用初探(1):环境配置: https://xz.aliyun.com/t/6009[2] git仓库: https://github.com/bsauce/kernel-security-learning
  往期推荐
  IO FILE之fread详解
  IO FILE之fwrite详解
  IO FILE 之fclose 详解
  IO FILE 之劫持vtable及FSOP
欢迎扫描下方二维码加入平凡路上知识星球
平凡路上是二进制技术交流的圈子,致力于二进制逆向与漏洞分析的经验交流与分享。



温馨提示:
1.如果您喜欢这篇帖子,请给作者点赞评分,点赞会增加帖子的热度,评分会给作者加学币。(评分不会扣掉您的积分,系统每天都会重置您的评分额度)。
2.回复帖子不仅是对作者的最好奖励,还可以获得学币奖励,请尊重作者的劳动成果,拒绝做伸手党!
3.发广告、灌水回复等违规行为一经发现直接禁言,如果本帖内容涉嫌违规,请点击论坛底部的举报反馈按钮,也可以在【投诉建议】板块发帖举报。
论坛交流群:672619046

0

主题

182

帖子

0

精华

解密专家

Rank: 16

学币
486
荣耀
0
rank
0
违规
0

神出鬼没

    发表于 2020-5-5 19:38:46 | 显示全部楼层
    非常不错啊,感谢楼主无私的共享精神!
    学逆向论坛-免费的逆向学习论坛

    0

    主题

    182

    帖子

    0

    精华

    解密专家

    Rank: 16

    学币
    486
    荣耀
    0
    rank
    0
    违规
    0

    神出鬼没

      发表于 2020-5-6 16:03:02 | 显示全部楼层
      感谢分享,我会认真学习的!
      学逆向论坛-免费的逆向学习论坛
      微信公众号
      快速回复 返回顶部 返回列表