サーバーの踏み台目的の不正アクセスの件 です。
cgi への不正アクセスの発見から、それへの対策をまとめてみました。
今年に入ってから、 1つの cgi へのアクセスが急に増えたので、Apache のログを調べて対応しています。
かなり前に、自前のサーバーを導入して数年後に、レンタルサーバーの公開機能として、Apache ログを解析しやすいように、
Perl でCGI を組んで置いたのが、今、大変役立っています。コッホ!!
Apacheアクセスログの機能としては、
1) 日別のアクセス数の一覧
2) 1日内での、ページ (html,cgi,php) 毎のアクセス数の一覧
3) さらに、その1ページに関して、
- アクセス元 ip 毎のアクセス数の一覧
- 参照元および参照内容 の一覧
- 生ログの表示
があれば、不自然なアクセスを見つけやすいです。
それは、さて置き、どうやら、cgi の不備をついて、別のサイトへリダイレクトさせる、URL をしきりに送りつけているようです。
当初、cgi の簡単な修正で、外部の URL へのリンクを出さないで、'/' の出力のみにして、様子を見ました。
それでもアクセスが減らないので、それならと cgi をリネームして、http エラーで返すようにしました。
なので、エラーが表示されて、リダイレクトされないので、送りつけてきても意味が無いのですが、
それでも、旧 cgi名称 でしきりにアクセスしてきます。
数日様子をみていましたが、サーバーへの不正アクセスのトラフィックが一向に減らないので、
これでは、いけないと思い、次の対策をこうじました。
現状、fail2ban のapache-noscript.conf のフィルターで、script not found ... として検出できているので、
検出回数や、検出時間をもっとシビアにして 以前より早期に、iptables へ登録して対応するようにしました。
これで、少しは、トラフィックを逓減できているので、もう少し検出回数、時間を制限するか様子みです。
ただ、 気になったので、apache のログで、どこの IP からアクセスしているのか、また参照元は、どこなのか調べてみました。
しつこくアクセスしてくる、IP の Host は、もしかしたら、ハッキングされているのかもしれません。
今回、この IP を fail2ban で、接続不能にするように、Server の iptables をActiveに設定しようとしています。
参照元 (html,cgi,php 等) は、色ありますが、
それらの殆どが、他の URL へリダイレクトする不正コードを見逃す、不備があるのでしょう。
其のなかに、
http://www.xxx.xx/bitrix/redirect.php
と言うのが結構あります。
bitrix/redirect.php とは何か良く知りませんが、
どうやら、リダイレクトするコードを見逃す不備があるのでしょう。
配布元にコンタクトを取って、知らせてやりたいですが、....
bitrix/redirect.php を利用されている方、一度、他のサイトへリダイレクトしていないか調べられたほうが良いと思います。
注) 特に、この php に問題が有ると言うことではありません。他に、不正コードの実行を見逃している、
html 、php 、cgi 、aspx も一杯あります。誤解のないように。
さて、問題の不具合のある perl CGI の改修ですが、
入力パラメータに、外部 URL が入っていないか、入念にチェックして、もし、部外 URL が渡されたら、perl で、
Apache のエラーログに前述の、"script not found or unable to stat ...." を出力して、fail2ban で処理させようかと考えちょります。
perl cgi で、 Apache のエラーログに書き出す例
warn "script not found or unable to stat:"; で、
STDERR に出力されて、Apache のエラーログに記録されます。
但し、注意が必要です。
Apache のエラーログには、本来の内容と少しことなります。
上が、本当に script が無い場合のログで、下が、cgi で、warn で出力したログです。
stat: の後が、 /xxx か at /xxx の違いがあります。
なので、fail2ban のフィルター filter.d/apache-noscript.conf で少し対応しないといけません。
これで、cgi 出力したエラーログを fil2ban で捉えて、規定回数繰り返したら、
不正 ip と判断して iptables に登録できるようになると思います。
注) 正規表現は、python になります。fail2ban が python で書かれているので。
念のため、ローカルのサーバーで動作確認をしてから、実機へ反映させてみます。
余談ですが、今不正に、他サイトへのリダイレクトを送ってくる奴は、200個以上は、 IP をもっているようです。
fail2ban で対応して、3日位どんどこ iptables に登録したら、少しは、アクセスが減少してきたみたいです。
短時間に10数回、繰り返して送信できる IPが枯渇してきて、数回しか送れないIP ばかりになったのかも知れません。
そのうち、この cgi でのエラーは、fail2ban の jail.local で、[apache-noscript] とは、別にして、1日の内に、
1回来ただけでも、iptables へ登録してはと考えちょります。
追記。
CentOS7 では、ちょっと異ります。
1. httpd.conf で、Apache エラーログフォーマットを、旧形式にします。
/etc/httpd/conf/httpd.conf
2. 上記設定で、エラーログを確認すると。
上が、実際に script が無い場合のログ
下の2行が、warn で吐き出したログになすます。
3. 実際に、script が無い場合への対応。
CentOS5 のエラーログと少し異なるので、fail2ban のフィルターで対応します。
/etc/fail2ban/filter.d/apache-noscript.conf
<HOST>の後のポート番号と、 AH01264: を無視します。
4. warn で吐き出したログ への対応。
何故、従来のログ形式と異なるのか、原因は、調査しないといけませんが、
安直な対応としては、 warn で、自分で全て出力する。
但し、時刻、IP は、自分で作成する。
上記、安直の設定でも、fail2ban で、無事検出できました。
または、fail2ban が2行にまたがってチェック出来るバージョンであれば、
2行をチェックすれば、対応できます。
fail2ban の古いバージョンは、できなったけれど、今のバージョンはどうでしょうか?
おんちゃんは、古いバージョンを自分で修正して、2行でのチェックができるので、
failregex = で対応します。
因みの、この改造版は、おんちゃんのブログで触れているので、ご覧下さい。
その src rpm を、 CentOS7 でビルドすれば、そのまま使えると思います。
その後の、状況ですが、まだ結構不正アクセスはありますが、対策以前よりは、かなり
抑えられているようです。
もう一つ。
fail2ban で早く、Ban したければ、 warn を一度に、2回以上、出せば良いと思います。
これが意外と便利かも。本来の script not found or unable to stat を余り制限せずに、
不正アクセスのみ狙い撃ちできそうです。 by nishi 2021.2.3
5. 最終対応。
現在も、頻繁に、IP を変えて、そのたびに、fail2ban で、iptables へ自動登録をしています。
これは、これで良いのですが、余りにしつこいので、今後の対応としては、
Apache のエラーログから、該当 cgi への不正アクセスの IPだけ の一覧を出す。
fail2ban-regex /var/log/httpd/error_log apache-noscript.conf で集計がでるが、通常のエラーも含まれるので、
直接、error_log を、grep で振るいにかけて、python でScriptを作ってIPの一覧を出します。
#grep 'script not found or unable to stat: at' /var/log/httpd/error_log > xxx.txt
その中から、同じネットワークだと思われそうな IP だけ選んで、 ネットワークマスクを、24bit、16bit か 8bit(最強) だけ指定して、
ネットワーク単位で、まとめて、 /etc/sysconfig/iptables に登録する予定です。
これで、一網打尽に接続拒否できるので、それで、しばらく様子見です。
但し、ネットワーク単位で指定する時は、該当 IP の場所を http://www.utrace.de/ https://liveipmap.com/ 等で検索して、
外国籍の確認をしてからにします。
python で、ip を集計する例
comp_ip.py
取り敢えず、24Bit のマスクで、不正Host が多い、ネットワークを 静的 iptables に登録しようかと思います。
下記に、 24Bit のネットワークマスクで、アクセス数 50 以上、Host数が、30 以上のネットワークをピックアップしてみました。
この中から、日本とは関係ない物を対象にします。
現状で、全不正HOST に対して、15 パーセント 程度、静的 iptables で処理して、残りを fail2ban で処理する事になるみたいです。
方針としては、何パーセントを、 静的 iptables で行い、残りを fail2ban で行うかを決めればよいと思います。
python comp_ip.py > results.txt
Total Host Count = 20,226
Drop Host Count = 3,001
Drop rate = 0.148373
Drop ip24 Network Count = 55
Drop ip24 Network Hosts Count = 14,080
Non responsible Host rate = 0.786861
どうやら、不正Host は、 20,226 みたいです。
iptables の記述は、下記の様になります。
/etc/sysconfig/iptables
5. ip の地域を調べる Python スクリプトを作ってみました。
参考にしたのは、https://stackoverflow.com/questions/24678308/how-to-find-location-with-ip-address-in-python
get_ip_region.py