本文为看雪论坛精华文章
看雪论坛作者ID:零加一
并对系统内核以及文件系统进行提取,为后面漏洞挖掘做铺垫。以及提升自身对linux系统逆向知识面。
1
环境搭建
从提供的下载包可以看出这是软路由的系统,没有硬件限制,所以下面用vmware进行了安装。
配置好后,进入后台管理界面如下:
初始环境安装完后,发现系统并没有提供输入。所以需要上qemu进行调试将文件系统提取出来。
2
文件系统提取
对img进行进行提取,在grub中的menu.list可以看出initrd对应的是root.gz。
可以看到root.gz是属于加密的。
GRUB调试
寻找启动设备并将设备的第0个扇区载入到0x7c00处,即载入MBR
从0x7c00处开始执行,并将第1个扇区载入到0x2000,并跳转到0x2000处继续执行,这里为加载Stage1.5。
将第1个扇区之后的几个扇区装载到0x2200,并跳转到0x2200处继续执行,并加载Stage2加载到0x8000处后跳转到0x8200处开始执行。
读取配置文件,根据配置文件进行执行操作,其中包括了内核镜像(这里是bzImage)的加载,当内核镜像加载完毕后会有3个地址需要关注。
1.linux_data_tmp_addr指向bzImage数据。
2.LINUX_BZIMAGE_ADDR指向压缩后的kernel数据。
3.linux_data_real_addr指向部分bzImage数据
从linux_data_tmp_addr开始将部分数据拷贝到linux_data_real_addr并切换到实模式跳转到linux_data_real_addr+200处执行。
./qemu-system-i386 -s -S -m 512 -drive file=Wowfk.img,format=raw,index=0
MBR
随后将第1个扇区载入到0x70000处。
将第0x70000的数据复制到0x2000即Stage1.5然后跳转到0x2000处继续执行。
Stage1.5
接着将数据复制到0x2200+index处
数据载入完后跳转到0x2200处继续执行
在经过一系列的初始化后,便开始将Stage2载入到0x8000,大小是0x400
注:圈起来的函数是grub_read,参考源码:/stage2/stage1_5.c:cmain
剩余的Stage2数据载入到0x8400,并跳转到0x8200处执行
call near ptr unk_2360在源码中对应的是/stage2/asm.S:chain_stage2
用于转移ip
0x8200的代码位于:/stage2/asm.S:_start
在asm.S:_start结尾调用了init_bios_info
init_bios_info最后跳转到了00027E9C(/stage2/stage2.c:cmain)处继续执行
最后开始解析配置文件寻找对应的处理函数进行调用,如下是kernel命令对应的。
/stage2/builtins.c中对应的kernel_func函数,最终调用load_image
load_image中在将bzImage的前0x2000大小的数据读取到0x66000处后,再从0x66000处复制到linux_data_tmp_addr(0x5CFD30)中。
继续读取之后的0x1800字节,保存到linux_data_tmp_addr+0x2000处。
接着将0x3800之后的所有数据读取到LINUX_BZIMAGE_ADDR(0x100000)。
…
当到了boot命令后,便进入boot_func函数。
kernel_type是3,最终调用big_linux_boot函数。
在/stage2/asm.S:big_linux_boot中可以清晰的看到
从linux_data_tmp_addr将0x9400大小的数据复制到(linux_data_real_addr)0x90000
切换到实模式后,通过jmp far跳转到90200处执行,改变了cs=9020 ip=0
且ida并不能去识别这样的进程环境,导致出现了反汇编的窗口指向了错误的页面但能F7 F8。
解决这样情况的办法就是将cs清零,将ip修改成正确的地址即可,但是遇到ip被改变的需要修改回原来的样子再执行。所以等一手正版人员给ida提一个issues,非常感谢!
至此,就进入了内核,GRUB的过程结束。
内核调试
注:该处执行的代码均在/arch/x86/boot/compressed/head_32.S中
随后将内核解密,并将该快内存dump
使用vmlinux-to-elf将内核程序提取出来
完成后会将内核程序的+0x1000处填充到0x1000000,并跳转到该处执行。
在0x1000000往下执行,重新将内核复制到0x81000000处,并跳转到0x818B6CEB
经过了漫长的调试,配合linux源码看,最终定位到了0x81BDC9CE处,调用的函数具体是干嘛的我也不知道,只知道eax是指向root.gz解密后的数据,edx为长度。
最后写脚本将所有数据进行dump:
3
总结
2、在保护模式和实模式的切换间16位和32位的调试,对系统底层有了一个模糊的了解。
3、心一定要稳,不要浮躁,F8一定不能快!
看雪ID:零加一
https://bbs.pediy.com/user-home-749276.htm
# 往期推荐
球分享
球点赞
球在看
点击“阅读原文”,了解更多!
原文始发于微信公众号(看雪学苑):某系统漏洞挖掘之固件分析