Skip to content

Update examples with argument parsing#298

Open
zeroSteiner wants to merge 19 commits into
rapid7:masterfrom
zeroSteiner:feat/examples-with-args
Open

Update examples with argument parsing#298
zeroSteiner wants to merge 19 commits into
rapid7:masterfrom
zeroSteiner:feat/examples-with-args

Conversation

@zeroSteiner
Copy link
Copy Markdown
Contributor

This updates each of the examples scripts to use OptionParser and respond to -h / --help. This allows the operator to get the help output from the script and see the arguments without needing to review the source code.

Can validate the arguments for each by running for script in examples/*; do ruby "$script" -h; done.

The arguments that each take are standardized and were already used by the handful that originally used OptionParser such as read_file.rb.

Replace raw ARGV access with OptionParser following the convention used
in examples/read_file.rb and examples/anonymous_auth.rb. Adds --[no-]smbv1/2/3,
--username (with domain\username splitting), and --password flags. Prints
the help banner when target is missing or when -h/--help is given. The
existing five-combination test cycle is preserved but filtered by the
user's selected SMB versions.
Replace raw ARGV access with OptionParser following the existing convention.
Adds --[no-]smbv1/2/3, --username (with domain\username splitting), and
--password flags. Prints the help banner when a required positional is
missing or when -h/--help is given.
Replace raw ARGV access with OptionParser following the existing convention.
Adds --[no-]smbv1/2/3, --username (with domain\username splitting), and
--password flags. Prints the help banner when a required positional is
missing or when -h/--help is given.
Replace raw ARGV access with OptionParser following the existing convention.
Adds --username (with domain\username splitting) and --password flags;
keeps the AD lookup domain and SID as positional arguments. Prints the help
banner when a required positional is missing or when -h/--help is given.

Also requires 'ruby_smb' so the script loads independently — the previous
'ruby_smb/dcerpc/client' require alone was failing with an uninitialized
Net::NTLM constant.
Replace raw ARGV access with OptionParser following the existing convention.
Adds --[no-]smbv1/2/3, --username (with domain\username splitting), and
--password flags; keeps the AD lookup domain as a positional argument.
Prints the help banner when a required positional is missing or when
-h/--help is given.
Replace raw ARGV access with OptionParser following the existing convention.
Adds --[no-]smbv1/2/3, --username (with domain\username splitting), and
--password flags. Prints the help banner when a required positional is
missing or when -h/--help is given.
Replace raw ARGV access with OptionParser following the existing convention.
Adds --[no-]smbv1/2/3, --username (with domain\username splitting), and
--password flags. Prints the help banner when a required positional is
missing or when -h/--help is given.
Replace raw ARGV access with OptionParser following the existing convention.
Adds --[no-]smbv1/2/3, --username (with domain\username splitting), and
--password flags. Prints the help banner when target is missing or when
-h/--help is given.
Replace raw ARGV access with OptionParser following the existing convention.
Adds --[no-]smbv1/2/3, --username (with domain\username splitting), and
--password flags. Prints the help banner when a required positional is
missing or when -h/--help is given.
Replace raw ARGV access with OptionParser following the existing convention
used in examples/authenticate.rb. Adds --[no-]smbv1/2/3 flags that filter
the seven hardcoded SMB version combinations. Drops the unused hardcoded
msfadmin credentials (negotiate does not authenticate). Prints the help
banner when target is missing or when -h/--help is given.
Replace raw ARGV access with OptionParser following the existing convention.
Adds --[no-]smbv1/2/3 flags that filter the five hardcoded SMB version
combinations and a --netbios-name flag (default *SMBSERVER) replacing the
optional second positional. Drops the unused hardcoded msfadmin credentials
(this script does not authenticate). Prints the help banner when target is
missing or when -h/--help is given.
Replace raw ARGV access with OptionParser following the existing convention.
Adds --[no-]smbv1/2/3, --username (with domain\username splitting), and
--password flags. Prints the help banner when target is missing or when
-h/--help is given.
Replace raw ARGV access with OptionParser following the existing convention.
Adds --[no-]smbv1/2/3, --username (with domain\username splitting), and
--password flags. Prints the help banner when a required positional is
missing or when -h/--help is given.
Replace raw ARGV access with OptionParser following the existing convention.
Adds --[no-]smbv1/2/3, --username (with domain\username splitting), and
--password flags. Prints the help banner when a required positional is
missing or when -h/--help is given.
Replace raw ARGV access with OptionParser following the existing convention.
Adds --[no-]smbv1/2/3 (defaults: SMB1/2 disabled, SMB3 enabled to force
encryption-capable negotiation), --username (with domain\username
splitting), and --password flags. Prints the help banner when a required
positional is missing or when -h/--help is given.

Also splat the client options hash so the call works on Ruby 3.x where
non-keyword hash positionals are no longer auto-converted.
Replace raw ARGV access with OptionParser following the existing convention.
Adds --[no-]smbv1/2/3, --username (with domain\username splitting), and
--password flags. Prints the help banner when a required positional is
missing or when -h/--help is given.
Replace raw ARGV access with OptionParser following the existing convention.
Adds --[no-]smbv1/2/3, --username (with domain\username splitting), and
--password flags. Prints the help banner when a required positional is
missing or when -h/--help is given.
Replace raw ARGV access with OptionParser following the existing convention.
Adds --[no-]smbv1/2/3, --username (with domain\username splitting), and
--password flags. Prints the help banner when a required positional is
missing or when -h/--help is given.
Without this, the positional pop consumed -h/--help as the target and the
script then tried to open a TCP socket to that string. Now matches the
behavior added to authenticate.rb and the other examples.
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR standardizes argument parsing across the examples/ Ruby scripts by switching them to OptionParser and aligning common flags (SMB version toggles and credentials) so operators can discover usage via -h/--help.

Changes:

  • Adds OptionParser-based CLI parsing to many example scripts, including SMB dialect toggles and --username/--password (with optional DOMAIN\user parsing).
  • Updates example usage text and refactors scripts to consume named options plus positional arguments consistently.
  • Adjusts specific examples to support additional parameters (e.g., NetBIOS called name flag, SMBv3 encryption defaults).

Reviewed changes

Copilot reviewed 19 out of 19 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
examples/write_file.rb Adds OptionParser + positional parsing for target/share/file/data and SMB dialect toggles.
examples/rename_file.rb Adds OptionParser + positional parsing for target/share/file/new_name and SMB dialect toggles.
examples/read_registry_key_value.rb Adds OptionParser + positional parsing for target/registry_key/value_name and SMB dialect toggles.
examples/read_file_encryption.rb Adds OptionParser + positional parsing for target/share/file; defaults to SMBv3-only for encryption testing.
examples/query_service_status.rb Adds OptionParser + positional parsing for target/service and SMB dialect toggles.
examples/pipes.rb Adds OptionParser + positional parsing for target/pipename and SMB dialect toggles.
examples/net_share_enum_all.rb Adds OptionParser + positional parsing for target and SMB dialect toggles.
examples/negotiate_with_netbios_service.rb Adds OptionParser + SMB dialect toggles + --netbios-name for the NetBIOS called name.
examples/negotiate.rb Adds OptionParser + SMB dialect toggles and iterates supported negotiation combinations.
examples/list_directory.rb Adds OptionParser + positional parsing for target/share/directory and SMB dialect toggles.
examples/get_computer_info.rb Adds OptionParser + positional parsing for target and SMB dialect toggles.
examples/enum_registry_values.rb Adds OptionParser + positional parsing for target/registry_key and SMB dialect toggles.
examples/enum_registry_key.rb Adds OptionParser + positional parsing for target/registry_key and SMB dialect toggles.
examples/enum_domain_users.rb Adds OptionParser + positional parsing for target/domain and SMB dialect toggles.
examples/dump_secrets_from_sid.rb Adds OptionParser + positional parsing for target/domain/sid and credentials flags.
examples/delete_file.rb Adds OptionParser + positional parsing for target/share/file and SMB dialect toggles.
examples/authenticate.rb Adds OptionParser + SMB dialect toggles + credentials/domain handling for auth testing.
examples/append_file.rb Adds OptionParser + positional parsing for target/share/file/data and SMB dialect toggles.
examples/anonymous_auth.rb Adds -h/--help handling around OptionParser for anonymous authentication example.

Impact Analysis: isolated change; no meaningful downstream impact identified from diff.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread examples/write_file.rb
Comment on lines +26 to +30
options[:data] = args.pop
options[:file] = args.pop
options[:share] = args.pop
options[:target] = args.pop
optparser = OptionParser.new do |opts|
Comment thread examples/write_file.rb
@@ -35,8 +78,8 @@
puts "Failed to connect to #{path}: #{e.message}"
Comment on lines +4 to 7
# Example usage: ruby negotiate_with_netbios_service.rb 192.168.172.138 NBNAME
# This will connect to 192.168.172.138 (139/TCP) and request a NetBIOS session with NBNAME as the called name.
# If successful, a SMB negotiation is performed using this NetBIOS session.
# The default *SMBSERVER name is used if the NetBIOS name is not provided.
@jheysel-r7 jheysel-r7 self-assigned this May 20, 2026
Copy link
Copy Markdown
Contributor

@jheysel-r7 jheysel-r7 left a comment

Choose a reason for hiding this comment

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

Thanks @zeroSteiner - co-pilot has a few comments with regards to positional args that might need addressing? Let me know what you think. Testing looks great.

Testing

Looping over all example scripts printing -h

➜  ruby_smb git:(5dc2515) for script in examples/*; do ruby "$script" -h; done
Usage: anonymous_auth.rb [options] target
        --[no-]smbv1                 Enable or disable SMBv1 (default: Enabled)
        --[no-]smbv2                 Enable or disable SMBv2 (default: Enabled)
        --[no-]smbv3                 Enable or disable SMBv3 (default: Enabled)
Usage: append_file.rb [options] target share file data
        --[no-]smbv1                 Enable or disable SMBv1 (default: Enabled)
        --[no-]smbv2                 Enable or disable SMBv2 (default: Enabled)
        --[no-]smbv3                 Enable or disable SMBv3 (default: Enabled)
        --username USERNAME          The account's username (default: )
        --password PASSWORD          The account's password (default: )
Usage: auth_capture.rb [options]
        --[no-]smbv1                 Enable or disable SMBv1 (default: Enabled)
        --[no-]smbv2                 Enable or disable SMBv2 (default: Enabled)
        --[no-]smbv3                 Enable or disable SMBv3 (default: Enabled)
Usage: authenticate.rb [options] target
        --[no-]smbv1                 Enable or disable SMBv1 (default: Enabled)
        --[no-]smbv2                 Enable or disable SMBv2 (default: Enabled)
        --[no-]smbv3                 Enable or disable SMBv3 (default: Enabled)
        --username USERNAME          The account's username (default: )
        --password PASSWORD          The account's password (default: )
Usage: delete_file.rb [options] target share file
        --[no-]smbv1                 Enable or disable SMBv1 (default: Enabled)
        --[no-]smbv2                 Enable or disable SMBv2 (default: Enabled)
        --[no-]smbv3                 Enable or disable SMBv3 (default: Enabled)
        --username USERNAME          The account's username (default: )
        --password PASSWORD          The account's password (default: )
Usage: dump_secrets_from_sid.rb [options] target domain sid
        --username USERNAME          The account's username (default: )
        --password PASSWORD          The account's password (default: )
Usage: enum_domain_users.rb [options] target domain
        --[no-]smbv1                 Enable or disable SMBv1 (default: Enabled)
        --[no-]smbv2                 Enable or disable SMBv2 (default: Enabled)
        --[no-]smbv3                 Enable or disable SMBv3 (default: Enabled)
        --username USERNAME          The account's username (default: )
        --password PASSWORD          The account's password (default: )
Usage: enum_registry_key.rb [options] target registry_key
        --[no-]smbv1                 Enable or disable SMBv1 (default: Enabled)
        --[no-]smbv2                 Enable or disable SMBv2 (default: Enabled)
        --[no-]smbv3                 Enable or disable SMBv3 (default: Enabled)
        --username USERNAME          The account's username (default: )
        --password PASSWORD          The account's password (default: )
Usage: enum_registry_values.rb [options] target registry_key
        --[no-]smbv1                 Enable or disable SMBv1 (default: Enabled)
        --[no-]smbv2                 Enable or disable SMBv2 (default: Enabled)
        --[no-]smbv3                 Enable or disable SMBv3 (default: Enabled)
        --username USERNAME          The account's username (default: )
        --password PASSWORD          The account's password (default: )
Usage: script.rb [options] TARGET PROTOCOL UUID
        --major-version N            Specify major version number (default: 1)
        --minor-version N            Specify minor version number ((default: 0)
        --max-towers N               Set the maximum number of towers (default: 1)
    -h, --help                       Prints this help
Usage: file_server.rb [options]
        --share-name SHARE_NAME      The share name (default: home)
        --[no-]anonymous             Allow anonymous access (default: true)
        --[no-]guests                Allow guest accounts (default: false)
        --[no-]smbv1                 Enable or disable SMBv1 (default: Enabled)
        --[no-]smbv2                 Enable or disable SMBv2 (default: Enabled)
        --[no-]smbv3                 Enable or disable SMBv3 (default: Enabled)
        --username USERNAME          The account's username (default: RubySMB)
        --password PASSWORD          The account's password (default: password)
        --share-path SHARE_PATH      The path to share (default: .)
Usage: get_computer_info.rb [options] target
        --[no-]smbv1                 Enable or disable SMBv1 (default: Enabled)
        --[no-]smbv2                 Enable or disable SMBv2 (default: Enabled)
        --[no-]smbv3                 Enable or disable SMBv3 (default: Enabled)
        --username USERNAME          The account's username (default: )
        --password PASSWORD          The account's password (default: )
Usage: list_directory.rb [options] target share directory
        --[no-]smbv1                 Enable or disable SMBv1 (default: Enabled)
        --[no-]smbv2                 Enable or disable SMBv2 (default: Enabled)
        --[no-]smbv3                 Enable or disable SMBv3 (default: Enabled)
        --username USERNAME          The account's username (default: )
        --password PASSWORD          The account's password (default: )
Usage: negotiate_with_netbios_service.rb [options] target
        --[no-]smbv1                 Enable or disable SMBv1 (default: Enabled)
        --[no-]smbv2                 Enable or disable SMBv2 (default: Enabled)
        --[no-]smbv3                 Enable or disable SMBv3 (default: Enabled)
        --netbios-name NAME          The NetBIOS called name (default: *SMBSERVER)
Usage: negotiate.rb [options] target
        --[no-]smbv1                 Enable or disable SMBv1 (default: Enabled)
        --[no-]smbv2                 Enable or disable SMBv2 (default: Enabled)
        --[no-]smbv3                 Enable or disable SMBv3 (default: Enabled)
Usage: net_share_enum_all.rb [options] target
        --[no-]smbv1                 Enable or disable SMBv1 (default: Enabled)
        --[no-]smbv2                 Enable or disable SMBv2 (default: Enabled)
        --[no-]smbv3                 Enable or disable SMBv3 (default: Enabled)
        --username USERNAME          The account's username (default: )
        --password PASSWORD          The account's password (default: )
Usage: pipes.rb [options] target pipename
        --[no-]smbv1                 Enable or disable SMBv1 (default: Enabled)
        --[no-]smbv2                 Enable or disable SMBv2 (default: Enabled)
        --[no-]smbv3                 Enable or disable SMBv3 (default: Enabled)
        --username USERNAME          The account's username (default: )
        --password PASSWORD          The account's password (default: )
Usage: pwsh_service.rb [options] target command
        --[no-]smbv1                 Enable or disable SMBv1 (default: Enabled)
        --[no-]smbv2                 Enable or disable SMBv2 (default: Enabled)
        --[no-]smbv3                 Enable or disable SMBv3 (default: Enabled)
        --username USERNAME          The account's username (default: )
        --password PASSWORD          The account's password (default: )
Usage: query_service_status.rb [options] target service
        --[no-]smbv1                 Enable or disable SMBv1 (default: Enabled)
        --[no-]smbv2                 Enable or disable SMBv2 (default: Enabled)
        --[no-]smbv3                 Enable or disable SMBv3 (default: Enabled)
        --username USERNAME          The account's username (default: )
        --password PASSWORD          The account's password (default: )
Usage: read_file_encryption.rb [options] target share file
        --[no-]smbv1                 Enable or disable SMBv1 (default: Disabled)
        --[no-]smbv2                 Enable or disable SMBv2 (default: Disabled)
        --[no-]smbv3                 Enable or disable SMBv3 (default: Enabled)
        --username USERNAME          The account's username (default: )
        --password PASSWORD          The account's password (default: )
Usage: read_file.rb [options] target share file
        --[no-]smbv1                 Enable or disable SMBv1 (default: Enabled)
        --[no-]smbv2                 Enable or disable SMBv2 (default: Enabled)
        --[no-]smbv3                 Enable or disable SMBv3 (default: Enabled)
        --username USERNAME          The account's username (default: )
        --password PASSWORD          The account's password (default: )
Usage: read_registry_key_value.rb [options] target registry_key value_name
        --[no-]smbv1                 Enable or disable SMBv1 (default: Enabled)
        --[no-]smbv2                 Enable or disable SMBv2 (default: Enabled)
        --[no-]smbv3                 Enable or disable SMBv3 (default: Enabled)
        --username USERNAME          The account's username (default: )
        --password PASSWORD          The account's password (default: )
Usage: registry_key_security_descriptor.rb [options] target reg_key
        --[no-]smbv1                 Enable or disable SMBv1 (default: Enabled)
        --[no-]smbv2                 Enable or disable SMBv2 (default: Enabled)
        --[no-]smbv3                 Enable or disable SMBv3 (default: Enabled)
    -u, --username [USERNAME]        The account's username (default: )
    -p, --password [PASSWORD]        The account's password (default: )
    -o, --operation OPERATION        The operation to perform on the registry key (default: read)
                                     (r, w, read, write)
    -i [SECURITY INFORMATION],       The security information value (default: 7)
        --info
    -s, --sd [SECURITY DESCRIPTOR]   The security descriptor to write as an hex string
Usage: rename_file.rb [options] target share file new_name
        --[no-]smbv1                 Enable or disable SMBv1 (default: Enabled)
        --[no-]smbv2                 Enable or disable SMBv2 (default: Enabled)
        --[no-]smbv3                 Enable or disable SMBv3 (default: Enabled)
        --username USERNAME          The account's username (default: )
        --password PASSWORD          The account's password (default: )
Usage: tree_connect.rb [options] target share
        --[no-]smbv1                 Enable or disable SMBv1 (default: Enabled)
        --[no-]smbv2                 Enable or disable SMBv2 (default: Enabled)
        --[no-]smbv3                 Enable or disable SMBv3 (default: Enabled)
        --username USERNAME          The account's username (default: )
        --password PASSWORD          The account's password (default: )
Usage: virtual_file_server.rb [options]
        --share-name SHARE_NAME      The share name (default: home)
        --[no-]anonymous             Allow anonymous access (default: true)
        --[no-]guests                Allow guest accounts (default: false)
        --[no-]smbv1                 Enable or disable SMBv1 (default: Enabled)
        --[no-]smbv2                 Enable or disable SMBv2 (default: Enabled)
        --[no-]smbv3                 Enable or disable SMBv3 (default: Enabled)
        --username USERNAME          The account's username (default: RubySMB)
        --password PASSWORD          The account's password (default: password)
        --virtual-content CONTENT    The virtual share contents
        --virtual-name NAME          The virtual share file name
        --virtual-type TYPE          The virtual share type
Usage: write_file.rb [options] target share file data
        --[no-]smbv1                 Enable or disable SMBv1 (default: Enabled)
        --[no-]smbv2                 Enable or disable SMBv2 (default: Enabled)
        --[no-]smbv3                 Enable or disable SMBv3 (default: Enabled)
        --username USERNAME          The account's username (default: )
        --password PASSWORD          The account's password (default: )

Also this updated version of examples/authenticate.rb was used to test rapid7/metasploit-framework#21390 without issue 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants