zeek/src/analyzer/protocol/mqtt/mqtt-protocol.pac
Seth Hall a42b3a1d63 MQTT Analyzer heavily updated and ported from the analyzer originally by Supriya Kumar
This analyzer generates three logs to fully display what is happening over the MQTT connection.
  - mqtt_connect.log
  - mqtt_subscribe.log
  - mqtt_publish.log

At this time it only supports MQTT 3.1 and 3.1.1
2019-07-29 13:45:10 -04:00

61 lines
1.5 KiB
JavaScript

##! MQTT control packet parser, contributed by Supriya Sudharani Kumaraswamy
enum MQTT_msg_type {
MQTT_RESERVED = 0,
MQTT_CONNECT = 1,
MQTT_CONNACK = 2,
MQTT_PUBLISH = 3,
MQTT_PUBACK = 4,
MQTT_PUBREC = 5,
MQTT_PUBREL = 6,
MQTT_PUBCOMP = 7,
MQTT_SUBSCRIBE = 8,
MQTT_SUBACK = 9,
MQTT_UNSUBSCRIBE = 10,
MQTT_UNSUBACK = 11,
MQTT_PINGREQ = 12,
MQTT_PINGRESP = 13,
MQTT_DISCONNECT = 14,
};
type MQTT_string = record {
len : uint16;
str : bytestring &length=len;
};
# These values are all defined in the commands/*.pac files...
type Command(pdu: MQTT_PDU, msg_type: uint8) = case msg_type of {
default -> unknown : empty;
};
type MQTT_PDU(is_orig: bool) = record {
fixed_header : uint8;
remaining_length : uint8[] &until(($element & 0x80) != 1);
command : Command(this, msg_type) &length=real_length;
} &let {
msg_type : uint8 = (fixed_header >> 4);
real_length = $context.connection.calc_header_length(remaining_length);
} &byteorder=bigendian;
refine connection MQTT_Conn += {
# This implementation is ripped straight from the spec.
function calc_header_length(vals: uint8[]): uint32
%{
int multiplier = 1;
uint32_t value = 0;
for ( auto encoded_byte: *vals )
{
value += (encoded_byte & 127) * multiplier;
multiplier *= 128;
if ( multiplier > 128*128*128 )
{
// This is definitely a protocol violation
this->bro_analyzer()->ProtocolViolation("malformed 'remaining length'");
return 0;
}
}
return value;
%}
};