Uncontrolled Resource Consumption with XMPP-Layer Compression
Unknown
Vulnerability Details
The bug information described below is based on a publicly available security notice here http://xmpp.org/resources/security-notices/uncontrolled-resource-consumption-with-highly-compressed-xmpp-stanzas/
These discoveries are part of the results of my research activities.
OVERVIEW
---------------------
Several XMPP server implementations that support application-layer compression (XEP-0138) suffer from an uncontrolled resource consumption vulnerability (CWE-400). This vulnerability can be remotely exploited by attackers to mount Denial-of-Service attacks by sending highly-compressed XML elements over XMPP streams.
In addition to that, the XMPP Standards Foundation committed into changing the XEP-0138 in or
DESCRIPTION
---------------------
XMPP stream compression is a desirable feature that reduces the amount of data transferred between the protocol principals. In XMPP, compression can be negotiated at the TLS layer (as described in RFC 6120) or at the application layer (as described in XEP-0138). The vulnerability that has been discovered applies specifically to application-layer compression; such compression is negotiated between an XMPP client and server (or two servers). After a successful negotiation, all the protocol messages are compressed.
When decompressing XMPP stanzas, an XMPP server must limit the resources allocated to this task. If the server fails to do that, it can monopolize the CPU usage and allocate all the available memory. As a result, remote attackers can exploit this vulnerability to mount a Denial of Service attack (DoS) by submitting highly-compressed XML elements over an XMPP stream (we call these “xmppbombs” for short).
An “xmppbomb” is a valid XML element sent over an XML stream but containing a huge number of white spaces. See for example the following element sent during stream negotiation:
<?xml version='1.0' ?>
<stream:stream $SPACES to='$SERVER'
xmlns='jabber:client'
xmlns:stream='http://etherx.jabber.org/streams'
version='1.0'>
where $SPACES is a 4GB long string of spaces and $SERVER is the server domain name. By using the zlib compression algorithm, it is possible to compress the above message to 4MB (compression ratio of ~1:1000).
XEP-0170 on “Recommended Order of Stream Feature Negotiation” suggests to negotiate stream compression after the authentication of the principals. This suggests that xmppbombs can be used only after the user authentication. However, it has been reported that some implementations allow the use of compression before the authentication phase therefore opening up this vulnerability to unknown attackers.
IMPACT
---------------------
Affected servers are reported to:
1) Consume the virtual memory; in certain cases, it has been reported that servers are terminated by the operating system for out of memory conditions;
2) Monopolize the use of the CPU;
3) In certain cases, not allow administrators to disable stream compression.
SOLUTION
---------------------
It is best to upgrade to corrected server code. An alternative, temporary workaround is to disable XMPP-level compression.
PROOFS OF CONCEPT
---------------------
Two proofs of concept are available here http://trouge.net/misc/xmppbomb_exploit.tar.bz2 (don't worry, no zipbombs here :) ). Please refer to the README file for more information.
It contains two attacks: #1 before the principal authentication and #2 after. I used these two attacks to confirm the vulnerability on 3 implementations: Prosody 0.9.3, Openfire 3.9.1, and Tigase server 5.2.0. The vulnerability and the DoS has been monitored in a black-box settings by monitoring the resources consumed (i.e., CPU usage, RSS/VSZ memory, and disk I/O). In addition, we measured the availability of the XMPP server under test as the number of (honest) requests processed per second during the attack and compared when not under attack.
The code and the explanation below has been shared with the XMPP community (vendors and admin).
The list of affected vendors can be found here http://xmpp.org/resources/security-notices/uncontrolled-resource-consumption-with-highly-compressed-xmpp-stanzas/
PRELIMINARIES
---------------------
xmppbombs can be generated with XMPPBombGen.java. In all our tests, we used xmppbombs of the size of 4MB that amounts to 4GB of uncompressed XMPP message each.
ATTACK #1: xmppbomb before authentication
---------------------
An example of this attack is in XMPPBombNoAuth.java. The attack is the following:
1) the attacker prepares offline a xmppbomb
2) the attacker then starts the XMPP protocol with the target by sending:
<?xml version='1.0'?><stream:stream to='server' xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' version='1.0'>
3) afterwards, the attacker requests to enable on the DEFLATE compression:
<compress xmlns='http://jabber.org/protocol/compress'><method>zlib</method></compress>
4) finally, the attacker sends the xmppbomb
The steps 2-4 can be executed concurrently (e.g., by colluded attackers, or with a botnet).
We found out that Prosody and Openfire are vulnerable to this attack. Prosody allocates up to 7GB of physical memory (RSS memory) with a single xmppbomb with 4GB of payload. The process is finally killed by the kernel due to an out of memory. Openfire uses instead 100% of the CPU and a bit less memory than Prosody (3GB) plus it writes to disk about 400 MB of data. We monitored delays on the availability of the service from x100 times to x10000 with parallel xmppbombs (12 or 24 parallel bombs).
ATTACK #2: xmppbomb after authentication:
---------------------
An example of this attack is in XMPPBombAuth.java. The attack is the following:
1) the attacker prepares offline an xmppbomb
2) the attacker then starts the XMPP protocol (see step 2 in Attack #1)
3) the attacker logs in:
<auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='PLAIN' client-uses-full-bind-result='true'>$TOKEN</auth>
where $TOKEN is the base 64 of the user name and password.
The attack then continues with step 3 and 4 of the attack #1.
Tigase is vulnerable to this attack and one 4GB xmppbomb pushes the CPU usage up to 100% for about 10 minutes.
OTHER RELEVANT INFORMATION
---------------------
During the coordination process, I suggested the XMPP community to review the specifications.
This is part of my suggestions :
"
[...]
I think that also the specs may warn developers on the risk of DoS via xmppbombs. The points 4 and 6 of Section 13.12 of RFC 6120 are SHOULDs rather than MUSTs and they refer only to uncompressed data. Then, XEP-0138 doesn't mention any XMPP-specific security consideration and it refers to the security consideration of TLS (See https://tools.ietf.org/html/rfc3749#page-5) that addresses (1) a binary-oriented protocol (2) concerns when combining compression and encryption and (3) risk of data size expansion. I think that this left a grey area in which developers took different decisions leading to these vulnerabilities. IMHO, XEP-0138 should be amended with a subsection inside Section 7 saying that if points 4 and 6 of Section 13.12 of RFC 6120 are not implemented then the implementation may be vulnerable to DoS via xmppbombs.
[...]"
The community agreed on that and the corrected version of XEP0138 is on his way however I am not aware of a publication date.
VENDOR INFORMATION
---------------------
The list of affected vendors can be found here http://xmpp.org/resources/security-notices/uncontrolled-resource-consumption-with-highly-compressed-xmpp-stanzas/
Actions
View on HackerOneReport Stats
- Report ID: 5928
- State: Closed
- Substate: resolved
- Upvotes: 3