Rizin 是一个从 radare2 分支出来的逆向工程框架,在其 ELF 解析器代码中发现了一个缺陷,允许构造的文件执行拒绝服务攻击。这将阻止用户将文件加载到 rizin 中,但对文件本身的执行没有影响。
普通的 ELF 文件依赖于动态链接/加载,因此嵌入了大量信息。其中一项信息是在 .dynamic 部分中找到的 DT_VERNEEDNUM 条目,该字段指定了符号版本依赖表中的条目数量。因此,该值应用于解析每个版本依赖项,但表的设计使得在最后一个 verneed 条目上,vn_next 字段将等于 0。然而,rizin 并非循环遍历每个条目直到检测到末尾,而是使用从 DT_VERNEEDNUM 条目中检索到的值来遍历表条目。这造成了 DT_VERNEEDNUM 值可能被伪造为非常大的情况,例如 0xFFFFFFFFFFFFFFFF,导致 ELF 解析器不断在最后一个条目上旋转,认为它还有更多条目要迭代,通过计算下一个条目的偏移量(使用现在为空的 vn_next 字段)。尽管这影响了 rizin 的 elf 解析器,但不会对二进制的执行产生任何影响,因为 Linux 加载器会检测到它已到达表的末尾,而 DT_VERNEEDNUM 是假的。这提供了一个简单的解决方案,只需检测 vn_next 何时为空,然后跳出循环。
该漏洞存在于 v0.5.0 之前的版本中,并在提交 4564986ef29f8872a95733416ce0a860ac2aa7e5 中修复,受影响文件和函数为 librz/bin/format/elf/elf_info.c:get_gnu_verneed(ELFOBJ *bin)。
https://github.com/rizinorg/rizin/pull/3214
https://github.com/rizinorg/rizin/pull/3214/commits/4564986ef29f8872a95733416ce0a860ac2aa7e5