做过不少ctf中的pwn,但还是头一次复现windows的溢出漏洞。

   目的有二:

  •   第一:学会使用windbg,了解它的适用情况和优势。
  •   第二:体验在windows下调试溢出漏洞,看看和linux下调试有何不同。

#0x01 漏洞背景

  2017.11.14   微软发布11月补丁,修复了包括CVE-2017-11882在内的多个漏洞。 随后不久,安全公司EMBEDI在官方博客上公开了其向微软提交的编号为CVE-2017-11882的Office远程代码执行漏洞:https://embedi.com/blog/skeleton-closet-ms-office-vulnerability-you-didnt-know-about,讲述了漏洞的发现过程和部分细节。

  漏洞出现在模块EQNEDT32.EXE中,该模块为公式编辑器,在Office的安装过程中被默认安装。该模块以OLE技术(Object Linking and Embedding,对象链接与嵌入)将公式嵌入在Office文档内。当插入和编辑数学公式时,EQNEDT32.EXE并不会被作为Office进程(如Word等)的子进程创建,而是以单独的进程形式存在。这就意味着对于WINWORD.EXE, EXCEL.EXE等Office进程的保护机制,无法阻止EQNEDT32.EXE这个进程被利用。

  漏洞存在于EQNEDT32.EXE处理Office OLE Equation对象中标记为字体名称记录的字节流中,如果Equation对象中存在标记为字体名称的超长字节流,则程序在处理该字符串的过程,会由于判断字符串长度而发生栈溢出漏洞。

  攻击者可以通过刻意构造的数据内容覆盖掉栈上的函数地址,从而劫持程序流程,可以利用漏洞以当前登录的用户的身份执行任意命令。而且该漏洞没有弹窗,用户感觉不到。

  影响版本:

Office 365

Microsoft Office 2000      

Microsoft Office 2003      

Microsoft Office 2007 Service Pack 3

Microsoft Office 2010 Service Pack 2

Microsoft Office 2013 Service Pack 1

Microsoft Office 2016

#0x02 漏洞复现

  复现环境:win7sp1+Microsoft office 2013

  首先在github上找一个poc:https://github.com/embedi/CVE-2017-11882

  在漏洞环境上运行成功弹出计算器。

  

通过Process Explorer查看进程情况,可以看到最终执行命令的父进程是EQNEDT32.EXE。

  

根据漏洞的描述可知,EQNEDT32.EXE是一个单独执行的进程。所以对它的调试相当于调试一个由进程创建的另一个进程。

大佬们早已给出了方法:https://www.52pojie.cn/thread-196194-1-1.html

在HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersioin\Image File Execution Options\下创建字段EQNEDT32.EXE。

下面创建一个名为debugger的字符串,值为windbg的路径。

由于触发结果是创建了进程打开cmd.exe。

所以可以在WinExec和CreateProcessw下断点。然后执行。

bp 下断点
bl  显示断点
g   GO执行
bc  [index]删除断点

程序中断后,观察栈里的返回地址和参数。

 定位到代码里,是对winexec的调用。

再往上找:

继续跟进找到第一个call:

查看伪代码其伪代码:

int __cdecl sub_41160F(char *a1, char *a2, int a3)
{
  int result; // eax@12
  char v4; // [sp+Ch] [bp-88h]@5
  char v5; // [sp+30h] [bp-64h]@4
  __int16 v6; // [sp+51h] [bp-43h]@5
  char *v7; // [sp+58h] [bp-3Ch]@7
  int v8; // [sp+5Ch] [bp-38h]@1
  __int16 v9; // [sp+60h] [bp-34h]@1
  int v10; // [sp+64h] [bp-30h]@1
  __int16 v11; // [sp+68h] [bp-2Ch]@1
  char v12; // [sp+6Ch] [bp-28h]@1
  int v13; // [sp+90h] [bp-4h]@1

  LOWORD(v13) = -1;
  LOWORD(v8) = -1;
  v9 = strlen(a1);
  strcpy(&v12, a1);
  _strupr(&v12);
  v11 = sub_420FA0();
  LOWORD(v10) = 0;
  while ( v11 > (signed __int16)v10 )
  {
    if ( sub_420FBB(v10, &v5) )
    {
      strcpy(&v4, &v5);
      if ( v6 == 1 )
        _strupr(&v4);
      v7 = strstr(&v4, a1);
      if ( v7 || (v7 = strstr(&v4, &v12)) != 0 )
      {
        if ( !a2 || !strstr(&v4, a2) )
        {
          if ( (signed __int16)strlen(&v5) == v9 )
          {
            strcpy((char *)a3, &v5);
            return 1;
          }
          if ( v7 == &v4 )
            LOWORD(v8) = v10;
          else
            LOWORD(v13) = v10;
        }
      }
    }
    LOWORD(v10) = v10 + 1;
  }
  if ( (signed __int16)v8 < 0 )
  {
    if ( (signed __int16)v13 < 0 )
    {
      result = 0;
    }
    else
    {
      sub_420FBB(v13, &v5);
      strcpy((char *)a3, &v5);
      result = 1;
    }
  }
  else
  {
    sub_420FBB(v8, &v5);
    strcpy((char *)a3, &v5);
    result = 1;
  }
  return result;
}

可以看到在其对strcpy的处理中没有限制长度,复制位置在bp-0x28,如果a1长度超过0x28,就会覆盖接下来的ebp和返回地址。

查看其参数情况:

 

在执行完strcpy后,ebp-0x28的位置被修改。

而返回地址被修改为0x00430c12,就是执行winexec的地址:

所以可以对应到poc的关键位置。

修改payload:

打开新的poc文件,成功弹出notepad:

 ps:获取shell的方法可以利用mshta,参考:https://blog.csdn.net/qq_27446553/article/details/78694488

  

#0x03 参考

    1. https://bbs.pediy.com/thread-247740.htm
    2. https://www.freebuf.com/vuls/154462.html
posted on 2018-12-21 15:16  apossin  阅读(657)  评论(0编辑  收藏  举报