#!/bin/sh
export LANG=ja_JP.UTF-8

# Ver 20120104

# 攻撃判断回数（デフォルト10回以上）
NG="10"

# ログ監視の有効化設定　「no」で無効。（デフォルトは全て有効）
SSH_CHECK="yes"
FTP_CHECK="yes"
MAIL_CHECK="yes"
HTTP_CHECK="yes"

# 監視ログファイル
SSH_LOG="/var/log/secure"
FTP_LOG="/var/log/vsftpd.log"
MAIL_LOG="/var/log/maillog"
HTTP_LOG="/var/log/httpd/error_log"
HTTP_LOG2="/var/log/httpd/access_log"

# HTTP監視除外ディレクトリ及びファイル設定（デフォルトでは「/home」ディレクトリ以下に存在するファイル全て）
DIR="/home"

# 攻撃を検知した際にメールを送信するか否か。「no」で無効。（デフォルト有効）
MAILMESSAGES="yes"
# メール送信先アドレス。（デフォルトroot宛）
MAILADDRESS="root"

# 動作ログのファイル名
BR_LOG="/var/log/brute_force_attack.log"

# ホワイトリストファイルの指定
WHITE_LIST="/root/allow_ip"
# ブラックリストファイルの指定
BLACK_LIST="/root/deny_ip"
#BLACK_LIST="/etc/hosts.deny"
# →TCP Wrapperを使用する場合は後者

# 一時ファイル作成ディレクトリの指定
TMP_DIR="/tmp"

# 以降設定不要

# タイムスタンプ設定
LOG_DATE=`date '+%Y/%m/%d %k:%M:%S'`
# 一時ファイル設定
TMP="$TMP_DIR/brute_force_attack.tmp"
TMP2="$TMP_DIR/brute_force_attack2.tmp"

function_CORE()
{
	if [ $1 = "SSH" -a $SSH_CHECK = "yes" ] ; then
		SYSTEM_NAME="$1"
		grep "sshd" $SSH_LOG | grep "Invalid user" | grep -o "[0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+" > $TMP
		grep "sshd" $SSH_LOG | grep "Failed password" | grep -o "[0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+" >> $TMP
	elif [ $1 = "FTP" -a $FTP_CHECK = "yes" ] ; then
		SYSTEM_NAME="$1"
		grep "FAIL LOGIN" $FTP_LOG | grep -o "[0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+" > $TMP
	elif [ $1 = "MAIL" -a $MAIL_CHECK = "yes" ] ; then
		SYSTEM_NAME="$1"
		grep "authentication failure" $MAIL_LOG | grep -o "[0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+" > $TMP
	elif [ $1 = "HTTP" -a $HTTP_CHECK = "yes" ] ; then
		SYSTEM_NAME="$1"
		DIR_LIST=`ls $DIR`
		grep "error" $HTTP_LOG | grep "File does not exist" | grep -v "$DIR_LIST" | grep -o "[0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+" > $TMP
		grep "error" $HTTP_LOG | grep "script" | grep "not found or unable to stat" | grep -o "[0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+" >> $TMP
		grep "\.\./" $HTTP_LOG2 | grep -o "[0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+" >> $TMP
	fi

	cp -pr $TMP $TMP2
	if [ -s $WHITE_LIST ]; then
		WHITE=`cat $WHITE_LIST`
		grep -v "$WHITE" $TMP2 > $TMP
		cp -pr $TMP $TMP2
	fi
	if [ -s $BLACK_LIST ]; then
		BLACK=`cat $BLACK_LIST`
		grep -v "$BLACK" $TMP2 > $TMP
	fi

	LIST=`cat $TMP`
	for IP in $LIST
	do
		COUNT=`grep -w "$IP" $TMP | wc -l`
		if [ $COUNT -ge $NG ] ; then
			if [ -s $WHITE_LIST ]; then
				if [ `grep -w "$IP" $WHITE_LIST` ] ; then
					WHITE_FLAG=1
				else
					WHITE_FLAG=0
				fi
			else
				WHITE_FLAG=0
			fi
			if [ -s $BLACK_LIST ]; then
				if [ `grep -w "$IP" $BLACK_LIST` ] ; then
					BLACK_FLAG=1
				else
					BLACK_FLAG=0
				fi
			else
				BLACK_FLAG=0
			fi
			if [ $WHITE_FLAG -eq 1 -o $BLACK_FLAG -eq 1 ] ; then
				:
			else
				echo "["$LOG_DATE"] ""[$SYSTEM_NAMEログ監視] IPをブラックリストへ登録："$COUNT "回 ["$IP"]" >> $BR_LOG
                                echo $IP >> $BLACK_LIST
                                iptables -I INPUT -s $IP -j DROP
                                UP_FLAG=1
				if [ $MAILMESSAGES = "yes" ] ; then
					echo -e "[$SYSTEM_NAME]ログ監視にて、"$COUNT"回の不正なアクセスログを確認。\n対象ホストのIPアドレスをiptables及びブラックリストファイルへ追加しました。\n\nIPアドレス [$IP]"| mail -s "$0" $MAILADDRESS
				fi
			fi
		fi
	done
# IPTABLES更新時に設定を保存
        if [ $UP_FLAG -eq 1 ] ; then
                /etc/rc.d/init.d/iptables save
        fi
# 一時ファイル削除
        rm -rf $TMP $TMP2
}

# 実行
function_CORE SSH
function_CORE FTP
function_CORE MAIL
function_CORE HTTP

