Chuck
Principal Security Engineer
Blog

The IoT Just Got a Wake Up Call

August 19, 2016 by Chuck McAuley

With Defcon and Blackhat two weeks in the rearview mirror, I have finally caught up with the work I didn’t do while in Vegas. Looking back, one presentation that really stood out as deserving more attention was Lucas Lundgren’s talk on MQTT. (Not only for the retro imagery!) MQTT is a light-weight protocol designed for the era of Internet of Things (IoT). Well, that’s not true in the least. MQTT is about 18 years old, but due to its lightweight, low bandwidth design, has seen a resurgence in use to support the burgeoning market of the connected home and world.

Lucas discovered almost 60,000 open MQTT brokers that allowed access without any authentication. No authentication means any MQTT client was able to connect to the message broker, subscribe to and publish messages on any channel. He found amongst this collection messaging apps, hospital communications, prison controls, shipment tracking systems, and potential satellite communication systems. He demonstrated a quick way to subscribe to all channels on the message broker by using the special channel name “#”. By subscribing to this channel, all messages on the broker are delivered to the client. He also showed how these message brokers can be used as hidden communication channels for botnet command and control systems rather effectively.

Almost immediately at Ixia, the question that came from the field was “do we support MQTT for emulation and testing?” The answer is, and has been for quite a while, “yes!” As you might imagine, security operation staff are trying to determine if they are using this protocol and if they have any open message brokers.

Lundgren left good crumbs to follow as well as a quick and dirty “subscribe all the things!” ruby script. Let’s look into the packet capture to see the details of an MQTT subscribe message. Then let’s see how we can recreate this probe in BreakingPoint for application and threat signature testing. This is a simple protocol with a fundamental subscribe/publish system. We tested our implementation along with a modified version of Lundgren’s script against iot.eclipse.org, an open, Internet accessible server for testing MQTT.

First, the client connects on TCP port 1883 and sends a “Connect Command” that is represented in the first 4 bits with a decimal value of 1. The second 4 bits are control-level messages not normally needed. Then you have a length value specifying the total message length minus the control bits and length value itself. This is an interesting place for further examination later (think protocol fuzzing). Next, there is a length-value string specifying the protocol name, which seemingly doesn’t matter. Our implementation uses the string “MQTT,” but Lungren’s script uses the name “MQIsdp” – probably caused by the MQTT Ruby Gem that is imported. Similarly, the ClientID message values seem to only need to be unique. The Version header value difference wasn’t important for our testing, and neither were the presence of the “Will Topic” and “Will Message” blocks.

IoT1

As verification that our client is working, when we look at the response between sending these two packets, we see the same response from iot.eclipse.org:

IoT2

There’s really nothing interesting to see here. This response is pretty standard.

Next up, our clients send out subscribe messages. This is where you see the impact of the change we made to both setups. We decided not to oversubscribe the test server, so we replaced channel # for joining with the channel name “Test”. Using the channel “Test”, we will know that we only get one channel of messages back. Once again, both our requests look identical:

IoT3

This sets us up to receive messages published on the channel “Test”. In this case, we get one response:

IoT4

Envio desde el cliente! Not sure what exactly that means, but let’s go with it. As you can see, both our implementation and the ruby implementation both return the same thing. Now let’s get interesting. What happens if we hit the test server with a request not for a specific channel, but for #:

IoT5

Aha! And there we go, pulling everything out of the broker at once. So, what have we proven here? Well, MQTT message brokers should not allow users to subscribe to the all channel list (#), and should also make use of the built-in authentication controls. But more importantly for us, we have like-for-like emulation of MQTT, to the point where we can test a live server with it. Let’s breakdown how that works inside of Ixia’s BreakingPoint. Below is a screenshot of what we call a SuperFlow. SuperFlows allow users to arrange specific actions within a protocol—incorrectly or correctly, it’s within their control. Although typically most of our built-in SuperFlows are examples of the protocol interactions as they are meant to be:

IoT6

You can see here in this example that all of the actions are client only. This is because we are driving this as a one-arm test, which is jargon for “client only.” One-arm tests are used to test servers, proxies, and other devices that are termination points. We also use the term Two-Arm test to signify a test that emulates both servers and clients. If we expand one of these actions out, we can see a list of tunable options:

IoT7

Notably, you can see that we can change the protocol name, flags, topics, identifiers, and more. If you leave an item blank, a default will be provided. We also support randomization within these structures, so you can start adding more levels of realism (random channel joins, different client ID’s, test username/password fields) instead of simply banging on a server with the same content repeatedly. So, if we want to change this standard channel join over into a probe very similar to Lundgren’s hashtag hack, we really only need to change one value:

IoT8

And we’re done. Send that over to your favorite MQTT server you want to test, or maybe through your IDP/IDS and see if it detects the probe. Either way, you’ve now got emulation at scale of this reconnaissance probe. And when we say scale, we mean millions of unique clients on a single port. Because I’m sure Lundgren isn’t the only one out there looking for open brokers.

Leverage Subscription Service to Stay Ahead of Attacks

The Ixia BreakingPoint Application and Threat Intelligence (ATI) Subscription provides bi-weekly updates of the latest application protocols and attacks for use with Ixia platforms.