diff --git a/lib/msf/core/exploit/dcerpc.rb b/lib/msf/core/exploit/dcerpc.rb index 3f3d73b281..f99055f726 100644 --- a/lib/msf/core/exploit/dcerpc.rb +++ b/lib/msf/core/exploit/dcerpc.rb @@ -51,8 +51,13 @@ module Exploit::Remote::DCERPC return end - # Send the bind request - sock.put(bind) + begin + # Send the bind request + sock.put(bind) + rescue => e + print_status("Socket error: #{e.to_s}") + return + end # Parse the response resp = DCERPCClient.read_response(sock) @@ -81,7 +86,14 @@ module Exploit::Remote::DCERPC end print_status("Sending " + pkts.size.to_s + " DCERPC fragments...") - pkts.each { |chunk| sock.put(chunk) } + + begin + pkts.each { |chunk| sock.put(chunk) } + rescue => e + print_status("Socket error: #{e.to_s}") + return + end + resp = DCERPCClient.read_response(sock) return resp end diff --git a/lib/msf/core/exploit/smb.rb b/lib/msf/core/exploit/smb.rb index 7b984b9940..ac4bf3b2a9 100644 --- a/lib/msf/core/exploit/smb.rb +++ b/lib/msf/core/exploit/smb.rb @@ -48,6 +48,11 @@ module Exploit::Remote::SMB ], Msf::Exploit::Remote::SMB) end + # Convert a standard ASCII string to 16-bit Unicode + def unicode (str) + str.unpack('C*').pack('v*') + end + def smb_login self.simple = SIMPLE.new(self.sock, datastore['SMBDirect']) @@ -138,7 +143,7 @@ module Exploit::Remote::SMB while(true) rsize = rand(pipe_read_max - pipe_read_min) + pipe_read_min t = (fid.read(rsize, rand(1024)+1)) - last if ! t.length + last if t.length == 0 data << t end rescue XCEPT::NoReply diff --git a/lib/rex/io/stream.rb b/lib/rex/io/stream.rb index b89e1dd8f4..d3eda8ec3f 100644 --- a/lib/rex/io/stream.rb +++ b/lib/rex/io/stream.rb @@ -120,6 +120,26 @@ module Stream return true end + + # + # This method emulates the behavior of Pex::Socket::Recv in MSF2 + # + def get_once(length = -1, timeout = def_read_timeout) + + if (has_read_data?(timeout) == false) + return nil + end + + bsize = (length == -1) ? def_block_size : length + + begin + return read(bsize) + rescue Exception + end + + return '' + end + # # This method reads as much data as it can from the wire given a maximum # timeout. @@ -202,7 +222,7 @@ module Stream # data has been found. # def def_read_loop_timeout - 0.5 + 0.1 end # diff --git a/lib/rex/proto/dcerpc/client.rb b/lib/rex/proto/dcerpc/client.rb index 2ae3a1cf4c..dd284e3830 100644 --- a/lib/rex/proto/dcerpc/client.rb +++ b/lib/rex/proto/dcerpc/client.rb @@ -8,35 +8,38 @@ require 'rex/proto/dcerpc/response' require 'rex/text' # Process a DCERPC response packet from a socket - def self.read_response (socket) + def self.read_response (socket, timeout=5) - begin - head = socket.timed_read(10, 5) - rescue Timeout::Error - # puts "Error: #{ $! }" - end - - if (! head or head.length() != 10) + data = socket.get_once(-1, timeout) + + # We need at least 10 bytes to find the FragLen + if (! data or data.length() < 10) return end - resp = Rex::Proto::DCERPC::Response.new(head) + # Pass the first 10 bytes to the constructor + resp = Rex::Proto::DCERPC::Response.new(data.slice!(0, 10)) + # Something went wrong in the parser... if (! resp.frag_len) return resp end - begin - body = socket.timed_read(resp.frag_len - 10, 10) - rescue Timeout::Error - # puts "Error: #{ $! }" + # Do we need to read more data? + if (resp.frag_len > (data.length + 10)) + begin + data << socket.timed_read(resp.frag_len - data.length - 10, timeout) + rescue Timeout::Error + end end - - if (body.nil? or body.length() != resp.frag_len - 10) + + # Still missing some data... + if (data.length() != resp.frag_len - 10) + $stderr.puts "Truncated DCERPC response :-(" return resp end - resp.parse(body) + resp.parse(data) return resp end diff --git a/lib/rex/proto/smb/client.rb b/lib/rex/proto/smb/client.rb index d8ffd441ae..f5fa2bcf4e 100644 --- a/lib/rex/proto/smb/client.rb +++ b/lib/rex/proto/smb/client.rb @@ -34,49 +34,39 @@ EVADE = Rex::Proto::SMB::Evasions # Read a SMB packet from the socket def smb_recv - head = nil + data = socket.get_once(-1, self.read_timeout) - begin - head = self.socket.timed_read(4, self.read_timeout) - rescue Timeout::Error - rescue + + if (data.nil? or data.length < 4) raise XCEPT::NoReply end - if (head == nil) - raise XCEPT::NoReply - end - - if (head.length != 4) - raise XCEPT::ReadHeader - end - recv_len = head[2,2].unpack('n')[0] + recv_len = data[2,2].unpack('n')[0] if (recv_len == 0) - return head + return data end - body = '' - while (body.length != recv_len) + recv_len += 4 + + while (data.length != recv_len) buff = '' begin - buff = self.socket.timed_read(recv_len, self.read_timeout) + buff << self.socket.timed_read(recv_len - data.length, self.read_timeout) rescue Timeout::Error rescue raise XCEPT::ReadPacket end - # Failed to read one packet within the time limit - if (buff == nil or buff.length == 0) + if (buff.nil? or buff.length == 0) raise XCEPT::ReadPacket end - # Append this packet to the read buffer and continue - body << buff + data << buff end - return head + body + return data end # Send a SMB packet down the socket diff --git a/lib/rex/socket/comm.rb b/lib/rex/socket/comm.rb index 03188740f8..f6e05e157f 100644 --- a/lib/rex/socket/comm.rb +++ b/lib/rex/socket/comm.rb @@ -67,7 +67,7 @@ module Comm def register_event_handler(handler) if (handlers == nil) self.handlers = [] - self.handlers_rwlock = Rex::Sync::ReadWriteLock.new + self.handlers_rwlock = Rex::ReadWriteLock.new end self.handlers << handler diff --git a/modules/exploits/windows/ms03_026_dcom.rb b/modules/exploits/windows/ms03_026_dcom.rb index 6aeec4219a..689b582d78 100644 --- a/modules/exploits/windows/ms03_026_dcom.rb +++ b/modules/exploits/windows/ms03_026_dcom.rb @@ -67,8 +67,6 @@ class Exploits::Windows::MS03_026_DCOM < Msf::Exploit::Remote # print_status("Building the malicious DCERPC request...") - p target - # Carefully create the combination of addresses and code for cross-os exploitation xpseh = Rex::Text.rand_text_alphanumeric(360, payload_badchars) diff --git a/modules/exploits/windows/ms04_011_lsass.rb b/modules/exploits/windows/ms04_011_lsass.rb index d86389f4ac..83c02ef379 100644 --- a/modules/exploits/windows/ms04_011_lsass.rb +++ b/modules/exploits/windows/ms04_011_lsass.rb @@ -85,7 +85,7 @@ class Exploits::Windows::MS04_011_LSASS < Msf::Exploit::Remote # # Check the remote OS name and version # - os = smb_peer_os + os = smb_peer_lm over ='' case os