赞
踩
照着师傅们的教程弄的,顺便记录一些自己遇到的问题
编译内核 or 下载内核
自己编译内核
安装所需要的依赖
sudo apt-get update
sudo apt-get install git fakeroot build-essential ncurses-dev xz-utils libssl-dev bc
解压源码,然后在源码目录
make menuconfig
进入kernel hacking
勾选以下项目
Kernel debugging
Compile-time checks and compiler options —> Compile the kernel with debug info和Compile the kernel with frame pointers
KGDB
然后保存退出
但基本上都默认保存了,所以检查一下然后退出就好了
生成kernel binary
make bzImage
等一段时间就会出现如下信息,就意味着编译成功,然后从/arch/x86/boot/拿到bzImage,从源码根目录拿到vmlinux
Setup is 17436 bytes (padded to 17920 bytes).
System is 6797 kB
CRC c4c988d7
Kernel: arch/x86/boot/bzImage is ready (#1)
☁ linux-4.4.72 file vmlinux
vmlinux: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, BuildID[sha1]=d1f415bda5dcb18a110c0c741a0b4d69ebcee3a7, not stripped
☁ linux-4.4.72 cd arch/x86/boot
☁ boot file bzImage
bzImage: Linux kernel x86 boot executable bzImage, version 4.4.72 (hacker_mao@hacker-virtual-machine) #1 SMP Sat Jan 5 19:, RO-rootFS, swap_dev 0x6, Normal VGA
利用apt直接下载内核文件及源码
下载源码
先按照版本号搜索,例如4.15.0-22版本的
apt search linux-headers-4.15.0-22-
然后安装
sudo apt install linux-headers-4.15.0-22 linux-headers-4.15.0-22-generic
安装成功后就会在/usr/src目录下有源码了,4.4.0-21是本机的
☁ boot cd /usr/src
☁ src ls
linux-headers-4.15.0-22 linux-headers-4.15.0-22-generic linux-headers-4.4.0-21 linux-headers-4.4.0-21-generic
下载内核文件
同样先搜索各个版本的内核
sudo apt search linux-image-
然后再下载自己所需要版本的内核
apt download xxxx
下载下来是deb,我们解压之后在/data/boot文件夹下可以找到我们所需的内核镜像文件vmlinuz-4.15.0-22-generic,一般名字都是vmlinuz开头的
添加syscall
这里我们也跟着501师傅的教程在4.4.72版本的内核复现一下添加syscall的操作
源码根目录下创建helloworld目录,并在helloworld目录下添加两个文件
☁ linux-4.4.72 mkdir helloworld
☁ linux-4.4.72 cd helloworld
☁ helloworld touch helloworld.c
☁ helloworld touch Makefile
//helloworld.c
#include
asmlinkage long sys_helloworld(void){
printk("{==kernel==} hello world\n");
return 0;
}
//Makefile
obj-y=helloworld.o
编辑源码根目录下的Makefile,添加helloworld/
编辑include/linux/syscalls.h,添加函数原型
asmlinkage long sys_helloworld(void);
编辑arch/x86/entry/syscalls/syscall_32.tbl和arch/x86/entry/syscalls/syscall_64.tbl,添加系统调用号
//syscall_32.tbl
1337 i386 helloworld sys_helloworld
//syscall_64.tbl
1337 common helloworld sys_helloworld
编译kernel,然后在./arch/x86/boot/下获得新bzImage
make bzImage
编译成功
Setup is 17436 bytes (padded to 17920 bytes).
System is 6800 kB
CRC a4eb3388
Kernel: arch/x86/boot/bzImage is ready (#2)
编译busybox
解压源码,然后在根目录下
make menuconfig
进Settings,勾上Build static binary (no shared libs)
编译
make install -j4
编译完成后根目录多了一个_install的目录,这就是编译的结果,然后
cd _install
mkdir proc
mkdir sys
touch init
chmod +x init
touch packet
在init中写入下面内容,用于内核初始化,其中insmod用于将指定模块加载到内核中
#!/bin/sh
echo "{==DBG==} INIT SCRIPT"
mkdir /tmp
mount -t proc none /proc
mount -t sysfs none /sys
mount -t debugfs none /sys/kernel/debug
mount -t tmpfs none /tmp
# insmod /xxx.ko # load ko
mdev -s # We need this to find /dev/sda later
echo -e "{==DBG==} Boot took $(cut -d' ' -f1 /proc/uptime) seconds"
setsid /bin/cttyhack setuidgid 1000 /bin/sh #normal user
# exec /bin/sh #root
在packet中写入,用于将FileSystem打包成映像
#!/bin/sh
echo "Generate rootfs.img"
find . | cpio -o --format=newc > ./rootfs.img
编译ko文件
在kernel源码目录下创建一个新的文件夹
☁ linux-4.4.72 mkdir test_ko
☁ linux-4.4.72 cd test_ko
☁ test_ko touch hello.c
☁ test_ko touch Makefile
在hello.c和Makefile中写入东西,写Makefile的时候注意要使用Tab而不是空格
//hello.c
#include
#include
#include
#include
MODULE_LICENSE("Dual BSD/GPL");
struct cred c1;
static int hello_init(void)
{
printk("<1> Hello world!\n");
printk("size of cred : %d \n",sizeof(c1));
return 0;
}
static void hello_exit(void)
{
printk("<1> Bye, cruel world\n");
}
module_init(hello_init);
module_exit(hello_exit);
//Makefile
obj-m := hello.o
KERNELDR := /home/hacker_mao/desktop/kernel_pwn/linux-4.4.72
PWD := $(shell pwd)
modules:
$(MAKE) -C $(KERNELDR) M=$(PWD) modules
moduels_install:
$(MAKE) -C $(KERNELDR) M=$(PWD) modules_install
clean:
rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions
编译ko文件
make
编译成功,会出现hello.ko文件
☁ test_ko make
make -C /usr/src/linux-headers-4.15.0-22-generic M=/home/hacker_mao/desktop/kernel_pwn/linux-4.4.72/test_ko modules
make[1]: Entering directory '/usr/src/linux-headers-4.15.0-22-generic'
CC [M] /home/hacker_mao/desktop/kernel_pwn/linux-4.4.72/test_ko/hello.o
Building modules, stage 2.
MODPOST 1 modules
CC /home/hacker_mao/desktop/kernel_pwn/linux-4.4.72/test_ko/hello.mod.o
LD [M] /home/hacker_mao/desktop/kernel_pwn/linux-4.4.72/test_ko/hello.ko
make[1]: Leaving directory '/usr/src/linux-headers-4.15.0-22-generic'
☁ test_ko file hello.ko
hello.ko: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), BuildID[sha1]=1aa1e7d97868119d05876707c472a92a877048fa, not stripped
启动系统
将编译好的hello.ko放到busybox的_install目录下
再写个demo测试前面添加的syscall,将demo也放在_install目录下
//gcc test.c -static -o test
#include
int main(void){
syscall(1337);
return 0;
}
将FileSystem打包成映像
./packet
将生成的rootfs.img和编译的内核bzImage文件放在同一文件夹下,新建一个启动脚本boot.sh
#! /bin/sh
qemu-system-x86_64 \
-m 128M \
-kernel ./bzImage \
-initrd ./rootfs.img \
-append "root=/dev/ram rw oops=panic panic=1 kalsr" \
-netdev user,id=t0, -device e1000,netdev=t0,id=nic0 \
-monitor /dev/null \
-smp cores=2,threads=1 \
-cpu kvm64,+smep \
#-gdb tcp::1234 \
#-S
启动内核
./boot.sh
编译的syscall和hello.ko都生效了
通过lsmod命令还可以查看已加载的modul
调试ko
这里按照gdb调试内核模块的操作来,首先下载相关文件
在自己的内核源码根目录下拷贝vmlinux文件到arbitrarily_write文件夹下
启动内核,并安装模块
./start.sh
./mknod.sh
su hac425
为了调试内核模块,还需要加载驱动的符号文件,首先在系统里面获取驱动的加载基地址
/ $ cat /proc/modules | grep arb
arbitrarily_write 2168 0 - Live 0xffffffffa0000000 (O)
启动gdb,加载符号文件和驱动,对驱动的函数下断点
gdb -q ./vmlinux
pwndbg> target remote 127.0.0.1:1234
pwndbg> add-symbol-file ./arbitrarily_write.ko 0xffffffffa0000000
pwndbg> b arw_ioctl
pwndbg> c
这时候在系统运行test文件
./test
这时候gdb就会断在我们下断点的函数
参考文章:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。