zoukankan      html  css  js  c++  java
  • CVE-2017-11882---Microsoft Office数学公式编辑器内存损坏漏洞

     做过不少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_MACHINESOFTWAREMicrosoftWindows NTCurrentVersioinImage 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
  • 相关阅读:
    如何分析页面性能?
    Java io包 ByteArrayInputStream&ByteArrayOutStream
    Java io包 inputstream&outputstream
    Java executors创建线程池和使用ThreadPoolExecutor
    Android异步任务处理
    TCP报文格式
    Java 异常
    死锁
    计算机网络-传输层
    Linux 进程同步和通信
  • 原文地址:https://www.cnblogs.com/apossin/p/10155896.html
Copyright © 2011-2022 走看看