请选择 进入手机版 | 继续访问电脑版
搜索
房产
装修
汽车
婚嫁
健康
理财
旅游
美食
跳蚤
二手房
租房
招聘
二手车
教育
茶座
我要买房
买东西
装修家居
交友
职场
生活
网购
亲子
情感
龙城车友
找美食
谈婚论嫁
美女
兴趣
八卦
宠物
手机

针对某款摄像头设备的固件重打包及root shell获取过程侵占者古罗克

[复制链接]
查看: 73|回复: 0

1万

主题

1万

帖子

5万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
50195
发表于 2020-8-1 14:53 | 显示全部楼层 |阅读模式
Aodzip@海特实行室 H4lo@海特实行室
概述

近来在研讨一款 IPC 摄像头的固件,想要固件模拟举法子态调试然后发现由于固件给的 lib 库出了一些题目,致使没法模拟。手里恰好有实体装备,因而想到利用拆装备找串口的方式来举行调试,找到串口调试发现必要登录密码,且弱口令没法进入系统,因而又想到了利用固件重打包的方式去掉登录密码,所以对固件举行结构的分析以及对固件点窜后的重打包,同时记载下碰到的题目和响应的治理方式,终极获得 root shell 的进程。
串口调试信息

在一波物理进犯拆开装备外壳以后,找到 uart 串口后举行终端调试的常规操纵。按照串口的输出,在启动内核时,可以看到这里的内存地址映照:

  • [0.394000]0x000000000000-0x00000001d800:"factory_boot"
  • [0.405000] mtd: partition "factory_boot" doesn't end on an erase block -- force read-only
  • [    0.422000] 0x00000001d800-0x000000020000 : "factory_info"
  • [    0.433000] mtd: partition "factory_info" doesn't start on an erase block boundary -- force read-oy
  • [0.453000]0x000000020000-0x000000040000:"art"
  • [0.463000]0x000000040000-0x000000050000:"config"
  • [0.473000]0x000000050000-0x000000060000:"boot"
  • [0.484000]0x000000060000-0x0000001c7c00:"kernel"
  • [0.494000] mtd: partition "kernel" doesn't end on an erase block -- force read-only
  • [    0.510000] 0x0000001c7c00-0x0000007b0000 : "rootfs"
  • [    0.520000] mtd: partition "rootfs" doesn't start on an erase block boundary -- force read-only
  • [0.538000]0x0000007b0000-0x000000800000:"rootfs_data"
  • [0.549000] mtd: partition "rootfs_data" doesn't start on an erase block boundary -- force read-ony
  • [    0.568000] 0x000000060000-0x000000800000 : "firmware"
这里我们必要关注以下 kernel 以及 rootfs 的内存地址范围,kernel:0x000000060000-0x0000001c7c00,rootfs:0x0000001c7c00-0x0000007b0000。这里的内存地址范围对我们后续的重打包工作很是严重。
在启动内核、系统初始化以后,我们会发现这里有一个必要输入密码的 shell 登录命令行,利用 root 用户加上弱口令举行登录不乐成。因而对固件重打包并重新刷上固件就是本文必要研讨的内容。

固件分析

在主板上找到了存储文件系统的 flash 芯片,发现此芯片的存储容量只要 8M,用热风枪一顿操纵将其取下并利用编程器毗连获得其中的固件内容。
依照老例,间接利用 binwalk 来分析其固件结构:

这里发现此固件文件由五个部分组成,前四个部分都是紧缩数据,uboot 和 kernel 都位于此部分的紧缩数据中。末端一部分是 Squashfs 文件系统,我们这边的方针就是在文件系统中留下后门方便举行后续调试。
文件系统点窜

常见留后门的操纵严重有:点窜 passwd 文件、在文件系统的初始化启动剧本中加入 telnet 后门。比力方便的是修改 passwd 文件中的 root 用户的密码,这里可以挑选点窜也可以挑选删除密码(删除以后就无需密码便可以登录)。
检察 passwd 文件,这里的密码破解不出来,因而这里就举行了删除处置赏罚:

  • root:$1$aG9UJ4ev$gDdMidRwq4Rm6wrrfxcfT0:0:0:root:/root:/bin/ash
  • nobody:*:65534:65534:nobody:/var:/bin/false
  • admin:*:500:500:admin:/var:/bin/false
  • guest:*:500:500:guest:/var:/bin/false
  • ftp:*:55:55:ftp:/home/ftp:/bin/false
行将第一行改成:

  • root::0:0:root:/root:/bin/ash
在点窜完此文件以后,必要做的就是对根目录举行重打包。由于方针文件系统是 Squashfs 格式的,所以很自然就想到了用 mkquashfs 这个工具对根目录举行打包。
mkquashfs 打包文件系统

squashfs-tools 项目编译和安装

在这里可以找到 squashfs-tools 项方针源码:https://sourceforge.net/projects/squashfs/files/squashfs/
下载 4.4 版本的项目到当地以后解压,进入 /squashfs-tools 子文件夹下,点窜 Makefile 文件,去掉 XZ_SUPPORT = 1 这个表白(为了让此工具支持 xz 紧缩算法)。

接着 make & make install 即可。
打包命令

按照本来固件的输出,我们可以获得一些信息:

  • Squashfs filesystem,// Squashfs 格式文件系统
  • little endian,// 小端架构
  • version 4.0,// 文件系统打包版本为 4.0
  • compression:xz,// 此文件系统中采纳紧缩算法为 xz
  • size:6192298 bytes,// 此文件系统的巨细
  • 1179 inodes,// 节点数
  • blocksize:262144 bytes,// 文件系统块巨细页巨细
  • created:2020-03-1802:05:12// 建立时候
这里的信息对我们来说比力严重的两个地方是:

  • 文件系统紧缩算法为 xz
  • 块巨细为 256K(262144 bytes)
那末我们在利用 mkquashfs 命令以下:

  • mksquashfs squashfs-root/ squashfs-root.fs -comp xz -b 256K-nopad
打包的情况:

在获得打包好的文件系统以后,依照旧理,头部数据不修改,将其拼接到新的固件上:

  • dd if=firmware.bin of=header.bin bs=1 count=1866752// 提取固件头部
  • cat squashfs-root.fs >> header.bin                                        // 将文件系统拼接到头部
对照全部固件文件的巨细和文件系统的巨细我们会发现:打包好的全部固件的巨细是小于原始固件的,可是 Squashfs 文件系统的巨细却比原始的文件系统大。致使这里原因起因的题目现在还不太清楚,大如果由于原始固件的文件系统打包方式并由不是与运转此命令的方式类似。

  • h4lo@ubuntu:xxx$ ls -al header.bin firmware.bin
  • -rw-rw-r--1 h4lo h4lo 8388608Jul1611:45 firmware.bin
  • -rw-rw-r--1 h4lo h4lo 8084480Jul1612:24 header.bin




  • h4lo@ubuntu:xxx$ binwalk firmware.bin
  • ...
  • 18667520x1C7C00Squashfs filesystem, little endian, version 4.0, compression:xz, size:6192298 bytes,1179 inodes, blocksize:262144 bytes, created:2020-03-1802:05:12




  • h4lo@ubuntu:xxx$ binwalk header.bin
  • ...
  • 18667520x1C7C00Squashfs filesystem, little endian, version 4.0, compression:xz, size:6214768 bytes,1179 inodes, blocksize:262144 bytes, created:2020-07-1604:21:25
这样会致使一些题目,我们无妨先利用编程器将固件刷回 flash,用烙铁重新焊上 flash 到板子上。
题目定位

重新启动装备,检察 uart 串口的信息以下:

  • Autobootingin1 seconds
  • copying flash to 0x81500000
  • flash status is0,0,0
  • SF:Detected XM25QH64A with page size 256Bytes, erase size 64KiB, total 8MiB
  • SF:8388608 bytes @0x0Read: OK
  • verifying uboot partition...
  • ok
  • verifying kernel and romfs partition...
  • failed


  • Firmware check failed!
  • Enter recovery mode.
  • In:    serial
  • Out:   serial
  • Err:   serial
  • Net:RealtekPCIe GBE FamilyController mcfg =0024
  • no hw config header
  • new_ethaddr =00:00:23:34:45:66
  • r8168#0
  • Usingdefault environment
这里发现 verifying kernel and romfs partition. 是 failed 的状态。出现这类情况的原因起因严重有两种:一种是由于打包文件系统以后,在固件的某个地方做了某些考证大要类似 crc 的校验;还有一种情况我们在处置赏罚文件系统的时候内存偏移没有盘算好致使的。
此时窗口是处于 boot 形式,可以操纵一些命令:

检察一下关于 boot 的启动参数,这里的 bootcmd=jmpaddr 0xbfc50000 代表跳转 0xbfc50000 这个地址中,而这个地址即内核在内存中的绝对加载地址中:

  • rlxboot# printenv
  • addmisc=setenv bootargs ${bootargs}console=ttyS0,${baudrate}panic=1
  • baudrate=57600
  • bootaddr=(0xBC000000+0x120000)
  • bootargs=console=ttyS1,57600 root=/dev/mtdblock6 rts-quadspi.channels=quad
  • bootcmd=jmpaddr 0xbfc50000
  • bootdelay=1
  • bootfile=/vmlinux.img
  • ethact=r8168#0
  • ethaddr=74:05:a5:4c:e1:b0
  • gatewayip=192.168.1.1
  • ipaddr=192.168.1.60
  • load=tftp 80500000 ${u-boot}
  • loadaddr=0x81500000
  • netmask=255.255.255.0


  • Environment size:435/131068 bytes
这里我们手动实行一下这个命令,会发现这里确切会跳转到内核启动的地方,可是很快又会发现这里 kernel 出现了 panic,出现题方针原因起因是文件系统的位置没加载对。


  • 这里具体的原因起因是由于在利用 mkquashfs 命令举行文件系统打包以后的文件比原文件文件大,致使 kernel 在拜候分区表时,找到了 squashfs 文件系统的绝对加载地址,以及 size 的具体数值,可是由于全部文件系统的 size 变大致使没法一般举行解压致使的毛病提醒。
mtd 分区表修复

由于这里的文件系统在分区表中的 size 数值增大,是以这里我们研讨的重点就是关于此固件 kernel 部分 mtd 分区表的修复。
mtd 分区表分析

晓得了全部固件文件的内存映照以后,我们在 010 editor 中翻开原始固件,跳转到 kernel 部分:

0x60000 地址起头的前 0x200 个字节就是 mtd 分区表,关注到 0x60028 到 0x6006f 部分的数据,发现这实在就是分区表项的各个偏移。具体的格式为:

  • 地址开首+ size +地址开首+ size +地址开首+...
每个地址的开首对应了各个区段的肇端位置,再加上一个 size 值以后对应了该区段的竣事位置。这里总共是 8 个地址,恰好就对应了上文 kernel 打印出来的分区地址信息。



地址  size     地址      size    地址     size     地址      size     地址     size     地址      size   地址      size      地址      size      地址0x0  0x1d800  0x1d800  0x2800  0x20000  0x20000  0x40000  0x10000  0x50000  0x10000  0x60000  0x200  0x60200  0x167a00  0x1c7c00  0x5e8400  0x7b0000

  • 多出的 0x60000 - 0x60200 这个区段为 mtd 分区表自己,在 kernel 的输出信息中没有表现。从 0x60200 地址起头的数据为内核的 lzma 紧缩数据(利用 binwalk 可以快速定位)。
此外,这里 0x7b0000 这个地址就是文件系统的末端地址,我们可以跳转过去看看,比力故意义的是这里有一个类似标志位的十六进制数,猜测 uboot 就是经过此标志来判定加载的文件系统开首地址和竣事地址能否正确。

分区点窜

一样检察一下点窜以后的固件,首先 mtd 分区表稳定(没有举行点窜),我们照旧跳转到 0x7b0000 这个本来文件系统的竣事位置:

发现实在这里的文件系统的数据并没有竣事,由于在上文也可以晓得打包后的 squashfs 文件系统的 size 大了很多,所以在分区表对应的位置必要对文件系统的竣事地址举行扩大。

假定这里指定文件系统竣事地址为 0x7b6000,那末 size 巨细为:0x7b6000-0x1c7c00=0x5ee400。同时末端的 size 的值也要举行点窜,这个巨细为 rootfs_data 用户空间的数据段的长度,由于团体的 flash 空间巨细是 0x000000800000,所以这个值必要变小,具体为:0x800000-0x7b6000=0x4a000。
是以这里在响应的位置举行点窜,点窜后的成果以下:

点窜完分区表项以后,必要在固件文件末端以 0xff 举行加添到 0x7fffff 的地址位置。

  • python -c "print('\xff'*(0x7fffff-0x7b507c))">> modify.bin
以后在文件系统的末端,也就是 0x7b6000 位置补上十六进制:0xDEADC0DE。

固件重打包

将获得的固件重新刷入 flash 中就行了,开机检察 uart 串口信息,可以一般解压内核运转系统,同时利用 root 用户举行登录以后,就乐成获得了摄像头的 root shell。末端,感激 aodzip 徒弟的帮助和指导。



注:本文由E平安编译报道,转载请注原文地址 https://www.easyaq.com
举荐阅读:


  • “ BootHole”弊端致数十亿Windows和Linux装备遭到严重影响!

  • 权限绕过底子挖掘方式

  • 美国能源部试图10年完成“永久没法被劫持”的量子互联网蓝图!

  • 全数iPhone装备都大要被解锁!黑客公布新款逃狱软件“Unc0ver”
  • 征集 | 2020全国信息平安大会议题征集周全开启!



▼点击“阅读原文” 检察更多出色内容
爱好记得打赏小E哦!

免责声明:假如加害了您的权益,请联系站长,我们会实时删除侵权内容,感谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Copyright © 2006-2014 佛山家教网【佛山大学生家教中心】一对一名师家教--佛山最好的家教网站 [正规、专业、权威] 版权所有 法律顾问:高律师 客服电话:0791-88289918
技术支持:迪恩网络科技公司  Powered by Discuz! X3.2
快速回复 返回顶部 返回列表