Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
f565419
Update examples/authenticate.rb to use OptionParser
zeroSteiner Apr 28, 2026
cf9d8e5
Update examples/append_file.rb to use OptionParser
zeroSteiner Apr 28, 2026
e6868f8
Update examples/delete_file.rb to use OptionParser
zeroSteiner Apr 28, 2026
c1bf166
Update examples/dump_secrets_from_sid.rb to use OptionParser
zeroSteiner Apr 28, 2026
fd9c2bf
Update examples/enum_domain_users.rb to use OptionParser
zeroSteiner Apr 28, 2026
cae8892
Update examples/enum_registry_key.rb to use OptionParser
zeroSteiner Apr 28, 2026
94d0192
Update examples/enum_registry_values.rb to use OptionParser
zeroSteiner Apr 28, 2026
58f8c96
Update examples/get_computer_info.rb to use OptionParser
zeroSteiner Apr 28, 2026
63f2254
Update examples/list_directory.rb to use OptionParser
zeroSteiner Apr 28, 2026
551d485
Update examples/negotiate.rb to use OptionParser
zeroSteiner Apr 28, 2026
b9c913c
Update examples/negotiate_with_netbios_service.rb to use OptionParser
zeroSteiner Apr 28, 2026
f3807f1
Update examples/net_share_enum_all.rb to use OptionParser
zeroSteiner Apr 28, 2026
9308c5b
Update examples/pipes.rb to use OptionParser
zeroSteiner Apr 28, 2026
366b8a4
Update examples/query_service_status.rb to use OptionParser
zeroSteiner Apr 28, 2026
8141da3
Update examples/read_file_encryption.rb to use OptionParser
zeroSteiner Apr 28, 2026
f6b3c2d
Update examples/read_registry_key_value.rb to use OptionParser
zeroSteiner Apr 28, 2026
6be1ee0
Update examples/rename_file.rb to use OptionParser
zeroSteiner Apr 28, 2026
e96489d
Update examples/write_file.rb to use OptionParser
zeroSteiner Apr 28, 2026
5dc2515
Print help when -h/--help is the only argument to anonymous_auth.rb
zeroSteiner Apr 28, 2026
1090e5b
Don't continue if the tree isn't connected
zeroSteiner May 21, 2026
4108ff8
Remove the stale usage reference
zeroSteiner May 21, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions examples/anonymous_auth.rb
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,11 @@ def run_authentication(address, smb1, smb2, smb3)
end
optparser.parse!(args)

if options[:target] == '-h' || options[:target] == '--help'
puts optparser.help
exit
end

if options[:target].nil?
abort(optparser.help)
end
Expand Down
71 changes: 57 additions & 14 deletions examples/append_file.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,70 @@

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

require 'bundler/setup'
require 'optparse'
require 'ruby_smb'

address = ARGV[0]
username = ARGV[1]
password = ARGV[2]
share = ARGV[3]
file = ARGV[4]
data = ARGV[5]
smb_versions = ARGV[6]&.split(',') || ['1','2','3']
args = ARGV.dup
options = {
domain: '.',
username: '',
password: '',
smbv1: true,
smbv2: true,
smbv3: true,
target: nil,
share: nil,
file: nil,
data: nil
}
options[:data] = args.pop
options[:file] = args.pop
options[:share] = args.pop
options[:target] = args.pop
optparser = OptionParser.new do |opts|
opts.banner = "Usage: #{File.basename(__FILE__)} [options] target share file data"
opts.on("--[no-]smbv1", "Enable or disable SMBv1 (default: #{options[:smbv1] ? 'Enabled' : 'Disabled'})") do |smbv1|
options[:smbv1] = smbv1
end
opts.on("--[no-]smbv2", "Enable or disable SMBv2 (default: #{options[:smbv2] ? 'Enabled' : 'Disabled'})") do |smbv2|
options[:smbv2] = smbv2
end
opts.on("--[no-]smbv3", "Enable or disable SMBv3 (default: #{options[:smbv3] ? 'Enabled' : 'Disabled'})") do |smbv3|
options[:smbv3] = smbv3
end
opts.on("--username USERNAME", "The account's username (default: #{options[:username]})") do |username|
if username.include?('\\')
options[:domain], options[:username] = username.split('\\', 2)
else
options[:username] = username
end
end
opts.on("--password PASSWORD", "The account's password (default: #{options[:password]})") do |password|
options[:password] = password
end
end
optparser.parse!(args)

if [options[:target], options[:share], options[:file], options[:data]].any? { |a| a == '-h' || a == '--help' }
puts optparser.help
exit
end

if options[:target].nil? || options[:share].nil? || options[:file].nil? || options[:data].nil?
abort(optparser.help)
end

path = "\\\\#{address}\\#{share}"
path = "\\\\#{options[:target]}\\#{options[:share]}"

sock = TCPSocket.new address, 445
sock = TCPSocket.new options[:target], 445
dispatcher = RubySMB::Dispatcher::Socket.new(sock)

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

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

file = tree.open_file(filename: file, write: true, disposition: RubySMB::Dispositions::FILE_OPEN_IF)
file = tree.open_file(filename: options[:file], write: true, disposition: RubySMB::Dispositions::FILE_OPEN_IF)

result = file.append(data: data)
result = file.append(data: options[:data])
puts result.to_s
file.close
80 changes: 64 additions & 16 deletions examples/authenticate.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@
# including protocol negotiation and authentication.

require 'bundler/setup'
require 'optparse'
require 'ruby_smb'

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

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

address = ARGV[0]
username = ARGV[1]
password = ARGV[2]

# Negotiate with SMB1, SMB2 and SMB3 enabled on the client
run_authentication(address, true, true, true, username, password)
# Negotiate with both SMB1 and SMB2 enabled on the client
run_authentication(address, true, true, false, username, password)
# Negotiate with only SMB1 enabled
run_authentication(address, true, false, false, username, password)
# Negotiate with only SMB2 enabled
run_authentication(address, false, true, false, username, password)
# Negotiate with only SMB3 enabled
run_authentication(address, false, false, true, username, password)
args = ARGV.dup
options = {
domain: '.',
username: '',
password: '',
smbv1: true,
smbv2: true,
smbv3: true,
target: nil
}
options[:target] = args.pop
optparser = OptionParser.new do |opts|
opts.banner = "Usage: #{File.basename(__FILE__)} [options] target"
opts.on("--[no-]smbv1", "Enable or disable SMBv1 (default: #{options[:smbv1] ? 'Enabled' : 'Disabled'})") do |smbv1|
options[:smbv1] = smbv1
end
opts.on("--[no-]smbv2", "Enable or disable SMBv2 (default: #{options[:smbv2] ? 'Enabled' : 'Disabled'})") do |smbv2|
options[:smbv2] = smbv2
end
opts.on("--[no-]smbv3", "Enable or disable SMBv3 (default: #{options[:smbv3] ? 'Enabled' : 'Disabled'})") do |smbv3|
options[:smbv3] = smbv3
end
opts.on("--username USERNAME", "The account's username (default: #{options[:username]})") do |username|
if username.include?('\\')
options[:domain], options[:username] = username.split('\\', 2)
else
options[:username] = username
end
end
opts.on("--password PASSWORD", "The account's password (default: #{options[:password]})") do |password|
options[:password] = password
end
end
optparser.parse!(args)

if options[:target] == '-h' || options[:target] == '--help'
puts optparser.help
exit
end

if options[:target].nil?
abort(optparser.help)
end

# (smb1, smb2, smb3) combinations to exercise — filtered by the user's
# --[no-]smbv{1,2,3} flags so that any combo requiring a disabled version
# is skipped.
combinations = [
[true, true, true], # SMB1, SMB2 and SMB3 enabled
[true, true, false], # SMB1 and SMB2 enabled
[true, false, false], # only SMB1 enabled
[false, true, false], # only SMB2 enabled
[false, false, true] # only SMB3 enabled
]

combinations.each do |smb1, smb2, smb3|
next if smb1 && !options[:smbv1]
next if smb2 && !options[:smbv2]
next if smb3 && !options[:smbv3]
run_authentication(options[:target], smb1, smb2, smb3, options[:username], options[:password], options[:domain])
end
64 changes: 53 additions & 11 deletions examples/delete_file.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,68 @@

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

require 'bundler/setup'
require 'optparse'
require 'ruby_smb'

address = ARGV[0]
username = ARGV[1]
password = ARGV[2]
share = ARGV[3]
file = ARGV[4]
smb_versions = ARGV[5]&.split(',') || ['1','2','3']
args = ARGV.dup
options = {
domain: '.',
username: '',
password: '',
smbv1: true,
smbv2: true,
smbv3: true,
target: nil,
share: nil,
file: nil
}
options[:file] = args.pop
options[:share] = args.pop
options[:target] = args.pop
optparser = OptionParser.new do |opts|
opts.banner = "Usage: #{File.basename(__FILE__)} [options] target share file"
opts.on("--[no-]smbv1", "Enable or disable SMBv1 (default: #{options[:smbv1] ? 'Enabled' : 'Disabled'})") do |smbv1|
options[:smbv1] = smbv1
end
opts.on("--[no-]smbv2", "Enable or disable SMBv2 (default: #{options[:smbv2] ? 'Enabled' : 'Disabled'})") do |smbv2|
options[:smbv2] = smbv2
end
opts.on("--[no-]smbv3", "Enable or disable SMBv3 (default: #{options[:smbv3] ? 'Enabled' : 'Disabled'})") do |smbv3|
options[:smbv3] = smbv3
end
opts.on("--username USERNAME", "The account's username (default: #{options[:username]})") do |username|
if username.include?('\\')
options[:domain], options[:username] = username.split('\\', 2)
else
options[:username] = username
end
end
opts.on("--password PASSWORD", "The account's password (default: #{options[:password]})") do |password|
options[:password] = password
end
end
optparser.parse!(args)

if [options[:target], options[:share], options[:file]].any? { |a| a == '-h' || a == '--help' }
puts optparser.help
exit
end

if options[:target].nil? || options[:share].nil? || options[:file].nil?
abort(optparser.help)
end

path = "\\\\#{address}\\#{share}"
path = "\\\\#{options[:target]}\\#{options[:share]}"

sock = TCPSocket.new address, 445
sock = TCPSocket.new options[:target], 445
dispatcher = RubySMB::Dispatcher::Socket.new(sock)

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

protocol = client.negotiate
status = client.authenticate
Expand All @@ -35,7 +77,7 @@
puts "Failed to connect to #{path}: #{e.message}"
end

file = tree.open_file(filename: file, delete: true)
file = tree.open_file(filename: options[:file], delete: true)

data = file.delete
puts data
Expand Down
51 changes: 43 additions & 8 deletions examples/dump_secrets_from_sid.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,61 @@

# This example script is used for testing DCERPC client and DRSR structures.
# It will attempt to connect to a host and enumerate user secrets.
# Example usage: ruby dump_secrets_from_sid.rb 192.168.172.138 msfadmin msfadmin MYDOMAIN S-1-5-21-419547006-9448028-4223375872-500
# 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
# This will try to connect to \\192.168.172.138 with the msfadmin:msfadmin
# credentials and enumerate secrets of domain user with SID
# S-1-5-21-419547006-9448028-4223375872-500

require 'bundler/setup'
require 'optparse'
require 'ruby_smb'
require 'ruby_smb/dcerpc/client'

args = ARGV.dup
options = {
domain: '.',
username: '',
password: '',
target: nil,
lookup_domain: nil,
sid: nil
}
options[:sid] = args.pop
options[:lookup_domain] = args.pop
options[:target] = args.pop
optparser = OptionParser.new do |opts|
opts.banner = "Usage: #{File.basename(__FILE__)} [options] target domain sid"
opts.on("--username USERNAME", "The account's username (default: #{options[:username]})") do |username|
if username.include?('\\')
options[:domain], options[:username] = username.split('\\', 2)
else
options[:username] = username
end
end
opts.on("--password PASSWORD", "The account's password (default: #{options[:password]})") do |password|
options[:password] = password
end
end
optparser.parse!(args)

if [options[:target], options[:lookup_domain], options[:sid]].any? { |a| a == '-h' || a == '--help' }
puts optparser.help
exit
end

if options[:target].nil? || options[:lookup_domain].nil? || options[:sid].nil?
abort(optparser.help)
end

address = ARGV[0]
username = ARGV[1]
password = ARGV[2]
domain = ARGV[3]
sid = ARGV[4]
address = options[:target]
domain = options[:lookup_domain]
sid = options[:sid]

client = RubySMB::Dcerpc::Client.new(
address,
RubySMB::Dcerpc::Drsr,
username: username,
password: password,
username: options[:username],
password: options[:password],
)
client.connect
puts('Binding to DRSR...')
Expand Down
Loading
Loading