At Defcon 22 we presented several improvements in wifi rogue access point attacks. We entitled the talk "Manna from heaven" and released the MANA toolkit. I'll be doing two blog entries. The first will describe the improvements made at a wifi layer, and the second will cover the network credential interception stuff. If you just want the goodies, you can get them at the end of this entry for the price of scrolling down.
This work is about rogue access points, by which we mean a wireless access point that mimics real ones in an attempt to get users to connect to it. The initial work on this was done in 2004 by Dino dai Zovi and Shaun Macaulay. They realised that the way wifi devices probe for wireless networks that they've "remembered" happens without authentication, and that if a malicious access point merely responds to these directed probes, it can trick wireless clients into connecting to it. They called this a KARMA attack.
Additionally, Josh Wright and Brad Antoniewicz in 2008 worked out that if you man in the middle the EAP authentication on secured networks, you could crack that hash and gain access to the network yourself. They implemented this in freeradius-wpe (wireless pwnage edition).
However, KARMA attacks no longer work well, and we wanted to know why. Also, the WPE stuff seemed ripe for use in rogue access points rather than just for gaining access to the original network. This is what we implemented.
Changes in Probing
After a significant amount of time poring over radio captures of the ways in which various devices probed, and informed by our previous work on Snoopy, we realised two things. The first is that modern devices, particularly mobile ones, won't listen to directed probe responses for open, non-hidden networks if that AP didn't also/first respond to a broadcast probe. What this means is that our rogue access point needs to implement the same. However, the challenge is, what do we respond to the broadcast probe *with*?
To overcome that, we took the existing KARMA functionality built by Digininja, ported it to the latest version of hostapd and extended it to store a view of the "remembered networks" (aka the Preferred Network List (PNL)) for each device it sees. Then when hostapd-mana sees a broadcast probe from that device, it will respond with a directed probe response for each network hostapd-mana knows to be in that device's PNL. This is based on our finding, that wifi clients don't have a problem with a single BSSID (i.e. AP MAC address) to have several ESSIDs (aka SSID aka network name).
Practically, suppose there are two devices, one probing for a network foo, and the other probing for two networks bar and baz. When device1 sends a broadcast probe, hostapd-mana will respond with a directed probe response for foo to device1. Likewise when device2 sends a broadcast probe, hostapd-mana will respond with two directed probe responses to device 2, one for bar and one for baz. In addition, the "normal" KARMA functionality of responding to directed probes will also occur. Practically, we found this significantly improved the effectiveness of our rogue AP.
iOS and hidden networks
iOS presented an interesting challenge to us when it came to hidden networks. A hidden network is one configured not to broadcast its ESSID in either its beacons or broadcast probe response. Practically, the only way a client device can know if the hidden network it has remembered is nearby is by constantly sending out directed probes for the network. This is why hidden networks aren't a very good design, as their clients need to spew their names out all over the place. However, when observing iOS devices, while they could join a hidden network just fine, they seemed to not probe for it most of the time. This had us constructing faraday cages, checking other factors like BSSID and geolocation to no avail. Until we realised that iOS will not probe for any hidden networks in its PNL, unless there is at least one hidden network nearby. So, if you'd like to maximise your rogue'ing, make sure you have a hidden network nearby. It doesn't even need to be a real network; use a mifi, use airbase-ng or just create another hostapd network.
Limits in probing
Modern mobile devices probe for networks on their PNL *significantly* less than laptops or older devices do. In an ideal world, manufacturers would change the implementation to never probe for open network, and only wait for a response to a broadcast, effectively limiting these attacks to requiring pre-knowledge, common networks or being performed in the vicinity of the actual network. Actually, a patch was pushed to wpa_supplicant to limit the stupid probing behaviour Android does in low power mode a few months ago, this will make it into Android proper sometime soon. Also, iOS has significantly reduced how often it probes.
There are two ways to work around this. The first is manual; go for a common network. The rise of city-wide wifi projects makes this somewhat easy. Or if you're going for a corporate network, just do some recon and name one of your access points after that. But, we wanted to make things work better than that. The default behaviour of hostapd-mana is to build up a view of each devices PNL and only respond to broadcasts with networks specific to that device. However, we can remove that limitation and build a global PNL, and respond to each broadcast with every network every device has probed for. We call this loud mode, and it's configurable in the hostapd-mana config. This relies on the fact that many devices, particularly laptops and older mobile devices still probe for networks a lot. It also relies on the fact that many devices have networks in common (have they been in the same city, same airport, same conference, same company, same pocket etc.). This works *very* well in less crowded areas, and you'll get a much higher number of devices connecting.
However, in busy areas, or if your antenna is large enough, you'll quickly exceed the capacity for your average wifi device to respond fast enough to all of the devices, and as the number of response probes grows exponentially with each new device, even in quiet areas over time, this problem crops up (but didn't on stage at Defcon miraculously). So, it's *good enough* for now, but needs an in-kernel or in-firmware implementation with some network ageing to scale a bit better (one of the many opportunities for extending this work if you're up for some open source contribution).
Auto Crack 'n Add
freeradius-wpe is great, it provides a nice way to grab EAP hashes for clients that don't validate certificates presented via EAP's that implement SSL (PEAP, EAP-GTC, PEAL-TTLS). However, the patches are for freeradius v1 and, much like the KARMA patches for hostapd, have aged. But, hostapd contains a radius server, and so we could port the freeradius-wpe work to that, something we based off some initial but incomplete patches by Brad Antoniewicz. So hostapd-mana will also let you grab EAP hashes without needing another tool.
However, the KARMA attacks only work against open wifi networks. EAP networks are increasingly common (especially corporate ones) and we wanted to be able to have a go at getting devices probing for those to connect to our rogue AP. To do this, we modified hostapd-mana to always accept any EAP hash, but send it off for cracking. It simply writes these to a file, from which the simple python tool crackapd (included) will grab it and send it off to another process for cracking. Currently, we use asleap (also by Josh) and the rockyou password list, but these can all be easily modified. For example, to use CloudCracker and its incredibly optimised MS-CHAPv2 cracking setup.
The net result is pretty great for simple EAP hashes. The device will try and connect, and fail as we don't know enough to do the challenge response right. But after the hash is cracked, when it retries to connect (something a device will keep doing) it will succeed (and you'll have your first creds). For simple hashes, this is transparent to the user. Of course, very complex hashes will only work if you crack them in time. Worst case scenario, you leave with hashes.
So that's what we built into hostapd-mana. You get improved KARMA attacks, a modern hostapd version, an integrated hash stealer, and the possibility of rogue'ing some EAP networks. You can get the full toolkit at MANA toolkit on GitHub or our hostapd-mana at hostapd-mana on GitHub.
The next blog entry will cover what we did once we got a device to connect.
The Defcon talk:
The supporting slide deck with more information:
The final toolkit: MANA toolkit on GitHub You can also get this on Kali with "apt-get install mana-toolkit"
The modified hostapd (for hackers or people who want to build their own setup): hostapd-mana on GitHub
We're looking for an intern to join our newly formed 'Innovation Centre' arm of SensePost/SecureData. Have a read below for some more information, and drop us a mail if you're interested or would like some more info (email@example.com).
The purpose of the Innovation Centre is to offer an incubation hub through which new ideas, concepts and other technical and business innovations can be collected & captured and then rapidly described, prioritised researched, prototyped, tested, advocated and transitioned into the business.
About the Intern Position:
The ideal candidate should have a computer science or similar background, but equivalent work experience or self taught candidates will also be considered. The following specific requirements are required:
* Familiarity with at least one scripting language, preferably Python
* Fundamental understanding of networking
* Linux experience
* A positive attitude with a capable problem solving capabilities
The following points would be seen as a bonus:
* Strong computer science degree
* Industry experience (e.g. holiday internship).
* Web development capabilities
* Security knowledge / experience
* Experience with embedded or similar systems (e.g. Pi, Arduino, etc)
Whilst SensePost is an information security company, this specific internship does not directly relate to an info-sec position, but the projects worked on will relate to info-sec. The internship is for placement in the Innovation Centre. Day to day tasks are likely to include:
* Writing PoC scripts
* Providing support to InnoCentre analysts (e.g. writing Maltego plugins, debugging issues, testing new hardware/software).
* Liaising with partners/clients
It was originally released as a PoC at 44Con 2012, but this version is a complete re-write, is 99% Python, modular, and just feels better. The 'modularity' is possibly the most important improvement, for reasons which will become apparent shortly.
We've also made it much easier to run Snoopy by itself, rather than requiring a server to sync to as the previous version did. However, Snoopy is still a distributed framework and allows the deployment of numerous Snoopy devices over some large area, having them all sync their data back to one central server (or numerous hops through multiple devices and/or servers). We've been working on other protocols for data synchronisation too - such as XBee. The diagram below illustrates one possible setup:
|ZigBee||Digi Xbee||1km to 80kms|
The distances can be increased with appropriate antennas. More on that in a later blog post.
git clone https://github.com/sensepost/snoopy-ng.git
1. To save data from the wireless, sysinfo, and heartbeat plugins locally:
snoopy -v -m wifi:iface=wlanX,mon=True -m sysinfo -m heartbeat -d <drone name> -l <location name>
snoopy_auth --create <drone name> # Create account
snoopy -v -m server # Start server plugin
snoopy -v -m wifi:iface=mon0 -s http://<server hostname>:9001/ -d <drone name> -l <location name> -k
There sure is a lot of stunt hacking in the media these days, with people taking existing hacks and duct-taping them to a cheap drone for media attention. We were concerned to see stories on snoopy airborne take on some of this as the message worked its way though the media. What's the benefit of having Snoopy airborne, then? We can think of a few reasons:
This blog post is about the process we went through trying to better interpret the masses of scan results that automated vulnerability scanners and centralised logging systems produce. A good example of the value in getting actionable items out of this data is the recent Target compromise. Their scanning solutions detected the threat that lead to their compromise, but no humans intervened. It's suspected that too many security alerts were being generated on a regular basis to act upon.
The goal of our experiment was to steer away from the usual data interrogation questions of "What are the top N vulnerabilities my scanner has flagged with a high threat?" towards questions like "For how many of my vulnerabilities do public exploits exist?". Near the end of this exercise we stumbled across this BSides talk "Stop Fixing All The Things". Theses researchers took a similar view-point: "As security practitioners, we care about which vulnerabilities matter". Their blog post and video are definitely worth having a look at.
At SensePost we have a Managed Vulnerability Scanning service (MVS). It incorporates numerous scanning agents (e.g. Nessus, Nmap, Netsparker and a few others), and exposes an API to interact with the results. This was our starting point to explore threat related data. We could then couple this data with remote data sources (e.g. CVE data, exploit-db.com data).
We chose to use Maltego to explore the data as it's an incredibly powerful data exploration and visualisation tool, and writing transforms is straight forward. If you'd like to know more about Maltego here are some useful references:
It's also worth noting that for the demonstrations that follow we've obscured our clients' names by applying a salted 'human readable hash' to their names. A side effect is that you'll notice some rather humorous entries in the images and videos that follow.
Jumping into the interesting results, these are some of the tasks that we can perform:
In summary, building 'clever tools' that allow you to combine human insight can be powerful. An experiences analyst with the ability to ask the right questions, and building tools that allows answers to be easily extracted, yields actionable tasks in less time. We're going to start using this approach internally to find new ways to explore the vulnerability data sets of our scanning clients and see how it goes.
In the future, we're working on incorporating other data sources (e.g. LogRhythm, Skybox). We're also upgrading our MVS API - you'll notice a lot of the Maltego queries are cumbersome and slow due to its current linear exploration approach.
The source code for the API, the somewhat PoC Maltego transforms, and the MVS (BroadView) API can be downloaded from our GitHub page, and the MVS API from here. You'll need a paid subscription to incorporate the exploit-db.com data, but it's an initiative definitely worth supporting with a very fair pricing model. They do put significant effort in correlating CVEs. See this page for more information.
Do get in touch with us (or comment below) if you'd like to know more about the technical details, chat about the API (or expand on it), if this is a solution you'd like to deploy, or if you'd just like to say "Hi".
Recently a security researcher reported a bug in Facebook that could potentially allow Remote Code Execution (RCE). His writeup of the incident is available here if you are interested. The thing that caught my attention about his writeup was not the fact that he had pwned Facebook or earned $33,500 doing it, but the fact that he used OpenID to accomplish this. After having a quick look at the output from the PoC and rereading the vulnerability description I had a pretty good idea of how the vulnerability was triggered and decided to see if any other platforms were vulnerable.
The basic premise behind the vulnerability is that when a user authenticates with a site using OpenID, that site does a 'discovery' of the user's identity. To accomplish this the server contacts the identity server specified by the user, downloads information regarding the identity endpoint and proceeds with authentication. There are two ways that a site may do this discovery process, either through HTML or a YADIS discovery. Now this is where it gets interesting, HTML look-up is simply a HTML document with some meta information contained in the head tags:
Whereas the Yadis discovery relies on a XRDS document:
Now if you have been paying attention the potential for exploitation should be jumping out at you. XRDS is simply XML and as you may know, when XML is used there is a good chance that an application may be vulnerable to exploitation via XML External Entity (XXE) processing. XXE is explained by OWASP and I'm not going to delve into it here, but the basic premise behind it is that you can specify entities in the XML DTD that when processed by an XML parser get interpreted and 'executed'.
From the description given by Reginaldo the vulnerability would be triggered by having the victim (Facebook) perform the YADIS discovery to a host we control. Our host would serve a tainted XRDS and our XXE would be triggered when the document was parsed by our victim. I whipped together a little PoC XRDS document that would cause the target host to request a second file (198.x.x.143:7806/success.txt) from a server under my control. I ensured that the tainted XRDS was well formed XML and would not cause the parser to fail (a quick check can be done by using http://www.xmlvalidation.com/index.php)
In our example the fist <Service> element would parse correctly as a valid OpenID discovery, while the second <Service> element contains our XXE in the form of <URI>&a;</URI>. To test this we set spun up a standard LAMP instance on DigitalOcean and followed the official installation instructions for a popular, OpenSource, Social platform that allowed for OpenID authentication. And then we tried out our PoC.
It worked! The initial YADIS discovery (orange) was done by our victim (107.x.x.117) and we served up our tainted XRDS document. This resulted in our victim requesting the success.txt file (red). So now we know we have some XXE going on. Next we needed to turn this into something a little more useful and emulate Reginaldo's Facebook success. A small modification was made to our XXE payload by changing the Entity description for our 'a' entity as follows: <!ENTITY a SYSTEM 'php://filter/read=convert.base64-encode/resource=/etc/passwd'>. This will cause the PHP filter function to be applied to our input stream (the file read) before the text was rendered. This served two purposes, firstly to ensure the file we were reading to introduce any XML parsing errors and secondly to make the output a little more user friendly.
The first run with this modified payload didn't yield the expected results and simply resulted in the OpenID discovery being completed and my browser trying to download the identity file. A quick look at the URL, I realised that OpenID expected the identity server to automatically instruct the user's browser to return to the site which initiated the OpenID discovery. As I'd just created a simple python web server with no intelligence, this wasn't happening. Fortunately this behaviour could be emulated by hitting 'back' in the browser and then initiating the OpenID discovery again. Instead of attempting a new discovery, the victim host would use the cached identity response (with our tainted XRDS) and the result was returned in the URL.
Finally all we needed to do was base64 decode the result from the URL and we would have the contents of /etc/passwd.
This left us with the ability to read *any* file on the filesystem, granted we knew the path and that the web server user had permissions to access that file. In the case of this particular platform, an interesting file to read would be config.php which yields the admin username+password as well as the mysql database credentials. The final trick was to try and turn this into RCE as was hinted in the Facebook disclosure. As the platform was written in PHP we could use the expect:// handler to execute code. <!ENTITY a SYSTEM 'expect://id'>, which should execute the system command 'id'. One dependency here is that the expect module is installed and loaded (http://de2.php.net/manual/en/expect.installation.php). Not too sure how often this is the case but other attempts at RCE haven't been too successful. Armed with our new XRDS document we reenact our steps from above and we end up with some code execution.
And Boom goes the dynamite.
All in all a really fun vulnerability to play with and a good reminder that data validation errors don't just occur in the obvious places. All data should be treated as untrusted and tainted, no matter where it originates from. To protect against this form of attack in PHP the following should be set when using the default XML parser:
A good document with PHP security tips can be found here: http://phpsecurity.readthedocs.org/en/latest/Injection-Attacks.html