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.
@@ -1,24 +1,11 @@
1
1
  #!/usr/bin/ruby
2
2
 
3
- # This example script is used for testing the reading of a file.
3
+ # This example script is used for testing the reading of a file with SMBv3 encryption.
4
4
  # It will attempt to connect to a specific share and then read a specified file.
5
- # Example usage: ruby read_file.rb 192.168.172.138 msfadmin msfadmin TEST_SHARE short.txt
5
+ # Example usage: ruby read_file_encryption.rb --username msfadmin --password msfadmin 192.168.172.138 TEST_SHARE short.txt
6
6
  # This will try to connect to \\192.168.172.138\TEST_SHARE with the msfadmin:msfadmin credentials
7
7
  # and read the file short.txt
8
8
 
9
- require 'bundler/setup'
10
- require 'ruby_smb'
11
-
12
- address = ARGV[0]
13
- username = ARGV[1]
14
- password = ARGV[2]
15
- share = ARGV[3]
16
- filename = ARGV[4]
17
- path = "\\\\#{address}\\#{share}"
18
-
19
- sock = TCPSocket.new address, 445
20
- dispatcher = RubySMB::Dispatcher::Socket.new(sock)
21
-
22
9
  # To require encryption on the server, run this in an elevated Powershell:
23
10
  # C:\> Set-SmbServerConfiguration -EncryptData $true
24
11
 
@@ -26,20 +13,78 @@ dispatcher = RubySMB::Dispatcher::Socket.new(sock)
26
13
  # C:\ Set-SmbServerConfiguration -EncryptData $false
27
14
  # C:\ Set-SmbShare -Name <share name> -EncryptData 1
28
15
 
29
- # For this encryption to work, it has to be SMBv3. By only setting smb3 to true,
30
- # we make sure the server will negotiate this version, if it supports it
31
- opts = {
32
- smb1: false,
33
- smb2: false,
34
- smb3: true,
35
- username: username,
36
- password: password,
16
+ # For this encryption to work, it has to be SMBv3. By default, SMBv1 and SMBv2
17
+ # are disabled here so the server will negotiate SMBv3 if it supports it.
18
+
19
+ require 'bundler/setup'
20
+ require 'optparse'
21
+ require 'ruby_smb'
22
+
23
+ args = ARGV.dup
24
+ options = {
25
+ domain: '.',
26
+ username: '',
27
+ password: '',
28
+ smbv1: false,
29
+ smbv2: false,
30
+ smbv3: true,
31
+ target: nil,
32
+ share: nil,
33
+ file: nil
37
34
  }
35
+ options[:file] = args.pop
36
+ options[:share] = args.pop
37
+ options[:target] = args.pop
38
+ optparser = OptionParser.new do |opts|
39
+ opts.banner = "Usage: #{File.basename(__FILE__)} [options] target share file"
40
+ opts.on("--[no-]smbv1", "Enable or disable SMBv1 (default: #{options[:smbv1] ? 'Enabled' : 'Disabled'})") do |smbv1|
41
+ options[:smbv1] = smbv1
42
+ end
43
+ opts.on("--[no-]smbv2", "Enable or disable SMBv2 (default: #{options[:smbv2] ? 'Enabled' : 'Disabled'})") do |smbv2|
44
+ options[:smbv2] = smbv2
45
+ end
46
+ opts.on("--[no-]smbv3", "Enable or disable SMBv3 (default: #{options[:smbv3] ? 'Enabled' : 'Disabled'})") do |smbv3|
47
+ options[:smbv3] = smbv3
48
+ end
49
+ opts.on("--username USERNAME", "The account's username (default: #{options[:username]})") do |username|
50
+ if username.include?('\\')
51
+ options[:domain], options[:username] = username.split('\\', 2)
52
+ else
53
+ options[:username] = username
54
+ end
55
+ end
56
+ opts.on("--password PASSWORD", "The account's password (default: #{options[:password]})") do |password|
57
+ options[:password] = password
58
+ end
59
+ end
60
+ optparser.parse!(args)
61
+
62
+ if [options[:target], options[:share], options[:file]].any? { |a| a == '-h' || a == '--help' }
63
+ puts optparser.help
64
+ exit
65
+ end
66
+
67
+ if options[:target].nil? || options[:share].nil? || options[:file].nil?
68
+ abort(optparser.help)
69
+ end
70
+
71
+ path = "\\\\#{options[:target]}\\#{options[:share]}"
72
+
73
+ sock = TCPSocket.new options[:target], 445
74
+ dispatcher = RubySMB::Dispatcher::Socket.new(sock)
38
75
 
39
76
  # By default, the client uses encryption even if it is not required by the server. Disable this by setting always_encrypt to false
40
- #opts[:always_encrypt] = false
77
+ client_opts = {
78
+ smb1: options[:smbv1],
79
+ smb2: options[:smbv2],
80
+ smb3: options[:smbv3],
81
+ username: options[:username],
82
+ password: options[:password],
83
+ domain: options[:domain]
84
+ }
85
+ #client_opts[:always_encrypt] = false
41
86
 
42
- client = RubySMB::Client.new(dispatcher, opts)
87
+ client = RubySMB::Client.new(dispatcher, **client_opts)
43
88
  protocol = client.negotiate
44
89
  status = client.authenticate
45
90
 
@@ -49,7 +94,7 @@ rescue StandardError => e
49
94
  puts "Failed to connect to #{path}: #{e.message}"
50
95
  end
51
96
 
52
- file = tree.open_file(filename: filename)
97
+ file = tree.open_file(filename: options[:file])
53
98
 
54
99
  data = file.read
55
100
  puts data
@@ -2,23 +2,69 @@
2
2
 
3
3
  # This example script is used for testing the Winreg registry key value read functionality.
4
4
  # It will attempt to connect to a host and reads the value of a specified registry key.
5
- # Example usage: ruby enum_registry_key.rb 192.168.172.138 msfadmin msfadmin HKLM\\My\\Key ValueName
5
+ # Example usage: ruby read_registry_key_value.rb --username msfadmin --password msfadmin 192.168.172.138 HKLM\\My\\Key ValueName
6
6
  # This will try to connect to \\192.168.172.138 with the msfadmin:msfadmin credentialas and reads the ValueName data corresponding to the HKLM\\My\\Key registry key.
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
- registry_key = ARGV[3]
15
- value_name = ARGV[4]
16
- smb_versions = ARGV[5]&.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
+ registry_key: nil,
22
+ value_name: nil
23
+ }
24
+ options[:value_name] = args.pop
25
+ options[:registry_key] = args.pop
26
+ options[:target] = args.pop
27
+ optparser = OptionParser.new do |opts|
28
+ opts.banner = "Usage: #{File.basename(__FILE__)} [options] target registry_key value_name"
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[:registry_key], options[:value_name]].any? { |a| a == '-h' || a == '--help' }
52
+ puts optparser.help
53
+ exit
54
+ end
55
+
56
+ if options[:target].nil? || options[:registry_key].nil? || options[:value_name].nil?
57
+ abort(optparser.help)
58
+ end
59
+
60
+ address = options[:target]
61
+ registry_key = options[:registry_key]
62
+ value_name = options[:value_name]
17
63
 
18
64
  sock = TCPSocket.new address, 445
19
65
  dispatcher = RubySMB::Dispatcher::Socket.new(sock, read_timeout: 60)
20
66
 
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)
67
+ client = RubySMB::Client.new(dispatcher, smb1: options[:smbv1], smb2: options[:smbv2], smb3: options[:smbv3], username: options[:username], password: options[:password], domain: options[:domain])
22
68
  protocol = client.negotiate
23
69
  status = client.authenticate
24
70
 
@@ -30,4 +76,3 @@ key_value = client.read_registry_key_value(address, registry_key, value_name)
30
76
  puts key_value
31
77
 
32
78
  client.disconnect!
33
-
@@ -1,28 +1,71 @@
1
1
  #!/usr/bin/ruby
2
2
 
3
- # This example script is used for testing the deleting of a file.
3
+ # This example script is used for testing the renaming of a file.
4
4
  # It will attempt to connect to a specific share and then rename a specified file.
5
- # Example usage: ruby rename_file.rb 192.168.172.138 msfadmin msfadmin TEST_SHARE short.txt shortrenamed.txt
5
+ # Example usage: ruby rename_file.rb --username msfadmin --password msfadmin 192.168.172.138 TEST_SHARE short.txt shortrenamed.txt
6
6
  # This will try to connect to \\192.168.172.138\TEST_SHARE with the msfadmin:msfadmin credentials
7
- # and rename the file short.txt
7
+ # and rename the file short.txt to shortrenamed.txt
8
8
 
9
9
  require 'bundler/setup'
10
+ require 'optparse'
10
11
  require 'ruby_smb'
11
12
 
12
- address = ARGV[0]
13
- username = ARGV[1]
14
- password = ARGV[2]
15
- share = ARGV[3]
16
- file = ARGV[4]
17
- new_name = 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
+ new_name: nil
25
+ }
26
+ options[:new_name] = 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 new_name"
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[:new_name]].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[:new_name].nil?
60
+ abort(optparser.help)
61
+ end
19
62
 
20
- path = "\\\\#{address}\\#{share}"
63
+ path = "\\\\#{options[:target]}\\#{options[:share]}"
21
64
 
22
- sock = TCPSocket.new address, 445
65
+ sock = TCPSocket.new options[:target], 445
23
66
  dispatcher = RubySMB::Dispatcher::Socket.new(sock)
24
67
 
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])
26
69
 
27
70
  protocol = client.negotiate
28
71
  status = client.authenticate
@@ -36,8 +79,8 @@ rescue StandardError => e
36
79
  puts "Failed to connect to #{path}: #{e.message}"
37
80
  end
38
81
 
39
- file = tree.open_file(filename: file, write: true, delete: true)
82
+ file = tree.open_file(filename: options[:file], write: true, delete: true)
40
83
 
41
- data = file.rename(new_name)
84
+ data = file.rename(options[:new_name])
42
85
  puts data
43
86
  file.close
@@ -2,27 +2,70 @@
2
2
 
3
3
  # This example script is used for testing the writing to a file.
4
4
  # It will attempt to connect to a specific share and then write to a specified file.
5
- # Example usage: ruby write_file.rb 192.168.172.138 msfadmin msfadmin TEST_SHARE test.txt "data to write"
5
+ # Example usage: ruby write_file.rb --username msfadmin --password msfadmin 192.168.172.138 TEST_SHARE test.txt "data to write"
6
6
  # This will try to connect to \\192.168.172.138\TEST_SHARE with the msfadmin:msfadmin credentials
7
- # and write "data to write" the file test.txt
7
+ # and write "data to write" to the file test.txt
8
8
 
9
9
  require 'bundler/setup'
10
+ require 'optparse'
10
11
  require 'ruby_smb'
11
12
 
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
19
62
 
20
- path = "\\\\#{address}\\#{share}"
63
+ path = "\\\\#{options[:target]}\\#{options[:share]}"
21
64
 
22
- sock = TCPSocket.new address, 445
65
+ sock = TCPSocket.new options[:target], 445
23
66
  dispatcher = RubySMB::Dispatcher::Socket.new(sock)
24
67
 
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])
26
69
  protocol = client.negotiate
27
70
  status = client.authenticate
28
71
 
@@ -32,11 +75,11 @@ begin
32
75
  tree = client.tree_connect(path)
33
76
  puts "Connected to #{path} successfully!"
34
77
  rescue StandardError => e
35
- puts "Failed to connect to #{path}: #{e.message}"
78
+ abort("Failed to connect to #{path}: #{e.message}")
36
79
  end
37
80
 
38
- file = tree.open_file(filename: file, write: true, disposition: RubySMB::Dispositions::FILE_OVERWRITE_IF)
81
+ file = tree.open_file(filename: options[:file], write: true, disposition: RubySMB::Dispositions::FILE_OVERWRITE_IF)
39
82
 
40
- result = file.write(data: data)
83
+ result = file.write(data: options[:data])
41
84
  puts result.to_s
42
85
  file.close
@@ -1,3 +1,3 @@
1
1
  module RubySMB
2
- VERSION = '3.3.19'.freeze
2
+ VERSION = '3.3.20'.freeze
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby_smb
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.3.19
4
+ version: 3.3.20
5
5
  platform: ruby
6
6
  authors:
7
7
  - Metasploit Hackers
@@ -13,7 +13,7 @@ authors:
13
13
  autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
- date: 2026-04-27 00:00:00.000000000 Z
16
+ date: 2026-05-21 00:00:00.000000000 Z
17
17
  dependencies:
18
18
  - !ruby/object:Gem::Dependency
19
19
  name: redcarpet