@
プロローグ:
ほとんどのインターネットに接続されたサーバの管理者は、自分が管理している
サーバに侵入されるとは夢にも思っていない。
ある管理者は、そもそもサーバがクラックされるという事実を知らない。また、
ある管理者は、自分のサーバなど無名であり、攻撃する価値がないのでクラックされる
ことはないと思っている。また、別の管理者は、自分はきちんとサーバを管理している
と過信している。しかし、クラッキングはある日突然現実のものとなる。例えば、
こんな風に。
@
兆候:
最初にその異常に気がついたのは、インターネットへ接続しているルータを
監視しているモニタ・プログラムだった。
モニタ・プログラムは、定期的にルータが動作しているか、ルータが応答するか
どうかを確認している。いわゆる ping による応答確認である。
その日、モニタ・プログラムは、ルータからの応答がないという警告のメールを
ネットワーク管理者に送りはじめた。
@
初日朝:
いつもの通り、H師匠は会社に着くと、メール・チェックを行った。
しかしその日は、ふだんは見かけないメールが幾つも届いていた。モニタ・プログラム
からの警告メールである。
時刻は深夜、1時間程度の間、ルータからの応答がなかった
ことになる。ルータとモニタ・プログラムが稼働しているサーバは、
同じ
スイッチング・ハブ
に
接続されており、これは、ルータが本当にダウンしたのでなければ、極めて異常なこと
である。ただし、警告のメールは約1時間後にはなくなっていた。
深夜に 1時間だけルータが故障してその後、自然回復したとは考えにくい。
何かが起こっている?
ルータを通過する
トラフィック(通信データ量)
は、モニタ・プログラムが
稼働するサーバとは別のサーバで
SNMP
により記録されている。
ルータからの応答がなかった
時間帯の記録を見ると、異常に大きな外向きのトラフィックが記録されていた。
しかも内向きのトラフィックはほとんど発生していない。
深夜にこれ程のトラフィックがあることは、通常考えられない。
もしあるとすれば、
DoS(サービス不能)攻撃
を行っているのではないかという
疑惑が生じた。
つまり、いずれかのサーバがクラックされており、サーバに侵入され
DDoS攻撃
用のソフトがインストールされているということである。
部下のあつし君がやって来た。
「おはようございます。ルータがダウンしたってメールが来てますね。」
「ああ、その時間帯に異常なトラフィックが出ている。」
「深夜にあのトラフィックは変ですね。」
「しかも外向きだ。ユーザが何か大きなデータをどこかからダウンロードした
というわけではないね。」
「1時間程 1Mbps のトラフィックですからね。」
「ああ、だがその程度のトラフィックでは、ルータが応答しなくなるような
ことはないはずだ。」
「それもそうですね。実際にはもっと多いということでしょうか?」
「トラフィック記録は 5分間の平均だからね。瞬間的にはもっと出ているんじゃない?
考えられるのは...」
「DoS攻撃を行っている? ということでしょうか。」
「それくらいしかないね。」
@
パケット記録:
「どのサーバでしょうか?」
「それを特定できるログはないだろう。何か記録とってる?」
「いえ、
パケット
の記録まではありません。」
「サーバは何十台もある。すべてを調査するのは難しい。」
「そうですね。管理者も沢山いますし。」
「となると、まず、パケットを記録して、どのサーバがこのトラフィックを出して
いるのか突き止める必要があるな。パケット記録用にひとつ FreeBSD のサーバを
作ってくれないか。」
「ディスクは大きい方がいいですよね。30GB くらいでいいですか?」
「いや、あまりに大きいとログの解析が大変になる。3GB も記録できれば
充分だ。」
「わかりました。」
「あと、サーバの時計は必ず合わせておいてくれ。」
H師匠は、ルータをスイッチング・ハブから
シェアード・ハブ
へ繋ぎ直し、同じハブに
パケット記録用の FreeBSDサーバを接続した。
「tcpdump でこのネットワークすべての通信を記録しよう。」
# tcpdump -w log_file net 203.174.72 &
「これで今度異常なトラフィックが発生すれば、何処から何処へパケットが
飛んでいるのかわかりますね。」
「ああ。あとはもう一台 FreeBSDサーバを用意してくれないか。」
「今度はなんでしょうか?」
「パケット記録の解析用だよ。ディスクは 10GB 以上空きを確保してくれ。」
@
パケット解析:
翌日、やはり異常な外向きのトラフィックが深夜に発生しており、パケット記録用の
FreeBSDサーバのディスクは溢れていた。
「あ、ディスクが溢れています。」
「そうなるだろうと思ったよ。」
「いいんですか?」
「問題のトラフィックの一部は確実に記録されているだろう。パケット記録ファイルを
解析用のサーバへ転送してくれ。」
「これであとは、パケットの記録を解析すれば、どのサーバからどこへの通信か
わかりますね。」
あつし君はパケットの解析を始めた。
異常なトラフィックが発生している時間帯のパケット記録を見ると、
# tcpdump -r log_file
意外なことが
判明した。
「ありました。wwwサーバからイギリスのサーバへ大量のパケットが出ています。」
「あれ、今度は、メール・サーバからです。」
「えぇー!? これはダイアルアップ・ルータからもパケットがイギリスのサーバへ飛んでいます。」
「1秒間に 1万パケット以上でています。」
トラフィックは、複数のマシンから特定のイギリスのサーバへ
向けられたものであった。ただし、複数のサーバが、順番にイギリスのサーバ
のあらゆる
ポート
へ向けてパケットを送っている。DoS攻撃を行っていることは
間違いがない。
さらに記録を調べて行くと、
「H師匠、今度は、PPP接続してるマシンからパケットが出ています。」
「そんなに沢山のマシンがクラックされているはずはないな。」
クラックせずにこのような
トラフィックを発生させる
Smurf DoS攻撃
の進化したような新たな攻撃方法が発見されたのか?
いや、そもそも PPP接続の 64Kbps 程度では、これだけのパケットを出す
ことは無理だ。
「この IPアドレスは使用されていないはずですが、そこからもパケットが
出ています。」
IPアドレスは偽造されている!
@
IPアドレス偽造:
「あつし君、発信元の IPアドレスは偽造されているね。
サーバに侵入せずにそんなに大量のパケットを送らせることはできない。
発信元の IPアドレスは信用できない。MACアドレスを調べなくてはならない。」
「わかりました。」
MACアドレスを表示させてみると、
# tcpdump -e -r log_file
「すべて同じ MACアドレスから送信されています。」
「やはりそうか。」
つまり、パケットを出しているマシンはひとつだ。
「パケット記録用の FreeBSDサーバの arpテーブルを表示して一致するマシンが
あるか調べてくれ。」
# arp -an | grep 0:b0:d0:aa:aa:aa
? (203.174.72.56) at 0:b0:d0:aa:aa:aa [ethernet]
「ありました。これは、RedHatサーバです。」
この RedHatサーバはクラックされている?!
@
RedHatサーバ:
この RedHatサーバがクラックされている?!
「このサーバの管理者に連絡してくれ。OS のバージョンは?」
「記録によると、RedHat 6.2J ですね。」
サーバの管理者が呼ばれ、3人でこのサーバの精査が開始された。
OS は RedHat 6.2J で間違いないとのことであった。
「このサーバのネットワーク・カードの MACアドレスを確認しよう。」
# /sbin/ifconfig eth0
eth0 Link encap:Ethernet HWaddr 00:B0:D0:AA:AA:AA
inet addr:203.174.72.56 Bcast:203.174.72.255 Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:43363770 errors:0 dropped:0 overruns:0 frame:0
TX packets:547478758 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:100
Interrupt:16 Base address:0xccc0 Memory:f00b0000-f00b0c40
「同じですね。間違いないです。」
「では、変なプロセスがないか確認しよう。」
# ps auxw
「特に変なプロセスはないですね。」
「ああ、/var/log/ に wzap というプログラムがあります。」
「サーバへのログイン記録(/var/log/wtmp)を改竄するソフトだな。このサーバは
間違いなくクラックされて侵入されている。しかも root権限を取られている!!」
「とりあえず、
find_ddos
をダウンロードして実行してみよう。」
「わかりました。」
@
stacheldraht:
「あぁ、
stacheldraht demon
が見つかりました。」
# cat LOG
Log started for crack.hoge.jp at Fri Dec 1 14:54:51 2000
Scanning running processes:
/proc/148/exe:
identified as: stacheldraht daemon
with no symbol table
with the following differences:
IP address found: 3.3.3.3 (spoofed address)
Grabbing: /proc/148/exe
to: /usr/home/root/find_ddos/files/148
Scanning "/tmp":
Scanning "/":
/usr/src/.puta/td:
identified as: stacheldraht daemon
with no symbol table
IP address found: 3.3.3.3 (spoofed address)
Grabbing: /usr/src/.puta/td
to: /usr/home/root/find_ddos/files/td
Log finished Fri Dec 1 15:01:49 2000
「/proc/148/exe はリンクです。」
「/usr/src/.puta というディレクトリがあるはずだ。」
しかし、
# cd /usr/src
# ls -al
としても .puta は表示されない。
「おかしいな。ls -al で表示されませんね。あれ、cd すると確かにあります。」
「ls が変更されているな。」
# strings /bin/ls | grep puta
/usr/src/.puta/.1file
やはり ls が変更されている。
「とりあえず、passwd と su を ftp.redhat.com からダウンロードして
再度インストールしよう。変更されていないかも確認してみてくれ。」
「わかりました。」
# which passwd su
/usr/bin/passwd
/bin/su
# rpm -q -f /usr/bin/passwd
passwd-0.64.1-1
# rpm -q -f /bin/su
sh-utils-2.0-5
# ftp ftp.redhat.com
Connected to ftp.redhat.com.
220 "Red Hat FTP server ready. All transfers are logged, please have a nice day."
Name (ftp.redhat.com:root): ftp
331 Guest login ok, send your complete e-mail address as password.
Password:
230 Guest login ok, access restrictions apply.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> cd /pub/redhat/linux/6.2/ja/os/i386/RedHat/RPMS
250 CWD command successful.
ftp> bin
200 Type set to I.
ftp> mget passwd*
mget passwd-0.64.1-1.i386.rpm? y
200 PORT command successful.
150 Opening BINARY mode data connection for passwd-0.64.1-1.i386.rpm (11608 bytes).
226 Transfer complete.
11608 bytes received in 1.06 secs (11 Kbytes/sec)
ftp> mget sh-utils*
mget sh-utils-2.0-5.i386.rpm? y
200 PORT command successful.
150 Opening BINARY mode data connection for sh-utils-2.0-5.i386.rpm (180669 bytes).
226 Transfer complete.
180669 bytes received in 6.96 secs (25 Kbytes/sec)
ftp> quit
221-You have transferred 192277 bytes in 2 files.
221-Total traffic for this session was 193514 bytes in 4 transfers.
221-Thank you for using the FTP service on sub1.nyc.redhat.com.
221 Goodbye.
# ls -l /usr/bin/passwd
-r-s--x--x 1 root root 12244 Feb 7 2000 /usr/bin/passwd
# md5sum /usr/bin/passwd
29438cc9ff2c76e29167ffd4ff356b0a /usr/bin/passwd
# rpm -Uvh --replacepkgs passwd-0.64.1-1.i386.rpm
passwd ##################################################
# ls -l /usr/bin/passwd
-r-s--x--x 1 root root 12244 Feb 7 2000 /usr/bin/passwd
# md5sum /usr/bin/passwd
29438cc9ff2c76e29167ffd4ff356b0a /usr/bin/passwd
# ls -l /bin/su
-rwsr-xr-x 1 root root 14188 Mar 7 2000 /bin/su
# md5sum /bin/su
ffe87fdeddf32221320af3cdd9985433 /bin/su
# rpm -Uvh --replacepkgs sh-utils-2.0-5.i386.rpm
sh-utils ##################################################
# ls -l /bin/su
-rwsr-xr-x 1 root root 14188 Mar 7 2000 /bin/su
# md5sum /bin/su
ffe87fdeddf32221320af3cdd9985433 /bin/su
「passwd と su は、変更されていないようです。」
「とりあえず全アカウントのパスワードを変更しよう。」
「ls もインストールし直してくれ。」
# rpm -q -f /bin/ls
fileutils-4.0-21
# ftp ftp.redhat.com
(略)
ftp> cd /pub/redhat/linux/6.2/ja/os/i386/RedHat/RPMS
(略)
ftp> bin
(略)
ftp> mget fileutils*
(略)
# ls -l /bin/ls
-rwxr-xr-x 1 root root 139979 Mar 8 2000 /bin/ls
# rpm -Uvh --replacepkgs fileutils-4.0-21.i386.rpm
fileutils ##################################################
# ls -l /bin/ls
-rwxr-xr-x 1 root root 43024 Mar 8 2000 /bin/ls
「完了しました。」
「ありがとう。しかし、肝心の侵入経路は何処だ? それにかなり
やりたい放題、やられているので、まだまだ油断できないな。」
@
対応方針:
「このサーバですが、ネットワークから切り放せますか?」
「うーん。このサーバは、顧客のウェブ・サーバなんです。それ程
重要なデータはないはずですが、会社の公式サーバなので、いきなり止める
わけには...」
「ウェブ・ページの改竄はなかったわけですね。」
「それはないみたいです。」
「とすると、DDoS攻撃が主目的みたいですね。ウェブ・コンテンツの
バックアップはありますか?」
「ええ、それはもちろん。」
「では、とりあえずこのまま止めずにできることをやりましょう。」
「あつし君、まず、パケット記録をこのサーバに限定しよう。パスワードの
変更はとりあえず中止だ。」
「了解です。」
# tcpdump -w log_file host 203.174.72.56
「パケット記録開始しました。」
@
侵入経路:
「起動しているデーモンをリスト・アップしてくれ。」
「httpd, sendmail, portmap, rpc.statd, rpc.lockd, lpd, xntpd, sshd, identd
が起動しています。」
「この中で不要なデーモンはありますか?」
「ああ、そういえば NFS と lpd は使ってません。」
「あつし君、rpc と portmap、lpd を、停止させてくれ。」
# cd /etc/rc.d/init.d
# ./nfslock stop
# ./portmap stop
# ./lpd stop
「デーモンのバージョンを確認しよう。」
rpc.statd のバージョンを確認する。
# rpm -qa | grep nfs
nfs-utils-0.1.6-2
「ちょっと前に、rpc.statd にはセキュリティ・ホールがあったはずだ。
CERT Advisory を確認してくれ。」
「ありました。
CERT Advisory CA-2000-17 Input Validation Problem in rpc.statd
です。」
「
RHSA-2000-043-03
が出ていますね。nfs-utils-0.1.9.1-1 にバージョン・アップしなければいけないと
あります。」
「これか!」
「ログを確認しよう。」
# cd /var/log
# grep rpc messages*
messages:Dec 1 16:49:22 crack rpc.statd[359]: Caught signal 15, un-registering
and exiting.
messages:Dec 1 16:49:22 crack nfslock: rpc.statd shutdown succeeded
messages.2:Nov 15 19:34:51 crack nfslock: rpc.statd shutdown succeeded
messages.2:Nov 15 19:45:04 crack nfslock: rpc.lockd startup succeeded
messages.2:Nov 15 19:45:04 crack nfslock: rpc.statd startup succeeded
「11/15 はマシンを再起動したものですか?」
「ええ、確かに、その日はマシンを再起動しています。」
「ということは、rpc.statd はもともと自動起動するようになっていたと。」
他のデーモンには、知られているセキュリティ・ホールはなかった。
「侵入経路としては、rpc.statd が最有力ですね。」
「たぶん間違いないだろう。」
@
ps:
「あつし君、次は、ps を再インストールしてくれないか。」
「あっ、ps も変更されてるんですね。」
# ls -l /bin/ps
-rwxr-xr-x 1 root root 39359 Mar 8 2000 /bin/ps
# rpm -Uvh --replacepkgs procps-2.0.6-5.i386.rpm
procps ##################################################
# ls -l /bin/ps
-r-xr-xr-x 1 root root 60080 Mar 8 2000 /bin/ps
「やはり ps も変更されていました。」
「これでプロセスを再確認だ。」
# ps axuw
「あぁ!! lpsched .puta/td という明らかにあやしいプロセスがあります。」
「とりあえずそれは kill して。」
「はい。」
# kill 394
「それにさっきはなかった nscd というデーモンが動いてます。」
「Name Service Cache Daemon だな。使っていますか?」
「いえ、インストールした覚えはありません。」
「nscd も kill して。」
「はい。」
# kill 393
@
.puta/td:
「あれ、kill したはずの lpsched .puta/td がまた立ち上がっています。」
「起動時刻は?」
「あれ、kill したはずなのに古いですね。」
「kill できていないな。-KILLオプションをつけて確実にプロセスを
終了させよう。」
「わかりました。」
# kill -KILL 394
# ps axuw | grep lpsched
「今度こそ、kill しました。」
「ok。では、/usr/src/.puta を tar で固めて保存して、
/usr/src/.puta は削除しよう。」
# cd /usr/src
# tar zcvf puta.tar.gz .puta
# rm -rf .puta
@
nscd:
「じゃ、nscd を strings して何かわからないか見てみよう。」
# strings /usr/sbin/nscd | less
「/usr/info/.t0rn/shcf という文字列があります。」
「そのファイルがあるか確認して。」
# ls -l /usr/info/.t0rn/
-rwxr-xr-x 1 root root 498 Feb 6 2000 shcf
-rwxr-xr-x 1 root root 524 Mar 13 2000 shhk
-rwxr-xr-x 1 root root 328 Mar 13 2000 shhk.pub
-rwxr-xr-x 1 root root 512 Nov 30 08:45 shrs
「ありました。これは、sshd の設定と鍵のようですね。shcf には、
Port 47017 とあります。」
「バックドアだな。」
@
ポート・スキャン:
「あつし君、この RedHatサーバを nmap でポート・スキャンしておこう。
君のノートから、全ポートをスキャンしてくれないか。」
「わかりました。」
# nmap -sS -p 1-65535 203.174.72.56
Starting nmap V. 2.53 by fyodor@insecure.org ( www.insecure.org/nmap/ )
Interesting ports on crack.hoge.jp (203.174.72.56):
(The 65531 ports scanned but not shown below are in state: closed)
Port State Service
22/tcp open ssh
25/tcp open smtp
80/tcp open http
113/tcp open auth
Nmap run completed -- 1 IP address (1 host up) scanned in 50 seconds
「必要なサーバのポート以外は、空いてないですね。」
@
後始末:
やっとこのクラッキングの全体が見えた。
rpc.statd のセキュリティ・ホールを突いて、クラッカーがサーバに侵入。
DDoS攻撃ツール/バックドア用sshd をインストールして、侵入の記録を全て削除。
侵入がばれないように
また、攻撃ツールが発見されないように一部のプログラムを置き換えた。あとは、
リモートから、DDoS攻撃プログラムに命令を送り、指定したサーバを自由自在に
DDoS攻撃していたということである。
とるべき対応は、
念のためデータをすべてバックアップして、OS からインストールし直す。
OS のアップデートをすべて適用して、不要なデーモンを起動しないように
設定する。必要なサーバの最新版をインストールして、データを
リストア。
データを過去のバックアップ・データと比較して改竄されていないことを
確認。変更されたものがあれば過去のバックアップ・データをリストア。
他のサーバについて、セキュリティ・ホールのある rpc.statd が
動作していないことを確認。また、不要なデーモンが起動していないことと
デーモンのバージョンを確認し、セキュリティ・ホールが知られていない
ことを確認である。
「OS からの再インストールをした方がいいですね。」
「ええ、全くお恥ずかしい話です。」
@
バックドア:
その後の調査で、
/usr/bin/du
/usr/bin/find
/sbin/ifconfig
/usr/sbin/in.fingerd
/bin/login
/bin/netstat
/usr/bin/top
も全て変更されていたことが判明した。また、
/etc/rc.d/rc.sysinit に
# Name Server Cache Daemon..
/usr/sbin/nscd -q
# td start
/usr/src/.puta/td
と追加されていたことも判明した。nscd は改造された sshd バージョン1 であり、
サーバのポート47017 を待ち受けすることも確認された。むろん、このポート番号
は設定ファイルで自由に変更可能である。
また、このセキュリティ・ホールがあったのは、今回クラックされた
サーバただ 1台であることが判明し、侵入経路は rpc.statd であると
結論された。
@
外部対応:
「あつし君、あとは外部対応だ。DDoS攻撃の犯人を見付けるのはまず
無理だが、踏み台になっているサーバくらいは発見できるだろう。」
「まず、stacheldraht は、DDoS攻撃開始を指示するため ICMP echo reply を
使っているから、ICMP echo reply パケットが飛んで来たサーバは、
クラックされたものだろう。」
「それから、ポート47017 へアクセスしようしたマシンがあれば、
クラッカーがバックドアを使ってサーバに再度侵入しようとしたことに
なる。」
「あと、
JPCERT
と
IPA
にも情報提供をしておこう。」
「わかりました。」
@
宴の後:
幸、サーバ上のデータに改竄されたものはなかった。また、ICMP echo reply
とポート47017 へのアクセスはその後のパケット記録に記録されたので、
各々のサーバ/ネットワーク管理者へクラックされている可能性が高いというメールを
送った。
「H師匠、今回のクラッキングですが、終ってみれば、典型的なクラッキング
でしたね。」
「ああ、でもサーバへの不正侵入のほとんどはそんなものだよ。見つかっていない
セキュリティ・ホールを利用したものなど滅多にお目にかかるものじゃない。」
「よくいわれていることですが、
- 不要なデーモンは起動するな
- アップデートはすべて当てろ
このふたつをきちんとやっておけば、問題ないってことですね。」
「まあ、ユーザのパスワードが破られないならば。」
「それに、以前は、運が良ければクラックされなかったが、今は、
穴があれば必ずそのサーバがやられる。今回も 26台ある Linuxサーバの
内でやられたのは、穴があったその 1台だ。」
@
エピローグ:
ほとんどのインターネットに接続されたサーバの管理者は、自分が管理している
サーバに侵入されるとは夢にも思っていない。