Quantcast
Channel: CodeSection,代码区,网络安全 - CodeSec
Viewing all articles
Browse latest Browse all 12749

【系列分享】Linux 内核漏洞利用教程(一):环境配置

$
0
0
【系列分享】linux 内核漏洞利用教程(一):环境配置

2017-04-05 15:53:11
来源:安全客 作者:o0xmuhe

阅读:643次
点赞(0)
收藏





【系列分享】Linux 内核漏洞利用教程(一):环境配置

作者:o0xmuhe

预估稿费:300RMB

投稿方式:发送邮件至linwei#360.cn,或登陆网页版在线投稿


0x00: 前言

一直想入门linux kernel exploit,但是网络上比较成熟的资料很少,只能找到一些slide和零碎的文档,对于入门选手来说真的很困难。还好在自己瞎摸索的过程中上了joker师傅的装甲车,师傅说:要有开源精神,要给大家学习的机会。

所以就有了这个系列的文章,第一篇记录是环境配置篇,包含了linux内核编译、添加系统调用并测试的过程。在这个过程中我还是遇到很多坑点的,踩了一段时间才把这些坑填好,成功搞定,希望我的经历能给大家一点帮助。


0x01: 环境说明


ubuntu14.04x86 qemu

使用的内核版本2.6.32.1

busybox版本1.19.4

使用busybox是因为文件添加方便.


0x02: 内核编译并测试

1. 下载内核源码

$wgethttps://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.32.1.tar.gz-Olinux-2.6.32.1.tar.gz $tar-xjvflinux-2.6.32.1.tar.gz

2. 编译过程

首先要安装一些依赖库以及qemu。

$cdlinux-2.6.32.1/ $sudoapt-getinstalllibncurses5-dev $sudoapt-getinstallqemuqemu-system $makemenuconfig $make $makeall $makemodules 3. 编译的时候遇到的问题以及解决方案

3.1 问题1

问题

Can'tuse'defined(@array)'(Maybeyoushouldjustomitthedefined()?)atkernel/timeconst.plline373. /home/muhe/linux_kernel/linux-2.6.32.1/linux-2.6.32.1/kernel/Makefile:129:recipefortarget'kernel/timeconst.h'failed make[1]:***[kernel/timeconst.h]Error255 Makefile:878:recipefortarget'kernel'failed make:***[kernel]Error2

解决方案: 尝试修改这个文件

@val=@{$canned_values{$hz}}; -if(!defined(@val)){ +if(!@val){ @val=compute_values($hz); } output($hz,@val); --

3.2 问题2

问题描述

.... arch/x86/kernel/ptrace.c:1472:17:error:conflictingtypesfor‘syscall_trace_enter’ asmregparmlongsyscall_trace_enter(structpt_regs*regs) ^ Infileincludedfrom/home/muhe/linux_kernel/linux-2.6.32.1/arch/x86/include/asm/vm86.h:130:0, from/home/muhe/linux_kernel/linux-2.6.32.1/arch/x86/include/asm/processor.h:10, from/home/muhe/linux_kernel/linux-2.6.32.1/arch/x86/include/asm/thread_info.h:22, frominclude/linux/thread_info.h:56, frominclude/linux/preempt.h:9, frominclude/linux/spinlock.h:50, frominclude/linux/seqlock.h:29, frominclude/linux/time.h:8, frominclude/linux/timex.h:56, frominclude/linux/sched.h:56, fromarch/x86/kernel/ptrace.c:11: /home/muhe/linux_kernel/linux-2.6.32.1/arch/x86/include/asm/ptrace.h:145:13:note:previousdeclarationof‘syscall_trace_enter’washere externlongsyscall_trace_enter(structpt_regs*); ^ arch/x86/kernel/ptrace.c:1517:17:error:conflictingtypesfor‘syscall_trace_leave’ asmregparmvoidsyscall_trace_leave(structpt_regs*regs) ^ Infileincludedfrom/home/muhe/linux_kernel/linux-2.6.32.1/arch/x86/include/asm/vm86.h:130:0, from/home/muhe/linux_kernel/linux-2.6.32.1/arch/x86/include/asm/processor.h:10, from/home/muhe/linux_kernel/linux-2.6.32.1/arch/x86/include/asm/thread_info.h:22, frominclude/linux/thread_info.h:56, frominclude/linux/preempt.h:9, frominclude/linux/spinlock.h:50, frominclude/linux/seqlock.h:29, frominclude/linux/time.h:8, frominclude/linux/timex.h:56, frominclude/linux/sched.h:56, fromarch/x86/kernel/ptrace.c:11: /home/muhe/linux_kernel/linux-2.6.32.1/arch/x86/include/asm/ptrace.h:146:13:note:previousdeclarationof‘syscall_trace_leave’washere externvoidsyscall_trace_leave(structpt_regs*); ^ make[2]:***[arch/x86/kernel/ptrace.o]错误1 make[1]:***[arch/x86/kernel]错误2 make:***[arch/x86]错误2

解决方案

patchpatch-p1</tmp/1.patch ---linux-2.6.32.59/arch/x86/include/asm/ptrace.h +++fix_ptrace.o_compile_error/arch/x86/include/asm/ptrace.h @@-130,6+130,7@@ ifdefKERNEL include +#include structcpuinfo_x86; structtask_struct; @@-142,8+143,8@@ interror_code,intsi_code); voidsignal_fault(structpt_regsregs,void__userframe,char*where); -externlongsyscall_trace_enter(structpt_regs); -externvoidsyscall_trace_leave(structpt_regs); +externasmregparmlongsyscall_trace_enter(structpt_regs); +externasmregparmvoidsyscall_trace_leave(structpt_regs); staticinlineunsignedlongregs_return_value(structpt_regs*regs) { 3.3 问题3

问题描述

gcc:error:elf_i386:没有那个文件或目录 gcc:error:unrecognizedcommandlineoption‘-m’

解决方案

arch/x86/vdso/Makefile VDSO_LDFLAGS_vdso.lds=-melf_x86_64-Wl,-soname=linux-vdso.so.1\-Wl,-z,max-page-size=4096-Wl,-z,common-page-size=4096把"-melf_x86_64"替换为"-m64" VDSO_LDFLAGS_vdso32.lds=-melf_i386-Wl,-soname=linux-gate.so.1中的"-melf_i386"替换为"-m32"

3.4 问题4

问题描述

drivers/net/igbvf/igbvf.h15:error:duplicatemember‘page’ structpagepage; ^ make[3]:**[drivers/net/igbvf/ethtool.o]错误1 make[2]:[drivers/net/igbvf]错误2 make[1]:[drivers/net]错误2 make:*[drivers]错误2

解决方案

//修改名字重复 struct{ structpage*_page; u64page_dma; unsignedintpage_offset; }; }; structpage*page;

0x03:增加syscall

增加syscall的方式和之前文章写的差不多,只是这次内核版本更低,所以更简单一点。我这里添加了两个系统调用进去。

1. 在syscall table中添加信息

文件 arch/x86/kernel/syscall_table_32.S中添加自己的调用

.longsys_muhe_test .longsys_hello

2. 定义syscall的宏

文件arch/x86/include/asm/unistd_32.h中添加

#define__NR_hello337 #define__NR_muhe_test338 #ifdef__KERNEL__ #defineNR_syscalls339

要注意NR_syscalls要修改成现有的调用数目,比如原来有0~336一共337个调用,现在增加了两个,那就改成339。

3. 添加函数定义

文件include/linux/syscalls.h

asmlinkagelongsys_muhe_test(intarg0); asmlinkagelongsys_hello(void);

4. 编写syscall代码

新建目录放自定义syscall的代码

#muhe@ubuntuin~/linux_kernel/linux-2.6.32.1/linux-2.6.32.1/muhe_test[2:43:06] $catmuhe_test.c #include<linux/kernel.h> asmlinkagelongsys_muhe_test(intarg0){ printk("Iamsyscall"); printk("syscallarg%d",arg0); return((long)arg0); } asmlinkagelongsys_hello(void){ printk("hellomykernelworld\n"); return0; } #muhe@ubuntuin~/linux_kernel/linux-2.6.32.1/linux-2.6.32.1/muhe_test[2:43:12] $catMakefile obj-y:=muhe_test.o

5. 修改Makefile

#muhe@ubuntuin~/linux_kernel/linux-2.6.32.1/linux-2.6.32.1[2:44:59] $catMakefile|grepmuhe core-y+=kernel/mm/fs/ipc/security/crypto/block/muhe_test/

6. 编译

make-j2

我虚拟机分配了两个核,所以使用-j2 这样能稍微快一点。


0x04: busybox编译配置

1. 编译步骤

$makemenuconfig $make $makeinstall

2. 遇到的问题

2.1 问题一以及解决方案

错误

loginutils/passwd.c:188:12:error:‘RLIMIT_FSIZE’undeclared(firstuseinthisfunction) setrlimit(RLIMIT_FSIZE,&rlimit_fsize);

解决

$viminclude/libbb.h $addaline#include<sys/resource.h> #include<sys/mman.h> #include<sys/resource.h> #include<sys/socket.h>

2.2 问题二以及解决方案

错误

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

解决

LinuxSystemUtilities---> []mkfs_ext2 []mkfs_vfat

3. 编译完成之后如下配置

1. 方案1

$cd_install $mkdir-pv{bin,sbin,etc,proc,sys,usr/{bin,sbin}} $catinit #!/bin/sh echo"INITSCRIPT" mount-tprocnone/proc mount-tsysfsnone/sys mount-tdebugfsnone/sys/kernel/debug mkdir/tmp mount-ttmpfsnone/tmp mdev-s#Weneedthistofind/dev/sdalater echo-e"\nBoottook$(cut-d''-f1/proc/uptime)seconds\n" exec/bin/sh $chmod+xinit $find.-print0\ |cpio--null-ov--format=newc\ |gzip-9>/tmp/initramfs-busybox-x86.cpio.gz $qemu-system-i386-kernelarch/i386/boot/bzImage-initrd/tmp/initramfs-busybox-x86.cpio.gz
【系列分享】Linux 内核漏洞利用教程(一):环境配置

2. 方案2

后面为了方便,使用了另一种方式:

目录结构和之前差不多,添加inittab文件:

$catetc/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文件

$catetc/init.d/rcS #!/bin/sh #!/bin/sh mount-tprocnone/proc mount-tsysnone/sys /bin/mount-n-tsysfsnone/sys /bin/mount-tramfsnone/dev /sbin/mdev- $chmod+x./etc/init.d/rcS

配置下dev目录

mkdirdev sudomknoddev/ttyAMA0c20464 sudomknoddev/nullc13 sudomknoddev/consolec51 $find.|cpio-o--format=newc>../rootfs.img $qemu-system-i386-kernelarch/i386/boot/bzImage-initrd../busybox-1.19.4/rootfs.img-append"root=/dev/ramrdinit=/sbin/init"
【系列分享】Linux 内核漏洞利用教程(一):环境配置

0x05: 测试系统调用


#muhe@ubuntuin~/linux_kernel/linux-2.6.32.1/linux-2.6.32.1[2:45:04] $cdmuhe_test_syscall_lib #muhe@ubuntuin~/linux_kernel/linux-2.6.32.1/linux-2.6.32.1/muhe_test_syscall_lib[2:51:48] $catmuhe_test_syscall_lib.c #include<stdio.h> #include<linux/unistd.h> #include<sys/syscall.h> intmain(intargc,char**argv) { printf("\nDivingtokernellevel\n\n"); syscall(337,1337); return0; } #muhe@ubuntuin~/linux_kernel/linux-2.6.32.1/linux-2.6.32.1/muhe_test_syscall_lib[2:51:51] $gccmuhe_test_syscall_lib.c-omuhe-static

一定要静态链接,因为你进busybox链接库那些是没有的。

#muhe@ubuntuin~/linux_kernel/linux-2.6.32.1/linux-2.6.32.1/muhe_test_syscall_lib[2:52:20] $cpmuhe_test_syscall_lib/muhe../busybox-1.19.4/_install/usr/muhe

这里要注意,每次拷贝新文件到busybox的文件系统中去,都要执行find . | cpio -o --format=newc > ../rootfs.img去生成新的rootfs。

然后qemu起系统

#muhe@ubuntuin~/linux_kernel/linux-2.6.32.1/linux-2.6.32.1[2:53:33] $qemu-system-i386-kernelarch/i386/boot/bzImage-initrd../busybox-1.19.4/rootfs.img-append"root=/dev/ramrdinit=/sbin/init"
【系列分享】Linux 内核漏洞利用教程(一):环境配置

0x06:引用与参考

adding-hello-world-system-call-to-linux

Adding a new system call to the Linux kernel

Adding a system call in X86 QEMU Environment

Create a simple file system

Setup for linux kernel dev using qemu

root-file-system-for-embedded-system


【系列分享】Linux 内核漏洞利用教程(一):环境配置
【系列分享】Linux 内核漏洞利用教程(一):环境配置
本文由 安全客 原创发布,如需转载请注明来源及本文地址。
本文地址:http://bobao.360.cn/learning/detail/3700.html

Viewing all articles
Browse latest Browse all 12749

Trending Articles