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-b9f4589650da
unstable
HD Moore 2005-11-16 17:56:07 +00:00
parent 855bd6625c
commit 16c5e232f5
8 changed files with 75 additions and 47 deletions

View File

@ -51,8 +51,13 @@ module Exploit::Remote::DCERPC
return return
end end
# Send the bind request begin
sock.put(bind) # Send the bind request
sock.put(bind)
rescue => e
print_status("Socket error: #{e.to_s}")
return
end
# Parse the response # Parse the response
resp = DCERPCClient.read_response(sock) resp = DCERPCClient.read_response(sock)
@ -81,7 +86,14 @@ module Exploit::Remote::DCERPC
end end
print_status("Sending " + pkts.size.to_s + " DCERPC fragments...") 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) resp = DCERPCClient.read_response(sock)
return resp return resp
end end

View File

@ -48,6 +48,11 @@ module Exploit::Remote::SMB
], Msf::Exploit::Remote::SMB) ], Msf::Exploit::Remote::SMB)
end end
# Convert a standard ASCII string to 16-bit Unicode
def unicode (str)
str.unpack('C*').pack('v*')
end
def smb_login def smb_login
self.simple = SIMPLE.new(self.sock, datastore['SMBDirect']) self.simple = SIMPLE.new(self.sock, datastore['SMBDirect'])
@ -138,7 +143,7 @@ module Exploit::Remote::SMB
while(true) while(true)
rsize = rand(pipe_read_max - pipe_read_min) + pipe_read_min rsize = rand(pipe_read_max - pipe_read_min) + pipe_read_min
t = (fid.read(rsize, rand(1024)+1)) t = (fid.read(rsize, rand(1024)+1))
last if ! t.length last if t.length == 0
data << t data << t
end end
rescue XCEPT::NoReply rescue XCEPT::NoReply

View File

@ -120,6 +120,26 @@ module Stream
return true return true
end 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 # This method reads as much data as it can from the wire given a maximum
# timeout. # timeout.
@ -202,7 +222,7 @@ module Stream
# data has been found. # data has been found.
# #
def def_read_loop_timeout def def_read_loop_timeout
0.5 0.1
end end
# #

View File

@ -8,35 +8,38 @@ require 'rex/proto/dcerpc/response'
require 'rex/text' require 'rex/text'
# Process a DCERPC response packet from a socket # Process a DCERPC response packet from a socket
def self.read_response (socket) def self.read_response (socket, timeout=5)
begin data = socket.get_once(-1, timeout)
head = socket.timed_read(10, 5)
rescue Timeout::Error # We need at least 10 bytes to find the FragLen
# puts "Error: #{ $! }" if (! data or data.length() < 10)
end
if (! head or head.length() != 10)
return return
end 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) if (! resp.frag_len)
return resp return resp
end end
begin # Do we need to read more data?
body = socket.timed_read(resp.frag_len - 10, 10) if (resp.frag_len > (data.length + 10))
rescue Timeout::Error begin
# puts "Error: #{ $! }" data << socket.timed_read(resp.frag_len - data.length - 10, timeout)
rescue Timeout::Error
end
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 return resp
end end
resp.parse(body) resp.parse(data)
return resp return resp
end end

View File

@ -34,49 +34,39 @@ EVADE = Rex::Proto::SMB::Evasions
# Read a SMB packet from the socket # Read a SMB packet from the socket
def smb_recv def smb_recv
head = nil data = socket.get_once(-1, self.read_timeout)
begin
head = self.socket.timed_read(4, self.read_timeout) if (data.nil? or data.length < 4)
rescue Timeout::Error
rescue
raise XCEPT::NoReply raise XCEPT::NoReply
end 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) if (recv_len == 0)
return head return data
end end
body = '' recv_len += 4
while (body.length != recv_len)
while (data.length != recv_len)
buff = '' buff = ''
begin 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 Timeout::Error
rescue rescue
raise XCEPT::ReadPacket raise XCEPT::ReadPacket
end 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 raise XCEPT::ReadPacket
end end
# Append this packet to the read buffer and continue data << buff
body << buff
end end
return head + body return data
end end
# Send a SMB packet down the socket # Send a SMB packet down the socket

View File

@ -67,7 +67,7 @@ module Comm
def register_event_handler(handler) def register_event_handler(handler)
if (handlers == nil) if (handlers == nil)
self.handlers = [] self.handlers = []
self.handlers_rwlock = Rex::Sync::ReadWriteLock.new self.handlers_rwlock = Rex::ReadWriteLock.new
end end
self.handlers << handler self.handlers << handler

View File

@ -67,8 +67,6 @@ class Exploits::Windows::MS03_026_DCOM < Msf::Exploit::Remote
# #
print_status("Building the malicious DCERPC request...") print_status("Building the malicious DCERPC request...")
p target
# Carefully create the combination of addresses and code for cross-os exploitation # Carefully create the combination of addresses and code for cross-os exploitation
xpseh = Rex::Text.rand_text_alphanumeric(360, payload_badchars) xpseh = Rex::Text.rand_text_alphanumeric(360, payload_badchars)

View File

@ -85,7 +85,7 @@ class Exploits::Windows::MS04_011_LSASS < Msf::Exploit::Remote
# #
# Check the remote OS name and version # Check the remote OS name and version
# #
os = smb_peer_os os = smb_peer_lm
over ='' over =''
case os case os