嵌入式软件是物联网的核心,尽管嵌入式应用程序安全通常不被认为是嵌入式开发人员和物联网设备制造商的优先事项,这可能是由于缺乏安全编码知识或团队代码库之外的其他挑战造成的。
开发人员面临的其他挑战可能包括但不限于原始设计制造商(ODM)供应链、有限内存、小堆栈,以及将固件更新安全推送到端点的挑战。
防止内存损坏漏洞
在使用低级语言(如C)时,如果开发人员没有以编程方式正确检查和验证边界,则很有可能出现内存损坏错误。防止使用已知的危险函数和API有助于防止固件中的内存损坏漏洞。例如,已知的、不安全的C函数的非详尽列表包括:strcat、strcpy、sprintf、scanf和gets。
常见内存损坏漏洞可能包括堆栈或堆溢出。攻击这些特定内存损坏漏洞时的影响因操作系统平台而异。例如,商用RTOS平台(如QNX Neutrino)将每个进程及其堆栈与文件系统隔离,从而最大限度地减少攻击面。但是,对于常见的嵌入式Linux发行版,情况可能并非如此。在嵌入式开发中,嵌入式Linux中的缓冲区溢出可能导致攻击者任意执行恶意代码和修改操作系统。
一些内存安全控制方法可用于防止内存损坏漏洞,例如:
使用安全的编译器标志,例如-fPIE、-fstack-protector-all、-Wl、-z、noexecstack,-Wl、-z、noexecaspect和其他可能取决于特定编译器版本的标志。
首选包含内存管理单元(MMU)的片上系统(SoC)和微控制器(MCU)。MMUs隔离线程和进程,以在内存漏洞被利用时减少攻击面。
首选包含内存保护单元(MPU)的片上系统(SoC)和微控制器(MCU)。MPUs强制执行内存和独立进程的访问规则,以及强制执行特权规则。
如果没有MMU或MPU可用,则使用已知位监控堆栈,通过确定堆栈中有多少不再包含已知位来监控堆栈的消耗量。
使用后,请注意缓冲区和空闲缓冲区中放置的内容。
利用地址空间布局随机化(ASLR)和其他堆栈控件的内存漏洞进行攻击需要攻击者付出大量努力。尽管如此,在某些情况下仍然是可能的。确保代码具有弹性,并对存储在内存中的数据采用深入防御的方法,这将有助于嵌入式开发设备的安全态势。
防止注入攻击
注入攻击是任何web应用程序中最常见的漏洞之一,尤其是在物联网系统中。有许多类型的注入攻击,如操作系统(OS)命令注入、跨站点脚本(例如JavaScript注入)、SQL注入、日志注入,以及表达式语言注入等。在物联网和嵌入式系统中,最常见的注入攻击类型是操作系统命令注入;应用程序接受不受信任的用户输入并传递该值以执行shell命令,而无需输入验证或正确的转义和跨站点脚本(XSS)。
以下是防止注入攻击的常见最佳做法和控制措施列表:
如果可能,避免直接调用操作系统调用。
如果需要,白名单接受命令并在执行之前验证输入值。
使用数字的查找映射来为可能传递到操作系统(如{1:ping-c5})的用户驱动字符串命令字符串。
对代码库执行静态代码分析,并在使用OS命令(如os.system())时发出警报。
将所有用户输入视为不可信的,并输出返回给用户的数据的编码字符。(例如,Convert&to&,Convert<to<,Convert>to>,等等。)
对于XSS,使用HTTP响应头,如X-XSS-Protection和Content-Security策略,并配置相应的指令。
确保在生产固件构建上禁用带有命令执行的调试接口。
在生产环境中使用固件之前,上述控件始终需要进行测试。通过注入攻击,设备和用户将面临被攻击者和胭脂设备接管的风险。2017年,IoT收割者和Persirai僵尸网络发生此类事件,这只是开始。
构成物联网(IoT)主干的连接设备存在多个漏洞,可供黑客渗透。为了减轻这些设备中底层固件的威胁,嵌入式开发人员需要熟悉大量的安全技术。