From 8e4b007edc764c2ecdb7966a6a2c5f0366245dad Mon Sep 17 00:00:00 2001 From: William Vu Date: Wed, 13 Dec 2017 22:39:15 -0600 Subject: [PATCH] Move verify_arch to dcerpc_getarch We can use this code elsewhere, such as the MS17-010 scanner. --- lib/msf/core/exploit/dcerpc.rb | 64 +++++++++++++++++++ .../windows/smb/ms17_010_eternalblue.rb | 60 +---------------- 2 files changed, 67 insertions(+), 57 deletions(-) diff --git a/lib/msf/core/exploit/dcerpc.rb b/lib/msf/core/exploit/dcerpc.rb index b658a9193d..8b1bed8e84 100644 --- a/lib/msf/core/exploit/dcerpc.rb +++ b/lib/msf/core/exploit/dcerpc.rb @@ -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) diff --git a/modules/exploits/windows/smb/ms17_010_eternalblue.rb b/modules/exploits/windows/smb/ms17_010_eternalblue.rb index f5d6921f73..34582476a6 100644 --- a/modules/exploits/windows/smb/ms17_010_eternalblue.rb +++ b/modules/exploits/windows/smb/ms17_010_eternalblue.rb @@ -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)