news 2026/7/10 11:53:34

你的嵌入式设备有多不安全?看看攻击者是怎么进来的

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
你的嵌入式设备有多不安全?看看攻击者是怎么进来的

大学实验室里有块STM32开发板,连着电机驱动和WiFi模块,挂在校园网上跑了三年。没人碰过它,代码是研究生一届传一届的,密码没改过。一个学弟在毕业设计的最后一晚,用nmap扫了一下网段,发现端口23开着——Telnet,没加密,默认密码。他连上去看了一眼,说"噢,这板子能控制整栋楼的门禁"。

这不是段子。这是真实发生在某高校的事。所以今天想聊聊嵌入式安全这件事,它不是"加个密码防君子"那么简单。

攻击面比你想象的大

嵌入式系统和PC最大的区别在于——它被物理暴露在环境中。一个联网的门禁控制器、一台工业PLC、一个智能水表,攻击者可能摸得到它,可能用逻辑分析仪夹它的走线,也可能在它附近用电磁手段干扰。

先看软件层面的入口。

最常见的漏洞入口是未加密的通信通道。很多设备用UART、SPI、I2C这些总线传数据,裸数据直接走线。攻击者在板子上焊几根杜邦线,接个Saleae逻辑分析仪,就能读到你在总线上传什么。比如你用一个stm32通过UART给WiFi模块发AT指令:"AT+CIPSEND=xxx"——攻击者看到的就是明文,连协议都不用逆向。

一个有意思的地方是,很多设备出厂时调试接口没封。JTAG/SWD接口用Tag-Connect或者排针引出来了,上面印着"SWDIO""SWCLK"——等于把门钥匙挂在了门上。用JLink或者ST-Link连上去,OpenOCD一把读Flash,固件就出来了。

然后是固件本身。Cortex-M系列芯片很多没有开启读保护(RDP),或者只是开了Level 1——对应着stm32的RDP选项字节设成0x00或者0xBB。level 1还能用全局擦除或者某些侧信道手段攻破。真正需要的是Level 2,永久锁定调试口。当然代价是厂内返修也读不了,所以要权衡。

一个简单的内存越界,能让整个系统沦陷

这个问题值得单独拿出来说。

嵌入式开发里最常见的错误是什么?大概率是缓冲区溢出。malloc之后忘了检查返回是不是NULL、memcpy时src比dst长、sprintf往固定数组里塞可变长度的字符串——这些写法在嵌入式代码里太常见了。

我们来看一个典型的场景。

void process_command(char *cmd) { char buf[64]; strcpy(buf, cmd); // 解析buf,执行操作... }

如果cmd是从网络包或者串口数据里解析出来的,攻击者可以构造一个超过64字节的payload——strcpy没有长度限制,多出来的内容直接覆盖栈上的返回地址。这在Cortex-M上意味着什么?攻击者可以控制PC指针,把执行流redirect到他自己构造的payload上。如果MCU开了XIP(eXecute In Place),甚至可以在外部Flash里藏一段shellcode。

防止这个问题的标准做法是用strncpy或者snprintf,限定目标缓冲区的大小。但光这样还不够,更好的方案是配合MPU(Memory Protection Unit)做区域隔离。Cortex-M3/M4/M7多半都有MPU,只是很多人不用。设定好region属性,把栈区标记为不可执行,把代码区标记为只读——即使攻击者覆写了栈,也没法执行上面放的东西。

密码和密钥管理,不应该是草草了事

很多嵌入式设备出厂时用的密码是"admin/123456"、"root/root"、"user/password"这种组合。更糟的是有些设备的密码hardcode在固件里,还不会过期,用户也改不了。之前在某个品牌的IP摄像头固件里找到过后门账户,那是一行硬编码的comparison——"if (!strcmp(input, \"Zte521\"))"——搜一下互联网,这密码十年前就在GitHub上公开了。

密钥存储也是个问题。把AES密钥放在const数组里:

const uint8_t aes_key[16] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c};

这段代码在固件bin里就是连续16个字节,用hexdump或者binwalk -E一搜就找到了。稍微有点经验的逆向工程师会用sigfind去找这类模式。

解决这个问题,可以考虑用MCU内置的OTP(One-Time Programmable)区域或者eFuse来存密钥。STM32L5/H7系列带有CRYP硬件加密和HASH模块,密钥存到内部的BSEC区域,软件层面读不到裸密钥。另一种方案是使用ATECC608A这类独立安全芯片来做密钥协商和签名,密钥永远不离开芯片本身。

安全启动链,从reset vector就开始了

Secure Boot的思路是芯片上电后,ROM里的一段不可更改的bootloader先校验Flash里第一级boot的签名。通过之后一级boot校验二级boot或者app的签名。每一级都信任上一级签过名的下一级,直到整个固件完成自验。这样只要ROM没被篡改,整个信任链是完整的。

ST、NXP、Microchip这些厂商的中高端MCU现在都带这个功能。以STM32H7为例,它的SFI(Secure Firmware Install)方案支持在产线上用加密的方式把固件灌进去,芯片内部解密后再写进Flash——代码在产线工人手里已经是密文了。

但Secure Boot也不是万能的。如果bootloader本身有漏洞——比如前几年的"CVE-2021-xxxx"系列,某厂商的bootloader在处理签名校验时有一个off-by-one漏洞,攻击者可以构造一个能通过checksum但实际内容已被篡改的固件镜像。所以安全是一个持续对抗的过程,不是装一个功能就完事了。

几条可以现在就动手的建议

回到开头那个故事。现在那栋楼的门禁系统换成了带安全启动和加密通信的新方案。而如果你也想让自己手上的嵌入式设备更安全,可以从这几步开始:

关闭不用的接口。出货前把JTAG/SWD锁住(RDP Level 2),把UART除debug口外都disable掉,没用的GPIO设成analog输入省电也省事。

通信加个壳。UART也好SPI也罢,在应用层加一个简单的加密隧道。不一定要用TLS(很多MCU扛不住),一个轻量级的XTS-AES或者ChaCha20就够了。STM32的CRYP外设可以硬件加速AES,几乎不占CPU。

开MPU。哪怕只配两三个region,把关键段保护起来,都能拦下大部分简单的栈溢出攻击。

审计你的密码。不要让密码硬编码在一个const char里。至少要做到支持每个设备生成不同的默认凭据,或者强制用户在首次上电时修改。

最后——永远假设攻击者能拿到你的硬件。如果有人能物理接触你的设备,他迟早能读你的Flash。所以尽量让"即使读到了Flash也干不了什么"——密钥单独存、代码签名校验、敏感操作需要Challenge-Response认证。这是一种深度防御的思路,每一层都不完美,但合起来能挡住绝大多数攻击。

这是个很有意思的领域,安全设计和功能开发往往有冲突——加了MPU调度延迟会变,加密通信会占带宽和功耗,Secure Boot增加了产线复杂度。你在自己的项目里有没有遇到过这种取舍?

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/10 11:52:36

GB200部署DeepSeek-V3.2为何必须用SGLang?硬件级调度深度解析

1. 项目概述:为什么在GB200上跑DeepSeek-V3.2必须用SGLang?最近两周,我连续在三台不同配置的GB200集群节点上部署DeepSeek-V3.2,目标很明确:实现在单卡GB200上稳定支撑128并发、平均首token延迟低于85ms、P99尾延迟压到…

作者头像 李华
网站建设 2026/7/10 11:50:46

大数据毕设项目:基于 SpringBoot 的超市热销商品数据处理系统的设计与实现 大型超市数据清洗与处理系统 (源码+文档,讲解、调试运行,定制等)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

作者头像 李华
网站建设 2026/7/10 11:49:53

被ATS系统自动淘汰?留学生如何修正网申履历偏差「蒸汽求职分享」

很多刚回国的名校留学生都在遭遇同一种玄学困境:背景明明挑不出毛病,海外学校在QS排名上也很靠前,但在网申国内互联网大厂、外企或头部金融科技机构时,却总是卡在“简历评估中”石沉大海。更让人崩溃的是,有的时候点击…

作者头像 李华
网站建设 2026/7/10 11:48:59

高精度ADC与DSC在工业测量中的实战应用

1. 从模拟到数字的跨越:为什么选择MCP3551和dsPIC30F4011在工业测量和嵌入式系统开发中,模拟信号到数字信号的转换一直是核心挑战。我十年前第一次接触温度传感器项目时,就深刻体会到——高精度ADC(模数转换器)和强大处…

作者头像 李华