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
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

View File

@ -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

View File

@ -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
#

View File

@ -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
data = socket.get_once(-1, timeout)
if (! head or head.length() != 10)
# 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

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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