零、某科学的起因

突然开了个脑洞,现在很多设备底层是封装的定制Linux,包括某些路由、防火墙等等。

比如最常见的第三方路由系统,pfSense、OpenWRT(LEDE)、爱快等等。部分系统是比较开放的,比如OpenWRT提供ROOT权限,并且文件系统可读写,可以安装各种软件,并且对系统作深度定制,而且是开源的,还可以自己编译自己想要的环境,做自己想要的修改。

当然不会所有系统都是这样,很多设备用的存储,本身读写就有寿命限定,而且还有部分商业原因,不面向用户开放权限的,这几波折腾的就是这种情况的。

因受限,可能部分截图没法展示,所有实验均在虚拟机进行,对Linux有一定了解的可以忽略P1基本操作,直接跳P2。

一、某跳板机

首先折腾的第一台设备是某跳板机,原系统默认开机进入定制终端,登陆后只能做一些预定义的维护操作,比如修改IP、校时、诊断、开关机重启等等。遇到这样的机器上手第一波就先试试Ping能不能带参数,一波1.1.1.1 $$ reboot,提示参数错误,那看来还是做了一些基础的过滤的。

设备实际是可以进Shell的,但是得@厂家拿挑战码。就像海康DVR要重置密码也得400或者wx提交,那有木有办法可以自己进Shell呢,当然有辣。

一波研究后发现系统用的是CentOS 6.x(新版本用的是CentOS 7.x),那可以用RHCSA的基本操作,单用户进系统。在系统GRUB启动时先敲方向键或其他键打断倒计时,敲E。

然后再次敲E,到编辑模式,并且添加"[空格]single",回车然后敲B启动,就会进维护模式了,敲完密码(同系统密码)登陆是/bin/bash了。

当然如果是CentOS 6.x,这里就不用敲密码了,如果是CentOS 7.x,而且密码忘了的话,可以编辑的时候改敲"[空格]rd.break[空格]console=tty0",然后进去挂载分区读写,chroot,passwd一波。

嗯,这个环境有点太简单了,而且是CentOS,各种命令齐全,yum装包都能跑,而且看了下文件系统是独立挂盘没有什么读写限制,也就是修改重启后也是保留的。

find|grep www 一波后,找到Web目录,可以开始你的前端定制操作研究了√。

二、某防火墙

什么?P1都是基本操作,你的设备没法这样进?或者重启后修改复原了?那你可能遇到另外一种情况了。

因为默认没有大量读写需要,许多路由、防火墙可以依靠一个小容量电子盘或者CF卡等等启动,例如1G左右就足够,存储的系统可能压缩前一两个G,压缩后就几百兆,或者某些路由压缩前上百兆压缩后不到16M以存储在闪存上。

这些系统会在开机时自动解压到内存,就像Windows PE一样,在内存中运行,然后如果需要文件的临时读写(例如running-config,或者存储更新),都是先写到内存的,所以说很多设备是不即时保存配置的,需要手动/命令保存,以保护存储寿命。对于大量需要持久读写保存的数据,例如日志等是可以存储在外部设备(此处指非系统盘,例如独立的3.5 HDD等等)。

那么问题来了,如何修改一个已封装的系统呢?如果直接对内存里的文件系统修改的话,重启也就还原了没得意义。

整了个某防火墙,首先试试P1的姿势能不能进,啊咧,好像吧GRUB交互跳过了,没有给机会。

那咋办鸭,那就先分析一下硬盘目录结构咯?当然我是在虚拟机测试,仅供交流与学习,如果直接拆出实体机硬盘可能会影响保修。(*而且例如Sophos等厂商对非授权Shell的操作都是不受维保支持的)

如果你的也是虚拟机?那么非常OK,你可以直接用7zip一层一层拨开vmdk,但是没法直接修改。

如果你要修改的话,就需要一波挂载了,可以先用"StarWind V2V Image Converter",转换VMDK(VMware的格式)到VHD(巨硬格式),然后在磁盘分区挂载,当然即使能挂载上,Windows也读不了EXT分区的内容,除非上一个"Paragon ExtFS for Windows"。

然后发现里面没有啥可以折腾的内容,调查一波后发现系统被封装在rootfs.img,这不是普通的可以DD用的磁盘映像,而是CPIO的打包,套一个[email protected]的压缩,Windows下确实对其很难操作。

还是转到Linux环境8,先上个常用工具,对于Win最常用的维护莫过于PE了,可以跑各种程序,对于Linux,我这边先选了个Gparted的启动盘(主要服务器ISO库有现成的)。

Gparted是一个Linux环境下的GUI分区工具,说白了就是带界面,对于EXT相关分区调整比Win的同类软件方便点,比较平台不一样,官方也有打包好的启动盘,开机即用。

不过这次并不是要重新分区,而是要对封装的文件做修改。因为7z的解包对软连接等文件有些偏差,可能会造成意料外的后果,所以还是先找正常操作提取文件。

首先是基本的分区挂载:

sudo su

mkdir /mnt/sda1

mount /dev/sda1 /mnt/sda1

cd /mnt/sda1

ls

至此我们就可看到硬盘分区内的各种文件了,但是系统是封装在rootfs.img的,得从这里面再继续解包。

那之前说的,rootfs.img是一个CPIO的打包,套一个[email protected]的压缩,这个是怎么看出来的呢?initramfs的打包有多个版本,之前一个交换机看的是GZ的打包,因为系统开机自动打印出来了2333,而后来有变成XZ的打包。可以用File命令查询文件信息。

图个方便,先把rootfs.img考到tmp下面处理,相当于在内存处理,然后:

file rootfs.img

可以看到是LZMA压缩,那就改下后缀,使用XZ解压一波:

xz -dv rootfs.xz

file rootfs

再次File一下,看到是CPIO打包,那就再用CPIO解包。

那现在就可以看到是最终文件了,也是find一波找Web目录,可以应用常见的修改了。

修改完以后可以再次吧系统封装打包上,也是常见操作,先cpio打包,然后xz打包。

可以看到目录已经打包到rootfs文件了
确认过眼神,是对的 (SVR4 with no CRC),然后继续XZ打包

这里有个坑了,我之前打包的时候没加-H newc,结果直接启动不能,报RAMDISK incomplete write,而且错误看起来就像是没有为RAMDISK指定足够的大小容纳文件。一开始尝试换gz打包,也没成,而且发现gz打包明显大小多了20M。折腾一小时后发现file读源文件和新打包的文件有区别,最后加-H newc就解决了。

打包好把rootfs.xz更名为rootfs.img,替换掉原来的文件即可,重启见效√

Before
After

如上方,不但可以简单修改CSS等达到个性化,因为是PHP写的Web,还可以增添文件管理等等操作。

当然,每次解包修改再打包,很麻烦,特别是打包很耗时间,有没有可以一劳永逸的方法呢?当然是有的辣。

截图因涉及受控信息就不能提供了,原理是这样,可以研究一下系统的启动脚本,然后增加自定义的脚本,调用挂载sda1下boot目录的脚本文件,并且可以跳过虚拟Shell的启动,直接进Busybox。

因为sda的boot是可读可写的,所以可以把需要定制的内容存在里面,配合PHP的文件管理等,可以在启动后实时修改并保存。在被调用的引导脚本做文件替换,或直接做LS软连接映射等等方式,达到定制效果的持久化。

 

 


升空的焰火,从下面看还是从侧面看?