Category Archives: Uncategorized

Web application penetration testing with Source Maps

What is a Source Map?

Modern web applications can include large quantities of JavaScript (JS) and Cascading Style Sheets (CSS) to enable a great user experience. We all appreciate a slick web app, and these technologies are significant components for achieving that.

When web applications have large amounts of JS and CSS, the web developer will often consider how to deal with two side-effects of having all this code:

  • the speed the application loads and the level of expectation from the user
  • the cost and load of transferring all that extra code across the Internet

To help combat this, developers will often “minify” their code. Minification is the process of removing as much as possible from the code, including long variable names and superfluous white space. This practice reduces transmission across the Internet, improves loading times, and lowers costs.

There are a few ways to achieve minification. One such method is to write using another language, such as TypeScript or CoffeeScript, which gets used to machine-generate the code sent to the user’s browser.
Source Maps are a converter that takes minified code and returns it to the complete state of the original code. Using a Source Map means that the code becomes human-readable again.

Why do Source Maps matter to Penetration Testers?

When performing a cyber security assessment of a modern web application, it can often be crucial to fully understand how the code behaves within the user’s web browser. It can be challenging to understand minified code, especially when identifying security flaws.

It is not unreasonable to suggest that the developers could send a copy of the original code to the penetration tester, but this would be stand-alone code not processed alongside the rest of the web application. The original code is rebuilt and can be read and understood using Source Maps. Crucially, this is also then possible within the web browser. Having the original code within the browser allows the penetration tester to understand the inner mechanics of the code during execution.

It is possible to complete the work without the Source Maps as the executed code is still present. However, it will likely just take more time to complete the task. With all of this in mind, we recommend that Source Maps are shared with penetration testers to ensure they have as comprehensive visibility of the web application as possible. There is also the question about allowing Source Maps to be available publicly. The context of the web application will dictate whether providing Source Maps openly to the public is acceptable. However, most developers are cautious on this matter and only provide them if there is a justifiable reason.

BeagleBone, nu-map and preparing for USB fuzzing

USB fuzzing is pretty low-level and can require a fair bit of brain-bending to get your head around what is needed and what the results are. Here we discuss how USB fuzzing can be done. We show the setup and installation of the BeagleBone Black hardware device and the open-source software nu-map, a decendant of NCC Group’s umap.

TL;DR; if you have a working BeagleBoard Black and you just want the instructions, go to step five “Build a patched Kernel” below. The rest is stuff you might already know.

There are lots of reasons why doing hardware fuzzing of USB is a bad idea, but occasionally, it is the only way of achieving the objectives. As a result, there are lots of discussions about alternatives, and very few articles written about how to actually do it in hardware that are accessible by mere mortals. This post aims to show exactly what is required with the hardware and software that is available today.

To recap why you shouldn’t do this, there are a few big reasons:

  • Difficult to see what data is actually sent and received to and from the target. This makes it hard to actually analyse the results of the fuzzing
  • It is slow
  • Difficult to integrate the hardware with fuzz test-case generators

There is a bigger discussion about the relative merits of software-based USB fuzzing by F-Secure and it talks about the potential alternatives. If you find a circumstance where nothing else will do (or you just want to play), the below should help you get started.

The steps needed:

  • Buy the hardware
  • Flash the BeagleBone to the latest version of Debian
  • Update it
  • Mount an SD card
  • Build a patched Kernel
  • Build the GadgetFS kernel moduleQQQ
  • Install nu-map
  • Start Gadget-FS
  • Start nu-map
  • Start the Kitty fuzzer

Should be a breeze…

Purchasing

First step is hard. You have to press the “Pay” button on a web site and wait. Oh how the waiting hurts. You can buy these from a variety of places depending on where you are in the world.

Flashing the firmware

This should be straight forward, but, I found that the mechanism for flashing the firmware didn’t work as directed, I am sure it does if you have more patience that I do, but… Instead if you edit a boot file you can comment out a function that always tried to flash the on-board eMMC contents with whatever is on the SD card. Potentially dangerous if you leave it in place, but means you don’t need ti guess if it is flashing correctly or not. I suggest you undo this once flashing is complete (some builds do this automatically).

Change the file /boot/uEnv.txt

So that the following line is uncommented:

cmdline=init=/opt/scripts/tools/eMMC/init-eMMC-flasher-v3.sh

Download the latest Debian image from the BeagleBoard people and write that to your SD card. Pop that shiny SD card into your BeagleBone Black and turn it on. It should flash a bit, then all four LEDs will stay on together for a few seconds and then it will start the flashing process. During this you might not get any LED lights or indication that much is going on, or you might get the LEDs flashing in sequence. Eventually all the LEDs will turn off and you know you are good to take the SD card out and reboot.

Software update

Step three is the usual Debian update commands plus one:

sudo apt update && sudo apt upgrade -y
cd /opt/scripts
git pull

Build a patched Kernel

Build this on your local machine, not on the BeagleBone. It can’t pull the Git Repo for the Kernel as it is too large. This is a very long stage, so get ready to run the set of commands and go and get a cup of tea or something…

The nu-map project documentation specifically references Kernel 4.7. At first I didn’t question this as I didn’t want to stray from instructions but that led to a nightmare of Kernel building and dependency resolution, specifically when it comes to building the GedgetFS Kernel module later on.

The trick here is to search for all Apt-installable Linux headers packages (in the same major version as otherwise it will take weeks to complete the search) and work out which one you can build from Robert Nelson’s repo. In my example, I found that Kernel v4.19 had a bone architecture available and the repo had no missing dependencies (check by trying to build each option until you find one that works).

On the BeagleBone search like so:

sudo apt search linux-headers-4
...
SNIP
...
linux-headers-4.19.182-bone63/unknown 1buster armhf

Then on your local machine build the Kernel:

git clone https://github.com/RobertCNelson/bb-kernel.git
cd bb-kernel
git checkout am33x-v4.19 # change this to your Kernel choice from above
sudo apt install -y fakeroot gettext bison flex libmpc-dev
./build_deb.sh
scp deploy/linux-image-*.deb debian@[IP]:.

You might notice that I chose to use the “build_deb.sh” script instead of the “build_kernel.sh” script. This is because I am being lazy and want apt to install it for me when it is done. Also, I *believe* this is an easy way to stop auto updates from upgrading the Kernel in the future if you do an apt upgrade.

Once it has finished creating the Kernel and you have transferred the Deb packages to the BeagleBone, install it and the relevant headers with:

sudo apt install -y ./linux-image-*.deb
sudo apt install -y linux-headers-[VERSION]
sudo reboot

Just in case it isn’t clear, don’t install the Linux headers package made with the custom kernel build script as it gets compiled for the local workstation’s architecture, not for the BeagleBone’s architecture and is therefore useless.

Install nu-map

Let’s install nu-map itself.

git clone https://github.com/usb-tools/nu-map
cd nu-map
sudo python3 setup.py install

Build the GadgetFS kernel module

There are some typos in the original documentation. They can take a while to spot. There is also a patch needed for the inode.c file as later Kernels don’t appear to have CURRENT_TIME support. The fix is to swap CURRENT_TIME for current_time(inode). The following should actually work.

cd ~/nu-map/gadget
cp inode.c.4.6_and_up inode.c
nano inode.c # edit the reference to "CURRENT_TIME" to be "current_time(inode)"
sudo make modules
sudo cp gadgetfs.ko /root

Start Gadget-FS

This should just be a case of running the script provided in the nu-map repo:

sudo ~/nu-map/gadget/start_gadgetfs.sh

What comes next?

Well this is where the USB fuzzing really gets going and is a topic in its own right. Here you will likely need nu-map and KittyFuzzer. But that depends largely on what you are trying to achieve. Good luck!

Athom Homey Security | Static and well-known keys (CVE-2020-28952)


TL;DR: All Athom Homey and Athom Homey Pro devices, before version 5.0.0, have a static and well-known ZigBee communications encryption key. Official CVE can be found here: CVE-2020-28952.


Previous work

I’ve been doing security research against the Athom Homey and Athom Homey Pro as time permits for a while. I have previously reported another issue with the Homey (CVE-2020-9462) that was similar in nature. Both issues are about communications crypto. The previous issue was only vulnerable for a specific period of time because it was only vulnerable during device setup. This issue is a bit bigger. It affects every Homey device out there and the user couldn’t do anything about it. Despite this, I’m still a big fan of Athom’s Homey devices. They seem to be built for geeks by geeks and that just makes me happy.

Looking at ZigBee traffic

As part of another project I have spent a fair amount of time looking at ZigBee traffic. I thought I would have a look at the ZigBee meshing capabilities of the Athom Homey. This post doesn’t go into meshing at all. ZigBee meshing is a very complex topic in its own right and deserves a whole series of posts.

For my work, I have a “ZigBee Sniffer Array”. This array is essentially 16 x CC25xx ZigBee receivers plugged into a couple of USB hubs. I use the KillerBee software suite which allows me to dump all ZigBee traffic in RF range.

Half the ZigBee Sniffer Array and the KillerBee toolset

Once the capture is complete, looking at the pcap in Wireshark you can see all the usual ZigBee traffic types. In ZigBee there is a publicly-known cryptographic key exchange flaw. Devices in the public ZigBee ecosystem all start with knowledge of a globally-known default Trust Center Link (TCL) key. This key is the hexadecimal equivalent of “ZigBeeAlliance09” (which is 5A:69:67:42:65:65:41:6C:6C:69:61:6E:63:65:30:39). This default TCL key isn’t a great design decision by the ZigBee Alliance but it is what it is. This is not the part that Athom got wrong.

Why is a global default Trust Centre Link Key bad?

The implications of having a default TCL key are that an attacker can sniff the communications of devices being “paired” with a ZigBee network. When ZigBee devices are being paired, the hub device shares the network key with the new device for future communications. If an attacker doesn’t capture the key exchange, they are “outside” the ZigBee network. Being outside the network eans they cannot examine the content of any messages or impersonate any devices.

The default TCL key is installed in my Wireshark as a matter of course these days. This means I can immediately read those network key exchange messages. Inserting a key is fairly trivial. It can be added in the protocol dissector configuration in the key management function.

Installing the default TCL key

Spotting the vulnerability in Athom Homey

I regularly find myself looking for network key exchange packets. This is so I can extract the network key to be able to do further analysis against the encrypted packets.

Key exchange without the global default TCL key installed into Wireshark

I quickly found the packet I was looking for and added the Network key to Wireshark in the same manner as before.

Key exchange packet with the global default TCL key installed into Wireshark

In the image above you can see that the network key being exchanged is:

01:03:05:07:09:0b:0d:0f:00:02:04:06:08:0a:0c:0d

It took longer than I really want to admit for me to realise that this network key wasn’t machine generated. Eventually it dawned on me that the pattern in the key was a little to regular to be a coincidence. I immediately went to check with another Homey in case the same key was in use there… and it was.

Worse still, the default Network key I observed I later found out is a ZigBee chipset defined default key. So this key is likely used in all manner of ZigBee devices around the world. A quick search online for that key finds dozens of hits.

Responsible disclosure

As always, I got in contact with the vendor on the 19th November 2020:

Hi Athom Support Team,

Just getting in contact because my slow-time research has brought another issue to light that I am hoping you will be interested in discussing.

As per my previous contact, I will be applying for a CVE for this, I am not looking for any form of payment / reward, instead I am just hoping to make the world a better place. This email marks the start of a 90 day period before this vulnerability is published unless our discussions indicate that an extension is wise.

I have been looking at ZigBee communications and packet sniffing and know the protocol reasonably well. I know that the weak point for all encrypted ZigBee communications is the pairing / enrolment process. This is because the vast majority of ZigBee devices are within the public ecosystem and the key exchange process must use a Global Master Key – this is publicly known and is the hexadecimal equivalent of “ZigBeeAlliance09”. What is supposed to happen is that the hub generates a unique Standard Network Key which is then exchanged with all enrolled devices so that all communications with that device and between those devices is encrypted in a secure fashion from that point onwards. Unfortunately I found that your devices use another widely known key that is designed for testing purposes:

“01030507090b0d0f00020406080a0c0d”
This is the decimal equivalent of 1 3 5 7 9 11 13 15 0 2 4 6 8 10 12 13 which is clearly human generated.

To confirm that this is not just a coincidence I repeated the packet
capturing with a second Athom Homey and a different model ZigBee device and found the keys were consistent.

What this implies is that all Athom Homeys use the same standard Network key for all ZigBee traffic. This means that if I can find one of these devices deployed, I will be able to capture the decrypted traffic, inject my own traffic and modify existing traffic within the targeted network. For this to work, I do not need to be present for the enrolment process to capture the network key during the known-insecure key exchange process.

To be clear, what I am not saying is that Athom should attempt to fix the Key Exchange problem – this is with the ZigBee spec. However, I am saying that it is inappropriate to use a static Standard Network Key, let alone one that is publicly known.

Please do let me know that you have received this email. I am happy to help / give advise and would be keen to hear how you are planning on correcting the issue. Once again, this is not any form of extortion – I do not expect payment of any kind.

I won’t name the individual, but my friendly Athom support desk contact was on the case within an hour. Within 10 days they were in contact again saying that they were releasing a fix alongside their major version release that was scheduled for the not-too-distant future. That major version was released on the 11th February 2021.

Confirming the fix

I came to perform testing of their fix when version 5.0.1 had been released. I can only assume it was in place for the earlier sub-version, but, it is possible that the behaviour may have changed. Rather frustratingly, upon performing the upgrade from v4.2.0 to v5.0.1 my ZigBee network simply stopped working. Knowing what I was looking for this wasn’t that big a surprise. I got out my ZigBee Sniffer Array and had added a device back into my ZigBee network. Low-and-behold, a completely new network key was found. This is why my previously-connected devices stopped working: they no longer had a valid network key.

From a user-perspective the lack of warning, or better key-management is a bit frustrating. I imagine there are plenty of people who upgraded and then found that they had a non-functional ZigBee network. However, this is arguably better than what the guys at Athom had originally planned. They wanted the encryption key update to be an “opt-in” feature. This would mean the user would have to actively go into the settings and reset the network to get a new key. This option clearly leaves all existing user’s without protection.

The good news is that it is possible for an average user to confirm that they don’t have the global default TCL key in their system. They can check this themselves by using the developer tools that Athom provides. Go to this website and access the developer tools where you can inspect the self-reported status of the ZigBee network. This status includes details about what ZigBee channel is in use, mesh routing, the extended PAN ID, and the Network Key.

EDIT (2021-03-12): I had an automated update for another Homey I own to v5.0.1. This one didn’t get an automated key rotation… I am going to have to do it manually and I suspect that is going to be painful and require re-building the whole network from scratch. This is frustrating both personally as well as from a security perspective as this means there will be significant numbers of installations that are left unprotected.