Still working on the simpleclient interface

git-svn-id: file:///home/svn/incoming/trunk@2946 4d416f70-5f16-0410-b530-b9f4589650da
unstable
HD Moore 2005-10-02 06:53:39 +00:00
parent fbb562a12e
commit cb69d58ca5
5 changed files with 95 additions and 17 deletions

View File

@ -473,6 +473,10 @@ EVADE = Rex::Proto::SMB::Evasions
self.server_guid = ack['Payload'].v['GUID']
end
if (ack['Payload'].v['ServerDate'] > 0)
stamp = UTILS.servertime(ack['Payload'].v['ServerDate'],ack['Payload'].v['ServerTime'])
end
return ack
end
@ -760,7 +764,7 @@ EVADE = Rex::Proto::SMB::Evasions
# Creates a file or opens an existing pipe
# TODO: Allow the caller to specify the hardcoded options
def create(file_name, disposition = 1)
def create(filename, disposition = 1)
pkt = CONST::SMB_CREATE_PKT.make_struct
self.smb_defaults(pkt['Payload']['SMB'])
@ -771,14 +775,14 @@ EVADE = Rex::Proto::SMB::Evasions
pkt['Payload']['SMB'].v['WordCount'] = 24
pkt['Payload'].v['AndX'] = 255
pkt['Payload'].v['FileNameLen'] = file_name.length
pkt['Payload'].v['FileNameLen'] = filename.length
pkt['Payload'].v['CreateFlags'] = 0x16
pkt['Payload'].v['AccessMask'] = 0x02019f
pkt['Payload'].v['ShareAccess'] = 7
pkt['Payload'].v['CreateOptions'] = 0x40
pkt['Payload'].v['Impersonation'] = 2
pkt['Payload'].v['Disposition'] = disposition
pkt['Payload'].v['Payload'] = file_name + "\x00"
pkt['Payload'].v['Payload'] = filename + "\x00"
self.smb_send(pkt.to_s)
@ -793,7 +797,7 @@ EVADE = Rex::Proto::SMB::Evasions
end
# Deletes a file from a share
def delete(file_name, tree_id = self.last_tree_id)
def delete(filename, tree_id = self.last_tree_id)
pkt = CONST::SMB_DELETE_PKT.make_struct
self.smb_defaults(pkt['Payload']['SMB'])
@ -806,7 +810,7 @@ EVADE = Rex::Proto::SMB::Evasions
pkt['Payload'].v['SearchAttributes'] = 0x06
pkt['Payload'].v['BufferFormat'] = 4
pkt['Payload'].v['Payload'] = file_name + "\x00"
pkt['Payload'].v['Payload'] = filename + "\x00"
self.smb_send(pkt.to_s)
@ -816,8 +820,7 @@ EVADE = Rex::Proto::SMB::Evasions
end
# Opens an existing file or creates a new one
# TODO: Allow the caller to specify the hardcoded options
def open(file_name, mode = 0x12)
def open(filename, mode = 0x12, access = 0x42)
pkt = CONST::SMB_OPEN_PKT.make_struct
self.smb_defaults(pkt['Payload']['SMB'])
@ -828,10 +831,10 @@ EVADE = Rex::Proto::SMB::Evasions
pkt['Payload']['SMB'].v['WordCount'] = 15
pkt['Payload'].v['AndX'] = 255
pkt['Payload'].v['Access'] = 0x42
pkt['Payload'].v['Access'] = access
pkt['Payload'].v['SearchAttributes'] = 0x06
pkt['Payload'].v['OpenFunction'] = mode
pkt['Payload'].v['Payload'] = file_name + "\x00"
pkt['Payload'].v['Payload'] = filename + "\x00"
self.smb_send(pkt.to_s)

View File

@ -36,6 +36,25 @@ NT_TRANSACT_NOTIFY_CHANGE = 4 # Start directory watch
NT_TRANSACT_RENAME = 5 # Reserved (Handle-based)
NT_TRANSACT_QUERY_SECURITY_DESC = 6 # Retrieve security
# Open Modes
OPEN_MODE_CREAT = 0x10 # Create the file if file does not exists. Otherwise, operation fails.
OPEN_MODE_EXCL = 0x00 # When used with SMB_O_CREAT, operation fails if file exists. Cannot be used with SMB_O_OPEN.
OPEN_MODE_OPEN = 0x01 # Open the file if the file exists
OPEN_MODE_TRUNC = 0x02 # Truncate the file if the file exists
# Shared Access
OPEN_SHARE_COMPAT = 0x00
OPEN_SHARE_DENY_EXCL = 0x10
OPEN_SHARE_DENY_WRITE = 0x20
OPEN_SHARE_DENY_READEXEC = 0x30
OPEN_SHARE_DENY_NONE = 0x40
# File Access
OPEN_ACCESS_READ = 0x00
OPEN_ACCESS_WRITE = 0x01
OPEN_ACCESS_READWRITE = 0x02
OPEN_ACCESS_EXEC = 0x03
# Wildcard NetBIOS name
NETBIOS_REDIR = 'CACACACACACACACACACACACACACACAAA'
@ -134,8 +153,8 @@ SMB_NEG_RES_NT_HDR_PKT = Rex::Struct2::CStructTemplate.new(
[ 'uint32v', 'MaxRaw', 0 ],
[ 'uint32v', 'SessionKey', 0 ],
[ 'uint32v', 'Capabilities', 0 ],
[ 'uint32v', 'DosTime', 0 ],
[ 'uint32v', 'DosDate', 0 ],
[ 'uint32v', 'ServerTime', 0 ],
[ 'uint32v', 'ServerDate', 0 ],
[ 'uint16v', 'Timezone', 0 ],
[ 'uint8', 'KeyLength', 0 ],
[ 'uint16v', 'ByteCount', 0 ],

View File

@ -147,8 +147,11 @@ attr_accessor :socket, :client, :direct, :shares, :last_share
self.shares.delete(share)
end
def open (path, mode=0)
ok = self.client.open(path, mode)
def open (path, perm)
mode = UTILS.open_mode_to_mode(perm)
access = UTILS.open_mode_to_access(perm)
ok = self.client.open(path, mode, access)
file_id = ok['Payload'].v['FileID']
fh = OpenFile.new(self.client, path, self.client.last_tree_id, file_id)
@ -158,6 +161,12 @@ attr_accessor :socket, :client, :direct, :shares, :last_share
self.client.delete(*args)
end
def open_mode_to_access(mode)
open_func = 0
open_perm = 0
end
end
end
end

View File

@ -31,7 +31,7 @@ class Rex::Proto::SMB::Client::UnitTest < Test::Unit::TestCase
pass = 'SMBTest'
share = 'C$'
write_data = ('A' * (1024 * 1024 * 1))
write_data = ('A' * (1024 * 8))
filename = 'smb_tester.txt'
s = Rex::Socket.create_tcp(
@ -40,22 +40,28 @@ class Rex::Proto::SMB::Client::UnitTest < Test::Unit::TestCase
)
c = Klass.new(s, true)
c.client.evasion_level = 0
begin
c.login('*SMBSERVER', user, pass)
c.connect(share)
f = c.open(filename, FILE_CREATE|FILE_TRUNC)
f = c.open(filename, 'rwct')
f << write_data
f.close
f = c.open(filename, FILE_OPEN)
f = c.open(filename, 'ro')
d = f.read()
f.close
c.delete(filename)
c.disconnect(share)
assert_equal(write_data, d)
c.connect('IPC$')
f = c.create_pipe('\BROWSER')
rescue
puts $!.to_s + $!.backtrace.join("\n")
return

View File

@ -4,12 +4,53 @@ module SMB
class Utils
require 'rex/text'
require 'rex/proto/smb/constants'
CONST = Rex::Proto::SMB::Constants
# Convert a standard ASCII string to 16-bit Unicode
def self.unicode (str)
str.unpack('C*').pack('v*')
end
# Creates an access mask for use with the CLIENT.open() call based on a string
def self.open_mode_to_access(str)
access = CONST::OPEN_ACCESS_READ | CONST::OPEN_SHARE_DENY_NONE
str.each_byte { |c|
case [c].pack('C').downcase
when 'w'
access |= CONST::OPEN_ACCESS_READWRITE
end
}
return access
end
# Creates a mode mask for use with the CLIENT.open() call based on a string
def self.open_mode_to_mode(str)
mode = 0
str.each_byte { |c|
case [c].pack('C').downcase
when 'x' # Fail if the file already exists
mode |= CONST::OPEN_MODE_EXCL
when 't' # Truncate the file if it already exists
mode |= CONST::OPEN_MODE_TRUNC
when 'c' # Create the file if it does not exist
mode |= CONST::OPEN_MODE_CREAT
when 'o' # Just open the file, clashes with x
mode |= CONST::OPEN_MODE_OPEN
end
}
return mode
end
# Convert a 64-bit signed SMB time to a unix timestamp
def self.servertime(time_high, time_low)
(((time_high * 0x100000000) + time_low) / 10000000) - 11644473600
end
# Convert a name to its NetBIOS equivalent
def self.nbname_encode (str)
encoded = ''