CNVD-2017-03792
披露信息:https://www.cnvd.org.cn/flaw/show/CNVD-2017-03792
CNVD 编号:CNVD-2017-03792
漏洞评分:6.8(AV:L/AC:M/Au:S/C:N/I:N/A:C)
漏洞描述:深信服EasyConnect PC客户端7.1.0.4版本由于二进制路径有空格(Program Files)并且整个路径没有用没有双引号括起来,存在exe劫持漏洞,允许攻击者利用漏洞可以以SYSTEM权限在受害者机器上执行任意代码。
easyconnect 7.1.0.4 版本软件下载地址:
1 | 链接:https://pan.baidu.com/s/1f1xX4ypV0zTtQ5Q_fnaGCQ |
漏洞描述中提到攻击者可以利用这个漏洞实现提权,以 SYSTEM 权限执行任意代码,安装好软件之后通过任务管理器可以看到名为 SangforPromoteService.exe 的程序,它运行在 SYSTEM 权限下。
首先打开终端,执行 tasklist 命令查看此进程的 PID:
然后执行 netstat -ano 查看它是否监听了端口:
1 | TCP 127.0.0.1:10000 0.0.0.0:0 LISTENING 4244 |
这个进程监听 TCP 10000 以及 UDP 40000 两个端口,根据 C 语言中网络编程相关内容,我们可以在程序中通过 recv 以及 recvfrom 两个函数定位关键代码。
SangforPromoteService.exe 逻辑简述
注:程序版本为 7.1.0.1,MD5:a82bff2f271c86b125def8a1138adde3
关键函数:sub_413720
1 | void __cdecl sub_413720(SOCKET s) |
第 5 行调用 recv 函数接收从 10000 端口发送过来的数据,保存到 buf 中。第 21 行对接收到的数据中某些字节判断,如果不满足就执行函数 sub_401695。
1 | int __thiscall sub_40FBC0(void *this, int ArgList, int a2, int a3) |
第 11 行存在 switch 结构,v4 是从用户输入的数据中提取得到,根据不同的值执行 4 个不同的功能函数。
- UpdateSuperService:更新文件 SangforPromote.exe
- StartSuperExe:执行文件 SangforPromote.exe
- StopSuperExe:停止 SangforPromote.exe 进程
- IsServiceOK:查询 SangforPromote.exe 进程是否正常
其中 StartSuperExe 函数代码如下
1 | strcpy(&Src, "%ProgramFiles%\Sangfor\SSL\Promote"); |
仔细观察 CreateProcessAsUserA 函数的使用,其中 lpApplicationName 参数设置成 null,lpCommandLine 参数是 Dst,即经过 ExpandEnvironmentStringsA 处理的路径。
这是一个比较经典的问题,如果 lpApplicationName 中包含有空值,且 lpCommandLine 变量中的完整模块路径包含有空白符,但是没有包含在引号中的话,就可能会执行其他程序。
例如路径 C:\Program Files (x86)\Sangfor\SSL\Promote\SangforPromote.exe,如果没有被引号包裹就传递进入 CreateProcessAsUserA,系统可能会解析成以下情况
1 | C:\Program.exe Files (x86)\Sangfor\SSL\Promote\SangforPromote.exe |
此时如果 C 盘根目录下有一个名为 Program.exe 的程序,它就会被执行。
通过交叉引用,可以定位到一个能够自动被触发的调用位置: sub_4120F0
1 | if ( !sub_4015DC(Dest, 0x104u) ) |
其中 dest 参数就是上述路径。
利用 OD 调试观察。首先简单编写一个小程序,将其命名为 Program.exe,放在目标系统的 C 根目录下,用 OD 附加到 SangforPromoteService.exe 进程,在地址 0x41228A 下断点,继续运行程序。
稍微等待几分钟断点会被触发
观察到此时 lpCommandLine 为目标程序路径,而且并没有引号包裹,步过发现 Program.exe 被启动,此外,程序还会运行到函数 sub_411820,代码如下
1 | int __stdcall sub_411820(unsigned __int8 *Source) |
第 27 行调用 CreateProcessA,第二个参数是 lpCommandLine,发现还是之前的程序路径,并且不包含引号。
执行完上述两部分代码,出现以下界面
我们的 Program.exe 被执行两次,一次以当前用户身份执行(CreateProcessAsUserA),第二次以 SYSTEM 身份执行(CreateProcessA)。
注:SangforPromoteService.exe 内部有一些 log 信息,可以使用 DebugView 软件来查看。
来看一下新版本中的修复措施,新版本添加一些代码片段
1 | snprintf_wrap(&Buffer, 260, "\"%s\"", &CommandLine); |
在 CommandLine 参数中添加了 “%s” 双引号约束,可以避免执行其他程序。
整数溢出导致非法地址访问
依旧是 EasyConnect PC 客户端,这里分析的版本是 7.6.3,下载链接
1 | 链接:https://pan.baidu.com/s/1YZJ7RoVADfD_TaZrt3sSQQ |
目标程序是 SangforPromote.exe,关键函数 sub_411B80
1 | signed int v10; // eax |
在上述代码片段中,v10 是用户可控的数据,并且被定义为 signed int,在进行长度判断时,没有考虑负数的情况,如果我们传入 0x80000000 类似的数据,会导致 qmemcpy (实际上是汇编代码的简化表示)拷贝过多的数据,并访问到非法内存地址。
POC:
1 | #!/usr/bin/python |
程序的启动方法:SangforPromote.exe /StartServer
OD 附加到进程,在地址 0x411F7F 下断点,然后运行 poc
观察发现此时 ECX 为 0x20000000,拷贝的次数远大于内存容量,继续执行会出现错误信息:
- 本文作者: CataLpa
- 本文链接: https://wzt.ac.cn/2021/03/16/vulns1/
-
版权声明:
本作品采用知识共享署名-相同方式共享 4.0 国际许可协议进行许可。