WCTF刚结束,有很多知识树需要点,内核、浏览器、windows下的pwn、堆…

先从linux内核的pwn开始吧,这篇主要记录一下环境和调试。

编译内核

wgets下载源码,编译

1
2
make menuconfig
make bzImage

之后在./arch/x86/boot/下拿到bzImage,源码目录下拿到vmlinux。

添加syscall

  • 源码根目录创建helloworld文件夹,添加hello.c和Makefile
  • 编辑源码根目录下的Makefile,添加helloworld/
  • 编辑include/linux/syscalls.h添加函数原型
  • 编辑arch/x86/entry/syscalls/syscall_32.tbl和arch/x86/entry/syscalls/syscall_64.tbl添加系统调用号
  • make bzImage编译内核

编译busybox

拿到源码编译安装

1
2
make menuconfig
make nstall -j4

编译完之后的_install目录就是文件系统的根目录

1
2
3
4
5
cd _install
mkdir proc
mkdir sys
touch init
chmod +x init

init内容:

1
2
3
4
5
6
7
8
9
10
11
12
#!/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

再写一个package脚本用于打包:

1
2
3
#!/bin/sh
echo "Generate rootfs.img"
find . | cpio -o --format=newc > ./rootfs.img

运行后在当前目录生成rootfs.img。

启动qemu

将rootfs.img、boot.sh、bzImage放在同一目录下:

1
2
3
4
5
6
.
├── boot.sh
├── bzImage
└── rootfs.img

0 directories, 3 files

其中boot.sh的内容为:

1
2
3
4
5
6
7
8
9
10
11
12
13
#! /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即可。

加载ko

在busybox的init文件中加入insmod ko的名称:

1
2
3
4
5
6
7
8
9
10
11
12
#!/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 /hello.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

调试ko

一般会加入nokaslr。注销boot.sh的最后两行,就可以用gdb连接。使用脚本进行连接:

1
2
3
4
5
6
7
8
#!/bin/sh
gdb \
-ex "target remote localhost:1234" \
-ex "continue" \
-ex "disconnect" \
-ex "set architecture i386:x86-64:intel" \
-ex "target remote localhost:1234" \
-ex "add-symbol-file ./busybox/baby.ko 0xdeadbeef" \

其中add-symbol-file后面的地址通过lsmod得到。

Ref