主要记录一下学习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.下载源码# 最好还是从国内镜像上下载
$ 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.增加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中添加自己的调用 [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)编译
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
欢迎扫描下方二维码加入平凡路上知识星球 平凡路上是二进制技术交流的圈子,致力于二进制逆向与漏洞分析的经验交流与分享。
|