技术分享:逆向破解华为路由器第二部分
引文
在第一部分,我通过UART进行了调试,并在最后利用命令行页面利用shell 命令就可以获取root权限了。也就是在这一点上,我已经可以访问路由器了,之后就可以像测试人员一样去调试路由器了。开始的时候给人感觉这个路由器还是相对容易访问,不需要昂贵的工具,往往也会产生非常有趣的结果。如果想要在硬件方向进行逆向工作,但是没有什么时间。这往往会进行不到一个更高的层次,例如网络漏洞、ISP 协议等。
本文仅代表原文作者意图,同时文章中介绍的工具、技术带有一定的攻击性,请合理合法使用。
回顾
下图都是之前分析的结果
按下回车,就会看到“Welcome to ATP Cli ”信息以及一个登陆提示。经过尝试之后就可以利用默认密码 admin:admin成功登陆,然后我们得到了BusyBox。
------------------------------- -----Welcome to ATP Cli------ ------------------------------- Login: admin Password: #Password is ‘admin' ATP>shell BusyBox vv1.9.1 (2013-08-29 11:15:00 CST) built-in shell (ash) Enter 'help' for a list of built-in commands. # ls var usr tmp sbin proc mnt lib init etc dev bin
在这里我们可以分析到固件(Ralink IC)的三个层面
U-boot: 设备引导程序。可以分析到设备的内存映射,可以启动固件程序以及执行一些相对低级别的任务。
ATP: 可控制裸机、并行处理等。基本上可以被看做是linux内核。
Busybox:一个集成了一些最常用linux命令和工具的工具箱,它同时为我们提供了一些shell命令。
如果在整个过程中获取低级别的访问权限,当然不会访问所有的数据。但在这里合理使用BusyBox是一个很好的机会。现在我把注意力集中在引导顺序,而再启动过程中显示的一些数据也是很重要的,下面就来看看哪些能被我用到。
引导顺序
在引导顺序中出现了多个随机项,当然还有一些其它的信息,比如压缩算法(flash segments)
Intel的闪存很有用,在这我可以分析它。
更多的信息
当我们访问闪存数据的时候,就需要处理压缩算法,这样可以更好地了解哪些是被使用的。
ATP 以及BusyBox
在路由器里面的Ralink IC,它主要是和固件( ATP)来控制存储单元以及并行处理数据,同时保证了硬件的工作状态。也就是它(ATP)可以被认为是一个Linux内核,之前所知道的ATP的CLI,但非常有局限性。
ATP>help Welcome to ATP command line tool. If any question, please input "?" at the end of command. ATP>? cls debug help save ? exit ATP>
在这里的shell命令中没提及help命令,但它通常是出现在sh以及shell。 ATP CLI里面有少于10个命令,当然这里面就没有复杂的控制文件方式以及文件导航,这就是为什么BusyBox出现的原因。
BusyBox含有二进制文件以及常见的Unix命令,开发很方便,值得注意的是节约内存。从 ls、cd 命令到top,系统开始启动脚本程序,这些都可以允许我可以将Ralink IC当Linux box一样使用。
进入BusyBox可以看到 shell命令,以及运行这些命令
ATP>shell BusyBox vv1.9.1 (2013-08-29 11:15:00 CST) built-in shell (ash) Enter 'help' for a list of built-in commands. # ls var usr tmp sbin proc mnt lib init etc dev bin # # ls /bin zebra swapdev printserver ln ebtables cat wpsd startbsp pppc klog dns busybox wlancmd sntp ping kill dms brctl web smbpasswd ntfs-3g iwpriv dhcps atserver usbserver smbd nmbd iwconfig dhcpc atmcmd usbmount sleep netstat iptables ddnsc atcmd upnp siproxd mount ipp date at upg sh mldproxy ipcheck cwmp ash umount scanner mknod ip cp adslcmd tr111 rm mkdir igmpproxy console acl tr064 ripd mii_mgr hw_nat cms ac telnetd reg mic ethcmd cli tc radvdump ls equipcmd chown switch ps log echo chmod #
你会注意到BusyBox的不同,而分析文件系统,如busybox的链接文件/bin/,这不是一个很好的开始,敏感的数据不会存放在这里(BusyBox binary)的。
分析文件系统
现在我已经得出哪些命令是可用的了,然后再看看有什么有用处的数据在那,所以先对系统有个大致的了解之后,我不想显示每一处的详细数据。而这里也需要用到top命令,top命令用来显示执行中的程序进程,使用权限是所有用户。虽然目前路由器闲置,但是没有显示更多信息。
有一个进程显示正在运行usbmount,而在这里路由器的USB接口也起到了作用,插上一个U盘。
usb 1-1: new high speed USB device using rt3xxx-ehci and address 2 [...] ++++++sambacms.c 2374 renice=renice -n +10 -p 1423
插入之后,安装位置在 /mnt/usb1_1/,然后一个samba服务器启动了,这些相关文件都是在/etc/samba/
# ls -l /etc/samba/ -rw-r--r-- 1 0 0 103 smbpasswd -rw-r--r-- 1 0 0 0 smbusers -rw-r--r-- 1 0 0 480 smb.conf -rw------- 1 0 0 8192 secrets.tdb # cat /etc/samba/smbpasswd nobody:0:XXXXXXXXXXXXXXXXXXX:564E923F5AF30J373F7C8_______4D2A:[U ]:LCT-1ED36884:
更多的数据
netstat -a: 查看开启了哪些端口
iptables –list:我们可以设置远程登录以及继续连接网络,但我更愿意维持裸机状态。
wlancmd help: 远程控制无线信号。
/var/:系统运行时所用到的文件位置
/etc/: 系统配置文件等
/var/ 以及 /etc/ 这些位置都包含了大量的文件,那么/etc/serverkey.pem是什么情况?
在嵌入式设备中发现TLS证书(私匙)是很正常的一件事情,在单一型号的设备可以获取到私匙,这也有助于你检测同一型号的设备。该私匙可以从服务商获得,另一方面获得公共证书用于远程的服务器通信也很常见。我在这里找到了两个,这两个都是来自“同一个人的签名”。
/etc/servercert.pem:最有可能是服务器密钥
/etc/root.pem:可以连接服务器吧(不确定)
更多的数据在/etc/ppp256/config 以及/etc/ppp258/config:
这些验证身份凭据的信息也会通过 HTTP接口,这也是我为什么提出这个概念的原因,以后会提及。有了这么多的信息可能需要消耗更多的时间去分析,这里需要用到之前的盘来复制数据进行分析。
收集信息
一旦将收集到的数据信息复制到计算机之后,可以搜索一些文件find . -name *.pem,但没有出现其它的TLS证书。想要在文件中搜索password肿么办?grep -i -r password 。
在这里我可以看到证书信息,主要是提供给TR-069、本地服务以及STUN协议,STUN是一种网络协议,它允许位于NAT(或多重NAT)后的客户端找出自己的公网地址,查出自己位于哪种类型的NAT之后以及NAT为某一个本地端口所绑定的Internet端端口。当然这些都可以通过HTTP接口来实现,但这些通常是隐藏的。如果想要想要相信了解可以看 这篇文章“Beyond Your Cable Modem”,这里有很多有关TR-069协议以及其它一些内容。我也可以获取到BASE64格式的证书信息,但是数据加密稍微差一点。
$ echo “QUJCNFVCTU4=” | base64 -D
ABB4UBMN
这是在路由器里面设置的WiFi密码,它向我们展示了两个有趣的文件,不仅仅指的是内容,而是路由器在工作时的重要组成部分
/var/curcfg.xml: 当前配置文件,主要是包括当时设置的WiFi密码(base64格式)。
/etc/defaultcfg.xml: 默认配置文件,被用于恢复出厂设置,但不包括路由器的默认密码信息。
ATP(CLI)
ATP(CLI)仅仅提供少量的命令,最有意思的是-shell-调试,但看起来并不是像真正意义的调试( debug display),而仅仅给我提供一些命令igmpproxy、 cwmp、 sysuptime以及atpversion,但这些没有太大用。我在考虑cwmp命令是否可以起到作用,是不是和路由器的远程配置有关?
值得注意的是,CWMP (TR-069)也是与路由器远程有关联的,甚至可能都没有编码时间。而在这一点上其余(ATP)命令是没有用的,清屏、帮助菜单、保存以及退出,这些貌似对于这一步作用都不大。
引导程序命令行界面
引导程序命令行界面可以访问某些内存区域,但不幸的是,它没有给我权限让我直接能够访问闪存芯片,下面就可以看到相关信息
Please choose operation: 3: Boot system code via Flash (default). 4: Entr boot command line interface. You choosed 4 Stopped Uboot WatchDog Timer. 4: System Enter Boot Command Line Interface. U-Boot 1.1.3 (Aug 29 2013 - 11:16:19) RT3352 # help ? - alias for 'help' bootm - boot application image from memory cp - memory copy erase - erase SPI FLASH memory go - start application at address 'addr' help - print online help md - memory display mdio - Ralink PHY register R/W command !! mm - memory modify (auto-incrementing) mw - memory write (fill) nm - memory modify (constant address) printenv- print environment variables reset - Perform RESET of the CPU rf - read/write rf register saveenv - save environment variables to persistent storage setenv - set environment variables uip - uip command version - print monitor version RT3352 #
这里需要注意的是不要启用这些命令 erase、mm、 mw以及nm,除非你需要用到这些的时候,当然这些应该和这一步没有关系,在某些情况下会导致设备重启,然后设备变成了砖头。在此情况下,md(内存显示)以及printenv命令引起我的注意。
RT3352 # printenv bootcmd=tftp bootdelay=2 baudrate=57600 ethaddr="00:AA:BB:CC:DD:10" ipaddr=192.168.1.1 serverip=192.168.1.2 ramargs=setenv bootargs root=/dev/ram rw addip=setenv bootargs $(bootargs) ip=$(ipaddr):$(serverip):$(gatewayip):$(netmask):$(hostname):$(netdev):off addmisc=setenv bootargs $(bootargs) console=ttyS0,$(baudrate) ethaddr=$(ethaddr) panic=1 flash_self=run ramargs addip addmisc;bootm $(kernel_addr) $(ramdisk_addr) kernel_addr=BFC40000 u-boot=u-boot.bin load=tftp 8A100000 $(u-boot) u_b=protect off 1:0-1;era 1:0-1;cp.b 8A100000 BC400000 $(filesize) loadfs=tftp 8A100000 root.cramfs u_fs=era bc540000 bc83ffff;cp.b 8A100000 BC540000 $(filesize) test_tftp=tftp 8A100000 root.cramfs;run test_tftp stdin=serial stdout=serial stderr=serial ethact=Eth0 (10/100-M) Environment size: 765/4092 bytes
我可以看到类似于UART 的波特率设定信息,以及一些有意思的存储单元地址。这些地址信息应该不是闪存的,虽然其存储器仅需要三个字节就可以搞定:[0x00000000, 0x00FFFFFF]。
让我们来看看这里都有哪些有用的信息,访问接口之类的,这个kernel_addr=BFC40000怎么样?
出现了有关badd的信息,也就意味着无效的地址。之前已经通过md命令来进行硬编码,来让你知道你正在试图访问无效的内存地址,这不是好的方案,但是也没有能够访问之前的启动信息。
值得注意的是,我在之前已经通过引导程序命令行界面停止linux内核加载到内存的进程,那么这个接口访问的信息就比较有限了。
我可以在内存中使用这种方法(SPI Flash 图像string编码)查找随机数据,但这个没有什么特别含义,仅仅用它来熟悉存储结构,例如在0x000d0000位置有明显变化。
在使用md命令之后,就可以看到0x000d0000位置的变化了。
以后的文章将会结合固件信息来分析详细数据,以及从系统方向下手来获取更多的数据。
*参考来源:jcjc-dev