레이블이 원격데스크탑인 게시물을 표시합니다. 모든 게시물 표시
레이블이 원격데스크탑인 게시물을 표시합니다. 모든 게시물 표시

2014년 5월 23일 금요일

원격데스크탑(RDP) 공격 자동 차단 파워쉘

EvlWatcher 를 사용하여 무작위 공격에 대해서 차단을 진행 했었는데, 이게 윈도우 2012에서는 작동을 안한다.

그래서 이벤트로그를 파악하여 지정된 회수 이상 접속 실패를 발생할 시 윈도우 방화벽에 차단 등록하는 스크립트를 만들었다.
# 이벤트로그를 사용하여 특정 회수 이상 로그인 실패 아이피에 대하여 
# MY BLACKLIST 방화벽 등록
# 2014.05.22 NDH
# version 1.1


###################### Config ######################
#regex2 부분이 영문 윈도우OS 같은 경우 source network address 인가로 바꿔주면 된다.
#MyIp 부분은 내 아이피를 등록하여 내꺼는 막히지 않도록 하는 부분이고,
#deny_count 는 5회이상 접속시도 실패 로그가 있을 시 방화벽에 차단 등록하는 변수이다.
#deny_rule_name 는 윈도우 방화벽에 차단하는 해당 룰 이름이 설정되어 있어야 한다.

#English versoin Windows
#$regex2 = [regex] "Source Network Address:\t(\d+\.\d+\.\d+\.\d+)";
#Korean version Windows
$regex2 = [regex] "원본 네트워크 주소:\t(\d+\.\d+\.\d+\.\d+)";
$MyIp = "111.222.333.*";
$deny_count = 5;
$deny_rule_name = "MY BLACKLIST"
###################### Config ######################

$fw=New-object -comObject HNetCfg.FwPolicy2; # http://blogs.technet.com/b/jamesone/archive/2009/02/18/how-to-manage-the-windows-firewall-settings-with-powershell.aspx
$RuleCHK=$fw.rules | where-object {$_.name –eq $deny_rule_name}
if(!$RuleCHK){ $deny_rule_name + " rule does not generate."; exit; }


$blacklist = @();
$list ="";

$startTime = (get-date);

"-----------------------------"
"log searching Start : " + $startTime;
"-----------------------------"


$ips = get-eventlog Security | Where-Object {$_.EventID -eq 4625 } | foreach {
$m = $regex2.Match($_.Message); $ip = $m.Groups[1].Value; $ip; } | Sort-Object | Tee-Object -Variable list | Get-Unique


if($list.length -gt 0) {
foreach ( $attack_ip in $list)
{
if($attack_ip){
$myrule = $fw.Rules | where {$_.Name -eq $deny_rule_name} | select -First 1; # Potential bug here?

if (-not ($blacklist -contains $attack_ip))
{
$attack_count = ($list | Select-String $attack_ip -SimpleMatch | Measure-Object).count;
if ($attack_count -ge $deny_count) {
if (-not ($myrule.RemoteAddresses -match $attack_ip) -and -not ($attack_ip -like $MyIp))
{
"Found RDP attacking IP on 3389: " + $attack_ip + ", with count: " + $attack_count;
$blacklist = $blacklist + $attack_ip;
"Adding this IP into firewall blocklist: " + $attack_ip;
$myrule.RemoteAddresses+=(","+$attack_ip);
#echo $attack_ip >> C:\BlackListIP.txt

} else {
$attack_ip + " : Already registered IP"
}
}
}
}

}
< # $answer = read-host "`ndo you want delete security event log , yes or no" if ($answer -like "*y*" -and -not $Verbose) { Clear-EventLog -LogName Security cls "Security event log has been deleted" } else { # "`nScript terminated.`nPlease use your testing VM instead.`n" ; exit } #>


}else{
"인증 실패 이벤트 로그가 없습니다."
}

$endTime = (get-date);



"-----------------------------"
"log searching End : " + $endTime;
" 총 걸린 시간 : " + ($endTime - $startTime ) ;
".........실행 완료..........."
"-----------------------------"

regex2 부분이 영문 윈도우OS 같은 경우 source network address 인가로 바꿔주면 된다.
MyIp 부분은 내 아이피를 등록하여 내꺼는 막히지 않도록 하는 부분이고,
deny_count 는 5회이상 접속시도 실패 로그가 있을 시 방화벽에 차단 등록하는 변수이다.
deny_rule_name 는 윈도우 방화벽에 차단하는 해당 룰이 설정되어 있어야 한다. 설정하는 법은 여기

윈도우 2008,2012에서 정상 동작 확인 하였다.

 

스케쥴러 등록해서 사용.
schtasks /create /sc daily /ST 15:00 /tr "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe C:\Users\Administrator\Documents\rdp_block.ps1" /tn "RDP AUTO BLOCK"

 

ps1. 에러 발생.

Found RDP attacking IP on 3389: 1.234.45.48, with count: 23
Adding this IP into firewall blocklist: 1.234.45.48
"RemoteAddresses"을(를) 설정하는 동안 예외가 발생했습니다. "배열 경계가 잘못되었습니다. (예외가 발생한 HRESULT: 0x800706C6)"
위치 D:\관리프로그램\rdp_block.ps1:56 문자:37
+ $myrule. <<<< RemoteAddresses+=(","+$attack_ip);
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : PropertyAssignmentException

RemoteAddresses가 1000가 넘어가니 위의 에러 발생.

 

ps2. netsh.exe advfirewall firewall set rule name="$deny_rule_name" new remoteip="1.34.248.103/255.255.255.255,1.93.2.152/255.255.255.255,1.93.4.12/255.255.255.255,.." 이런식으로 추가 하려고 했으나,
잘못된 IP 주소 또는 주소 키워드를 지정했습니다. << 에러 발생.

결론.RemoteAddresses 가 1000개 이상 넘어 갈 수 없음.

 

ps.2016.05.25

remoteip 등록을 ip range로 등록시 대략 300개 정도를 추가하면 아래 오류가 나온다.
지정한 IP 주소 또는 주소 키워드가 올바르지 않습니다.

역시 limit이 있는 걸로 확인.

깃허브에 한번 등록 해봄.

2014년 1월 28일 화요일

원격데스크탑,MSSQL 공격 자동 차단 스크립트

원격데스크탑 과 mssql 의 기본 포트를 바꾸지 않는 이상, BRUTE FORCE 공격이 지속적으로 들어온다.

해당 포트를 바꾸는 게 가장 최선이지만, 사정상 바꾸기 힘든 경우는 이벤트로그를 보고 해당 IP를 차단하는 방법 밖에 없다.

리눅스 같은 경우 fail2ban 이라는 훌륭한 오픈소스가 존재하여 사용가능 하나 윈도우 같은 경우 그런 프로그램이 없다.

소스포지에서 검색 해보면 비슷한 프로그램들이 나오나, 동작도 제대로 안 되고 에러 투성이 프로그램들만 있어서 사용할 수 있는 게 없다.

물론 상용프로램은 제외.

RDP 공격 같은 경우 EvlWatcher 라는 프로그램이 있는데, 아주 잘 동작 된다.

주의 할점은 관리자 권한으로 설치 해야 서비스 등록 및 방화벽 룰 셋팅이 제대로 설정 된다.

그러나 MSSQL BRUTE FORCE 공격은 따로 막아 주지 않아 조금 아쉽다.

ps.2014.05.21 윈도우2012에서는 동작을 안한다.

-------------------------------------------------------------------------------------

그러다 파워셀 스크립트로 해당 기능을 수행 할 수 있지 않을 까 해서 검색 해 보니, 역시 있었다.

해당 스크립트를 약간 변형 하여 mssql 도 막을 수 있게끔 처리 하였다.

이 스크립트는 이벤트 로그 기록을 참조하여 현재 접속 중인 아이피만 확인 한다.
#$regex1,$regex2값을 서버 아이피로 변경한다.
#예를 들어 서버 아이피가 222.222.222.222 이면
# $regex1 = [regex] "222\.222\.222\.(?:222|51):3389\s+(\d+\.\d+\.\d+\.\d+)";
#제일 마지막은 or 연산이기 때문에 신경 안써도 된다. 한개만 들어가도 됨.

###################### Config ######################
$regex1 = [regex] "111\.222\.333\.(?:140|51):3389\s+(\d+\.\d+\.\d+\.\d+)";
$regex2 = [regex] "원본 네트워크 주소:\t(\d+\.\d+\.\d+\.\d+)";

$regex1_mssql = [regex] "111\.222\.333\.(?:140|51):1433\s+(\d+\.\d+\.\d+\.\d+)";
$regex2_mssql = [regex] "클라이언트: (\d+\.\d+\.\d+\.\d+)";

$MyIp = "123.123.123.123"; #현재 내가 접속한 IP 차단하지 않는다.
$deny_count = 5; #임계값
$loop_time = 30; #loop_time 마다 재 실행.(초)
###################### Config ######################

$tick = 0;
"Start to run at: " + (get-date);

while($True) {
$blacklist = @();

#Port 3389 RDP
"Running... (tick:" + $tick + ")"; $tick+=1;

$a = @()
netstat -no | Select-String ":3389" | ? { $m = $regex1.Match($_);
$ip = $m.Groups[1].Value; if ($m.Success -and $ip -ne $MyIp) {$a = $a + $ip;} }

if ($a.count -gt 0) {
$ips = get-eventlog Security -Newest 1000 | Where-Object {$_.EventID -eq 4625 } | foreach {
$m = $regex2.Match($_.Message); $ip = $m.Groups[1].Value; $ip; } | Sort-Object | Tee-Object -Variable list | Get-Unique

foreach ($ip in $a) { if ($ips -contains $ip) {
if (-not ($blacklist -contains $ip)) {
$attack_count = ($list | Select-String $ip -SimpleMatch | Measure-Object).count;
"Found RDP attacking IP on 3389: " + $ip + ", with count: " + $attack_count;
if ($attack_count -ge $deny_count) {$blacklist = $blacklist + $ip;}
}
}
}
}

#Port 1433 MSSQL

$a = @()
netstat -no | Select-String ":1433" | ? { $m = $regex1_mssql.Match($_);
$ip = $m.Groups[1].Value;
if ($m.Success -and $ip -ne $MyIp) {$a = $a + $ip;} }

if ($a.count -gt 0) {
$ips = get-eventlog Application -Newest 1000 | Where-Object {$_.EventID -eq 18456 -and ($_.Message -like "*sa*" ) } | foreach {
$m = $regex2_mssql.Match($_.Message); $ip = $m.Groups[1].Value; $ip; echo $m; } | Sort-Object | Tee-Object -Variable list | Get-Unique

foreach ($ip in $a) { if ($ips -contains $ip) {
if (-not ($blacklist -contains $ip)) {
$attack_count = ($list | Select-String $ip -SimpleMatch | Measure-Object).count;
"Found MSSQL attacking IP on 1433: " + $ip + ", with count: " + $attack_count;
if ($attack_count -ge $deny_count) {$blacklist = $blacklist + $ip;}
}
}
}
}

<# 주석처리. 사용안함. 미 테스트
#FTP
$MyFtpLogFile1 = "";
$now = (Get-Date).AddMinutes(-5); #check only last 5 mins.
#Get-EventLog has built-in switch for EventID, Message, Time, etc. but using any of these it will be VERY slow.
$count = (Get-EventLog Security -Newest 1000 | Where-Object {$_.EventID -eq 4625 -and $_.Message -match "Logon Type:\s+8" -and
$_.TimeGenerated.CompareTo($now) -gt 0} | Measure-Object).count;
if ($count -gt 50) #threshold
{
$ips = @();
$ips1 = dir "C:\inetpub\logs\LogFiles\FPTSVC2" | Sort-Object -Property LastWriteTime -Descending
| select -First 1 | gc | select -Last 200 | where {$_ -match "An\+error\+occured\+during\+the\+authentication\+process."}
| Select-String -Pattern "(\d+\.\d+\.\d+\.\d+)" | select -ExpandProperty Matches | select -ExpandProperty value | Group-Object
| where {$_.Count -ge 10} | select -ExpandProperty Name;

$ips2 = dir "C:\inetpub\logs\LogFiles\FTPSVC3" | Sort-Object -Property LastWriteTime -Descending
| select -First 1 | gc | select -Last 200 | where {$_ -match "An\+error\+occured\+during\+the\+authentication\+process."}
| Select-String -Pattern "(\d+\.\d+\.\d+\.\d+)" | select -ExpandProperty Matches | select -ExpandProperty value | Group-Object
| where {$_.Count -ge 10} | select -ExpandProperty Name;
$ips += $ips1; $ips += $ips2; $ips = $ips | where {$_ -ne "10.0.0.1"} | Sort-Object | Get-Unique;

foreach ($ip in $ips) {
if (-not ($blacklist -contains $ip)) {
"Found attacking IP on FTP: " + $ip;
$blacklist = $blacklist + $ip;
}
}
}
#>

#Firewall change

<# $current = (netsh advfirewall firewall show rule name="MY BLACKLIST" | where {$_ -match "RemoteIP"}).replace("RemoteIP:", "").replace(" ","").replace("/255.255.255.255",""); #inside $current there is no \r or \n need remove. foreach ($ip in $blacklist) { if (-not ($current -match $ip) -and -not ($ip -like "10.0.0.*")) {"Adding this IP into firewall blocklist: " + $ip; $c= 'netsh advfirewall firewall set rule name="MY BLACKLIST" new RemoteIP="{0},{1}"' -f $ip, $current; Invoke-Expression $c; } } #>

foreach ($ip in $blacklist) {

$fw=New-object -comObject HNetCfg.FwPolicy2; # http://blogs.technet.com/b/jamesone/archive/2009/02/18/how-to-manage-the-windows-firewall-settings-with-powershell.aspx
$myrule = $fw.Rules | where {$_.Name -eq "MY BLACKLIST"} | select -First 1; # Potential bug here?

if (-not ($myrule.RemoteAddresses -match $ip) -and -not ($ip -like "123.123.123.*"))
{"Adding this IP into firewall blocklist: " + $ip;
$myrule.RemoteAddresses+=(","+$ip);
#echo $ip > C:\BlackListIP.txt
}
}

"__________________________________________________________________________________"
Wait-Event -Timeout $loop_time #pause 30 secs

} # end of top while loop.

해당 코드를 Windows PowerShell ISE 실행하여 붙여넣고 실행하면 된다.
실행하기 전에 자기에게 맡게 IP,포트번호 등의 셋팅을 해야 하며, 윈도우 방화벽 규칙(MY BLACKLIST)이 추가 되어 있어야 한다.

 

#등록된 IP 전부를 deny 시키는 방화벽 룰 생성.
netsh advfirewall firewall add rule name="MY BLACKLIST" dir=in action=block localip=any remoteip=107.160.158.70

 107.160.158.70 아이피는 미국 어태커 IP.

 

1. 2008에서만 검증 확인. 2012에서도 가능 할 것으로 보임
2. 2003이하에서는 방화벽 동작 방식이 아예 달라서 사용 할 수 가 없다.
3. MY BLACKLIST 이름으로 차단 규칙 추가해야 한다.
4. FTP 스크립트는 테스트 안 해봄
5. 이벤트 로그가 있어야 하며, 현재 사용자가 계속 공격을 시도하고 있어야지 차단목록에 등록된다.
6. 공격자가 접속을 시도하는 상황에서만 차단 동작을 한다.

해당 스크립트를 저장하여 사용할 경우

오류: 이 시스템에서 스크립트를 실행할 수 없으므로 <Script name> 파일을 로드할 수 없습니다.  라는 메시지가 나타난다.

이럴 경우 파워셀을 관리자 권한으로 실행 후 아래의 명령어를 실행하면 된다.

Set-ExecutionPolicy RemoteSigned

출처

auto_blocking.ps1