ソース管理等を使った改ざん検知

最近、サイトに侵入して、
クレカのフォームを改ざんし、自サイトにカード番号を送信するといういたずらが流行っているようです。

一見正しく動いているプログラムが、実は改ざんされていることになかなか気が付きにくいものです。
運営されている会社も、クレジットカード会社から連絡があったりして発覚しているようです。

一方で、最近の開発環境はソース管理が導入されています。
デプロイツールも導入されているところがあるでしょう。

正しいソースコードがあるならば、それと比較して改ざんを簡単に検知できるのではないだろうか?
と、いうことで、ソース管理等を使った改ざん検知システムを作ってみた。

案1 ソース管理そのものを使った diff(ただしあまり安全ではない)

とても簡単な改ざん検知
例えば、SVN とかのソース管理で、サーバを管理している場合
(たぶん GITでも同じことができるはず)

#!/bin/sh
DIRGET_DIRECTORY="/var/www/vhost/example.com"
MAIL_TO="alert@example.com"
SUBJECT="[DIFF ERROR!]"
SCS_PROGRAM="svn"

#IS_ALIVE=`ps aux | grep "${SCS_PROGRAM} " | grep -v grep  | wc -l`
#if [ $IS_ALIVE -ge 1 ]; then
#	exit 1
#fi

cd $DIRGET_DIRECTORY
DF=`${SCS_PROGRAM} diff | wc -l`
if [ $DF -eq 0 ] ; then
	exit 0
fi

MAILTEMPFILE=`mktemp`
echo "To: ${MAIL_TO}"  >> $MAILTEMPFILE
echo "Subject: ${SUBJECT} ${HOSTNAME} ${DIRGET_DIRECTORY}"  >> $MAILTEMPFILE
echo "" >> $MAILTEMPFILE
echo "${SUBJECT} ${HOSTNAME} ${DIRGET_DIRECTORY}"  >> $MAILTEMPFILE
echo "-------------------------------------------" >> $MAILTEMPFILE
${SCS_PROGRAM} diff >> $MAILTEMPFILE

sendmail $MAIL_TO < $MAILTEMPFILE

/bin/rm $MAILTEMPFILE
exit 100

これで、改ざん者がサイトを改ざんしたら、
変更点が発生し、メールで通知を投げることが出来ます。

ただし、この方法では、本番のwebディレクトリにソース管理機能があるので、あまりよくありません。
まずは、apacheの設定等で、 .svn や .git などへのアクセスを遮断しないと危険です。
次に、逆流して侵入者に commitされないように、ユーザ権限を振らないといけないでしょう。

案2 deployツールを使った場合

deployツールをつかった場合はどうか?
1日1回ならともかく、10分に1回などの場合は、
毎回デプロイツールがチェックに行くのは現実的ではありません。

別のディレクトリにも同一内容をデプロイして、
そこと比較することが考えられます。
ただ、別のディレクトリにもデプロイできるか?というデプロイツールの制約の壁があります。

例えば、

本番
/var/www/vhost/example.com

デプロイしたときについでに取ったコピー
/var/backup/example.com

だったとすれば、以下のようなシェルスクリプトで、diffを使って比較できます。

#!/bin/sh
DIRGET_DIRECTORY="/var/www/vhost/example.com"
COPY_DIRECTORY="/var/backup/example.com"
MAIL_TO="alert@example.com"
SUBJECT="[DIFF ERROR!]"

#Ignore when deploying.
#IS_ALIVE=`ps aux | grep "rsync " | grep -v grep  | wc -l`
#if [ $IS_ALIVE -ge 1 ]; then
#	exit 1
#fi

LANG=C
DF=`diff -rq ${COPY_DIRECTORY} ${DIRGET_DIRECTORY} | grep '^Files' | wc -l`
if [ $DF -eq 0 ] ; then
	exit 0
fi

MAILTEMPFILE=`mktemp`
echo "To: ${MAIL_TO}"  >> $MAILTEMPFILE
echo "Subject: ${SUBJECT} ${HOSTNAME} ${DIRGET_DIRECTORY}"  >> $MAILTEMPFILE
echo "" >> $MAILTEMPFILE
echo "${SUBJECT} ${HOSTNAME} ${DIRGET_DIRECTORY}"  >> $MAILTEMPFILE
echo "-------------------------------------------" >> $MAILTEMPFILE
diff -rq ${COPY_DIRECTORY} ${DIRGET_DIRECTORY} | grep '^Files' >> $MAILTEMPFILE

sendmail $MAIL_TO < $MAILTEMPFILE

/bin/rm $MAILTEMPFILE
exit 100

diff | grep '^Files' と、しているのは、
webroot以下に本番にしか無いデータファイルがある場合を考慮してです。
アップロードされた画像とかがおいてあると、片方にしかないよという暴発がありえるので、このようにしています。

あとはcronで定期実行するようにすると、
改ざん検知ができるようになると思います。

どれくらいの頻度でチェックするべきかは、
負荷と相談してやるべきですね。


これで、万が一にもサイトが改ざんされたとしても、早期に気がつけるようになります。
早期に気がつけるということは、被害が拡大する前に即サイトを修正することもできるでしょう。
場合によって、改ざんした人が改ざんをしていろいろ試している時に、止められて被害ゼロということもあるかもしれません。