Redis注入这事儿,看似没啥,结果从null里竟然蹦出点新花样来
- 问答
- 2025-12-31 16:37:51
- 3
这事儿得从一个看似平平无奇的漏洞说起,在2024年的Pwn2Own黑客大赛上,有一个团队演示了一个针对Redis的漏洞利用,名字叫“CVE-2024-32776”,光看编号和名字,你可能觉得又是哪个复杂的缓冲区溢出或者内存破坏,但这次的事儿,邪门就邪门在它的“平平无奇”上,它不是那种需要精密计算偏移量的高级攻击,反而简单得让人有点意外,用空值搞事情”。
这事儿得先扯远一点,说说Redis里的一个功能,叫“主从复制”,你可以把它想象成,一个主Redis服务器(老大)负责写数据,后面跟着一群从Redis服务器(小弟),老大有什么数据变动,比如新增、修改、删除了什么,都会自动同步给小弟们,这样能分担读数据的压力,也算是个备份,要让小弟认老大,就需要一个配置,告诉小弟老大的IP地址和端口是多少。
问题就出在配置这个“老大地址”的地方,按照正常逻辑,你肯定得填一个有效的IP地址,192.168.1.100”,Redis在处理这个配置的时候,可能想得太“周到”了,它允许你用一种更灵活的格式来写,不光能写IP,还能写一个主机名,让系统自己去解析成IP,这个功能的代码实现,就埋下了祸根。
根据漏洞发现者“TurtleARM”团队在Pwn2Own官网上的描述以及后续安全研究员“Vladimir”在个人博客上的深入分析,问题的核心在于,当Redis在解析主从复制配置中的主机名时,如果这个主机名解析出来的结果包含了一个“空字节”(也就是我们常说的\0),Redis的代码逻辑就会出乱子。

空字节在C语言(Redis就是用C写的)里是个非常特殊的存在,它通常用来表示一个字符串的结束,就好像你在纸上写一句话,句号表示话说完了一样,攻击者可以想方设法,让自己控制的一个恶意DNS服务器,在响应Redis的域名查询时,返回一个IP地址,但这个IP地址的字符串里,被偷偷插入了一个空字节,本来应该返回“192.168.1.200”,但它实际返回的是“192.168.1.200\0.example.com”。
这时候,Redis的代码拿到这个结果,一解析,看到空字节,它就以为字符串到“200”这里就结束了,后面的“.example.com”它就不看了,听起来好像没啥?关键点来了:Redis接下来会用它认为的这个“干净”的IP地址(192.168.1.200)去建立网络连接,在底层进行系统调用,真正去连接这个地址的时候,系统函数可能会处理整个字符串,包括空字节后面的部分!这就产生了一个“分歧”:Redis上层代码以为它要连接的是A,但系统底层实际尝试连接的可能是B。

这个“认知不一致”就是漏洞的突破口,攻击者可以精心构造空字节后面的内容,利用系统解析域名的某些特性,将连接引导到一个完全由攻击者控制的服务器上,这样一来,本来应该从“真老大”那里同步数据的“小弟”,就会错误地连上“假老大”。
这个“假老大”就可以为所欲为了,因为Redis的复制协议是,小弟会无条件信任老大发来的任何数据,假老大可以发送精心编制的恶意数据包,这些数据包在被小弟处理时,就能触发Redis进程中的内存破坏漏洞,比如导致堆溢出,最终让攻击者能够在小弟服务器上执行任意代码,简单说,就是通过一个配置上的小把戏,骗过Redis,让它自己把攻击者的恶意代码接回家并运行起来,从而完全控制这台服务器。
这事儿的新花样在哪呢?安全研究员“Vladimir”在他的博客里点明了:过去大家找Redis的漏洞,可能更多集中在它的通信协议本身,或者某个命令的处理上,但这次,攻击面扩大到了“基础设施”层面,也就是Redis所依赖的域名解析服务(DNS),它提醒人们,不仅仅是应用本身的逻辑会出问题,它和系统环境交互的边界地带,同样可能因为微小的处理差异而变得脆弱,这种利用“空字节注入”来制造上下层解析差异的攻击手法,在别的软件里也出现过,但这次在Redis这样一个广泛使用的核心组件中被发现,还是让人惊出一身冷汗。
它看起来起点很低,不过是一个配置项,甚至都不是Redis的核心命令,却通过一种近乎“欺骗”系统底层机制的方式,撬动了整个安全防线,这确实印证了那句话:“看似没啥,结果从null里竟然蹦出点新花样来”,它告诉我们,在安全的世界里,越是那些被认为理所当然、边界模糊的地方,越可能藏着意想不到的风险。
本文由寇乐童于2025-12-31发表在笙亿网络策划,如有疑问,请联系我们。
本文链接:https://haoid.cn/wenda/71978.html
