十二年前的漏洞——对某旺控件栈溢出漏洞的学习
字数 1841 2025-08-25 22:58:20

阿里旺旺ImageMan.dll控件栈溢出漏洞分析与复现

漏洞概述

本文详细分析阿里旺旺6.50.00C版本中ImageMan.dll控件的AutoPic函数栈溢出漏洞。该漏洞存在于一个ActiveX控件中,通过构造特殊的参数可导致栈缓冲区溢出,最终实现任意代码执行。

环境准备

  • 目标软件:阿里旺旺6.50.00C
  • 操作系统:Windows XP
  • 调试工具:OllyDbg(OD)或x64dbg
  • 辅助工具:COMRaider(用于ActiveX控件Fuzz测试)
  • 漏洞文件:Pictool/ImageMan.dll

漏洞定位

漏洞存在于ImageMan.dll中的AutoPic函数,具体问题出在该函数对输入参数的处理不当,导致栈缓冲区溢出。

调试方法

ActiveX控件调试技巧

  1. 关键断点设置

    • 在OLEAUT32.dll的DispCallFunc函数下断点
    • 网页调用ActiveX组件时,浏览器会先后调用GetIDsOfNamesInvoke函数
    • Invoke函数内部最终会调用OLEAUT32!DispCallFunc
  2. 调试流程:

    • DispCallFunccall ecx指令处中断
    • F7单步进入函数入口点
    • 观察[ebp+C]参数和WideCharToMultiByte调用

漏洞分析

关键函数伪代码

int __stdcall AutoPic(int a1, LPCWSTR lpWideCharStr, int a3)
{
  const OLECHAR *v4; // eax
  char v5; // [esp+Ch] [ebp-314h]
  CHAR String; // [esp+10h] [ebp-310h]
  char v7; // [esp+11h] [ebp-30Fh]
  __int16 v8; // [esp+111h] [ebp-20Fh]
  char v9; // [esp+113h] [ebp-20Dh]
  char *v10; // [esp+114h] [ebp-20Ch]
  CHAR MultiByteStr; // [esp+118h] [ebp-208h]
  char v12; // [esp+119h] [ebp-207h]
  __int16 v13; // [esp+219h] [ebp-107h]
  char v14; // [esp+21Bh] [ebp-105h]
  char v15; // [esp+21Ch] [ebp-104h]
  char v16; // [esp+21Dh] [ebp-103h]
  __int16 v17; // [esp+31Dh] [ebp-3h]
  char v18; // [esp+31Fh] [ebp-1h]

  MultiByteStr = 0;
  memset(&v12, 0, 0x100u);
  v13 = 0;
  v14 = 0;
  WideCharToMultiByte(0, 0, lpWideCharStr, -1, &MultiByteStr, 260, 0, 0);
  String = 0;
  memset(&v7, 0, 0x100u);
  v8 = 0;
  v9 = 0;
  v10 = strrchr(&MultiByteStr, 92);  // 查找反斜杠'\'
  v15 = 0;
  memset(&v16, 0, 0x100u);
  v17 = 0;
  v18 = 0;
  mbsnbcpy((unsigned __int8 *)&v15, (unsigned __int8 *)&MultiByteStr, v10 - &MultiByteStr + 1);
  sub_100271FE(&v15);
  sub_10018BA1(&MultiByteStr, &String);
  sub_1001BFE0(&String);
  if ( a3 )
  {
    v4 = (const OLECHAR *)sub_1001C060(&v5);
    *(_DWORD *)a3 = SysAllocString(v4);
  }
  sub_1001C040(&v5);
  return 0;
}

漏洞触发流程

  1. 字符串转换

    • 使用WideCharToMultiByte将宽字符参数转换为多字节字符串
    • 转换结果存储在MultiByteStr缓冲区(260字节)
  2. 路径处理

    • 调用strrchr查找最后一个反斜杠''(ASCII码92)
    • 如果输入字符串中没有反斜杠,v10返回NULL
  3. 危险复制操作

    mbsnbcpy((unsigned __int8 *)&v15, (unsigned __int8 *)&MultiByteStr, v10 - &MultiByteStr + 1);
    
    • v10为NULL时,v10 - &MultiByteStr + 1计算结果为负值
    • 由于参数类型为unsigned __int8,负值会被解释为很大的正数
    • 导致mbsnbcpy复制过多数据到v15缓冲区(仅260字节),造成栈溢出

关键点分析

  1. mbsnbcpy函数

    • 类似strcpy的不安全函数
    • 微软文档指出其存在安全隐患
    • 函数原型:errno_t mbsnbcpy(unsigned char *strDest, const unsigned char *strSource, size_t count);
  2. 缓冲区大小

    • MultiByteStrv15缓冲区大小均为260字节
    • 但复制长度计算错误时,可以写入远超缓冲区大小的数据
  3. 漏洞触发条件

    • 输入字符串长度超过260字节
    • 输入字符串中不包含反斜杠''

漏洞复现

POC构造

  1. JavaScript POC

    // 创建ActiveX对象
    var obj = new ActiveXObject("ImageMan.ImageMan.1");
    // 构造超长无斜杠字符串
    var payload = "A".repeat(1000);
    // 调用漏洞函数
    obj.AutoPic(0, payload, 0);
    
  2. 调试观察

    • DispCallFunccall ecx处中断
    • 单步跟踪到mbsnbcpy调用
    • 观察栈区域被'A'(0x41)填充的情况
    • 最终EIP被覆盖为0x41414141,验证漏洞存在

漏洞利用

虽然本文未详细讨论利用细节,但实际利用可能涉及以下技术:

  1. 堆喷射(Heap Spraying)

    • 在内存中布置大量包含shellcode的块
    • 增加跳转到shellcode的概率
  2. ROP链构造

    • 绕过DEP保护
    • 组合现有代码片段实现任意功能
  3. ASLR绕过

    • 寻找未随机化的模块
    • 使用信息泄露获取模块基址

注意事项

  1. COMRaider测试问题

    • 使用COMRaider生成的VBS POC可能无法触发崩溃
    • 相同逻辑的JS POC可以成功触发
    • 可能原因:两种语言对ActiveX控件的调用方式存在差异
  2. 防护绕过

    • 现代系统有DEP、ASLR等防护机制
    • 实际利用需要结合多种绕过技术

修复建议

  1. 输入验证

    • 检查输入字符串长度
    • 确保路径格式合法
  2. 安全函数替换

    • 使用mbsnbcpy_s等安全版本
    • 或改用strncpy并明确指定最大长度
  3. 缓冲区大小检查

    • 在复制前验证源字符串长度
    • 确保不超过目标缓冲区大小

总结

该漏洞是典型的栈缓冲区溢出案例,由于对用户输入缺乏充分验证,加上使用了不安全的字符串复制函数,导致攻击者可以控制程序执行流程。通过分析此类漏洞,我们可以学习到:

  1. ActiveX控件的分析方法
  2. 不安全字符串函数的危害
  3. 栈溢出漏洞的调试技巧
  4. 实际漏洞利用中的各种挑战

对于安全研究人员,理解这类漏洞的原理和利用方式,有助于更好地发现和防范类似安全问题。

阿里旺旺ImageMan.dll控件栈溢出漏洞分析与复现 漏洞概述 本文详细分析阿里旺旺6.50.00C版本中ImageMan.dll控件的AutoPic函数栈溢出漏洞。该漏洞存在于一个ActiveX控件中,通过构造特殊的参数可导致栈缓冲区溢出,最终实现任意代码执行。 环境准备 目标软件:阿里旺旺6.50.00C 操作系统:Windows XP 调试工具:OllyDbg(OD)或x64dbg 辅助工具:COMRaider(用于ActiveX控件Fuzz测试) 漏洞文件: Pictool/ImageMan.dll 漏洞定位 漏洞存在于ImageMan.dll中的 AutoPic 函数,具体问题出在该函数对输入参数的处理不当,导致栈缓冲区溢出。 调试方法 ActiveX控件调试技巧 关键断点设置 : 在OLEAUT32.dll的 DispCallFunc 函数下断点 网页调用ActiveX组件时,浏览器会先后调用 GetIDsOfNames 和 Invoke 函数 Invoke 函数内部最终会调用 OLEAUT32!DispCallFunc 调试流程: 在 DispCallFunc 的 call ecx 指令处中断 F7单步进入函数入口点 观察 [ebp+C] 参数和 WideCharToMultiByte 调用 漏洞分析 关键函数伪代码 漏洞触发流程 字符串转换 : 使用 WideCharToMultiByte 将宽字符参数转换为多字节字符串 转换结果存储在 MultiByteStr 缓冲区(260字节) 路径处理 : 调用 strrchr 查找最后一个反斜杠'\'(ASCII码92) 如果输入字符串中没有反斜杠, v10 返回NULL 危险复制操作 : 当 v10 为NULL时, v10 - &MultiByteStr + 1 计算结果为负值 由于参数类型为 unsigned __int8 ,负值会被解释为很大的正数 导致 mbsnbcpy 复制过多数据到 v15 缓冲区(仅260字节),造成栈溢出 关键点分析 mbsnbcpy 函数 : 类似 strcpy 的不安全函数 微软文档指出其存在安全隐患 函数原型: errno_t mbsnbcpy(unsigned char *strDest, const unsigned char *strSource, size_t count); 缓冲区大小 : MultiByteStr 和 v15 缓冲区大小均为260字节 但复制长度计算错误时,可以写入远超缓冲区大小的数据 漏洞触发条件 : 输入字符串长度超过260字节 输入字符串中不包含反斜杠'\' 漏洞复现 POC构造 JavaScript POC : 调试观察 : 在 DispCallFunc 的 call ecx 处中断 单步跟踪到 mbsnbcpy 调用 观察栈区域被'A'(0x41)填充的情况 最终EIP被覆盖为0x41414141,验证漏洞存在 漏洞利用 虽然本文未详细讨论利用细节,但实际利用可能涉及以下技术: 堆喷射(Heap Spraying) : 在内存中布置大量包含shellcode的块 增加跳转到shellcode的概率 ROP链构造 : 绕过DEP保护 组合现有代码片段实现任意功能 ASLR绕过 : 寻找未随机化的模块 使用信息泄露获取模块基址 注意事项 COMRaider测试问题 : 使用COMRaider生成的VBS POC可能无法触发崩溃 相同逻辑的JS POC可以成功触发 可能原因:两种语言对ActiveX控件的调用方式存在差异 防护绕过 : 现代系统有DEP、ASLR等防护机制 实际利用需要结合多种绕过技术 修复建议 输入验证 : 检查输入字符串长度 确保路径格式合法 安全函数替换 : 使用 mbsnbcpy_s 等安全版本 或改用 strncpy 并明确指定最大长度 缓冲区大小检查 : 在复制前验证源字符串长度 确保不超过目标缓冲区大小 总结 该漏洞是典型的栈缓冲区溢出案例,由于对用户输入缺乏充分验证,加上使用了不安全的字符串复制函数,导致攻击者可以控制程序执行流程。通过分析此类漏洞,我们可以学习到: ActiveX控件的分析方法 不安全字符串函数的危害 栈溢出漏洞的调试技巧 实际漏洞利用中的各种挑战 对于安全研究人员,理解这类漏洞的原理和利用方式,有助于更好地发现和防范类似安全问题。