AMP dissector excessive memory and CPU consumption - denial of service
Summary
It is possible to reach an (almost) infinite loop (max guint64) in the AMP dissector by generating a specifically crafted AMP over LTP packet such that will create unlimited number of amp.rx_name
by manipulating the reading pointer 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
Asynchronous management Protocol (AMP) is a binary protocol which provides data monitoring, administration, and configuration for applications operating above the data link layer of the OSI networking model. Often used over Licklider Transmission Protocol (LTP) for deep space links.
AMP decodes CBOR objects which has type, length (size
) and value (uint
). Each AMP packet carries multiple CBOR objects which are parsed and decoded as TLV (type-length-value). The main dissection function is called dissect_amp_as_subtree
, which handles most of the parsing potion of CBOR items. However, in this function offset
is defined as int
while CBOR lengths are of type guint64
. Therefore, it's very easy to reach an int overflow situations which offset will go back instead of moving forward.
For example, ampHeader
type 0x01 iterates over a set of CBOR objects. First the dissector will read the number of items in the set and then read each CBOR object from the set. However, since we can manipulate offset
using the int-overflow vulnerability, we can force the dissector to keep reading the same object over and over again without advancing the packet offset
.
With a very small amount of bytes (~100) we can create a packet that will hung tshark because it will try to read inf number of objects.
Steps to reproduce
Open the provided pcaps with Wiresharkamp_ltp_dos.pcap
What is the current bug behavior?
Wireshark/tshark will try to parse up to max guint64 AMP rx_names
, while reading from the same place each time - the packet is manipulated in such way that the offset is never being advanced.
What is the expected correct behavior?
Once wirehshark/tshark encounter a malformed cborObj
and/or AMP packet, it should stop processing the current packet, or at least advance the reading pointer so no inf loops will occur.
The bug resides in bad arithmetic operations involving the packet offset variable (int overflow).
Sample capture file
Attached amp_ltp_dos.pcap
Relevant logs and/or screenshots
Build information
Version 3.6.0 (v3.6.0-0-g3a34e44d02c9)