Releasing mqttinfo and scanning all open brokers with BinaryEdge

Today we’re releasing mqttinfo, a command-line utility we wrote to collect information on the configuration and behavior of a remote MQTT broker service. mqttinfo also attempts to guess the product type of the underlying software, in the same spirit as nmap’s OS detection – but with fewer and simpler heuristics at the moment.

mqttinfo is available at https://github.com/teserakt-io/mqttinfo in version 0.1.0, with almost no documentation, probably dozens of bugs, but we hope it’ll be useful nonetheless to MQTT users! We’ll do our best to fix any bugs found and to add new features.

As an example, here’s the output of mqttinfo when analyzing the open test server of the popular open-source broker mosquitto:

As you can see, mqttinfo supports MQTT versions 3.1.1 and 5, which are respectively the most common version and the recently standardized one. In this example, mqttinfo directly connects without any authentication because the service is open, but you can also pass a username and password to analyze authenticated brokers, as documented:

In the above example, the option -j will tell mqttinfo to append the results in JSON to a file ./mqttinfo.json, for example:

{"Host":"test.mosquitto.org","Port":1883,"Username":"","Password":"","V4":true,"V5":true,"V4Anonymous":true,"V4PublishSYS":true,"V4FilterSYS":true,"V4SubscribeAll":true,"V4InvalidTopics":false,"V4InvalidUTF8Topic":false,"V4QoS1":true,"V4QoS2":true,"V4QoS3Response":false,"V5Anonymous":true,"V5PublishSYS":false,"V5FilterSYS":true,"V5SubscribeAll":true,"V5InvalidTopics":false,"V5InvalidUTF8Topic":false,"V5QoS1":true,"V5QoS2":true,"V5QoS3Response":false,"TypeGuessed":"mosquitto","Failed":false,"Error":""}

It’s of course interesting to analyze one broker service, for example to detect misconfigurations or shortcomings of the broker you’ll be using in production. But it’s even better to analyze many brokers, such as all brokers available on internet. To do this efficiently and reliably, we worked with our friends at BinaryEdge, who offered to help after they noticed mqttinfo’s teaser.

BinaryEdge deployed mqttinfo as a module of their scanning platform, and ran it on all the hosts with port 1883 open (the port typically used for MQTT unencrypted connections). The scan took several hours—notably because mqttinfo’s software detection can take up to 20 seconds—and the main observations are the following:

  • Of all the hosts with TCP port 1883 open, 23287 authorized an anonymous connection over MQTT v3.1.1, by sending back a CONNACK packet with reason code 0x00. Many of these brokers may be there for testing and/or open on purpose, but many are evidently used by real devices, as BinaryEdge had already observed.
  • Of these 23287 hosts, about 70% seemed to be running Mosquitto as a broker—but keep in mind that our product detection is based on heuristics and can be easily fooled, so take this number with a grain of salt.
  • 71,5% of the hosts authorized clients to publish to $SYS topics (a behavior that we discussed in a previous post), a number only slightly greater than that of the mosquitto, and indeed almost all hosts identified as mosquitto share this property.
  • 77.5% of the hosts accepted an invalid UTF-8 string as a topic, whereas the standard states that “If a Server or Client receives a Control Packet containing ill-formed UTF-8 it MUST close the Network Connection”. We used the string \xc3\x28 to test this, and of course could not test all invalid UTF-8 strings.
  • 2.3% of the hosts accepted the invalid topic “A+”, which includes the wildcard character “+” in a way that is invalid, as per the standard.
  • A bit less than 1% of the hosts did not seem to support QoS level 1, with a similar number of instances not supporting QoS2. Surprisingly, about 4.5% of the broker instances (1055) accepted a QoS level of 3, which is not defined by the standard and should be rejected as invalid.
  • 88.5% of the hosts authorized clients to subscribe to all topics at once, by subscribing to the topic filter “#”.
  • Only about 10% of the hosts (2430) supported MQTT v5, of which only approximately 1570 seemed to support QoS levels greater than 0.

We’ve been running mqttinfo on several versions of the main broker products, and have often noticed different behaviors, not only across products, as expected, but also across versions. Furthermore, and in part due to differences in the norms defined by the standards, MQTT v3.1.1 and v5 interfaces may also behave differently even in a same version of a broker.

We have reported some of our observations to broker product maintainers, who often helped us understand MQTT better and sometimes corrected our understanding. We’d like to thank in particular HiveMQ and VerneMQ for their insightful feedback.

Last but not least, we’d like to thank Tiago from BinaryEdge and his team for offering to extend their worldwide scan of MQTT brokers with mqttinfo, and for rapidly providing us with the results!