iptablesでいこう(2. 敵を知れ)

iptablesの敵を知れ

クラッカーと管理者との攻防をミクロに捉えると、ツール対ツールということになる。ツールを扱うのはもちろんヒトなんだけど、結局、ツールのことを熟知していないと始まらない。さて、本当にわかってんのか?と自分に聞いてみると結構不安になったので、とりあえず整理しておこうというわけで...。

ここでの話はUNIXに限るものとします。WindowsはなーんとRFCに逆らう動きをするので、ここでの説明に当てはまらない部分があるのですね。



■ ポートスキャナー ■

攻撃準備つーと、ホームページによる情報収集とか、企業狙うなら資料、電話とかいろいろあるでしょうが、そういったソーシャル寄りのものではなくて、ツールという観点ではやっぱポートスキャンでしょう?そういうことにしてください。


nmap

nmap は非常によく知られたポートスキャナー。Windows 版 (nmapNT) もある。ポートスキャンくらいはごたごた騒いだり気にしないで、「どーぞどーぞ気が済んだかあ?」という姿勢なのだが、現実には攻撃の一部であるので、ここで対策すればそれだけセキュアにはなるともいえるし、nmap については熟知していて損はないよね。

以下ではホスト GUNDAM から nmap を用いて、ホスト MANDAM に向けてスキャンを行い、MANDAM では tcpdump host GUNDAM でパケットをキャプチャしている。行番号は私が付加した。

ex 01: フィルタリングされていない 21 番ポート(icmp は許可)
nmap -sS MANDAM

1: 16:43:28.289567 eth0 < GUNDAM > MANDAM: icmp: echo request
2: 16:43:28.289619 eth0 > MANDAM > GUNDAM: icmp: echo reply
3: 16:43:28.289911 eth0 < GUNDAM.48298 > MANDAM.http: . 3452436483:3452436483(0) ack 4272022727 win 4096
4: 16:43:28.289959 eth0 > MANDAM.http > GUNDAM.48298: R 4272022727:4272022727(0) win 0 (DF)
5: 16:43:28.774683 eth0 < GUNDAM.48278 > MANDAM.ftp: S 2017535627:2017535627(0) win 4096
6: 16:43:28.774804 eth0 > MANDAM.ftp > GUNDAM.48278: S 2399911933:2399911933(0) ack 2017535628 win 5840  (DF)
7: 16:43:28.775219 eth0 < GUNDAM.48278 > MANDAM.ftp: R 2017535628:2017535628(0) win 0

では説明、
1、2行目では nmap がホストの生存確認を icmp を用いて行っている。-P0 や -PTXX
などのオプションを指定した場合はこれは省略される。

3行目では nmap がさらにホストの生存確認を tcp の ACK パケットを http(80) ポート
に向けて送ることで行っている。これはデフォルトの動作である。
これを変更するには -PTXX か -PSXX(ACK ではなく SYN 使用)を用いる。

4行目ではいきなり ACK を受け取った MANDAM が RFC にもとづき、RST で応えている。

5行目では RST を受け取った GUNDAM が MANDAM の稼動を確認したので、実際の
スキャンを開始している。-sS オプション(ハーフコネクトスキャン)を指定したので、
ここでは ftp(21) ポートに向けて SYN パケットを送りつけている。

6行目ではなんにもしらない MANDAM が 「へいらっしゃい、ftp ならやってるよ」
と SYN/ACK で応答している。

7行目では GUNDAM がこの接続を確立しないように(ログに残るから)RST で終了
させている。

GUNDAM 側で得られるのは

21/tcp   open   ftp

となる。


ex 02: フィルタリングされていない 21 番ポート(icmp は許可)
nmap -sA MANDAM
1: 16:43:40.324785 eth0 < GUNDAM > MANDAM: icmp: echo request
2: 16:43:40.324810 eth0 > MANDAM > GUNDAM: icmp: echo reply
3: 16:43:40.325127 eth0 < GUNDAM.43885 > MANDAM.http: . 4165468163:4165468163(0) ack 1269342061 win 2048
4: 16:43:40.325150 eth0 > MANDAM.http > GUNDAM.43885: R 1269342061:1269342061(0) win 0 (DF)
5: 16:43:40.689021 eth0 < GUNDAM.43865 > MANDAM.ftp: . 1698561998:1698561998(0) ack 2032859258 win 2048
6: 16:43:40.689048 eth0 > MANDAM.ftp > GUNDAM.43865: R 2032859258:2032859258(0) win 0 (DF)

こんどはさっきと同じ状態のホストに対して ACK スキャンを行う。
このスキャンはフィルタリングされているかどうかを調べるものである。
さっきと同じ部分は説明省略。

5行目ではさっき RST を受け取った GUNDAM が MANDAM の稼動を確認したので、実際の
スキャンを開始している。-sA オプションを指定したので、ACK パケットを送りつけている。

6行目では MANDAM が「なんだコノヤロ、ftp はやってっけど、いきなり ACK かよ!タコ」
と RST で応答している。ちなみに稼動していないポートの場合でも RST が返る。

RST で応答されたので、フィルタリングされてないことがわかる。
GUNDAM 側で得られるのは "Unfiltered" となる。


ex 03: フィルタリングされていない 21 番ポート(icmp は許可)
nmap -sF MANDAM
1: 16:43:34.298231 eth0 < GUNDAM > MANDAM: icmp: echo request
2: 16:43:34.298271 eth0 > MANDAM > GUNDAM: icmp: echo reply
3: 16:43:34.298563 eth0 < GUNDAM.40032 > MANDAM.http: . 1705508867:1705508867(0) ack 2582573751 win 3072
4: 16:43:34.298593 eth0 > MANDAM.http > GUNDAM.40032: R 2582573751:2582573751(0) win 0 (DF)
5: 16:43:34.664011 eth0 < GUNDAM.40012 > MANDAM.ftp: F 0:0(0) win 3072
6: 16:43:34.967182 eth0 < GUNDAM.40013 > MANDAM.ftp: F 0:0(0) win 3072

もうひとつだけ。さっきと同じ状態のホストに対して FIN スキャンを行う。

5行目では -sF オプションを指定したので、FIN パケットを送りつけている。
MANDAM は 「なんだコノヤロ、ftp はやってっけど、いきなり FIN 送ってきやがって」
ということで無視している。

6行目では念のためもう1回送って確かめている。

稼動していないポートの場合はRST で応答することになっているため、
応答がないことから、

◆フィルタリングされていないが無視された
◆フィルタリングされている

のいずれかということがわかる(フィルタリングされてれば
ここまでのプロセスがないので何も返ってこないのである)。

GUNDAM 側で得られるのは

21/tcp   open   ftp

であるが、言葉通りポートが open しているわけではない。
この判断はフィルタリング状況をあわせて考えねばならない。

-sX ,  -sN などで指定できるスキャンは -sF と似た動作となる。
また、これらのスキャンではフィルタリングされていても同じやりとりとなる。


ex 04: フィルタリングされた 21 番ポート(icmp は許可)
nmap -sS MANDAM
1: 23:50:28.034161 eth0 < GUNDAM > MANDAM: icmp: echo request
2: 23:50:28.034299 eth0 > MANDAM > GUNDAM: icmp: echo reply
3: 23:50:28.034350 eth0 < GUNDAM.46286 > MANDAM.http: . 33554435:33554435(0) ack 2955771689 win 4096
4: 23:50:28.034417 eth0 > MANDAM.http > GUNDAM.46286: R 2955771689:2955771689(0) win 0 (DF)
5: 23:50:28.401696 eth0 < GUNDAM.46266 > MANDAM.ftp: S 3273302783:3273302783(0) win 4096
6: 23:50:28.706494 eth0 < GUNDAM.46267 > MANDAM.ftp: S 3228915610:3228915610(0) win 4096
7: 23:50:29.026423 eth0 < GUNDAM.46268 > MANDAM.ftp: S 1673149016:1673149016(0) win 4096
8: 23:50:29.346438 eth0 < GUNDAM.46269 > MANDAM.ftp: S 3273302783:3273302783(0) win 4096
9: 23:50:29.666564 eth0 < GUNDAM.46270 > MANDAM.ftp: S 3228915610:3228915610(0) win 4096
10: 23:50:29.986466 eth0 < GUNDAM.46271 > MANDAM.ftp: S 1673149016:1673149016(0) win 4096

5行目以降ではスキャンを開始している。-sS オプション(ハーフコネクトスキャン)
を指定したので、ここでは ftp(21) ポートに向けて SYN パケットを送りつけている
のだが、応答の SYN/ACK がフィルタリングされているため何も返ってこないので、
6回リトライしてからやめている。

フィルタリングされている場合はこのようになる、などの知識は nmap を使うにあたって必須である。

この場合 GUNDAM 側で得られるのは

21/tcp   filtered   ftp

となる。


さて、nmap には -g(発信ポート調整) , -D(発信IPアドレス査証 --- 囮) というオプションがある。これをうまく使うと、よりスマートなスキャンができる。これまでの例でわかるように、簡単なものであってもフィルタリングされていると当該ポート関連サービスの情報が限られてしまう。

しかし、これも気づいたかもしれないが、どこかに穴があれば情報は取得できる。そのために -g, -D が使える。まあ、この用途で -D を使うまでもないだろうけど。

たとえば ex 04 の例では「フィルタリングされてるよん」という情報しか得られず、 実際にサービスが稼動しているかどうかはわからないが、 MANDAM で「リモート53番(DNS)は通す」とかいうフィルタリングルールの場合、 これを利用する
nmap -sS -p 21 -g 53 MANDAM 

この結果は ex 01 と同じになる。

もちろん稼動していないポート(65535 とする)に向ければ

nmap -sS -p 65535 -g 53 MANDAM 

closed となる。またもちろん、-sF などと組み合わすのも有効。

-g での指定については 21,53,110 あたりが使えることが多いでしょうね。

あと OS 判断の -O オプションというのがあるけど(大量のパケットを使用)、
テストは別として、黒の世界では実際に使われてんのかな?
もっと安全なほかの方法やツールがあるのでどうだろうなあ。
少なくとも自分だったら使わないけど。

■ バージョン調査 ■

ポートスキャナーでも、ツールや OS のバージョン特定、いわゆるスタックフィンガープリント関連に秀でたものがありますが、専用のツールもあります。


scanssh

scanssh というツールは SSH のバージョンと WEB 鯖の種類、バージョンを調べるツール(これはオマケでしょう)です。動作は非常に軽く、きっとクラッカーにとっては便利なんだろと想像できます。ただし、普通の接続に限りなく近いと言えなくもないですけど。まあそういうのがある、ということで。対策を立てる労力は見合わないコストになりそうですねえ、よほど暇だったらやりましょう、リストラされるとか。まあ SSH などを最新に保っておればよいのです。

ex 05: 何にも制限しない 80 番ポート
scanssh -n 80 XXX.XXX.XXX.XXX
19:53:57.174232 eth0 < GUNDAM.2073 > MANDAM.http: S 2473075190:2473075190(0) win 32120  (DF)
19:53:57.174386 eth0 > MANDAM.http > GUNDAM.2073: S 1582248488:1582248488(0) ack 2473075191 win 5792  (DF)
19:53:57.174752 eth0 < GUNDAM.2073 > MANDAM.http: . 1:1(0) ack 1 win 32120  (DF)
19:53:57.175071 eth0 < GUNDAM.2073 > MANDAM.http: P 1:28(27) ack 1 win 32120  (DF)
19:53:57.175155 eth0 > MANDAM.http > GUNDAM.2073: . 1:1(0) ack 28 win 5792  (DF)
19:53:57.181466 eth0 > MANDAM.http > GUNDAM.2073: P 1:414(413) ack 28 win 5792  (DF)
19:53:57.181705 eth0 > MANDAM.http > GUNDAM.2073: F 414:414(0) ack 28 win 5792  (DF)
19:53:57.182206 eth0 < GUNDAM.2073 > MANDAM.http: . 28:28(0) ack 414 win 32120  (DF)
19:53:57.182335 eth0 < GUNDAM.2073 > MANDAM.http: . 28:28(0) ack 415 win 32120  (DF)
19:53:57.183697 eth0 < GUNDAM.2073 > MANDAM.http: R 28:28(0) ack 415 win 32120  (DF)

説明は省略。

この場合 GUNDAM 側で得られるのは

XXX.XXX.XXX.XXX Server: Apache 1.3.XX(Unix)

とかなる。

※Apache では access.log にごくふつうのログが残る。


ex 06: 何にも制限しない 22 番ポート(/etc/hosts.allow に記述あり)
scanssh -n 22 XXX.XXX.XXX.XXX
19:53:51.438859 eth0 < GUNDAM.2072 > MANDAM.ssh: S 2452468379:2452468379(0) win 32120  (DF)
19:53:51.438984 eth0 > MANDAM.ssh > GUNDAM.2072: S 1573842964:1573842964(0) ack 2452468380 win 5792  (DF)
19:53:51.439316 eth0 < GUNDAM.2072 > MANDAM.ssh: . 1:1(0) ack 1 win 32120  (DF)
19:53:51.441649 eth0 > MANDAM.ssh > GUNDAM.2072: F 1:1(0) ack 1 win 5792  (DF)
19:53:51.442018 eth0 < GUNDAM.2072 > MANDAM.ssh: . 1:1(0) ack 2 win 32120  (DF)
19:53:51.442280 eth0 < GUNDAM.2072 > MANDAM.ssh: F 1:1(0) ack 2 win 32120  (DF)
19:53:51.442351 eth0 > MANDAM.ssh > GUNDAM.2072: . 2:2(0) ack 2 win 5792  (DF)

これも説明は省略。

この場合 GUNDAM 側で得られるのは

XXX.XXX.XXX.XXX SSH-X.XX-OPENSSH_X.X.X

とかなる。

※/var/log/secure にはスキャンがあった旨のログがきっちり残る。





ま、もとより完全に開けっぴろげのサービスであればスキャンはするまでもない場合もあるのだけどね。

ハッカー入門みたいになっちゃうのでここらへんでやめときましょー(笑)。 まあわしがハッカーじゃないんで(優れてないつーこと)、たいしたもんじゃないだろうケド(^^

これらのようなやりとりを頭において、パケットフィルタリングを行うときっちりしたものになる(かも)。



トップページ