Windowsパソコンのブルートフォースアタック対策【完成編】

powershell logo PowerShell

はじめに Introduction

今回は「Windowsパソコンのブルートフォースアタック対策」の完成編となります。
前回記事のフロー③から、かなり日が経ってしましたが、実はスクリプトは完成し、既に自身のパソコンに導入済みです。なので、今回は一気に
④カウント数が閾値以上のIPをブラックリストIPとして抜粋する
⑤ブラックリストIPをファイヤーウォールで拒否する
⑥以上の処理をタスクスケジューラーで5分毎に自動実行する
まで行きたいと思います。

フロー④カウント数が閾値以上のIPをブラックリストIPとして抜粋する

前回記事でIPごとの出現回数をカウントしましたので、次はブロックする基準となる閾値以上のIPを抜粋して別配列に抽出する工程です。

ループで処理

今回、閾値は3回とします。
ログから抽出したIPリストの配列を$Arr_IP_Countとして、それをループで回して閾値以上だったら、別のブラックリスト配列$Arr_BlockIPListに入れ直すという感じです。


$Arr_BlockIPList = @()
foreach($Val in $Arr_IP_Count){
	$Count = [int]$Val.Count
	if( $Count -gt 3 ){
		$Arr_BlockIPList = $Arr_BlockIPList + $Val.Name
	}
}

ホワイトIPを除外する

私自身もリモートデスクトップで自宅から会社パソコンへ接続する際にパスワードを入力間違いします。
自宅IPがブロックされたら、これまた問題なのでホワイトIPリストを事前に作成しておいて、そのホワイトIPリストは除外する処理を入れます。
ホワイトIPは「127.0.0.1」と「120.110.120.110」とします。
処理は単純で、ホワイトIPが「ne(!=)」で$Arr_BlockIPListに入っていない場合は$Arr_BlockIPListに入れ直すだけです。


# $Arr_BlockIPListにWhiteIPListのIP(自宅IP)が含まれていた場合は除去
$Arr_WhiteIPList = @("127.0.0.1", "120.110.120.110")
foreach($WhiteIP in $Arr_WhiteIPList){
	$Arr_BlockIPList = $Arr_BlockIPList -ne $WhiteIP
}

ブラックリストIPが存在するか確認

上記のホワイトIP除外で、ブラックリストIP配列の中身がからっぽになった場合、このまま処理するとどこかでエラーになるので、ここらへんで配列内を確認しておきます。
からっぽだったらexitで処理を終了します。


$Arr_BlockIPList
if($Arr_BlockIPList.Count -eq 0){
	# 空なので処理終了
	exit
}

フロー⑤ブラックリストIPをファイヤーウォールで拒否する

ファイヤーウォールのルール追加は「netsh advfirewall firewall set rule」で行うのですが、その前に既存ルール(同じ名前のルール)が存在する場合、エラーが発生しないようにチェックして、既存ルールに登録されているルールを抽出して、ブラックリストIP配列に追加してから、ルール追加していきます。


# ----------------------------
# 既存ルールがあるか確認
# ----------------------------
# 既存ルールにRemoteIPだけを追加する事が出来ないので既存ルールのRemoteIPを取得する
$FW_RuleName = "BlockList"
$CurrentRule = netsh advfirewall firewall show rule name="$FW_RuleName"
if( $? ){
	# 同じ名前のルールがある場合
	# リモートIPの8行目を抽出
	$CurrentRemoteIP = $CurrentRule[8] -replace "リモート IP:",""
	$CurrentRemoteIP = $CurrentRemoteIP -replace " ",""
	$CurrentRemoteIP_Arr = $CurrentRemoteIP.split(",")
}

# ----------------------------
# 既存ルールの変更か新規追加か
# ----------------------------
if( [bool]$CurrentRemoteIP_Arr ){
	# RemoteIPを追加
	$Arr_BlockIPList = $Arr_BlockIPList + $CurrentRemoteIP_Arr
	# 重複削除と並び替え
	$Arr_BlockIPList = $Arr_BlockIPList | Sort-Object | Get-Unique
	# 配列IPをカンマ区切り文字列に変換
	$Str_RemoteIP = $Arr_BlockIPList -join ","
	# ルール更新
	netsh advfirewall firewall set rule name="$FW_RuleName" new dir=in action=block protocol=any profile=any remoteip=$Str_RemoteIP
}else{
	# 配列IPをカンマ区切り文字列に変換
	$Str_RemoteIP = $Arr_BlockIPList -join ","
	# ルール作成
	netsh advfirewall firewall add rule name="$FW_RuleName" dir=in action=block protocol=any profile=any remoteip=$Str_RemoteIP
}

フロー⑥以上の処理をタスクスケジューラーで5分毎に自動実行する

あとはタスクスケジューラーに登録して5分毎に実行するだけなんですが、タスクスケジューラーでps1を実行すると、実行時にPowerShellのウインドウが表示されて、他の作業で出来なくなります。
どうもps1を実行すると必ずウンドウが表示されるらしく、色々調べてた結果、タスクスケジューラーでvbsファイルを叩き、vbs内で当該ps1ファイルを呼び出すフローにしました。
vbsはよくわからないので詳しく説明できないのでソースコードだけ貼り付けておきます。


'====================================
' ps1の起動用スクリプト TrigerForPS1_AutoUpdate_FWBlockList.vbs
' powershell実行時のウインドウを表示させないため
'====================================
Option Explicit

'FSOオブジェクト、Shellオブジェクト
Dim objFSO
Dim objWshShell

'VBSパス、VBS格納フォルダ、PS1パス
Dim strVBSPath
Dim strVBSFolder
Dim strPS1Path

'オブジェクト参照
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objWshShell = WScript.CreateObject("WScript.Shell")

'VBSパス、VBS格納フォルダ、PS1パス
strVBSPath = Wscript.ScriptFullName
strVBSFolder = objFSO.GetFile(StrVBSPath).ParentFolder

strPS1Path = strVBSFolder & "\AutoUpdate_FWBlockList.ps1"
Const OPT = "%Systemroot%\System32\WindowsPowerShell\v1.0\powershell.exe -ExecutionPolicy Bypass "

'ここで本題のps1ファイルを呼び出して実行
objWshShell.Run OPT & strPS1Path,0,false

'オブジェクト解放
Set objFSO = Nothing
Set objWshShell = Nothing

'終了
Wscript.Quit

あとがき、整理した実行スクリプト

注意する箇所だけ抜粋して記載してきましたので一連の処理になっていません。
内容を整理した一連の実行スクリプトは下記に記載しておきます。
Windowsパソコンのブルートフォースアタック対策をPowerShell+VBScriptでやってみる

コメント