ai for CVE-2025-6218

漏洞原理

一个逻辑处理错误导致的目录穿越漏洞,原理就是在处理路径时如果遇到了空格就直接跳过然后直接返回给解压的最终路径。

几个问题:

  1. 为什么没有空格就不会触发这个漏洞?
  2. 修复的方案是什么?

简单分析

核心的路径校验分几个阶段:

在提取路径的函数中上来就会进行一次对/../这类子串的去除:

1
2
.text:000000014014E370 49 8B CA                                                        mov     rcx, r10
.text:000000014014E373 E8 60 47 FA FF call CanonicalizePathWithDotDot ;这个函数主要处理/../和./等相对路径

debug\..\..\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup\这样路径的压缩包,可以看到经过这个函数以后,路径0x0000000140270F08里指针的路径的变化:

前:

1
2
000000014014E370  | 49:8BCA           | mov rcx,r10                             | r10:&L" \\..\\..\\AppData\\Roaming\\Microsoft\\Windows\\Start Menu\\Programs\\Startup\\POC2.bat"
000000014014E373 | E8 6047FAFF | call winrar.1400F2AD8 |

后:

1
2
3
000000014014E370  | 49:8BCA           | mov rcx,r10                             |
000000014014E373 | E8 6047FAFF | call winrar.1400F2AD8 |
000000014014E378 | 48:8D15 892B1200 | lea rdx,qword ptr ds:[140270F08] | 0000000140270F08:&L"AppData\\Roaming\\Microsoft\\Windows\\Start Menu\\Programs\\Startup\\POC2.bat" ;这里去除了/../

然后处理完了,还会进入14000990C函数对空格以及进一步对/../和/./这样的路径进行处理。但是该函数有一个逻辑缺陷,首先这个函数中直接处理/../这样相对路径的函数放在了函数体的开头:

1
2
3
//初始化变量的逻辑
CanonicalizePathWithDotDot(path);
//对其他特殊字符的处理逻辑

然后它虽然后续在1400F55A4的空格处理的过程中试图处理了/../这样的字符串,但是因为逻辑失误,导致遇到/../这样的字符串就会跳过处理:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
if ( v11[read_cur_index - 1] != '.' )
goto LABEL_81; // 此时假如当前的字符是'.',检查前一个字符是否为'.',如果是即存在'/../'就会直接跳过了,不会进入到LABEL_81中的删除字符逻辑
if ( operate_cur_index != 1 )
{
path_str_v12 = path_struct;
if ( path_struct[1].str_ptr > 7 )
path_str_v12 = path_struct->str_ptr;
if ( path_str_v12[read_cur_index - 2] != '\\'
&& path_str_v12[read_cur_index - 2] != '/'
&& (operate_cur_index != 3 || !IsWindowsDrivePath(path_struct)) )// 检查前两个字符是否为路径分隔符
{
LABEL_81:
WString_RemoveChars(path_struct, operate_cur_index, 1u);// 调用WString_InsertOrReplace删除字符;
--read_cur_index;
if ( --operate_cur_index >= 0 )
continue;
}
}

debug的payload中包含的\.. \.. \AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup\的字符串可以看到在经过这个函数以后,相对路径也不会去除:

前:

1
2
0000000140009A9C  | 75 08                        | jne winrar.140009AA6          |
0000000140009A9E | 48:8BCB | mov rcx,rbx | rbx:&L"C:\\Users\\test\\Desktop\\CVE-2025-6218\\ \\.. \\.. \\AppData\\Roaming\\Microsoft\\Windows\\Start Menu\\Programs\\Startup\\POC.bat"

后:

1
2
3
0000000140009A9E  | 48:8BCB                      | mov rcx,rbx                   | rbx:&L"C:\\Users\\test\\Desktop\\CVE-2025-6218\\\\..\\..\\AppData\\Roaming\\Microsoft\\Windows\\Start Menu\\Programs\\Startup\\POC.bat"
0000000140009AA1 | E8 FEBA0E00 | call winrar.1400F55A4 |
0000000140009AA6 | 48:8B5C24 30 | mov rbx,qword ptr ss:[rsp+30] |

按照这个思路,如果对判断前一个”.”的判断做处理,是”.”就跳到处理函数就可以了,实际测下来也确实可以修复漏洞:

1
2
3
0000000140009A9E  | 48:8BCB                      | mov rcx,rbx                   | rbx:&L"C:\\Users\\test\\Desktop\\CVE-2025-6218\\\\.\\.\\AppData\\Roaming\\Microsoft\\Windows\\Start Menu\\Programs\\Startup\\POC.bat"
0000000140009AA1 | E8 FEBA0E00 | call winrar.1400F55A4 |
0000000140009AA6 | 48:8B5C24 30 | mov rbx,qword ptr ss:[rsp+30] |

可以看到此时相对路径被修正了。

AI agent分析漏洞

那问题来了,如何使用agent挖掘这样一个路径穿越漏洞呢?

下面是一个初步的(最终失败了的)思路:

首先结合一个辅助agent分析的项目:https://github.com/P4nda0s/IDA-NO-MCP,它可以:

  1. 导出函数反编译伪代码;
  2. 导出函数导入导出表;
  3. 导出函数间的调用关系,

这些东西结合以下的流程:

1
2
3
4
5
6
7
8
9
分析出每个函数的作用<-使用上述工具export for ai的结果
->
攻击面分析:找出存在外部输入的函数调用(在winrar中外部入参主要是路径)/敏感导入函数的上层调用<-bincat分析的污点追踪结果
->
在存在外部输入的函数及子函数中分析漏洞<-历史的漏洞信息(winrar主要的历史漏洞为目录穿越)
->
分析的漏洞agent写exp测试
->
输出实锤的漏洞报告及poc/exp

这个逻辑大体上是可以在一些场景下发现漏洞的,为了验证这套流程,使用了之前找的一些没有加密的存在漏洞的路由器的固件,挖了下 httpd 服务的漏洞,可以得到一些明显的漏洞,比如命令注入:

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
50
51
52
53
54
55
56
57
58
59
int sub_A620C()
{
size_t v0; // r0
char v2[256]; // [sp+0h] [bp-40Ch] BYREF
char dest[256]; // [sp+100h] [bp-30Ch] BYREF
char v4[256]; // [sp+200h] [bp-20Ch] BYREF
char s[256]; // [sp+300h] [bp-10Ch] BYREF

memset(s, 0, sizeof(s));
memset(v4, 0, sizeof(v4));
memset(dest, 0, sizeof(dest));
memset(v2, 0, sizeof(v2));
GetValue();
GetValue();
if ( !s[0] )
memcpy(s, "admin", 5u);
if ( v4[0] )
{
// 如果存在密码进入这里的逻辑
v0 = strlen(v4);
strncpy(dest, v4, v0);
}
else
{
memcpy(dest, "admin", 5u);
}
fill_smbpasswd_input_file(dest); // 将用户密码填充到smbpasswd文件里
sprintf(v2, "smbpasswd -a %s -s < /tmp/smbpasswd", s); // 然后将用户添加到smb服务,使用smbpasswd作为密码
system(v2);
return 0;
}


int __fastcall fill_smbpasswd_input_file(const char *a1)
{
size_t v1; // r0
size_t v2; // r0
int fd; // [sp+8h] [bp-14h]

if ( unlink("/tmp/smbpasswd") == -1 )
puts("******* unlink /tmp/smbpasswd is fail ");
fd = open("/tmp/smbpasswd", 4674);
if ( fd > 0 && a1 )
{
v1 = strlen(a1);
write(fd, a1, v1);
write(fd, "\n", 1u);
v2 = strlen(a1);
write(fd, a1, v2);
close(fd);
return 1;
}
else
{
if ( !fd )
close(0);
return 0;
}
}

但是当我在用这个流程分析这个存在漏洞的版本的winrar时候就发现它会一直用旧的漏洞搪塞我:

反编译代码证据:

1
2
3
4
5
6
7
8
// IDA Pro 反编译输出 @ 0x14001c292
pExecInfo.cbSize = 112;
pExecInfo.fMask = 64;
pExecInfo.hwnd = hWndParent;
pExecInfo.lpFile = v42; // 用户控制的文件路径
pExecInfo.lpParameters = v43; // 用户控制的参数
pExecInfo.nShow = a1 != 0 ? 6 : 1;
v48 = ShellExecuteExW(&pExecInfo);

但其实这个代码的最上面就是刚才说的路径处理的函数。

然后也简单反思了下,为啥这套逻辑分析不了上面的漏洞:

  1. 就是上面这个漏洞更偏向于逻辑缺陷,而非常见的可以直接根据source->sink的逻辑就可以得到的漏洞。
  2. 给的skills里包含了历史的漏洞,让ai的幻觉增强了。

然后我实际上也让模型构建poc去验证这些漏洞(比如一个简单的压缩包),然后模型就老实了,说这些漏洞都已经修复:

除此以外,x64dbg也是有mcp的:https://github.com/AgentSmithers/x64DbgMCPServer

这里因为静态分析都没分析出来,就没必要调试了。。。

debug info

1
2
3
4
C:\Users\test\Desktop\CVE-2025-6218\\.. \.. \AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup\POC.bat

C:\Users\test\Desktop\CVE-2025-6218\\.. \.. \\AppData\\Roaming\\Microsoft\\Windows\\Start Menu\\Programs\\Startup\\POC.bat

  • 路径字符串的指针:0x0000000140270F08
  • 主解压函数:0x00000001400101FC
  • 处理路径格式的函数:0x000000014000990C
    • 处理特殊路径名称字符串的函数:0x00000001400F55A4
  • 检查字符串长度是否大于0(会将\\转换为/):00000001400F55DA
  • 检查下一个宽字节是否是\\或者/:0x00000001400F5600
  • 处理当前子串的起点:0x00000001400F561C