Addition of get_once() in io::stream, rewritten recv code for smb/dcerpc, error handling in exploit mixins
git-svn-id: file:///home/svn/incoming/trunk@3042 4d416f70-5f16-0410-b530-b9f4589650daunstable
parent
855bd6625c
commit
16c5e232f5
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
#
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue