内核调试环境搭建 |
您所在的位置:网站首页 › ubuntu中下载安装binwalk › 内核调试环境搭建 |
内核调试环境搭建
目录
经过测试好用的内核调试环境搭建过程ubuntu和linux版本
查看commit所属的内核版本查看Ubuntu版本号等信息 下载与安装内核
下载内核ubuntu更换内核手动下载并切换到指定源码用apt下载源码使用git下载对应版本 编译并安装linux内核(使用linux-5.15.10版本)
得到Ubuntu内核需要的编译选项常用的内核编译选项查看已有操作系统的编译选项源码编译Ubuntu内核得到有调试信息的源码编译结果查看编译结果 qemu的安装和使用
安装qemu使用 创建文件系统
文件系统的操作编译文件系统用busybox创建文件系统用别人创建的initrd(文件系统) 用文件系统启动内核
启动内核启动调试文件共享 调试技巧
关于符号信息的坑关于源代码安装vmlinux调试信息 调试qemu的Ubuntu虚拟机
创建qemu虚拟机qemu虚拟机和主机互通关闭kaslr(添加内核启动选项)(否则断点断不下来) 调试vmware虚拟机
启用调试问题vmware双机调试(用串口) 编译内核模块其他
参考 利用qemu+gdb在ubuntu下搭建调试kernel的环境 - EwanHai - 博客园 (cnblogs.com) 经过测试好用的内核调试环境搭建过程 1、使用qemu创建Ubuntu虚拟机2、使用git下载对应版本 获取源码3、源码编译Ubuntu内核 得到deb包4、qemu虚拟机和主机互通 传输文件5、Ubuntu更换内核 安装deb包6、关闭kaslr7、调试技巧在很多情况下,只使用linux内核加文件系统不能得到漏洞依赖的环境 VMware虚拟机调试方便,但是在进行测试时虚拟机会崩溃关机。 用make方式编译安装Ubuntu内核可能会有一些内核选项没有开启,导致Ubuntu黑屏,用官方提供的方式编译成deb包是很稳定的。 用apt安装内核调试信息的方法,调试信息和源码很可能对应不上,自己编译安装是最稳妥的方式。 ubuntu和linux版本https://blog.csdn.net/Breeze_CAT/article/details/123787636 举例:linux版本5.15.5 目前发布的主版本,增长很缓慢,通常后面的数字比较大了的时候该数字会增长。次版本号,表示稳定的版本号。修订版本号,代表改版本补丁次数,在下一个稳定版本发布之前出现补丁和修复会更新该版本号。非长期维护版本一般20多个。很久之前内核通过版本号中的第二个数字即B的奇偶来表示稳定版和预发布版。但现在已经取消这个规则,现在预发布版用-rcX来表示如5.17-rc3,X为数字,一般不超过rc8 长期维护版本:5.15、5.10、5.4、4.19、4.14、4.9 查看commit所属的内核版本如 kernel/git/torvalds/linux.git - Linux kernel source tree 查看tree中根目录下的Makefile文件可以看到对应的版本号 查看Ubuntu版本号等信息 cat /etc/issue Ubuntu 20.04.2 LTS \n \l 或 lsb_release -a 命令 No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 20.04.2 LTS Release: 20.04 版本 Codename: focal 别名 查看Ubuntu信息 ➜ uname -a Linux tower-virtual-machine 5.15.0-71-generic #78~20.04.1-Ubuntu SMP Wed Apr 19 11:26:48 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux ➜ uname -r 5.15.0-71-generic 内核版本 5.15表示内核稳定版本号,一般ubuntu中最后小修订号都是0,因为ubuntu会自己合入补丁。 71表示由ubuntu进行的第35次修订(合入补丁)。 generic:通用版本,除此之外还可能有服务器版server或老式处理器的i386版等。Ubuntu对应的别名 Ubuntu使用的内核 经过测试,其他版本的内核是可以安装的(如 focal系列的Ubuntu内核代码编译之后可以安装到Ubuntu18主机上)(没有经过更多测试) 下载与安装内核 下载内核下载ubuntu https://mirrors.aliyun.com/oldubuntu-releases/releases/20.04.0/?spm=a2c6h.25603864.0.0.10467ff3XF6iMS 阿里云镜像 https://old-releases.ubuntu.com/releases/ Ubuntu官方镜像 下载Ubuntu内核 https://kernel.ubuntu.com/~kernel-ppa/mainline/v5.15.10/ 较粗的deb包 下载linux内核源码 https://mirrors.edge.kernel.org/pub/linux/kernel/v5.x/ 版本比较粗 kernel/git/torvalds/linux.git - Linux kernel source tree Linux源码 Kernel/Dev/KernelGitGuide - Ubuntu Wiki Ubuntu内核源码 找到对应的源码: git tag | grep 4.10.0-19 git checkout ubuntu-4.10.0-19........ ubuntu更换内核 下载对应image和modulessudo dpkg -i *.deb重启或使用apt更换内核 sudo apt search 'linux-image-5.4.0-81-generic' sudo apt install 'linux-image-5.4.0-81-generic' 更新并重启 sudo update-initramfs -u -k all sudo update-grub reboot 安装新版本内核头文件,用于开发编译 sudo apt install linux-headers-$(uname -r)开机按esc选择选高级,找到对应版本内核启动 如果进不去需要修改引导启动信息: 修改文件/etc/default/grub 注释掉GRUB_TIMEOUT_STYLE=hidden 修改GRUB_TIMEOUT=0为GRUB_TIMEOUT=10 执行sudo update-grub启用修改 reboot 重启时会进入引导界面等待选择内核 手动下载并切换到指定源码https://bbs.kanxue.com/thread-249192.htm 在https://wiki.ubuntu.com/Kernel/Dev/KernelGitGuide选择对应的Ubuntu系列 查看主机的Ubuntu系列(这里需要下载被调试主机的源码) ➜ CVE-2021-3493 git:(main) ✗ cat /etc/apt/sources.list deb http://mirrors.aliyun.com/ubuntu/ focal main restricted universe multiverse如Ubuntu20可以下载 git clone https://git.launchpad.net/~ubuntu-kernel/ubuntu/+source/linux/+git/focal git tag | grep 4.10.0-19 git checkout ubuntu-4.10.0-19........gdb中指定源代码路径,或把source文件直接拷贝到gdb检测源码的目录(如/build/linux-kcrkKx/linux-5.4.0) set substitute-path PATH1 PATH2,PATH1是vmlinux中的路径信息,PATH2是source code存放的真实路径。 用apt下载源码 apt source linux-image-unsigned-5.11.0-44-generic # 版本号根据需求更改,可以用apt search搜索ubuntu 内核git:https://kernel.ubuntu.com/git/ubuntu/ 使用git下载对应版本可以查看分支名https://kernel.ubuntu.com/git/ubuntu/ubuntu-focal.git/refs/tags git clone git://kernel.ubuntu.com/ubuntu/ubuntu-focal.git -b Ubuntu-hwe-5.13-5.13.0-35.40_20.04.1 --depth 1 编译并安装linux内核(使用linux-5.15.10版本) make ARCH=x86_64 x86_64_defconfig make ARCH=x86_64 menuconfig 配置 Kernel-hacking -> Compile-time checks and compiler options Compile the kernel with debug info —> Provide GDB scripts for kernel debugging 关闭 Reduce debugging information make -j8 sudo make modules_install 安装模块 sudo make install 安装 sudo update-initramfs -c -k 5.3.10 启用(数字为版本号) sudo update-grub 更新grub reboot也可以使用docker编译https://registry.hub.docker.com/r/chenaotian/kernelcompile(编译5.x) docker run -ti --rm -h kc --name kc -v D:/share:/work chenaotian/kernelcompile:latest /bin/bash docker exec -it kc /bin/bash 得到Ubuntu内核需要的编译选项 常用的内核编译选项 # 设置调试符号 CONFIG_DEBUG_INFO=y # fuse 开启,一些漏洞利用会用到 CONFIG_FUSE_FS=y # VIPC 开启,可以使用msg系列 CONFIG_SYSVIPC=y CONFIG_SYSVIPC_SYSCTL=y CONFIG_SYSVIPC_COMPAT=y CONFIG_CHECKPOINT_RESTORE=y # 设置这个才能正确调用msg 里的copy 系列函数 查看已有操作系统的编译选项 cat /usr/src/linux-headers-`uname -r`/.config 或 cat /boot/config-`uname -r` 源码编译Ubuntu内核Kernel/BuildYourOwnKernel - Ubuntu Wiki 安装依赖 sudo apt-get build-dep linux sudo apt-get install libncurses-dev gawk flex bison openssl libssl-dev dkms libelf-dev libudev-dev libpci-dev libiberty-dev autoconf llvm编译 LANG=C fakeroot debian/rules clean LANG=C fakeroot debian/rules binary-headers binary-generic binary-perarch 快速编译 # if you need linux-tools or lowlatency kernel, run instead: 会多出来更多东西 LANG=C fakeroot debian/rules binary 得到有调试信息的源码编译结果 sudo apt-get install pkg-config-dbgsym LANG=C fakeroot debian/rules clean LANG=C fakeroot debian/rules binary-headers binary-generic binary-perarch skipdbg=false 查看编译结果System.map 文件可以查看一些关键函数有没有 cat System.map |grep function_name查看字符串 strings vmlinux |grep function_name qemu的安装和使用 安装qemu sudo apt-get install qemu qemu-system 使用常用的启动脚本 #! /bin/sh cd ./rootfs find . | cpio -o --format=newc > ../rootfs.img cd ../ qemu-system-x86_64 \ -m 512M \ -kernel ./bzImage \ -initrd ./rootfs.img \ -nographic \ -append "console=ttyS0 root=/dev/sda rw nokaslr quiet" \ -netdev user,id=t0, -device e1000,netdev=t0,id=nic0 \ -cpu kvm64,+smep,+smap \ -gdb tcp::10086 创建文件系统 文件系统的操作解包和打包 cpio -idmv ../rootfs.img #打包cpio有可能在外层更进行了一次gzip压缩,使用binwalk可以可以解包 binwalk -Me ./rootfs.img如果一定需要动态链接的exp,偷懒方法就是,ldd 查看exp 需要的动态库,然后将ld-linux-x86-64.so.2 和其他依赖的so全部拷贝到文件系统中,qemu 启动后,用LD_LIBRARY_PATH 来运行 将其依赖的so全部拷贝到一个文件夹内然后放入rootfs中制作成initrd.img,然后启动qemu,按照如下方法运行 cp ...so ./rootfs/exp #将so 拷贝到制作initrd.img的目录中 cd ./rootfs find . | cpio -o --format=newc > ../rootfs.img #制作initrd.img cd ../ ./boot.sh #启动qemu # qemu 启动后 cd /expdir export LD_LIBRARY_PATH=`pwd` ./ld-linux-x86-64.so.2 ./exploit 编译文件系统使用busybox构建文件系统比较复杂,用buildroot相对简单 git clone git://git.buildroot.net/buildroot cd buildroot make menuconfig 在跳出的UI界面依次选择Target options Target Architecture (x86_64) 在x86_64上按空格键,以选择该选项 再返回与Target options同一级的界面选择Filesystem images 在ext2/3/4 root filesystem按Y,并进入ext2/3/4 variant (ext4)选择ext4 make -j4 用busybox创建文件系统 wget https://busybox.net/downloads/busybox-1.35.0.tar.bz2 tar -jxvf busybox-1.35.0.tar.bz2 cd busybox-1.35.0 make defconfig make menuconfig选择settings中选择静态链接 make install会把文件拷贝到当前目录下的 _install目录 拷贝文件,创建init mkdir ramdisk cd ramdisk cp -r ../busy-1.25.0/_install/* . cd ramdisk ln -s bin/busybox init设置启动程序,init程序首先会访问etc/inittab文件,以获取开机要启动的程序列表,因此我们得编写一个inittab cd etc vim inittab ::sysinit:/etc/init.d/rcS ::askfirst:-/bin/sh ::restart:/sbin/init ::ctrlaltdel:/sbin/reboot ::shutdown:/bin/umount -a -r ::shutdown:/sbin/swapoff -a chmod +x etc/inittab系统初始化寻找etc/init.d/rcS,需要创建,内容添加 #!/bin/sh mount proc mount -o remount,rw / mount -a clear echo "My Tiny Linux Start :D ......"并加权限 chmod +x rcSrcS中,mount -a 是自动挂载 /etc/fstab 中的内容,因此我们需要一个fstab文件,以设置需要挂载的系统, 创建文件并添加内容 proc /proc proc defaults 0 0 sysfs /sys sysfs defaults 0 0 devtmpfs /dev devtmpfs defaults 0 0最后把文件压缩成镜像 cd ramdisk find . -print0 | cpio --null -ov --format=newc | gzip -9 > ../initramfs.img cpio --null或-0接受新增列控制字符,通常配合find指令的"-print0"参数使用。 -o或--create 执行copy-out模式,建立备份档。 -v或--verbose 详细显示指令的执行过程。 newc 新型 (SVR4) 跨平台格式, 支持大于 65536 i节点的文件系统,一般 制作 ramdisk 就用 这个 格式 -9 表示压缩率 用别人创建的initrd(文件系统) 用文件系统启动内核 启动内核使用buildroot编译的镜像 qemu-system-x86_64 -kernel bzImage -boot c -m 1024 -hda rootfs.ext2 -append "root=/dev/sda rw console=ttyS0, 115200 acpi=off nokaslr" -serial stdio -display none -s -S使用busybox构建的镜像启动命令 # 在A Terminal中运行以下命令 qemu-system-x86_64 -kernel bzImage -boot c -m 1024 -initrd initramfs.img -append "root=/dev/sda rw console=ttyS0, 115200 acpi=off nokaslr" -serial stdio -display none -s -S如果需要调试内核的kvm模块,则向上述命令添加 -enable-kvm 启动调试 gdb vmlinux target remote localhost:1234 文件共享把自己的文件放入文件系统 如果使用busybox创建文件系统,直接把文件拷贝到对应目录,执行命令把文件打包成镜像 find . -print0 | cpio --null -ov --format=newc | gzip -9 > ../initramfs.img 如果使用buildroot构建镜像,添加自定义文件到文件系统System configuration菜单下选择 Custom scripts to run before creating filesystem images写入命令,把文件拷贝到对应目录output/target目录下 ,在测试的时候报错命令出错。编译过之后,直接用手动拷贝文件到output/target然后再执行一次make -j4 得到的镜像内部有需要的文件 调试技巧 关于符号信息的坑vmlinux文件可能不包含一些符号,如图 原因是ovlerlay文件系统被编译成了内核模块文件,需要手动添加 gef➤ add-symbol-file ./fs/overlayfs/overlay.ko 0xffffffffc04ee000查看内核模块加载地址(内核模块被加载了之后才能看到,可能需要先执行一次相关的命令或执行相关的poc) cat /proc/modules 关于源代码用docker编译的内核会从docker中的路径寻找二进制源码,在调试时会出现找不到源码的情况 gef➤ list 46 in /work/ubuntu-focal/arch/x86/include/asm/irqflags.h用set命令重定位源码目录即可 set substitute-path /work/ubuntu-focal /home/tower/aiwencode/vul/CVE-2023-0386/ubuntu-focal 安装vmlinux调试信息Ubuntu内核默认不包含调试信息 安装内核调试信息 https://developer.aliyun.com/article/899339 获取Ubuntu内核调试信息 https://bbs.kanxue.com/thread-249192.htm cat /boot/config-uname -r| grep -i "GDB"查看当前内核是否支持KGDB 增加符号对应的源文件 codename=$(lsb_release -c | awk '{print $2}') sudo tee /etc/apt/sources.list.d/ddebs.list void *device_buf; size_t device_buf_len; }babydev_struct; module_init(kernel_module_init); module_exit(kernel_module_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("arttnba3"); static int __init kernel_module_init(void) { spin_lock_init(&spin); printk(KERN_INFO "[arttnba3_TestModule:] Module loaded. Start to register device...\n"); major_num = register_chrdev(0, DEVICE_NAME, &a3_module_fo); if(major_num unregister_chrdev(major_num, DEVICE_NAME); printk(KERN_INFO "[arttnba3_TestModule:] Failed to register class device!\n"); return PTR_ERR(module_class); } printk(KERN_INFO "[arttnba3_TestModule:] Class device register complete.\n"); module_device = device_create(module_class, NULL, MKDEV(major_num, 0), NULL, DEVICE_NAME); if(IS_ERR(module_device)) { class_destroy(module_class); unregister_chrdev(major_num, DEVICE_NAME); printk(KERN_INFO "[arttnba3_TestModule:] Failed to create the device!\n"); return PTR_ERR(module_device); } printk(KERN_INFO "[arttnba3_TestModule:] Module register complete.\n"); return 0; } static void __exit kernel_module_exit(void) { printk(KERN_INFO "[arttnba3_TestModule:] Start to clean up the module.\n"); device_destroy(module_class, MKDEV(major_num, 0)); class_destroy(module_class); unregister_chrdev(major_num, DEVICE_NAME); printk(KERN_INFO "[arttnba3_TestModule:] Module clean up complete. See you next time.\n"); } static long a3_module_ioctl(struct file * __file, unsigned int cmd, long unsigned int param) { if (cmd == 65537) { kfree(babydev_struct.device_buf); babydev_struct.device_buf = kmalloc(param, GFP_ATOMIC); babydev_struct.device_buf_len = param; printk(KERN_INFO "alloc done\n"); return 0; } else { printk(KERN_INFO "default arg is %ld\n", param); return -22; } } static int a3_module_open(struct inode * __inode, struct file * __file) { babydev_struct.device_buf = kmalloc(0x40, GFP_ATOMIC); babydev_struct.device_buf_len = 0x40; printk(KERN_INFO "device open\n"); return 0; } static int a3_module_release(struct inode * __inode, struct file * __file) { kfree(babydev_struct.device_buf); printk(KERN_INFO "device release\n"); return 0; } static ssize_t a3_module_read(struct file * __file, char __user * user_buf, size_t size, loff_t * __loff) { size_t result; if (!babydev_struct.device_buf) return -1LL; result = -2LL; if (babydev_struct.device_buf_len > size) { copy_to_user(user_buf, babydev_struct.device_buf, size); result = size; } return result; } static ssize_t a3_module_write(struct file * __file, const char __user * user_buf, size_t size, loff_t * __loff) { size_t result; if (!babydev_struct.device_buf ) return -1LL; result = -2LL; if ( babydev_struct.device_buf_len > size) { copy_from_user(babydev_struct.device_buf, user_buf, size); result = size; } return result; } 其他查看内核支持的选项 grep CONFIG_PID_NS /boot/config-$(uname -r)查看内核崩溃日志 /proc/last_kmsg /sys/fs/pstore/console-ramoops |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |