linux-kernel expoit study (2)---添加系统调用

<–more–>

添加一个新的系统调用

添加一个系统调用的文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
$ cd ~/linux_kernel/linux-2.6.32.1/
$ mkdir swing_test
$ cd swing_test
$ cat swing_test.c
#include <linux/kernel.h>
asmlinkage long sys_swing_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;
}

$ cat Makefile
#Makefile start
obj-y := joker_test.o
#Makefile end

修改linux-2.6.32.1根目录下的Makefile
$vim ~/linux_kernel/linux-2.6.32.1/Makefile
core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/ joker_test/

添加测试目录

修改系统调用表添加一个新的系统调用

1
2
$ vim arch/x86/kernel/syscall_table_32.S
.long sys_swing_test /* 337 */

修改系统调用头文件

1
2
$ vim ./arch/x86/include/asm/unistd_32.h
#define __NR_swing_test 337

添加库文件方便测试新的系统调用接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
在linux kernel源码根目录
$ mkdir swing_test_syscall_lib
$ vim swing_test_syscall_lib.c
$ cat swing_test_syscall_lib.c
#include <stdio.h>
#include <linux/unistd.h>
#include <sys/syscall.h>

#define _swing_test_ 337

int main(int argc,char **argv)
{
printf("\n Diving to kernel level\n\n");
syscall(_swing_test_,1234);
printf("\nRising to user level\n\n");
return 0;
}
$ gcc swing_test_syscall_lib joker_test_syscall_lib.c -o swing_test_sycall -stack

由于编译的内核中,只有下面的busybox文件系统缺少必要的c库等信息,需要把上述的测试文件使用静态编译的方式

编译

make

编译busybox

busybox内核下载

我这里用的和师傅们都不一样 我用的是busybox-1.22.1 版本

编译顺序

1
$ make menuconfig

由于之前一直遇到几个错误:

  • 一个是:
    1
    2
    错误
    linux/ext2_fs.h: 没有那个文件或目录

解决

1
2
3
4

Linux System Utilities --->
[ ] mkfs_ext2
[ ] mkfs_vfat

  • 另一个是之后qemu进系统发生的错误:

    解决:
    Busybox Settings ->Build Options ->Build BusyBox as a static binary (no shared libs)

    $ make
    $ make install
    1
    2
    3
    错误
    loginutils/passwd.c:188:12: error: ‘RLIMIT_FSIZE’ undeclared (first use in this function)
    setrlimit(RLIMIT_FSIZE, &rlimit_fsize);
1
2
3
4
5
6
解决
$ vim include/libbb.h
$ add a line #include <sys/resource.h>
#include <sys/mman.h>
#include <sys/resource.h>
#include <sys/socket.h>

配置busybox

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
$ 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) seconds\n"
exec /bin/sh
$ chmod +x init
$ find . -print0 \
| cpio --null -ov --format=newc \
| gzip -9 > /tmp/initramfs-busybox-x86.cpio.gz
$ qemu-system-i386 -kernel arch/i386/boot/bzImage -initrd /tmp/initramfs-busybox-x86.cpio.gz

在qemu中测试

把编译好的静态文件添加到busybox中

1
$ cp swing_test_syscall_lib ~/linux-kernel/busybox-1.22.1/_install/usr/

这里要注意,每次拷贝新文件到busybox的文件系统中去,都要生成新的镜像

1
2
3
4
$ find . -print0 \
| cpio --null -ov --format=newc \
| gzip -9 > /tmp/initramfs-busybox-x86.cpio.gz
$ qemu-system-i386 -kernel arch/i386/boot/bzImage -initrd /tmp/initramfs-busybox-x86.cpio.gz

在qemu中测试系统调用
$ qemu-system-i386 -kernel arch/i386/boot/bzImage -initrd /tmp/initramfs-busybox-x86.cpio.gz

进入到qemu

引用

【系列分享】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