一张图片就能黑掉你的电脑——LogoFAIL漏洞到底怎么攻破BIOS的
你以为开机Logo只是一张图?解析这张图的代码跑在DXE阶段,权限比操作系统还高。如果有人在这张图里藏了恶意代码,你的杀毒软件还睡着呢。
📖 本文速览
2023年曝光的LogoFAIL漏洞(CVE-2023-40230):通过一张精心构造的JPEG图片,在操作系统启动前攻破BIOS 攻击目标不是安全模块,而是开机Logo的图片解析器——一个几乎没人审计的代码路径 多家OEM厂商中招,根因是自研JPEG解码器缺乏边界检查 本文从BIOS工程师视角拆解完整攻击链:Logo加载 → 解析溢出 → 代码执行 → 持久化植入
一、🎯 开机Logo——固件里最不起眼的攻击面
按下电源键,屏幕上弹出品牌Logo,你从来没多看过它一眼。
但如果你是BIOS工程师,你应该多看两眼。因为显示这个Logo的代码,跑在DXE阶段——这时候CPU已经切到保护模式、内存初始化完毕、可以跑C代码了,但操作系统还没加载,所有安全软件都还没启动。
换句话说:Logo解析代码运行在一个没有任何防护的特权环境里。
Logo显示的大致流程:
核心代码位置:MdeModulePkg/Logo/Logo.c
问题来了:这个JPEG解码器是谁写的?安全审计过吗?
答案是——大部分OEM用的是第三方图形库或自研解码器,几乎没人做过安全审计。大家都觉得"就是个显示图片的功能,能出什么问题?"
LogoFAIL的回答是:能出大问题。
二、💥 CVE-2023-40230:一张图的精准打击
2023年12月,安全研究团队Binarly REsearch在Black Hat Europe上公布了LogoFAIL漏洞集。其中CVE-2023-40230是最典型的一个:
某些OEM固件的JPEG解码器存在堆缓冲区溢出,通过精心构造的JPEG图片可以在DXE阶段获得任意代码执行。
打个比方:你家的门锁是银行级别的(Secure Boot),但后门有个狗洞(Logo解析器),谁都能钻进来。
攻击路径非常直接:
为什么ESP分区可写?因为Windows下ESP默认不挂载,但用一行命令就能挂上:
更离谱的是,某些OEM连NVRAM都不用改——Logo路径在固件里硬编码,直接读取\EFI\OEM\Logo\bootlogo.jpg。攻击者不需要研究怎么改NVRAM,把恶意文件放对路径就行。
三、🔍 为什么图形解析是软肋?
我做BIOS代码审查时,图形相关的代码是最容易被跳过的模块。原因很简单:它不涉及安全功能,评审者觉得"就是显示个图而已"。
但实际上,图形解析库的复杂度和风险远超想象:
自研的图形解析器几乎一定有bug。libjpeg-turbo这种成熟的开源库相对安全——但OEM需要在固件包里集成它,而固件包的ROM空间寸土寸金,很多OEM选择自己写个简陋的JPEG解码器——省空间,但要命。
这就像你为了省钱不装防盗窗,结果小偷从窗户进来了。
四、⛓️ 从Logo文件到代码执行的完整攻击链
攻击者要实现代码执行需要过四关:
第一关:触发溢出
构造一张"合法"的JPEG文件——能通过基本的文件头检查,但在Huffman表或量化表中嵌入超长数据。简陋的解码器不会检查表的大小上限。
第二关:控制执行流
溢出覆盖返回地址或函数指针。DXE阶段的调用栈比较固定(没有ASLR,没有栈随机化),攻击者可以通过分析固件镜像确定精确偏移。
这跟传统软件漏洞利用的不同之处:固件里没有ASLR、没有DEP、没有Stack Cookie。一旦溢出,攻击者几乎可以100%控制执行流。
第三关:Payload执行
Shellcode跑起来后能做什么?常见目标:
- 写一个恶意UEFI驱动进NVRAM
,下次启动自动加载 - 篡改Secure Boot的db/dbx变量
,让合法签名失效 - 注入OS Loader的hook
,在加载Windows前植入内核级后门 - 直接写SPI Flash
——对,DXE阶段Flash是可写的,写入后重启也清不掉
第四关:恢复Logo显示
高级攻击者不会让屏幕蓝屏或卡死——那样太明显。溢出后会恢复Logo的正常显示,用户完全感知不到。
你按下电源键,看到熟悉的品牌Logo,正常进系统。没有任何异常。但你的BIOS已经被植入了后门。
五、📋 Binarly的真实发现:比你想象的更糟
Binarly团队在2023年详细研究了几家OEM的Logo解析器,发现的问题五花八门:
最离谱的是:同一个OEM的不同型号产品,有的用libjpeg-turbo(安全),有的用自研解码器(不安全)。因为不同项目组独立开发,没统一规范。你买的上一代产品是安全的,下一代反而变不安全了。
六、🛡️ 防御:不是换个图的问题
短期止血
把所有自研Logo解析器换成成熟的开源库(libjpeg-turbo / libpng) Logo文件只能从固件卷(FV)加载,禁止从ESP分区读取 解析前验证文件大小、图像尺寸的上限
中期加固
PEI/DXE阶段的代码启用栈保护(Stack Cookie / Stack Guard) 图形解析代码跑在隔离的执行环境中(类似SMM的sandbox) 启用Intel CET(Control-flow Enforcement Technology),硬件级阻止ROP攻击
长期方案
固件的驱动程序模型改进——Logo驱动崩溃不应该影响安全策略 UEFI规范增加"不可信数据处理模块"的隔离要求 OEM建立统一的第三方库管理规范、统一版本、统一审计
七、💡 老兵忠告
1. 别信任何来自固件外部的输入。
Logo文件也是外部输入——它可能来自用户替换、OEM定制工具修改、甚至供应链环节植入。任何"这只是个数据文件"的想法,都是攻击者的机会。
2. 图形库的安全审计要比安全模块更严格。
因为解析复杂数据格式的代码天然更容易出bug。一个JPEG解码器的代码量可能比你整个Secure Boot实现还多。
3. 测试时别只测"正常图片"。
用AFL等fuzz工具生成畸形图片往Logo路径塞,看固件会不会崩。如果崩了,恭喜你发现了一个潜在CVE。
4. 最简单的防御:只用BMP。
BMP是像素数组,几乎不需要解析。如果你家BIOS不需要花哨的开机动画,把JPEG/PNG的支持关掉。简单即安全。
八、🎯 LogoFAIL教给了行业什么
LogoFAIL教给行业最重要的一课:
固件的攻击面不只在安全模块里——任何处理外部数据的代码都是攻击面。
你花三年打磨Secure Boot,精心设计信任链,结果被一张JPEG图片打穿了。
这笑话不好笑。但它是真的。
📌 固件笔记 · 笔记本BIOS老兵实战记录
夜雨聆风