Summer Projects

Last summer a friend and I worked on some electronics projects so I thought I’d write a post about it.

MouseJack

Marc Newlin and the team over at Bastille released a vulnerability called MouseJack in early 2016. This vulnerability allows an attacker to send keystrokes directly to a wireless mouse or keyboard, similar to a Hak5 Rubber Ducky, but from up to hundreds of meters away.

I found out about the vulnerability around June last year and immediately set about to replicate the research. Shortly after, we published a tool called JackIt.

JackIt is a relatively simple Python script that leverages a CrazyRadio PA USB adapter to inject keystrokes into many Microsoft and Logitech keyboards and mice using the NRF24L01+ protocol. It uses the same HID attack description syntax as the Hak5 Rubber Ducky, called Duckyscript, and you can find example payloads in the project wiki.

Microcontroller MouseJack

After my friend and I wrote the JackIt tool, we realized that carrying around a laptop with a specialized USB radio was a bit sketchy. It would be much more effective to carry around a simple physical key fob that would opportunistically exploit the vulnerability.

In August, after a bit of Arduino tinkering and learning to solder, we found a platform that worked nicely and created a portable version called uC_Mousejack. Depending on the battery size and radio, it can run for up to a day per charge and still manages 25 meters of range.

The microcontroller version uses PlatformIO as the toolchain (which is brilliant), and includes a Python script to compile Duckyscripts into C arrays for easy firmware recompilation.

uDuck

During the uC_Mousejack project, I discovered that working with simple electronics is a breeze. I’m really surprised that there aren’t more custom hardware-based attacks in common use by penetration testers, especially considering that binary exploitation is a lot more challenging today.

My friend and I once again teamed up for the uDuck project and decided to make a simple PCB. The obvious choice was the USB HID attack popularized by the Hak5 Rubber Ducky. It’s a great attack, but unfortunately I can’t afford to drop a handful of $45 USB devices in a parking lot and hope for the best.

It’s worth mentioning that around the same time, Sensepost released the USaBUSe project. I really like the concept of a more feature rich version, but it doesn’t fit our use case well. We wanted ultra-cheap devices that we can label as “Confidential” and leave in parking lots or around employee smoke-break areas. uDuck is the philosophically opposite approach and embraces minimalism instead.

You can find the Github repo for uDuck here.

The uDuck can be reprogrammed over the same USB port that delivers the attack. To accomplish this, it leverages the Micronucleus bootloader. Essentially, it waits in the bootloader for 2 seconds after being connected, then changes into a keyboard device. The included Python script compiles a Duckyscript payload into a byte array, patches the firmware with the byte array (containing HID codes and delays) and waits for the USB device to be connected. Once connected, the new firmware is uploaded.

No more fishing a microSD card out of a tiny slot and finding a card reader :).

So why is uDuck interesting? The devices can be made for less than $2 in relatively small quantities. It changes the economics of carrying out this attack.

Conclusion

I figured that MouseJack would be obsolete by now — it’s been over a year. Unfortunately it seems many of the vulnerable devices can still be bought in stores. It’s interesting that we find vulnerabilities in information security every day, but the old ones never seem to go away.

Anyway, if you’re in the infosec community don’t be afraid to jump into electronics. In the past, the toolchains for microcontrollers were arcane, the specialized equipment required was expensive and the learning curve was steep. The Arduino community and the momentum behind IoT made all of that a thing of the past.

I highly recommend buying some Feather boards from Adafruit and running through some of their tutorials. If you don’t want to learn C/C++, you can try out other boards like Puck.js (uses Javascript) or the Pycom boards (which use Python).

Fortinet FSSO Exploits

In my last post, I fuzzed FSSO on port 8000 with Peach fuzzer to replicate the exploitable overflow discovered by Enrique Nissim of Core Security.  It turns out that the DC Agent service on UDP port 8002 also has an exploitable overflow that seems to have been patched after build 143.  In this post we’ll present an exploit for each of these issues.

DCAgent Protocol

The DCAgent protocol is a collector service that aggregates login events from other domain controllers.  There is no authentication and it’s transported over UDP.  We’ll ignore the obvious security flaw here — anyone can send a UDP packet and will be authenticated in FSSO as any user they choose.  Instead we’ll fuzz the service and see if we can find an exploitable crash.

To get an idea of the various fields in this protocol, you can download the Peach Pit from github.  It’s basically a header and trailer with a login record encapsulated within.  The login record is comprised of the user’s IP address and their “DOMAIN\user” AD username.

Fuzzing this protocol on build 143 results in some fairly obvious stack overwrites:

r
eax=00000000 ebx=75e89894 ecx=00000000 edx=11a9f744 esi=75ea47ad edi=75e8dbeb
eip=41fffe41 esp=11a9f848 ebp=1c6fcf60 iopl=0 nv up ei pl nz na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00010206
41fffe41 ?? ???

kb
ChildEBP RetAddr Args to Child
WARNING: Frame IP not in any known module. Following frames may be wrong.
11a9f844 41fffe41 41fffe41 41fffe41 41fffe41 0x41fffe41
11a9f848 41fffe41 41fffe41 41fffe41 41fffe41 0x41fffe41
11a9f84c 41fffe41 41fffe41 41fffe41 41fffe41 0x41fffe41
11a9f850 41fffe41 41fffe41 41fffe41 41fffe41 0x41fffe41
11a9f854 41fffe41 41fffe41 41fffe41 41fffe41 0x41fffe41
11a9f858 41fffe41 41fffe41 41fffe41 41fffe41 0x41fffe41

This appears to be triggered by overflowing the IP address string field in the login record, resulting in direct return address overwrite. Why they wouldn’t use /GS and SafeSEH (not to mention ASLR) on a service providing authentication is beyond me.

The first step towards developing a stack buffer overflow exploit is figuring out the buffer offset to the EIP overwrite.  I used Metasploit’s pattern_create/pattern_offset utilities for this purpose.  This provided reliable control over EIP.

Unfortunately, there is still DEP to contend with.  Normally, when DEP is combined with ASLR, it forms a fairly robust defense against stack buffer overflow exploitation.  DEP is opt-out on Windows 2008 and Windows 2012 Server, so it is enabled by default.  ASLR, on the other hand, is opt-in.  It requires that the libraries and binary are relocatable.  In the FSSO service, both collectoragent.exe and ssleay32.dll are not relocatable and no ASLR is applied to these modules.

Without ASLR, we can reuse existing pieces of the code contained in non-ASLR modules so that we are not required to directly execute code from the stack.  This can be accomplished by using a ROP Chain.  There are a few other issues however.

First, we have very limited buffer space since the exploit must fit in a small buffer within a single UDP packet.  This means we have to keep the ROP chain quite small.

Second, at the point of EIP overwrite, our buffer has been modifed — all lower case characters have been converted to upper case.  Normally this would make exploitation very difficult since it’s nearly impossible to build a ROP chain without any lower case characters (it’s tricky enough to build a ROP chain in the first place).  Using the debugger, I discovered that the original buffer is still on the stack.  We’ll have to adjust ESP through a phase I ROP chain in order to pivot to the unmodified buffer.

Third, we can’t use nulls since the exploitable condition is a result of a libc string handling function, probably an sprintf or strcpy (I haven’t actually checked).  To make things even more fun, we also can’t use the forward slash (byte value 0x2f) because this is the delimiter between the IP Address, domain and user name.  These values, 0x00 and 0x2f, are so-called bad characters.

The ROP Chain

Given the constraints above, I decided to keep things simple (or hacky, depending on your perspective).  I’ll use a short chain to call WinExec.  WinExec will launch a short snippet of Powershell code, which will call back to our web server and pull down a Powershell payload.

The WinExec function isn’t present in any of the non-ASLR module’s import address tables (IATs), so we’ll have to use an offset from a Kernel32 export present in the IAT.  I’m using GetTimeZoneInformation for this purpose, which is probably not a great choice.  The caveat with using a delta is that we must use hard-coded values.  The delta between the GetTZInfo function and WinExec is Windows version specific and it often changes between service pack or even between security updates.

Strictly speaking, we also can’t use a hard-coded delta since this contains nulls, instead we must use the binary 1’s complement in the actual ROP chain and hope that it doesn’t contain any bad characters.  I’ve included most of the magic values for versions of the kernel32.dll used by Windows Server 2008 R2 and 2012 R2 in the exploit.  If I missed a version you’d like to test with, use this short stand-alone Ruby script to generate magic values for kernel32.dll.  I admit it’s a bit of a kludge.

The PoC exploit, complete with ROP chain, is available on github here.  This issue seems to be patched after build 143.

FSSO Exploit

Now that we have a working ROP chain we can plug that into the FSSO exploit and it should just work.  Again we’ll need to use MSF pattern_create/pattern_offset to find the EIP overwrite.  For our exploit, this is at 96 bytes into the serial number field of the FSSO packet.  We can simply start the ROP chain right at offset 96.

You can find the PoC exploit for FSSO on TCP port 8000 here.  This issue is patched in build 237, but the ROP chain currently only works up to build 143 due to changes in the OpenSSL libraries (feel free to tweak if you need to pop build 161).

Next Steps

While the DCAgent overflow requires such a convoluted ROP chain due to bad characters and space limitations, the FSSO overflow does not have these limitations.  It is triggered via a bad memcpy into a stack buffer, so nulls are allowed.  If I have time I’ll write a new ROP chain for that exploit in order to make it more portable (or at least not Windows version specific).  Until then, happy exploitation!

How I Hacked Your Router

Some time ago a friend in infosec asked me to do a strange thing.  He asked me to hack him.  We will call him Bill, for the sake of anonymity.  Other names and places have been changed to protect the innocent.  Vendor names have been kept to incriminate the guilty.

Hacking a large corporation is easy(ish).  They have information assets that may span the globe, and despite investments in various protection technologies, it’s just hard to keep track of all that stuff.  It requires Zen-like discipline to rigorously follow the cycle of scan-patch-repeat day after day, on all assets in an organization, without fail.

Hacking a person can be tough.  It’s true that blackhats have the advantage in terms of the asymmetric nature of information security.  Sometimes it only takes one bug.  But the attack surface area of a single individual is quite small compared to a corporation.  In addition, most people trust large vendors with their information and the cloud vendors typically do a decent job of protecting people.

I started with basic recon.  I like to use Maltego, along with sites like checkusernames.com, knowem.com, pipl search, and other tools to enumerate online presence.  There’s also the classics like Google+, Facebook and Linkedin.  It helps to have a fake profile on Facebook for this kind of work.  A good bait profile should be tuned to your target.  It will help when extracting additional information via social engineering.

In terms of online presence, password reset questions are good low hanging fruit.  I’ve seen webmail accounts asking for information that you can pull right out of the target’s Facebook profile.  I’m sure most people don’t even make the connection; they may have written their reset questions 5 years ago.  None of this stuff was going to work in this case though.  My target was an infosec nerd, and he was expecting me.

Time to take the fight to him.  First, I checked to see if he is hosting anything on his home Internet connection.  He may have been doing this and not even know it.  Many apps and devices use UPnP to punch holes in consumer-grade firewalls without much fanfare.  Sometimes all it takes is a NAS or media server to open up a backdoor.  To find his home IP address, I used a Skype resolver, such as resolvme.org.  It worked brilliantly, so I scanned his IP address (and a few neighboring IPs) to see if I could find any services.  No dice though… I’m sure he figured I would do this.

Next up, 802.11.  Wireless networks are a great attack vector.  I have two Radeon 6990’s in an i7 rig that chews through WPA hashes.  I use a Markov predictive wordlist generator to feed guesses to oclHashcat.  It can achieve an 80% average crack rate over an 8 hour time frame.

So I set about to Bill’s address with various Alfa wifi cards in tow.  While in this case I actually know Bill’s address, I may have been able to get this information via recon or social engineering.  It’s not exactly a secret.  After successfully capturing a WPA handshake, I ran the cracker for a week.  Still no dice.  This would probably work on most people, but Bill is an infosec guy.  His WPA key is probably >32 characters long.

At this point you’re probably wondering why I didn’t just spear-phish him with a Java 0-day and go have my victory beer.  The answer is simple — I know my target.  He has mastered the mantra of scan-patch-repeat.  Java isn’t even installed.  And if I did have a browser 0-day in my back pocket, I would have used it to win the pwn2own last week.

After my visit to Bill’s place, I did come away with one useful piece of information.  The wireless MAC address (BSSID) of his router: 06:A1:51:E3:15:E3.  Since I have the OUI (the first 3 bytes of the MAC), I know that it’s a Netgear router.  I also know that Netgear routers have some issues, but Bill was running the latest firmware.  That doesn’t mean that all the vulnerabilities were patched in the latest firmware though.  The only way to be sure was to buy a Netgear router and test it myself.

Determining the exact model is probably not possible (not remotely anyway).  Consumer devices may have a lot of variation between different models as the reference platforms come from SoC vendors such as Broadcom and Atheros.  I know that Bill is a bit frugal, so I went with the WNDR3400v3 — the entry level unit.

After reading about some of the vulnerabilities this device has had in the past, I created two Metasploit modules.  In the first module, I would use a CSRF bug to POST to the UPnP interface and punch a hole to access the telnet service of the router itself.  This issue likely exists in numerous other devices and is worth emphasizing:

If you can spoof UPnP requests via CSRF, you can turn the entire network inside-out.

That’s an important point.  I was opening up a single port.  You can use Ajax requests from the victim’s browser to configure NAT entries for every IP in a subnet, effectively disabling the firewall.  There are hard limits to the number of UPnP NAT entries of course, but most devices will allow enough entries to map a few key ports for a hundred hosts or so.

In order to trick Bill into connecting to my exploit, I sent him an email with an embedded link.  Cobalt Strike has a tool to copy an existing email (headers and all), which makes this basically turn-key.  All you need to do is modify the links.  So what email does everyone always click?  What would work even against an infosec guy?  Linkedin invites.

EDIT: Some readers have wondered why Bill would fall for this. Even a cursory check of the sender domain or link would have been a dead giveaway. The key to a successful SE campaign is a good pretext. For a background on pretexting, read this article. In this case the invite appeared to be from someone he had a meeting with that afternoon. Well, more of an informal job interview really. I suppose it was confirmation bias — he wanted to believe he got the job.

Now before I sent the email, I needed a follow up payload.  By default, the telnet port is enabled on Netgear routers, but the service is unresponsive.  You have to connect to the port and send a special unlock key.  Public exploits exist for this flaw, but I wrote another MSF module because I love my Ruby (and Metasploit).

Bill clicked the link.  As soon as I saw the callback, I triggered the second module and logged into the router via telnet.  Once I obtained root access to the router, I immediately changed the DNS settings to point to a DNS server that I control.

Controlling DNS is a powerful thing; it effectively provides you with on-demand man-in-the-middle.  There are plenty of MITM attack vectors, but I like Evilgrade for stealth.  Evilgrade has been out for years, and still works great (some modifications necessary).  It took about a week before Bill decided to upgrade notepad++ to the new version.  When he did, he was fed a backdoored version that gave me a Meterpreter shell on his computer.  I immediately emailed him a few screen shots and a keystroke log, and he unplugged his computer a few minutes later.

For my efforts, I was rewarded with a six-pack of Ruby ale.  I do love my Ruby.