Skip to content

Commit da08e64

Browse files
authored
Merge pull request #298 from zeroSteiner/feat/examples-with-args
Update examples with argument parsing
2 parents 7c8fc13 + 4108ff8 commit da08e64

19 files changed

Lines changed: 976 additions & 239 deletions

examples/anonymous_auth.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,11 @@ def run_authentication(address, smb1, smb2, smb3)
4545
end
4646
optparser.parse!(args)
4747

48+
if options[:target] == '-h' || options[:target] == '--help'
49+
puts optparser.help
50+
exit
51+
end
52+
4853
if options[:target].nil?
4954
abort(optparser.help)
5055
end

examples/append_file.rb

Lines changed: 57 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,27 +2,70 @@
22

33
# This example script is used for testing the appending to a file.
44
# It will attempt to connect to a specific share and then append to a specified file.
5-
# Example usage: ruby append_file.rb 192.168.172.138 msfadmin msfadmin TEST_SHARE test.txt "data to write"
5+
# Example usage: ruby append_file.rb --username msfadmin --password msfadmin 192.168.172.138 TEST_SHARE test.txt "data to write"
66
# This will try to connect to \\192.168.172.138\TEST_SHARE with the msfadmin:msfadmin credentials
7-
# and write "data to write" the end of the file test.txt
7+
# and append "data to write" to the end of the file test.txt
88

99
require 'bundler/setup'
10+
require 'optparse'
1011
require 'ruby_smb'
1112

12-
address = ARGV[0]
13-
username = ARGV[1]
14-
password = ARGV[2]
15-
share = ARGV[3]
16-
file = ARGV[4]
17-
data = ARGV[5]
18-
smb_versions = ARGV[6]&.split(',') || ['1','2','3']
13+
args = ARGV.dup
14+
options = {
15+
domain: '.',
16+
username: '',
17+
password: '',
18+
smbv1: true,
19+
smbv2: true,
20+
smbv3: true,
21+
target: nil,
22+
share: nil,
23+
file: nil,
24+
data: nil
25+
}
26+
options[:data] = args.pop
27+
options[:file] = args.pop
28+
options[:share] = args.pop
29+
options[:target] = args.pop
30+
optparser = OptionParser.new do |opts|
31+
opts.banner = "Usage: #{File.basename(__FILE__)} [options] target share file data"
32+
opts.on("--[no-]smbv1", "Enable or disable SMBv1 (default: #{options[:smbv1] ? 'Enabled' : 'Disabled'})") do |smbv1|
33+
options[:smbv1] = smbv1
34+
end
35+
opts.on("--[no-]smbv2", "Enable or disable SMBv2 (default: #{options[:smbv2] ? 'Enabled' : 'Disabled'})") do |smbv2|
36+
options[:smbv2] = smbv2
37+
end
38+
opts.on("--[no-]smbv3", "Enable or disable SMBv3 (default: #{options[:smbv3] ? 'Enabled' : 'Disabled'})") do |smbv3|
39+
options[:smbv3] = smbv3
40+
end
41+
opts.on("--username USERNAME", "The account's username (default: #{options[:username]})") do |username|
42+
if username.include?('\\')
43+
options[:domain], options[:username] = username.split('\\', 2)
44+
else
45+
options[:username] = username
46+
end
47+
end
48+
opts.on("--password PASSWORD", "The account's password (default: #{options[:password]})") do |password|
49+
options[:password] = password
50+
end
51+
end
52+
optparser.parse!(args)
53+
54+
if [options[:target], options[:share], options[:file], options[:data]].any? { |a| a == '-h' || a == '--help' }
55+
puts optparser.help
56+
exit
57+
end
58+
59+
if options[:target].nil? || options[:share].nil? || options[:file].nil? || options[:data].nil?
60+
abort(optparser.help)
61+
end
1962

20-
path = "\\\\#{address}\\#{share}"
63+
path = "\\\\#{options[:target]}\\#{options[:share]}"
2164

22-
sock = TCPSocket.new address, 445
65+
sock = TCPSocket.new options[:target], 445
2366
dispatcher = RubySMB::Dispatcher::Socket.new(sock)
2467

25-
client = RubySMB::Client.new(dispatcher, smb1: smb_versions.include?('1'), smb2: smb_versions.include?('2'), smb3: smb_versions.include?('3'), username: username, password: password)
68+
client = RubySMB::Client.new(dispatcher, smb1: options[:smbv1], smb2: options[:smbv2], smb3: options[:smbv3], username: options[:username], password: options[:password], domain: options[:domain])
2669
protocol = client.negotiate
2770
status = client.authenticate
2871

@@ -35,8 +78,8 @@
3578
puts "Failed to connect to #{path}: #{e.message}"
3679
end
3780

38-
file = tree.open_file(filename: file, write: true, disposition: RubySMB::Dispositions::FILE_OPEN_IF)
81+
file = tree.open_file(filename: options[:file], write: true, disposition: RubySMB::Dispositions::FILE_OPEN_IF)
3982

40-
result = file.append(data: data)
83+
result = file.append(data: options[:data])
4184
puts result.to_s
4285
file.close

examples/authenticate.rb

Lines changed: 64 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,15 @@
44
# including protocol negotiation and authentication.
55

66
require 'bundler/setup'
7+
require 'optparse'
78
require 'ruby_smb'
89

9-
def run_authentication(address, smb1, smb2, smb3, username, password)
10+
def run_authentication(address, smb1, smb2, smb3, username, password, domain)
1011
# Create our socket and add it to the dispatcher
1112
sock = TCPSocket.new address, 445
1213
dispatcher = RubySMB::Dispatcher::Socket.new(sock)
1314

14-
client = RubySMB::Client.new(dispatcher, smb1: smb1, smb2: smb2, smb3: smb3, username: username, password: password)
15+
client = RubySMB::Client.new(dispatcher, smb1: smb1, smb2: smb2, smb3: smb3, username: username, password: password, domain: domain)
1516
protocol = client.negotiate
1617
status = client.authenticate
1718
puts "#{protocol} : #{status}"
@@ -28,17 +29,64 @@ def run_authentication(address, smb1, smb2, smb3, username, password)
2829
puts "OS Version: #{client.os_version}"
2930
end
3031

31-
address = ARGV[0]
32-
username = ARGV[1]
33-
password = ARGV[2]
34-
35-
# Negotiate with SMB1, SMB2 and SMB3 enabled on the client
36-
run_authentication(address, true, true, true, username, password)
37-
# Negotiate with both SMB1 and SMB2 enabled on the client
38-
run_authentication(address, true, true, false, username, password)
39-
# Negotiate with only SMB1 enabled
40-
run_authentication(address, true, false, false, username, password)
41-
# Negotiate with only SMB2 enabled
42-
run_authentication(address, false, true, false, username, password)
43-
# Negotiate with only SMB3 enabled
44-
run_authentication(address, false, false, true, username, password)
32+
args = ARGV.dup
33+
options = {
34+
domain: '.',
35+
username: '',
36+
password: '',
37+
smbv1: true,
38+
smbv2: true,
39+
smbv3: true,
40+
target: nil
41+
}
42+
options[:target] = args.pop
43+
optparser = OptionParser.new do |opts|
44+
opts.banner = "Usage: #{File.basename(__FILE__)} [options] target"
45+
opts.on("--[no-]smbv1", "Enable or disable SMBv1 (default: #{options[:smbv1] ? 'Enabled' : 'Disabled'})") do |smbv1|
46+
options[:smbv1] = smbv1
47+
end
48+
opts.on("--[no-]smbv2", "Enable or disable SMBv2 (default: #{options[:smbv2] ? 'Enabled' : 'Disabled'})") do |smbv2|
49+
options[:smbv2] = smbv2
50+
end
51+
opts.on("--[no-]smbv3", "Enable or disable SMBv3 (default: #{options[:smbv3] ? 'Enabled' : 'Disabled'})") do |smbv3|
52+
options[:smbv3] = smbv3
53+
end
54+
opts.on("--username USERNAME", "The account's username (default: #{options[:username]})") do |username|
55+
if username.include?('\\')
56+
options[:domain], options[:username] = username.split('\\', 2)
57+
else
58+
options[:username] = username
59+
end
60+
end
61+
opts.on("--password PASSWORD", "The account's password (default: #{options[:password]})") do |password|
62+
options[:password] = password
63+
end
64+
end
65+
optparser.parse!(args)
66+
67+
if options[:target] == '-h' || options[:target] == '--help'
68+
puts optparser.help
69+
exit
70+
end
71+
72+
if options[:target].nil?
73+
abort(optparser.help)
74+
end
75+
76+
# (smb1, smb2, smb3) combinations to exercise — filtered by the user's
77+
# --[no-]smbv{1,2,3} flags so that any combo requiring a disabled version
78+
# is skipped.
79+
combinations = [
80+
[true, true, true], # SMB1, SMB2 and SMB3 enabled
81+
[true, true, false], # SMB1 and SMB2 enabled
82+
[true, false, false], # only SMB1 enabled
83+
[false, true, false], # only SMB2 enabled
84+
[false, false, true] # only SMB3 enabled
85+
]
86+
87+
combinations.each do |smb1, smb2, smb3|
88+
next if smb1 && !options[:smbv1]
89+
next if smb2 && !options[:smbv2]
90+
next if smb3 && !options[:smbv3]
91+
run_authentication(options[:target], smb1, smb2, smb3, options[:username], options[:password], options[:domain])
92+
end

examples/delete_file.rb

Lines changed: 53 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,26 +2,68 @@
22

33
# This example script is used for testing the deleting of a file.
44
# It will attempt to connect to a specific share and then delete a specified file.
5-
# Example usage: ruby delete_file.rb 192.168.172.138 msfadmin msfadmin TEST_SHARE short.txt
5+
# Example usage: ruby delete_file.rb --username msfadmin --password msfadmin 192.168.172.138 TEST_SHARE short.txt
66
# This will try to connect to \\192.168.172.138\TEST_SHARE with the msfadmin:msfadmin credentials
77
# and delete the file short.txt
88

99
require 'bundler/setup'
10+
require 'optparse'
1011
require 'ruby_smb'
1112

12-
address = ARGV[0]
13-
username = ARGV[1]
14-
password = ARGV[2]
15-
share = ARGV[3]
16-
file = ARGV[4]
17-
smb_versions = ARGV[5]&.split(',') || ['1','2','3']
13+
args = ARGV.dup
14+
options = {
15+
domain: '.',
16+
username: '',
17+
password: '',
18+
smbv1: true,
19+
smbv2: true,
20+
smbv3: true,
21+
target: nil,
22+
share: nil,
23+
file: nil
24+
}
25+
options[:file] = args.pop
26+
options[:share] = args.pop
27+
options[:target] = args.pop
28+
optparser = OptionParser.new do |opts|
29+
opts.banner = "Usage: #{File.basename(__FILE__)} [options] target share file"
30+
opts.on("--[no-]smbv1", "Enable or disable SMBv1 (default: #{options[:smbv1] ? 'Enabled' : 'Disabled'})") do |smbv1|
31+
options[:smbv1] = smbv1
32+
end
33+
opts.on("--[no-]smbv2", "Enable or disable SMBv2 (default: #{options[:smbv2] ? 'Enabled' : 'Disabled'})") do |smbv2|
34+
options[:smbv2] = smbv2
35+
end
36+
opts.on("--[no-]smbv3", "Enable or disable SMBv3 (default: #{options[:smbv3] ? 'Enabled' : 'Disabled'})") do |smbv3|
37+
options[:smbv3] = smbv3
38+
end
39+
opts.on("--username USERNAME", "The account's username (default: #{options[:username]})") do |username|
40+
if username.include?('\\')
41+
options[:domain], options[:username] = username.split('\\', 2)
42+
else
43+
options[:username] = username
44+
end
45+
end
46+
opts.on("--password PASSWORD", "The account's password (default: #{options[:password]})") do |password|
47+
options[:password] = password
48+
end
49+
end
50+
optparser.parse!(args)
51+
52+
if [options[:target], options[:share], options[:file]].any? { |a| a == '-h' || a == '--help' }
53+
puts optparser.help
54+
exit
55+
end
56+
57+
if options[:target].nil? || options[:share].nil? || options[:file].nil?
58+
abort(optparser.help)
59+
end
1860

19-
path = "\\\\#{address}\\#{share}"
61+
path = "\\\\#{options[:target]}\\#{options[:share]}"
2062

21-
sock = TCPSocket.new address, 445
63+
sock = TCPSocket.new options[:target], 445
2264
dispatcher = RubySMB::Dispatcher::Socket.new(sock)
2365

24-
client = RubySMB::Client.new(dispatcher, smb1: smb_versions.include?('1'), smb2: smb_versions.include?('2'), smb3: smb_versions.include?('3'), username: username, password: password)
66+
client = RubySMB::Client.new(dispatcher, smb1: options[:smbv1], smb2: options[:smbv2], smb3: options[:smbv3], username: options[:username], password: options[:password], domain: options[:domain])
2567

2668
protocol = client.negotiate
2769
status = client.authenticate
@@ -35,7 +77,7 @@
3577
puts "Failed to connect to #{path}: #{e.message}"
3678
end
3779

38-
file = tree.open_file(filename: file, delete: true)
80+
file = tree.open_file(filename: options[:file], delete: true)
3981

4082
data = file.delete
4183
puts data

examples/dump_secrets_from_sid.rb

Lines changed: 43 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,26 +2,61 @@
22

33
# This example script is used for testing DCERPC client and DRSR structures.
44
# It will attempt to connect to a host and enumerate user secrets.
5-
# Example usage: ruby dump_secrets_from_sid.rb 192.168.172.138 msfadmin msfadmin MYDOMAIN S-1-5-21-419547006-9448028-4223375872-500
5+
# Example usage: ruby dump_secrets_from_sid.rb --username msfadmin --password msfadmin 192.168.172.138 MYDOMAIN S-1-5-21-419547006-9448028-4223375872-500
66
# This will try to connect to \\192.168.172.138 with the msfadmin:msfadmin
77
# credentials and enumerate secrets of domain user with SID
88
# S-1-5-21-419547006-9448028-4223375872-500
99

1010
require 'bundler/setup'
11+
require 'optparse'
12+
require 'ruby_smb'
1113
require 'ruby_smb/dcerpc/client'
1214

15+
args = ARGV.dup
16+
options = {
17+
domain: '.',
18+
username: '',
19+
password: '',
20+
target: nil,
21+
lookup_domain: nil,
22+
sid: nil
23+
}
24+
options[:sid] = args.pop
25+
options[:lookup_domain] = args.pop
26+
options[:target] = args.pop
27+
optparser = OptionParser.new do |opts|
28+
opts.banner = "Usage: #{File.basename(__FILE__)} [options] target domain sid"
29+
opts.on("--username USERNAME", "The account's username (default: #{options[:username]})") do |username|
30+
if username.include?('\\')
31+
options[:domain], options[:username] = username.split('\\', 2)
32+
else
33+
options[:username] = username
34+
end
35+
end
36+
opts.on("--password PASSWORD", "The account's password (default: #{options[:password]})") do |password|
37+
options[:password] = password
38+
end
39+
end
40+
optparser.parse!(args)
41+
42+
if [options[:target], options[:lookup_domain], options[:sid]].any? { |a| a == '-h' || a == '--help' }
43+
puts optparser.help
44+
exit
45+
end
46+
47+
if options[:target].nil? || options[:lookup_domain].nil? || options[:sid].nil?
48+
abort(optparser.help)
49+
end
1350

14-
address = ARGV[0]
15-
username = ARGV[1]
16-
password = ARGV[2]
17-
domain = ARGV[3]
18-
sid = ARGV[4]
51+
address = options[:target]
52+
domain = options[:lookup_domain]
53+
sid = options[:sid]
1954

2055
client = RubySMB::Dcerpc::Client.new(
2156
address,
2257
RubySMB::Dcerpc::Drsr,
23-
username: username,
24-
password: password,
58+
username: options[:username],
59+
password: options[:password],
2560
)
2661
client.connect
2762
puts('Binding to DRSR...')

0 commit comments

Comments
 (0)