ruby_smb 3.3.19 → 3.3.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,20 +2,62 @@
2
2
 
3
3
  # This example script is used for testing DCERPC WKST requests.
4
4
  # It will attempt to retrieve configuration information of a remote computer/server.
5
- # Example usage: ruby enum_domain_users.rb 192.168.172.138 msfadmin msfadmin MyDomain
5
+ # Example usage: ruby get_computer_info.rb --username msfadmin --password msfadmin 192.168.172.138
6
6
 
7
7
  require 'bundler/setup'
8
+ require 'optparse'
8
9
  require 'ruby_smb'
9
10
 
10
- address = ARGV[0]
11
- username = ARGV[1]
12
- password = ARGV[2]
13
- smb_versions = ARGV[3]&.split(',') || ['1','2','3']
11
+ args = ARGV.dup
12
+ options = {
13
+ domain: '.',
14
+ username: '',
15
+ password: '',
16
+ smbv1: true,
17
+ smbv2: true,
18
+ smbv3: true,
19
+ target: nil
20
+ }
21
+ options[:target] = args.pop
22
+ optparser = OptionParser.new do |opts|
23
+ opts.banner = "Usage: #{File.basename(__FILE__)} [options] target"
24
+ opts.on("--[no-]smbv1", "Enable or disable SMBv1 (default: #{options[:smbv1] ? 'Enabled' : 'Disabled'})") do |smbv1|
25
+ options[:smbv1] = smbv1
26
+ end
27
+ opts.on("--[no-]smbv2", "Enable or disable SMBv2 (default: #{options[:smbv2] ? 'Enabled' : 'Disabled'})") do |smbv2|
28
+ options[:smbv2] = smbv2
29
+ end
30
+ opts.on("--[no-]smbv3", "Enable or disable SMBv3 (default: #{options[:smbv3] ? 'Enabled' : 'Disabled'})") do |smbv3|
31
+ options[:smbv3] = smbv3
32
+ end
33
+ opts.on("--username USERNAME", "The account's username (default: #{options[:username]})") do |username|
34
+ if username.include?('\\')
35
+ options[:domain], options[:username] = username.split('\\', 2)
36
+ else
37
+ options[:username] = username
38
+ end
39
+ end
40
+ opts.on("--password PASSWORD", "The account's password (default: #{options[:password]})") do |password|
41
+ options[:password] = password
42
+ end
43
+ end
44
+ optparser.parse!(args)
45
+
46
+ if options[:target] == '-h' || options[:target] == '--help'
47
+ puts optparser.help
48
+ exit
49
+ end
50
+
51
+ if options[:target].nil?
52
+ abort(optparser.help)
53
+ end
54
+
55
+ address = options[:target]
14
56
 
15
57
  sock = TCPSocket.new address, 445
16
58
  dispatcher = RubySMB::Dispatcher::Socket.new(sock, read_timeout: 60)
17
59
 
18
- client = RubySMB::Client.new(dispatcher, smb1: smb_versions.include?('1'), smb2: smb_versions.include?('2'), smb3: smb_versions.include?('3'), username: username, password: password)
60
+ client = RubySMB::Client.new(dispatcher, smb1: options[:smbv1], smb2: options[:smbv2], smb3: options[:smbv3], username: options[:username], password: options[:password], domain: options[:domain])
19
61
  protocol = client.negotiate
20
62
  status = client.authenticate
21
63
 
@@ -38,5 +80,3 @@ puts "LAN Group: #{info.wki100_langroup.encode('utf-8')}"
38
80
  puts "OS Version: #{info.wki100_ver_major}.#{info.wki100_ver_minor}"
39
81
 
40
82
  client.disconnect!
41
-
42
-
@@ -2,27 +2,69 @@
2
2
 
3
3
  # This example script is used for testing directory listing functionality
4
4
  # It will attempt to connect to a specific share and then list all files in a
5
- # specified directory..
6
- # Example usage: ruby list_directory.rb 192.168.172.138 msfadmin msfadmin TEST_SHARE subdir1
5
+ # specified directory.
6
+ # Example usage: ruby list_directory.rb --username msfadmin --password msfadmin 192.168.172.138 TEST_SHARE subdir1
7
7
  # This will try to connect to \\192.168.172.138\TEST_SHARE with the msfadmin:msfadmin credentials,
8
8
  # and then list the contents of the directory 'subdir1'
9
9
 
10
10
  require 'bundler/setup'
11
+ require 'optparse'
11
12
  require 'ruby_smb'
12
13
 
13
- address = ARGV[0]
14
- username = ARGV[1]
15
- password = ARGV[2]
16
- share = ARGV[3]
17
- dir = ARGV[4]
18
- smb_versions = ARGV[5]&.split(',') || ['1','2','3']
14
+ args = ARGV.dup
15
+ options = {
16
+ domain: '.',
17
+ username: '',
18
+ password: '',
19
+ smbv1: true,
20
+ smbv2: true,
21
+ smbv3: true,
22
+ target: nil,
23
+ share: nil,
24
+ directory: nil
25
+ }
26
+ options[:directory] = args.pop
27
+ options[:share] = args.pop
28
+ options[:target] = args.pop
29
+ optparser = OptionParser.new do |opts|
30
+ opts.banner = "Usage: #{File.basename(__FILE__)} [options] target share directory"
31
+ opts.on("--[no-]smbv1", "Enable or disable SMBv1 (default: #{options[:smbv1] ? 'Enabled' : 'Disabled'})") do |smbv1|
32
+ options[:smbv1] = smbv1
33
+ end
34
+ opts.on("--[no-]smbv2", "Enable or disable SMBv2 (default: #{options[:smbv2] ? 'Enabled' : 'Disabled'})") do |smbv2|
35
+ options[:smbv2] = smbv2
36
+ end
37
+ opts.on("--[no-]smbv3", "Enable or disable SMBv3 (default: #{options[:smbv3] ? 'Enabled' : 'Disabled'})") do |smbv3|
38
+ options[:smbv3] = smbv3
39
+ end
40
+ opts.on("--username USERNAME", "The account's username (default: #{options[:username]})") do |username|
41
+ if username.include?('\\')
42
+ options[:domain], options[:username] = username.split('\\', 2)
43
+ else
44
+ options[:username] = username
45
+ end
46
+ end
47
+ opts.on("--password PASSWORD", "The account's password (default: #{options[:password]})") do |password|
48
+ options[:password] = password
49
+ end
50
+ end
51
+ optparser.parse!(args)
52
+
53
+ if [options[:target], options[:share], options[:directory]].any? { |a| a == '-h' || a == '--help' }
54
+ puts optparser.help
55
+ exit
56
+ end
57
+
58
+ if options[:target].nil? || options[:share].nil? || options[:directory].nil?
59
+ abort(optparser.help)
60
+ end
19
61
 
20
- path = "\\\\#{address}\\#{share}"
62
+ path = "\\\\#{options[:target]}\\#{options[:share]}"
21
63
 
22
- sock = TCPSocket.new address, 445
64
+ sock = TCPSocket.new options[:target], 445
23
65
  dispatcher = RubySMB::Dispatcher::Socket.new(sock)
24
66
 
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)
67
+ client = RubySMB::Client.new(dispatcher, smb1: options[:smbv1], smb2: options[:smbv2], smb3: options[:smbv3], username: options[:username], password: options[:password], domain: options[:domain])
26
68
  protocol = client.negotiate
27
69
  status = client.authenticate
28
70
 
@@ -35,7 +77,7 @@ rescue StandardError => e
35
77
  puts "Failed to connect to #{path}: #{e.message}"
36
78
  end
37
79
 
38
- files = tree.list(directory: dir)
80
+ files = tree.list(directory: options[:directory])
39
81
 
40
82
  files.each do |file|
41
83
  create_time = file.create_time.to_datetime.to_s
@@ -5,63 +5,75 @@
5
5
  # without any other parts.
6
6
 
7
7
  require 'bundler/setup'
8
+ require 'optparse'
8
9
  require 'ruby_smb'
9
10
 
10
- def run_negotiation(address, smb1, smb2, smb3, opts = {})
11
+ def run_negotiation(address, smb1, smb2, smb3)
11
12
  # Create our socket and add it to the dispatcher
12
13
  sock = TCPSocket.new address, 445
13
14
  dispatcher = RubySMB::Dispatcher::Socket.new(sock)
14
15
 
15
- client = RubySMB::Client.new(dispatcher, smb1: smb1, smb2: smb2, smb3: smb3, username: 'msfadmin', password: 'msfadmin')
16
+ client = RubySMB::Client.new(dispatcher, smb1: smb1, smb2: smb2, smb3: smb3, username: '', password: '')
16
17
  client.negotiate
17
18
  end
18
19
 
19
- begin
20
- puts "Negotiate with only SMB1 enabled..."
21
- puts " Negotiated version: #{run_negotiation(ARGV[0], true, false, false)}"
22
- rescue RubySMB::Error::RubySMBError => e
23
- puts "Error: #{e.message}"
20
+ args = ARGV.dup
21
+ options = {
22
+ smbv1: true,
23
+ smbv2: true,
24
+ smbv3: true,
25
+ target: nil
26
+ }
27
+ options[:target] = args.pop
28
+ optparser = OptionParser.new do |opts|
29
+ opts.banner = "Usage: #{File.basename(__FILE__)} [options] target"
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
24
39
  end
40
+ optparser.parse!(args)
25
41
 
26
- begin
27
- puts "Negotiate with only SMB2 enabled..."
28
- puts " Negotiated version: #{run_negotiation(ARGV[0], false, true, false)}"
29
- rescue RubySMB::Error::RubySMBError => e
30
- puts "Error: #{e.message}"
42
+ if options[:target] == '-h' || options[:target] == '--help'
43
+ puts optparser.help
44
+ exit
31
45
  end
32
46
 
33
- begin
34
- puts "Negotiate with only SMB3 enabled..."
35
- puts " Negotiated version: #{run_negotiation(ARGV[0], false, false, true)}"
36
- rescue RubySMB::Error::RubySMBError => e
37
- puts "Error: #{e.message}"
47
+ if options[:target].nil?
48
+ abort(optparser.help)
38
49
  end
39
50
 
40
- begin
41
- puts "Negotiate with both SMB1 and SMB2 enabled on the client..."
42
- puts " Negotiated version: #{run_negotiation(ARGV[0], true, true, false)}"
43
- rescue RubySMB::Error::RubySMBError => e
44
- puts "Error: #{e.message}"
45
- end
51
+ # (smb1, smb2, smb3) combinations to exercise — filtered by the user's
52
+ # --[no-]smbv{1,2,3} flags so any combo requiring a disabled version
53
+ # is skipped.
54
+ combinations = [
55
+ [true, false, false], # only SMB1
56
+ [false, true, false], # only SMB2
57
+ [false, false, true], # only SMB3
58
+ [true, true, false], # SMB1 and SMB2
59
+ [false, true, true], # SMB2 and SMB3
60
+ [true, false, true], # SMB1 and SMB3
61
+ [true, true, true] # SMB1, SMB2 and SMB3
62
+ ]
46
63
 
47
- begin
48
- puts "Negotiate with both SMB2 and SMB3 enabled on the client..."
49
- puts " Negotiated version: #{run_negotiation(ARGV[0], false, true, true)}"
50
- rescue RubySMB::Error::RubySMBError => e
51
- puts "Error: #{e.message}"
52
- end
64
+ combinations.each do |smb1, smb2, smb3|
65
+ next if smb1 && !options[:smbv1]
66
+ next if smb2 && !options[:smbv2]
67
+ next if smb3 && !options[:smbv3]
53
68
 
54
- begin
55
- puts "Negotiate with both SMB1 and SMB3 enabled on the client..."
56
- puts " Negotiated version: #{run_negotiation(ARGV[0], true, false, true)}"
57
- rescue RubySMB::Error::RubySMBError => e
58
- puts "Error: #{e.message}"
69
+ enabled = []
70
+ enabled << 'SMB1' if smb1
71
+ enabled << 'SMB2' if smb2
72
+ enabled << 'SMB3' if smb3
73
+ puts "Negotiate with #{enabled.join(', ')} enabled..."
74
+ begin
75
+ puts " Negotiated version: #{run_negotiation(options[:target], smb1, smb2, smb3)}"
76
+ rescue RubySMB::Error::RubySMBError => e
77
+ puts "Error: #{e.message}"
78
+ end
59
79
  end
60
-
61
- begin
62
- puts "Negotiate with SMB1, SMB2 and SMB3 enabled on the client..."
63
- puts " Negotiated version: #{run_negotiation(ARGV[0], true, true, true)}"
64
- rescue RubySMB::Error::RubySMBError => e
65
- puts "Error: #{e.message}"
66
- end
67
-
@@ -1,19 +1,19 @@
1
1
  #!/usr/bin/ruby
2
2
 
3
3
  # This script is for testing the NetBIOS Session Service Request on port 139/tcp.
4
- # Example usage: ruby negotiate.rb 192.168.172.138 NBNAME
5
- # This will connect to 192.168.172.138 (139/TCP) and request a NetBIOS session with NBNAME as the called name.
4
+ # This will connect to 192.168.172.138 (139/TCP) and request a NetBIOS session with NBNAME as the called name.
6
5
  # If successful, a SMB negotiation is performed using this NetBIOS session.
7
6
  # The default *SMBSERVER name is used if the NetBIOS name is not provided.
8
7
 
9
8
  require 'bundler/setup'
9
+ require 'optparse'
10
10
  require 'ruby_smb'
11
11
 
12
12
  def run_negotiation(address, smb1, smb2, smb3, netbios_name)
13
13
  sock = TCPSocket.new address, 139
14
14
  dispatcher = RubySMB::Dispatcher::Socket.new(sock)
15
15
 
16
- client = RubySMB::Client.new(dispatcher, smb1: smb1, smb2: smb2, smb3: smb3, username: 'msfadmin', password: 'msfadmin')
16
+ client = RubySMB::Client.new(dispatcher, smb1: smb1, smb2: smb2, smb3: smb3, username: '', password: '')
17
17
  begin
18
18
  client.session_request(netbios_name)
19
19
  rescue RubySMB::Error::NetBiosSessionService => e
@@ -25,16 +25,55 @@ def run_negotiation(address, smb1, smb2, smb3, netbios_name)
25
25
  puts "#{smb_version} successfully negotiated."
26
26
  end
27
27
 
28
- address = ARGV[0]
29
- netbios_name = ARGV[1] || '*SMBSERVER'
30
-
31
- # Negotiate with SMB1, SMB2 and SMB3 enabled on the client
32
- run_negotiation(ARGV[0], true, true, true, netbios_name)
33
- # Negotiate with both SMB1 and SMB2 enabled on the client
34
- run_negotiation(ARGV[0], true, true, false, netbios_name)
35
- # Negotiate with only SMB1 enabled
36
- run_negotiation(ARGV[0], true, false, false, netbios_name)
37
- # Negotiate with only SMB2 enabled
38
- run_negotiation(ARGV[0], false, true, false, netbios_name)
39
- # Negotiate with only SMB3 enabled
40
- run_negotiation(ARGV[0], false, false, true, netbios_name)
28
+ args = ARGV.dup
29
+ options = {
30
+ smbv1: true,
31
+ smbv2: true,
32
+ smbv3: true,
33
+ netbios_name: '*SMBSERVER',
34
+ target: nil
35
+ }
36
+ options[:target] = args.pop
37
+ optparser = OptionParser.new do |opts|
38
+ opts.banner = "Usage: #{File.basename(__FILE__)} [options] target"
39
+ opts.on("--[no-]smbv1", "Enable or disable SMBv1 (default: #{options[:smbv1] ? 'Enabled' : 'Disabled'})") do |smbv1|
40
+ options[:smbv1] = smbv1
41
+ end
42
+ opts.on("--[no-]smbv2", "Enable or disable SMBv2 (default: #{options[:smbv2] ? 'Enabled' : 'Disabled'})") do |smbv2|
43
+ options[:smbv2] = smbv2
44
+ end
45
+ opts.on("--[no-]smbv3", "Enable or disable SMBv3 (default: #{options[:smbv3] ? 'Enabled' : 'Disabled'})") do |smbv3|
46
+ options[:smbv3] = smbv3
47
+ end
48
+ opts.on("--netbios-name NAME", "The NetBIOS called name (default: #{options[:netbios_name]})") do |name|
49
+ options[:netbios_name] = name
50
+ end
51
+ end
52
+ optparser.parse!(args)
53
+
54
+ if options[:target] == '-h' || options[:target] == '--help'
55
+ puts optparser.help
56
+ exit
57
+ end
58
+
59
+ if options[:target].nil?
60
+ abort(optparser.help)
61
+ end
62
+
63
+ # (smb1, smb2, smb3) combinations to exercise — filtered by the user's
64
+ # --[no-]smbv{1,2,3} flags so any combo requiring a disabled version
65
+ # is skipped.
66
+ combinations = [
67
+ [true, true, true], # SMB1, SMB2 and SMB3 enabled
68
+ [true, true, false], # SMB1 and SMB2 enabled
69
+ [true, false, false], # only SMB1 enabled
70
+ [false, true, false], # only SMB2 enabled
71
+ [false, false, true] # only SMB3 enabled
72
+ ]
73
+
74
+ combinations.each do |smb1, smb2, smb3|
75
+ next if smb1 && !options[:smbv1]
76
+ next if smb2 && !options[:smbv2]
77
+ next if smb3 && !options[:smbv3]
78
+ run_negotiation(options[:target], smb1, smb2, smb3, options[:netbios_name])
79
+ end
@@ -2,23 +2,63 @@
2
2
 
3
3
  # This example script is used for testing NetShareEnumAll functionality
4
4
  # It will attempt to connect to a host and enumerate shares.
5
- # Example usage: ruby net_share_enum_all.rb 192.168.172.138 msfadmin msfadmin
5
+ # Example usage: ruby net_share_enum_all.rb --username msfadmin --password msfadmin 192.168.172.138
6
6
  # This will try to connect to \\192.168.172.138 with the msfadmin:msfadmin credentials
7
7
 
8
8
  require 'bundler/setup'
9
+ require 'optparse'
9
10
  require 'ruby_smb'
10
11
 
11
- address = ARGV[0]
12
- username = ARGV[1]
13
- password = ARGV[2]
14
- smb_versions = ARGV[3]&.split(',') || ['1','2','3']
12
+ args = ARGV.dup
13
+ options = {
14
+ domain: '.',
15
+ username: '',
16
+ password: '',
17
+ smbv1: true,
18
+ smbv2: true,
19
+ smbv3: true,
20
+ target: nil
21
+ }
22
+ options[:target] = args.pop
23
+ optparser = OptionParser.new do |opts|
24
+ opts.banner = "Usage: #{File.basename(__FILE__)} [options] target"
25
+ opts.on("--[no-]smbv1", "Enable or disable SMBv1 (default: #{options[:smbv1] ? 'Enabled' : 'Disabled'})") do |smbv1|
26
+ options[:smbv1] = smbv1
27
+ end
28
+ opts.on("--[no-]smbv2", "Enable or disable SMBv2 (default: #{options[:smbv2] ? 'Enabled' : 'Disabled'})") do |smbv2|
29
+ options[:smbv2] = smbv2
30
+ end
31
+ opts.on("--[no-]smbv3", "Enable or disable SMBv3 (default: #{options[:smbv3] ? 'Enabled' : 'Disabled'})") do |smbv3|
32
+ options[:smbv3] = smbv3
33
+ end
34
+ opts.on("--username USERNAME", "The account's username (default: #{options[:username]})") do |username|
35
+ if username.include?('\\')
36
+ options[:domain], options[:username] = username.split('\\', 2)
37
+ else
38
+ options[:username] = username
39
+ end
40
+ end
41
+ opts.on("--password PASSWORD", "The account's password (default: #{options[:password]})") do |password|
42
+ options[:password] = password
43
+ end
44
+ end
45
+ optparser.parse!(args)
46
+
47
+ if options[:target] == '-h' || options[:target] == '--help'
48
+ puts optparser.help
49
+ exit
50
+ end
15
51
 
16
- path = "\\\\#{address}\\IPC$"
52
+ if options[:target].nil?
53
+ abort(optparser.help)
54
+ end
55
+
56
+ address = options[:target]
17
57
 
18
58
  sock = TCPSocket.new address, 445
19
59
  dispatcher = RubySMB::Dispatcher::Socket.new(sock, read_timeout: 60)
20
60
 
21
- client = RubySMB::Client.new(dispatcher, smb1: smb_versions.include?('1'), smb2: smb_versions.include?('2'), smb3: smb_versions.include?('3'), username: username, password: password)
61
+ client = RubySMB::Client.new(dispatcher, smb1: options[:smbv1], smb2: options[:smbv2], smb3: options[:smbv3], username: options[:username], password: options[:password], domain: options[:domain])
22
62
  protocol = client.negotiate
23
63
  status = client.authenticate
24
64
 
@@ -32,4 +72,3 @@ rescue => e
32
72
  end
33
73
 
34
74
  client.disconnect!
35
-
data/examples/pipes.rb CHANGED
@@ -4,22 +4,66 @@
4
4
  # Example script for connecting to a named pipe and performing a peek operation.
5
5
  # This is used to demonstrate pipe operations.
6
6
  #
7
- # Usage: ruby pipes.rb ADDRESS PIPENAME USER PASS 1|2
7
+ # Usage: ruby pipes.rb --username USER --password PASS ADDRESS PIPENAME
8
8
  #
9
9
 
10
10
  require 'bundler/setup'
11
+ require 'optparse'
11
12
  require 'ruby_smb'
12
13
 
13
- address = ARGV[0]
14
- pipename = ARGV[1]
15
- username = ARGV[2]
16
- password = ARGV[3]
17
- smb_versions = ARGV[4]&.split(',') || ['1','2','3']
14
+ args = ARGV.dup
15
+ options = {
16
+ domain: '.',
17
+ username: '',
18
+ password: '',
19
+ smbv1: true,
20
+ smbv2: true,
21
+ smbv3: true,
22
+ target: nil,
23
+ pipename: nil
24
+ }
25
+ options[:pipename] = args.pop
26
+ options[:target] = args.pop
27
+ optparser = OptionParser.new do |opts|
28
+ opts.banner = "Usage: #{File.basename(__FILE__)} [options] target pipename"
29
+ opts.on("--[no-]smbv1", "Enable or disable SMBv1 (default: #{options[:smbv1] ? 'Enabled' : 'Disabled'})") do |smbv1|
30
+ options[:smbv1] = smbv1
31
+ end
32
+ opts.on("--[no-]smbv2", "Enable or disable SMBv2 (default: #{options[:smbv2] ? 'Enabled' : 'Disabled'})") do |smbv2|
33
+ options[:smbv2] = smbv2
34
+ end
35
+ opts.on("--[no-]smbv3", "Enable or disable SMBv3 (default: #{options[:smbv3] ? 'Enabled' : 'Disabled'})") do |smbv3|
36
+ options[:smbv3] = smbv3
37
+ end
38
+ opts.on("--username USERNAME", "The account's username (default: #{options[:username]})") do |username|
39
+ if username.include?('\\')
40
+ options[:domain], options[:username] = username.split('\\', 2)
41
+ else
42
+ options[:username] = username
43
+ end
44
+ end
45
+ opts.on("--password PASSWORD", "The account's password (default: #{options[:password]})") do |password|
46
+ options[:password] = password
47
+ end
48
+ end
49
+ optparser.parse!(args)
50
+
51
+ if [options[:target], options[:pipename]].any? { |a| a == '-h' || a == '--help' }
52
+ puts optparser.help
53
+ exit
54
+ end
55
+
56
+ if options[:target].nil? || options[:pipename].nil?
57
+ abort(optparser.help)
58
+ end
59
+
60
+ address = options[:target]
61
+ pipename = options[:pipename]
18
62
 
19
63
  sock = TCPSocket.new(address, 445)
20
64
  dispatcher = RubySMB::Dispatcher::Socket.new(sock)
21
65
 
22
- 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])
23
67
  smbver = client.negotiate
24
68
 
25
69
  if smbver == 'SMB1'
@@ -2,22 +2,66 @@
2
2
 
3
3
  # This example script is used for testing remote service status and start type query.
4
4
  # It will attempt to connect to a host and query the status and start type of the provided service.
5
- # Example usage: ruby query_service_status.rb 192.168.172.138 msfadmin msfadmin "RemoteRegistry"
5
+ # Example usage: ruby query_service_status.rb --username msfadmin --password msfadmin 192.168.172.138 "RemoteRegistry"
6
6
  # This will try to connect to \\192.168.172.138 with the msfadmin:msfadmin credentialas and get the status and start type of the "RemoteRegistry" service.
7
7
 
8
8
  require 'bundler/setup'
9
+ require 'optparse'
9
10
  require 'ruby_smb'
10
11
 
11
- address = ARGV[0]
12
- username = ARGV[1]
13
- password = ARGV[2]
14
- service = ARGV[3]
15
- smb_versions = ARGV[4]&.split(',') || ['1','2','3']
12
+ args = ARGV.dup
13
+ options = {
14
+ domain: '.',
15
+ username: '',
16
+ password: '',
17
+ smbv1: true,
18
+ smbv2: true,
19
+ smbv3: true,
20
+ target: nil,
21
+ service: nil
22
+ }
23
+ options[:service] = args.pop
24
+ options[:target] = args.pop
25
+ optparser = OptionParser.new do |opts|
26
+ opts.banner = "Usage: #{File.basename(__FILE__)} [options] target service"
27
+ opts.on("--[no-]smbv1", "Enable or disable SMBv1 (default: #{options[:smbv1] ? 'Enabled' : 'Disabled'})") do |smbv1|
28
+ options[:smbv1] = smbv1
29
+ end
30
+ opts.on("--[no-]smbv2", "Enable or disable SMBv2 (default: #{options[:smbv2] ? 'Enabled' : 'Disabled'})") do |smbv2|
31
+ options[:smbv2] = smbv2
32
+ end
33
+ opts.on("--[no-]smbv3", "Enable or disable SMBv3 (default: #{options[:smbv3] ? 'Enabled' : 'Disabled'})") do |smbv3|
34
+ options[:smbv3] = smbv3
35
+ end
36
+ opts.on("--username USERNAME", "The account's username (default: #{options[:username]})") do |username|
37
+ if username.include?('\\')
38
+ options[:domain], options[:username] = username.split('\\', 2)
39
+ else
40
+ options[:username] = username
41
+ end
42
+ end
43
+ opts.on("--password PASSWORD", "The account's password (default: #{options[:password]})") do |password|
44
+ options[:password] = password
45
+ end
46
+ end
47
+ optparser.parse!(args)
48
+
49
+ if [options[:target], options[:service]].any? { |a| a == '-h' || a == '--help' }
50
+ puts optparser.help
51
+ exit
52
+ end
53
+
54
+ if options[:target].nil? || options[:service].nil?
55
+ abort(optparser.help)
56
+ end
57
+
58
+ address = options[:target]
59
+ service = options[:service]
16
60
 
17
61
  sock = TCPSocket.new address, 445
18
62
  dispatcher = RubySMB::Dispatcher::Socket.new(sock, read_timeout: 60)
19
63
 
20
- client = RubySMB::Client.new(dispatcher, smb1: smb_versions.include?('1'), smb2: smb_versions.include?('2'), smb3: smb_versions.include?('3'), username: username, password: password)
64
+ client = RubySMB::Client.new(dispatcher, smb1: options[:smbv1], smb2: options[:smbv2], smb3: options[:smbv3], username: options[:username], password: options[:password], domain: options[:domain])
21
65
  protocol = client.negotiate
22
66
  status = client.authenticate
23
67
 
@@ -99,4 +143,3 @@ if svcctl
99
143
  svcctl.close
100
144
  end
101
145
  client.disconnect!
102
-