129 lines
2.5 KiB
Ruby
129 lines
2.5 KiB
Ruby
#!/usr/bin/env ruby
|
|
|
|
$:.unshift(File.join(File.dirname(__FILE__), '..', '..', '..'))
|
|
|
|
require 'rex/test'
|
|
require 'rex/proto/smb'
|
|
require 'rex/proto/dcerpc'
|
|
require 'rex/socket'
|
|
|
|
class Rex::Proto::SMB::SimpleClient::UnitTest < Test::Unit::TestCase
|
|
|
|
Klass = Rex::Proto::SMB::SimpleClient
|
|
|
|
# Alias over the Rex DCERPC protocol modules
|
|
DCERPCPacket = Rex::Proto::DCERPC::Packet
|
|
DCERPCClient = Rex::Proto::DCERPC::Client
|
|
DCERPCResponse = Rex::Proto::DCERPC::Response
|
|
DCERPCUUID = Rex::Proto::DCERPC::UUID
|
|
XCEPT = Rex::Proto::SMB::Exceptions
|
|
|
|
FILE_CREATE = 0x10
|
|
FILE_TRUNC = 0x02
|
|
FILE_OPEN = 0x01
|
|
|
|
|
|
def test_smb_open_share
|
|
user = 'SMBTest'
|
|
pass = 'SMBTest'
|
|
share = 'C$'
|
|
|
|
write_data = ('A' * (1024 * 8))
|
|
filename = 'smb_tester.txt'
|
|
begin
|
|
Timeout.timeout($_REX_TEST_TIMEOUT) {
|
|
s = Rex::Socket.create_tcp(
|
|
'PeerHost' => $_REX_TEST_SMB_HOST,
|
|
'PeerPort' => 445
|
|
)
|
|
|
|
c = Klass.new(s, true)
|
|
|
|
begin
|
|
c.login('*SMBSERVER', user, pass)
|
|
rescue XCEPT::LoginError
|
|
flunk('login failure')
|
|
end
|
|
|
|
c.connect(share)
|
|
|
|
f = c.open(filename, 'rwct')
|
|
f << write_data
|
|
f.close
|
|
|
|
f = c.open(filename, 'ro')
|
|
d = f.read()
|
|
f.close
|
|
|
|
c.delete(filename)
|
|
c.disconnect(share)
|
|
|
|
s.close
|
|
}
|
|
rescue Timeout::Error
|
|
flunk('timeout')
|
|
end
|
|
end
|
|
|
|
def test_smb_dcerpc
|
|
begin
|
|
Timeout.timeout($_REX_TEST_TIMEOUT) {
|
|
s = Rex::Socket.create_tcp(
|
|
'PeerHost' => $_REX_TEST_SMB_HOST,
|
|
'PeerPort' => 445
|
|
)
|
|
|
|
c = Klass.new(s, true)
|
|
|
|
user = ''
|
|
pass = ''
|
|
|
|
begin
|
|
c.login('*SMBSERVER', user, pass)
|
|
rescue XCEPT::LoginError
|
|
flunk('login failure')
|
|
end
|
|
|
|
c.connect('IPC$')
|
|
f = c.create_pipe('\BROWSER')
|
|
|
|
bind, ctx = DCERPCPacket.make_bind_fake_multi(
|
|
'4b324fc8-1670-01d3-1278-5a47bf6ee188', '3.0',
|
|
10,
|
|
4
|
|
)
|
|
|
|
# Evasion techniques:
|
|
# 1) Write the bind out a few bytes at a time with a random offset
|
|
# 2) Read the response back a few bytes at a time with a random offset
|
|
|
|
# Write the bind request out in random chunk sizes
|
|
while (bind.length > 0)
|
|
f.write( bind.slice!(0, (rand(20)+5)), rand(1024)+1 )
|
|
end
|
|
|
|
d = ''
|
|
# Read the response back a few bytes a time
|
|
begin
|
|
while(true)
|
|
t = (f.read((rand(20)+5), rand(1024)+1))
|
|
last if ! t.length
|
|
d << t
|
|
end
|
|
rescue XCEPT::NoReply
|
|
end
|
|
|
|
r = DCERPCResponse.new(d)
|
|
assert_equal(r.type, 12)
|
|
assert_equal(r.ack_result[ctx-0], 0)
|
|
assert_equal(r.ack_result[ctx-1], 2)
|
|
|
|
s.close
|
|
}
|
|
rescue Timeout::Error
|
|
flunk('timeout')
|
|
end
|
|
end
|
|
end
|
|
|