From f4736c3eae54ef631c54d8e5f05f221b9d7dd02f Mon Sep 17 00:00:00 2001 From: HD Moore Date: Sat, 8 Apr 2006 06:35:35 +0000 Subject: [PATCH] Minor improvements git-svn-id: file:///home/svn/incoming/trunk@3593 4d416f70-5f16-0410-b530-b9f4589650da --- lib/rex/proto/dcerpc/response.rb | 2 +- lib/rex/proto/smb/client.rb | 69 +++++++++++++++++++++++++++++++ lib/rex/proto/smb/simpleclient.rb | 18 +++++--- 3 files changed, 83 insertions(+), 6 deletions(-) diff --git a/lib/rex/proto/dcerpc/response.rb b/lib/rex/proto/dcerpc/response.rb index d0f39668a6..d28dfd9d5d 100644 --- a/lib/rex/proto/dcerpc/response.rb +++ b/lib/rex/proto/dcerpc/response.rb @@ -25,7 +25,7 @@ class Response self.ack_xfer_syntax_uuid = [] self.ack_xfer_syntax_vers = [] - if (data.length < 10) + if (! data or data.length < 10) raise Rex::Proto::DCERPC::Exceptions::InvalidPacket, 'Packet header must be at least 10 bytes long' end diff --git a/lib/rex/proto/smb/client.rb b/lib/rex/proto/smb/client.rb index 7cf1bf42da..f3d2ec8e81 100644 --- a/lib/rex/proto/smb/client.rb +++ b/lib/rex/proto/smb/client.rb @@ -1048,6 +1048,75 @@ EVADE = Rex::Proto::SMB::Evasions end + # Perform a transaction against a named pipe + def trans_named_pipe_oneway (file_id, data = '') + pipe = EVADE.make_trans_named_pipe_name(self.evasion_level) + self.trans_oneway(pipe, '', data, 2, [0x26, file_id].pack('vv') ) + end + + # Perform a transaction against a given pipe name (one way) + def trans_oneway (pipe, param = '', body = '', setup_count = 0, setup_data = '') + + # Null-terminate the pipe parameter if needed + if (pipe[-1] != 0) + pipe << "\x00" + end + + pkt = CONST::SMB_TRANS_PKT.make_struct + self.smb_defaults(pkt['Payload']['SMB']) + + # Packets larger than mlen will cause XP SP2 to disconnect us ;-( + mlen = 4200 + + # Figure out how much space is taken up by our current arguments + xlen = pipe.length + param.length + body.length + + filler1 = '' + filler2 = '' + + # Fill any available space depending on the evasion settings + if (xlen < mlen) + filler1 = EVADE.make_offset_filler(self.evasion_level, (mlen-xlen)/2) + filler2 = EVADE.make_offset_filler(self.evasion_level, (mlen-xlen)/2) + end + + # Squish the whole thing together + data = pipe + filler1 + param + filler2 + body + + # Throw some form of a warning out? + if (data.length > mlen) + # This call will more than likely fail :-( + end + + # Calculate all of the offsets + base_offset = pkt.to_s.length + (setup_count * 2) - 4 + param_offset = base_offset + pipe.length + filler1.length + data_offset = param_offset + filler2.length + param.length + + pkt['Payload']['SMB'].v['Command'] = CONST::SMB_COM_TRANSACTION + pkt['Payload']['SMB'].v['Flags1'] = 0x18 + pkt['Payload']['SMB'].v['Flags2'] = 0x2001 + pkt['Payload']['SMB'].v['WordCount'] = 14 + setup_count + + pkt['Payload'].v['ParamCountTotal'] = param.length + pkt['Payload'].v['DataCountTotal'] = body.length + pkt['Payload'].v['ParamCountMax'] = 1024 + pkt['Payload'].v['DataCountMax'] = 65504 + pkt['Payload'].v['ParamCount'] = param.length + pkt['Payload'].v['ParamOffset'] = param_offset + pkt['Payload'].v['DataCount'] = body.length + pkt['Payload'].v['DataOffset'] = data_offset + pkt['Payload'].v['SetupCount'] = setup_count + pkt['Payload'].v['SetupData'] = setup_data + + pkt['Payload'].v['Payload'] = data + pkt['Payload'].v['Flags'] = 2 + + self.smb_send(pkt.to_s) + return ack + end + + # Perform a transaction2 request using the specified subcommand, parameters, and data def trans2 (subcommand, param = '', body = '', setup_count = 0, setup_data = '') diff --git a/lib/rex/proto/smb/simpleclient.rb b/lib/rex/proto/smb/simpleclient.rb index f98259e406..1ae6675c9c 100644 --- a/lib/rex/proto/smb/simpleclient.rb +++ b/lib/rex/proto/smb/simpleclient.rb @@ -138,19 +138,19 @@ attr_accessor :socket, :client, :direct, :shares, :last_share return true end - def connect (share) + def connect(share) ok = self.client.tree_connect(share) tree_id = ok['Payload']['SMB'].v['TreeID'] self.shares[share] = tree_id self.last_share = share end - def disconnect (share) + def disconnect(share) ok = self.client.tree_disconnect(self.shares[share]) self.shares.delete(share) end - def open (path, perm) + def open(path, perm) mode = UTILS.open_mode_to_mode(perm) access = UTILS.open_mode_to_access(perm) @@ -160,17 +160,25 @@ attr_accessor :socket, :client, :direct, :shares, :last_share fh = OpenFile.new(self.client, path, self.client.last_tree_id, file_id) end - def delete (*args) + def delete(*args) self.client.delete(*args) end - def create_pipe (path, perm = 'c') + def create_pipe(path, perm = 'c') disposition = UTILS.create_mode_to_disposition(perm) ok = self.client.create(path, disposition) file_id = ok['Payload'].v['FileID'] fh = OpenFile.new(self.client, path, self.client.last_tree_id, file_id) end + def trans_pipe(fid, data) + client.trans_named_pipe(fid, data) + end + + def trans_pipe_oneway(fid, data) + client.trans_named_pipe_oneway(fid, data) + end + end end end