OpenFlow v5 dissector excessive memory and CPU consumption - denial of service
Summary
It is possible to reach an infinite loop in the OpenFlow v5 dissector by generating a specifically crafted OpenFlow Bundle Prop packet such that will create unlimited number of openflow_v5.bundle_prop.type
by manipulating the reading pointer offset
to the same place each time. The packet will consume an excessive amount of memory and 100% core cpu, which eventually lead to a denial of service via packet injection or crafted capture file.
Technical details
OpenFlow is a communications protocol that gives access to the forwarding plane of a network switch or router over the network. Usually it runs over TCP port 6653 (official) or 6633 (unofficial port). The protocol can also be detected heuristically by tshark if the header is properly identified.
One of the protocol function codes is OFPT_BUNDLE_CONTROL
which holds the following struct:
/* Message structure for OFPT_BUNDLE_CONTROL. */
struct ofp_bundle_ctrl_msg {
struct ofp_header header;
uint32_t bundle_id; /* Identify the bundle. */
uint16_t type; /* OFPBCT_*. */
uint16_t flags; /* Bitmap of OFPBF_* flags. */
/* Bundle Property list. */
struct ofp_bundle_prop_header properties[0]; /* Zero or more properties. */
};
The struct ofp_bundle_prop_header
is defined as follows:
/* Common header for all Bundle Properties */
struct ofp_bundle_prop_header {
uint16_t type; /* One of OFPBPT_*. */
uint16_t length; /* Length in bytes of this property. */
};
The OFPT_BUNDLE_CONTROL
message type is parsed in dissect_openflow_bundle_control_v5
which calls to dissect_openflow_bundle_prop_v5
in order to parse all ofp_bundle_prop_header properties
. However, if the reported length of a single property is 0, the offset will never be advanced and the same zero length property will be read again and again without control.
Inside dissect_openflow_bundle_prop_v5
offset is changed as follows: offset += prop_len - 4
but prop_len
is read from the packet, which can be manipulated to be 4 --> this will cause offset to never change.
Relevant functions:
dissect_openflow_message_v5
--> dissect_openflow_bundle_control_v5
--> dissect_openflow_bundle_prop_v5
Steps to reproduce
Open the provided pcaps with Wireshark poc_fixed.pcap
What is the current bug behavior?
Wireshark will get stuck when trying to dissect a single maliciously crafted packet
What is the expected correct behavior?
Wireshark should ignore the malicious packet
Sample capture file
Provided poc_fixed.pcap
Relevant logs and/or screenshots
[Protocols in frame: eth:ethertype:ip:tcp:openflow:openflow_v5]
....
....
OpenFlow 1.4
Version: 1.4 (0x05)
Type: OFPT_BUNDLE_CONTROL (33)
Length: 62
Transaction ID: 1526726656
Bundle ID: 335871
Type: Unknown (0x5b00)
Flags: 0x4500
.... .... .... ...0 = OFPBF_ATOMIC: False
.... .... .... ..0. = OFPBF_ORDERED: False
Bundle prop
Type: Unknown (0)
Length: 0
Unknown bundle prop body.
[Expert Info (Note/Undecoded): Unknown bundle prop body.]
[Unknown bundle prop body.]
[Severity level: Note]
[Group: Undecoded]
Bundle prop
Type: Unknown (0)
Length: 0
Unknown bundle prop body.
[Expert Info (Note/Undecoded): Unknown bundle prop body.]
[Unknown bundle prop body.]
[Severity level: Note]
[Group: Undecoded]
----- More bundle props... -------
Build information
TShark (Wireshark) 3.7.0 (v3.7.0rc0-844-g14a1dfbe1083)