找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

2873

积分

0

好友

405

主题
发表于 昨天 23:12 | 查看: 0| 回复: 0

物理接口访问与固件提取是 IoT 安全领域中非常独特且硬核的一环。今天,我们就来探讨一下如何拆解设备,寻找 UART 调试接口,并最终获取设备固件。

理解 UART

UART 并非像 HTTP/TCP 那样复杂的“软件协议”,它更像是一种“硬件摩斯密码”。 在 UART 线路(TTL 电平)上,信息就是电压的高低

  • 逻辑 1 (High):通常是 3.3V(或 5V)。
  • 逻辑 0 (Low):通常是 0V(GND)。
  • 空闲状态 (Idle):当没有数据传输时,线路上会一直保持高电平 (1)。这也是为什么你用万用表测量时,TX 引脚经常显示 3.3V 的原因。

在 Web 安全中,你的目标通常是找到后台登录页面或通过 Webshell 获得命令行界面。而在硬件世界里,UART 接口往往就是那个“开着门的 Root Shell”。开发者为了调试方便,经常会将系统控制台(Console)留在这个接口上。

如果你运气够好,只要在电路板上找到这几根线并正确连接,就可能直接获得设备的最高权限,甚至无需破解密码。

识别 UART 接口

要进行固件提取或获取 Shell,首先得在电路板上找到这扇“门”。UART 接口通常由 4 根线组成:

  1. VCC (电源)
  2. GND (地线)
  3. TX (发送 Transmit)
  4. RX (接收 Receive)

在理想情况下,它们会像下图这样被清晰地标注出来:

Netgear R6700v3路由器PCB板上的J252 UART接口特写

当然,现实中也可能是这样的形态:

电路板上的RX TX串口接口实物与俯视图

有时候接口标记会很清晰(VCC, GND, RX, TX)。但在量产设备上,为了防止被轻易利用,这些接口通常没有任何标记,可能只是四个裸露的焊点。

这时,我们可以借助万用表进行识别,过程其实并不复杂:

  1. 寻找 GND (地线):将万用表调到蜂鸣档。黑表笔接触电路板上较大的金属部件(如 USB 外壳、网口屏蔽壳),红表笔依次触碰那排未知的针脚。如果听到持续的“滴——”声,那这根针脚就是 GND。
  2. 寻找 VCC (电源):给设备通电,将万用表调到直流电压档 (DC 20V)。黑表笔固定在你找到的 GND 上,红表笔去测量剩下的 3 根针脚。如果发现读数稳定显示3.3V 或 5V 且不跳动,那通常就是 VCC。找到后请标记它,并且在连接时永远不要连接它(你的电脑和设备应独立供电,直接连接电源线可能导致损坏)。
  3. 区分 TX 和 RX:保持设备通电状态,黑表笔仍接 GND。设备在启动时,会通过 TX 引脚持续输出启动日志(Boot log),因此其电压会不断波动;而 RX 引脚主要用于接收,通常保持高电平(如3.3V)静止不动。观察剩余两根针脚的电压,电压值持续跳动(例如在 1.8V - 3.0V 间变化)的那根就是 TX,剩下那根自然就是 RX。
    • 细节务必在设备刚上电启动时进行测量,此时 TX 电压跳动最明显。如果设备已启动完毕进入空闲状态,TX 也可能稳定在高电平。

使用数字万用表测量电路板测试点电压,读数为2.54V

连接与通信

识别出引脚后,你需要一个 USB 转 TTL 模块(网上很容易买到)。连接时遵循:GND接GNDRX接TXTX接RX(即交叉连接)。

然后使用终端软件如 minicom、PuTTY 或 Screen 进行连接。如果屏幕上显示乱码,通常是因为波特率不匹配,需要手动调整。常见的波特率有 115200、57600、38400、9600(9600在工控设备中较常见)。

以 PuTTY 为例,配置如下:

PuTTY串口会话配置界面,设置COM4与115200波特率

如果尝试常见波特率均失败,可能需要借助逻辑分析仪来自动识别。

此外,还需确认串口参数:Data bits (数据位)、Parity (校验位)、Stop bits (停止位)。不过大多数设备默认使用 8N1 配置(即 Data bits=8, Parity=None, Stop bits=1)。特别注意 Flow Control (流控) 必须设置为 None 或关闭,否则你可能只能接收数据而无法发送命令。

获取 Root 权限

如果一切顺利,你可能直接就获得了 root 权限。如果需要密码,可以尝试一些常见弱口令。

若密码无效,可以尝试在启动过程中打断 U-Boot。路由器通电瞬间,U-Boot 会先运行并初始化硬件,通常会给出 1 到 3 秒 的时间窗口允许中断。

你可能会看到如下提示:

Hit any key to stop autoboot: 3... 2... 1...

务必在倒计时结束前,快速敲击回车键或空格键。成功后,滚动的日志会停止,并出现一个特殊的命令提示符,如 ath>Tenda>U-Boot>=>

恭喜,你现在正在与硬件底层的引导程序对话。

输入命令:

printenv

这相当于“查看源代码”。你会看到一系列环境变量,其中最关键的 bootargs,这是传递给 Linux 内核的启动参数。

它通常类似这样(注意 consoleroot 部分):

bootargs=console=ttyS0,115200 root=/dev/mtdblock2 rootfstype=squashfs ...

我们的目标是在这个参数字符串的末尾添加 init=/bin/sh。这行代码的意思是告诉内核:“启动后,直接运行 /bin/sh 作为初始进程。”

操作方法

  1. 复制 刚才 printenv 显示的整段 bootargs 的内容。
  2. 构造 新的设置命令。假设原内容为 OLD_CONTENT,则输入:
    setenv bootargs 'OLD_CONTENT init=/bin/sh'

    例如(假设原bootargs较短)

    setenv bootargs 'console=ttyS0,115200 root=/dev/mtdblock2 init=/bin/sh'

绝对不要输入 saveenv 命令! 我们只想让修改在当前内存中生效(临时性),而不是永久写入闪存。一旦错误参数被保存,设备下次启动可能会变砖。只要不保存,重启后一切都会恢复原状。

修改参数后,输入:

boot

bootm

设备会继续启动。但这次,在日志滚动结束后,可能不会出现 Login: 提示符。系统可能会停顿一下,然后直接显示:

/bin/sh: can‘t access tty; job control turned off
# whoami
root

恭喜,你在没有密码的情况下,拿到了这台设备的最高权限。如果提示 /bin/sh 为只读,可以尝试运行 mount -o remount,rw / 重新挂载根目录为可写。

固件提取

既然已经获得了 Shell,提取固件就变得非常简单。首先,查看设备的分区信息:

# 查看分区
# cat /proc/mtd
dev:    size   erasesize  name
mtd0: 01000000 00010000 "ALL"
mtd1: 00030000 00010000 "Bootloader"
mtd2: 00200000 00010000 "Kernel"
mtd3: 00dd0000 00010000 "RootFS"

其中 mtd0 通常代表整个闪存芯片的内容(完整固件)。

我们虽然通过 UART 串口连接,但可以通过网络将固件传输出来。

  • 电脑端(接收方):用网线连接电脑和路由器的 LAN 口,并配置好 IP(假设电脑 IP 为 192.168.0.2)。在终端使用 nc 命令监听一个端口,准备接收数据:
    nc -l -p 8888 > firmware_dump.bin
  • 路由器端(发送方):在获得的 Root Shell 中输入:
    cat /dev/mtd0 | nc 192.168.0.2 8888

至此,你已经完成了从物理识别 UART 接口 -> 避坑连线与通信 -> 利用引导程序提权 -> 导出完整固件的完整流程。这正是硬件安全研究中,从外部物理接口切入到获取设备内部核心数据的关键路径,也是许多 安全/渗透/逆向 研究的起点。掌握这些基础技能,能帮助你更深入地理解嵌入式设备的安全边界。对硬件安全感兴趣的朋友,欢迎在 云栈社区 的相关板块进行更深入的探讨与交流。




上一篇:微软CEO警告AI泡沫风险:警惕资本堆砌,重构知识型工作是关键
下一篇:互联网大厂岗位鄙视链与暑期实习求职全攻略:Java技术栈学习心得分享
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2026-1-25 21:00 , Processed in 0.362018 second(s), 42 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2026 云栈社区.

快速回复 返回顶部 返回列表