看到标题大家估计 都 猜到了,今天我们要介绍的就是CVE-2024-56161这个影响AMD Zen1至Zen4系列CPU的微码更新安全漏洞。首先请你don’t panic,这个影响的是EPYC处理器,除了 G.O.S.S.I.P这种 财大气粗的团队会用,个人基本上很少会买上一块放在家里供着。
这个由Google安全团队发现的问题被命名为EntrySign
,涉及到CPU的微码(microcode)更新过程中的验证存在的问题。什么是CPU的微码,以及为什么CPU要更新微码,这个大家可以去查阅相关资料,并且可以顺便了解一下1994年著名的“The Pentium FDIV bug”也就是 给Intel如今股价暴跌埋下伏笔的 奔腾处理器浮点运算单元中的bug是如何 导致Intel赔了一大笔钱 促使CPU厂商允许硬件也要支持更新。
言归正传,在AMD的Zen架构(也许还涉及到海光处理器)中,有一个专门存放微码的区域(只读,ROM),也有一个存放微码的补丁的区域(可写,RAM),下图是研究人员推测出的架构(毕竟到底怎么样,只有AMD 和海光 知道)。我们只需要知道,要更新这个微码,肯定需要非常高的权限,不然谁都可以任意修改CPU的执行流程,那不是乱套了吗?对,AMD确实考虑到了这个问题,并且设计了一套跟手机固件升级差不多的流程,也是依赖于密码学特别是公钥签名机制来保证只有官方签发的微码更新固件才能加载并且更新。那么,安全问题到底出在哪里?
不得不说,就连AMD这样的芯片巨头,在设计如此至关重要的功能时,也充分体现了“世界是个巨大的草台班子”的特色。好,我们来揭开谜底,首先看看AMD的微码更新固件的消息格式(如下图),这里面看上去没有大问题,整个消息部分都被完整签名了(使用的是RSASSA-PKCS1-v1_5
签名规范),同时AMD在硬件上也把相关的公钥固化在CPU上(这也算一种key pinning),在升级过程中首先检测固件中的公钥是否合法,如果合法就继续验证签名。好死不死的是,AMD不知道为什么在选择hash函数的时候抽风了,放着SHA-256、SHA-3甚至哪怕不安全的SHA-1和MD5都不用,去用AES-CMAC作为这个验证过程中的hash函数,然后就把整个安全体系全部搞塌房了!
我们稍微深入一下技术细节,在这个验证流程里面,有几个地方需要用到hash函数,并且都错误地使用了AES-CMAC算法。第一个地方当然是签名验证过程,我们都知道签名是对消息的hash(而不是消息本身)进行私钥加密运算,第二个地方则是前面讲到的公钥验证,CPU在收到微码更新固件之后,大概是工程师舍不得钱,只给片上留了128 bit去保存公钥的hash而不是公钥本身!那实际上我们针对这套体系进行攻击,并不需要去破坏公钥密码体系(虽然这里用的是RSA-2048,可能会被量子计算机降维打击),而是对准这里面的核心问题——hash函数误用——就好了。
回到AES-CMAC算法上来,它是一个负责生成消息认证码(Message Authentication Code,MAC)的操作。我们都知道,MAC并不是hash,它首先需要有一个保密的key,生成MAC的一方用这个key进行运算得到MAC,而验证MAC的一方也要用这个key去验证MAC,如果key被人知道了,那就没有什么安全性好说了,与之相反的是,我们目前广泛使用的密码学hash函数,所有的运算过程都是公开的,不需要什么秘密参数。
更为神奇的是,Google安全团队发现,在Zen1到Zen4的EPYC CPU上使用的AES-CMAC密钥,居然是直接从NIST SP 800-38B publication这个文档上抄下来的key sample(见Appendix D.1,2b7e1516 28aed2a6 abf71588 09cf4f3c
,估计是开发团队懒得去生成test vector,就直接抄了官方的key和test vector?)。看到这里你是不是想要大声喊出“What the Fxxk!”呢?更重要的是,AES-CMAC并不能提供hash函数所需要的抗碰撞特性,这也就意味着攻击者可以轻松找到不同的输入,得到相同的输出(在这里作为hash值),从而伪造签名。讲到这里,整个EntrySign
漏洞的核心问题其实就已经讲完了。
接下来我们要进入到“密码学从入门到放弃”时间,先从CMAC讲起,大家可能比较熟悉的是分组加密算法的CBC模式,那我们把一段消息用CBC模式加密(IV设置为全零),然后把最后一个分组的结果拿出来当作消息认证码,这个叫做CBC-MAC;不过CBC-MAC有很严重的安全问题,就是对于一个短消息和它对应的CBC-MAC值,可以轻松使用长度扩展攻击,构造一个更长的消息,具有同样的CBC-MAC值,因此CBC-MAC在使用时必须要约定好消息长度。而CMAC就是对CBC-MAC的改进,在密文长度不同的情况下,要使用不同的派生密钥,并且最后一个分组要进行填充。更详细的信息可以参考NIST文档 (https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-38b.pdf):
在AMD CPU微码更新过程中,假设攻击者知道了AES-CMAC的key,再利用CBC加密模式的弱点,可以伪造最后的输出:注意到除了第一个加密分组之外,攻击者可以通过修改后面任一个待加密的明文分组(也就是上图中的M_2到M_n),使得这个明文分组和前面的密文异或之后的内容是你想要的。
接下来就是对微码固件更新所使用的公钥的伪造:利用前面的AES-CMAC碰撞攻击原理,攻击者可以先随机选一些(样子看起来怪怪的)输入作为公钥(如下图中的下半部分),其中除了一个特定的"compensating" block之外都是0),这个输入的特点是它的AES-CMAC和AMD那个合法的公钥的AES-CMAC值是一样的!然后再尝试看这个随机的“怪公钥”能不能分解(就是搜索看它有没有一些小的素数因子,然后剩下的部分碰巧也是个素数,这个概率在密码学课程上都教过怎么算,其实很容易就能撞到),如果有(如下图中的上半部分所示,一个小的素因子为0x61),bingo!
当然,在Google安全团队的安全公告里面还提到,除了伪造公钥,在构造“合法”的固件格式的时候还要生成一个配套的蒙哥马利模乘(Montgomery Modular Multiplication)的变换系数,这个是密码学课程(特别是密码工程)都会讲的,我们也不再赘述了~
讲到这里,估计很多CTF竞赛马上会把这个当成下一次的比赛题目来用 估计你要大呼不妙,不过AMD也已经提供了安全更新 (https://www.amd.com/en/resources/product-security/bulletin/amd-sb-3019.html),具体通过更新AMD AGESA(AMD Generic Encapsulated Software Architecture,AMD X86-64架构主板BIOS里面负责处理器核心、内存和HyperTransport控制器初始化的代码)来实现。
最后你肯定想学一些 黑产知识 硬件知识,那就是怎么去实现自定义的微码。但是这是一门神秘的手艺,往往只能从一些古老而接近失传的书籍中寻觅到只言片语(例如Google安全团队提到的一本1998年的书籍《The anatomy of a high-performance microprocessor》中介绍了AMD K6 RISC86 架构的细节,以及2017年的USENIX Security论文Reverse Engineering x86 Processor Microcode中介绍的对AMD K8 和 K10 CPU的逆向)。Google安全团队不知道从什么地方打听到,目前的AMD处理器的微码设计主要参考了上古(其实也就是上世纪90年代)一个叫做NextGen的处理器的设计思想,那个年代正是RISC(注意不是现在这个RISC-V)思想兴盛(却被Intel CISC锤到没有市场)的时代,Intel和AMD这种CISC设计在背地里也悄悄吸收了RISC的精华,而且AMD后来还被NextGen公司给买下来了。反正目前能在有一个网站 (https://www.memotech.franken.de/NexGen/) 上找到一些资料,而这些资料对于理解当前的AMD处理器微码大有帮助。
前面都是给喜欢研究技术的理论派准备的,我们也有给喜欢实践的动手派介绍Google安全团队开源的一套 黑产 工具——zentool
https://github.com/google/security-research/blob/master/pocs/cpus/entrysign/zentool/README.md
这个工具的功能就是给你的EPYC处理器 植入新的恶意指令 已有微码打补丁,理论上它可以帮你hook原来CPU指令集中的任何一条指令,把它的功能改掉,比如我们知道经典的那个关于随机数的梗:
XKCD 221 - random_number 来源:https://xkcd.com/221/
[图片]
你可以用zentool
轻松实现:只需要hook RDRAND
指令就行了:
具体的实现细节可以去Google安全团队的博客原文里面了解,当然也可以参考GitHub repo里面的说明。
在整个安全分析中,我们注意到Google安全团队最厉害的一点是他们对这个微码更新机制的逆向工程,作为并没有购买Zen1资产的一家 小软件 公司的安全团队,他们究竟是怎么分析整个机制,识别出所使用的不安全(AES-CMAC)算法和恢复出CMAC key,以及分析相关的消息格式,简直可以评上2024年的逆向工程奥斯卡奖了。Google安全博客上也立了个flag,会在未来一段时间内公开细节,大家敬请期待!
最后,Google安全团队还鼓励大家利用这套机制去改造自家的EPYC处理器,玩出新的花样,因为这个也不是第一次有人这么干了,在2023年的OffensiveCon上就有一个议题。所以如果你对这个议题感兴趣,同时又苦于没有EPYC处理器,那么欢迎加入G.O.S.S.I.P,在我们的好多台EPYC服务器上做实验!
博客原文:https://bughunters.google.com/blog/5424842357473280/zen-and-the-art-of-microcode-hacking
原文始发于微信公众号(安全研究GoSSIP):G.O.S.S.I.P 阅读推荐 2025-03-06 禅与AMD CPU维修艺术
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论