Land #9299, Add arch to MS17-010 detection

This commit is contained in:
William Webb 2017-12-14 12:20:56 -08:00
commit 234ef5627e
No known key found for this signature in database
GPG Key ID: 341763D0308DA650
3 changed files with 83 additions and 60 deletions

View File

@ -143,6 +143,70 @@ module Exploit::Remote::DCERPC
end
end
# XXX: Copypasta from exploit/windows/smb/ms17_010_eternalblue
#
# https://github.com/CoreSecurity/impacket/blob/master/examples/getArch.py
# https://msdn.microsoft.com/en-us/library/cc243948.aspx#Appendix_A_53
def dcerpc_getarch
ret = nil
connect_timeout = (datastore['ConnectTimeout'] || 10).to_i
read_timeout = (datastore['DCERPC::ReadTimeout'] || 10).to_i
pkt = Rex::Proto::DCERPC::Packet.make_bind(
# Abstract Syntax: EPMv4 V3.0
'e1af8308-5d1f-11c9-91a4-08002b14a0fa', '3.0',
# Transfer Syntax[1]: 64bit NDR V1
'71710533-beba-4937-8319-b5dbef9ccc36', '1.0'
).first
begin
nsock = Rex::Socket::Tcp.create(
'PeerHost' => rhost,
'PeerPort' => 135,
'Proxies' => proxies,
'Timeout' => connect_timeout,
'Context' => {
'Msf' => framework,
'MsfExploit' => self
}
)
rescue Rex::ConnectionError => e
vprint_error(e.to_s)
return nil
end
nsock.put(pkt)
begin
res = nsock.get_once(60, read_timeout)
rescue EOFError
vprint_error('DCE/RPC socket returned EOFError')
return nil
end
disconnect(nsock)
begin
resp = Rex::Proto::DCERPC::Response.new(res)
rescue Rex::Proto::DCERPC::Exceptions::InvalidPacket => e
vprint_error(e.to_s)
return nil
end
# Ack result: Acceptance (0)
if resp.ack_result.first == 0
ret = ARCH_X64
end
# Ack result: Provider rejection (2)
# Ack reason: Proposed transfer syntaxes not supported (2)
if resp.ack_result.first == 2 && resp.ack_reason.first == 2
ret = ARCH_X86
end
ret
end
# Convert a standard ASCII string to 16-bit Unicode
def unicode(str)
Rex::Text.to_unicode(str)

View File

@ -4,6 +4,7 @@
##
class MetasploitModule < Msf::Auxiliary
include Msf::Exploit::Remote::DCERPC
include Msf::Exploit::Remote::SMB::Client
include Msf::Exploit::Remote::SMB::Client::Authenticated
@ -50,7 +51,8 @@ class MetasploitModule < Msf::Auxiliary
register_options(
[
OptBool.new('CHECK_DOPU', [true, 'Check for DOUBLEPULSAR on vulnerable hosts', true])
OptBool.new('CHECK_DOPU', [true, 'Check for DOUBLEPULSAR on vulnerable hosts', true]),
OptBool.new('CHECK_ARCH', [true, 'Check for architecture on vulnerable hosts', true])
])
end
@ -76,12 +78,23 @@ class MetasploitModule < Msf::Auxiliary
vprint_status("Received #{status} with FID = 0")
if status == "STATUS_INSUFF_SERVER_RESOURCES"
print_good("Host is likely VULNERABLE to MS17-010! (#{simple.client.peer_native_os})")
os = simple.client.peer_native_os
if datastore['CHECK_ARCH']
case dcerpc_getarch
when ARCH_X86
os << ' x86 (32-bit)'
when ARCH_X64
os << ' x64 (64-bit)'
end
end
print_good("Host is likely VULNERABLE to MS17-010! - #{os}")
report_vuln(
host: ip,
name: self.name,
refs: self.references,
info: 'STATUS_INSUFF_SERVER_RESOURCES for FID 0 against IPC$ -- (#{simple.client.peer_native_os})'
info: "STATUS_INSUFF_SERVER_RESOURCES for FID 0 against IPC$ - #{os}"
)
# vulnerable to MS17-010, check for DoublePulsar infection

View File

@ -10,7 +10,7 @@ require 'windows_error'
class MetasploitModule < Msf::Exploit::Remote
Rank = AverageRanking
include Msf::Exploit::Remote::Tcp
include Msf::Exploit::Remote::DCERPC
def initialize(info = {})
super(update_info(info,
@ -267,63 +267,9 @@ class MetasploitModule < Msf::Exploit::Remote
return ret
end
# https://github.com/CoreSecurity/impacket/blob/master/examples/getArch.py
# https://msdn.microsoft.com/en-us/library/cc243948.aspx#Appendix_A_53
def verify_arch
ret = false
return true if !datastore['VerifyArch']
pkt = Rex::Proto::DCERPC::Packet.make_bind(
# Abstract Syntax: EPMv4 V3.0
'e1af8308-5d1f-11c9-91a4-08002b14a0fa', '3.0',
# Transfer Syntax[1]: 64bit NDR V1
'71710533-beba-4937-8319-b5dbef9ccc36', '1.0'
).first
begin
sock = connect(false,
'RHOST' => rhost,
'RPORT' => 135
)
rescue Rex::ConnectionError => e
print_error(e.to_s)
return false
end
sock.put(pkt)
begin
res = sock.get_once(60)
rescue EOFError
print_error('DCE/RPC socket returned EOFError')
return false
end
disconnect(sock)
begin
resp = Rex::Proto::DCERPC::Response.new(res)
rescue Rex::Proto::DCERPC::Exceptions::InvalidPacket => e
print_error(e.to_s)
return false
end
case target_arch.first
when ARCH_X64
# Ack result: Acceptance (0)
if resp.ack_result.first == 0
ret = true
end
when ARCH_X86
# Ack result: Provider rejection (2)
# Ack reason: Proposed transfer syntaxes not supported (2)
if resp.ack_result.first == 2 && resp.ack_reason.first == 2
ret = true
end
end
ret
return true unless datastore['VerifyArch']
(dcerpc_getarch == target_arch.first) ? true : false
end
def print_core_buffer(os)