레이블이 PowerShell인 게시물을 표시합니다. 모든 게시물 표시
레이블이 PowerShell인 게시물을 표시합니다. 모든 게시물 표시

2016년 12월 8일 목요일

이벤트 실패 로그에 있는 공격 IP 뽑아내기.

이벤트 로그에 지속적인 공격이 들어오는 게 보인다. ㅅㅂㄹㄷ

이벤트 로그를 한개 한개 뒤져서 체크 하기가 힘들다.

예전에 작성했던 자동 차단 파워쉘을 조금 수정해서 목록만 뽑도록 만듬.

원격데스크탑(RDP)

###################### Config ######################

#아래의 형식으로 있는 IP 주소를 가져오기 위한 정규식
$regex2 = [regex] "원본 네트워크 주소:\t(\d+\.\d+\.\d+\.\d+)";

#아래 값 이상인 것만 차단 리스트($blacklist)에 추가
$deny_count = 5

#이벤트 로그가 많을 경우 어마무시하게 오래 걸림. 불러올 로그 개수
$newest = 1000

###################### Config ######################

##최종 공격자 IP 배열
$blacklist = @();

#초기화
$list=""

#메인 명령어( 이 스크립트의 코어임.)
#이벤트 실패 로그인 4625 ID 에서 아이피가 있는 message 부분에서 IP만 뽑아낸다.
#list 변수 = 이벤트 실패 로그 아이피 (중복포함)
$ips = get-eventlog Security -Newest $newest | Where-Object {$_.EventID -eq 4625 } | foreach {
$m = $regex2.Match($_.Message); $ip = $m.Groups[1].Value; $ip;
} | Sort-Object | Tee-Object -Variable list | Get-Unique
# ($list | Select-String 211.217.48.254 -SimpleMatch | Measure-Object).count;

foreach ($forIp in $ips) {
#로그인 실패 이벤트 로그 중에는 IP가 없는 것들도 있는 데, 그런 경우
#빈값이 들어오므로 continue로 넘겨준다.
if([string]::IsNullOrEmpty($forIp))
{
#'continue';
continue;
}
if (-not ($blacklist -contains $forIp)) {
$attack_count = ($list | Select-String $forIp -SimpleMatch | Measure-Object).count;
"Found RDP attacking IP on 3389: " + $forIp + ", with count: " + $attack_count;
if ($attack_count -ge $deny_count) {$blacklist = $blacklist + $forIp;}
}
}
""
"========$deny_count 회 이상 실패 IP==============="
#방화벽 등록 명령어를 이용해서 자동 차단으로 해도 된다.
$blacklist

 

MSSQL
로그 예제 : 사용자 'sa'이(가) 로그인하지 못했습니다. 원인: 암호가 제공된 로그인의 암호와 일치하지 않습니다. [클라이언트: 211.41.41.203]

###################### Config ######################

#아래의 형식으로 있는 IP 주소를 가져오기 위한 정규식
$regex2 = [regex] "클라이언트: (\d+\.\d+\.\d+\.\d+)";

#아래 값 이상인 것만 차단 리스트($blacklist)에 추가
$deny_count = 5;

#이벤트 로그가 많을 경우 어마무시하게 오래 걸림. 불러올 로그 개수
$newest = 1000

###################### Config ######################

##최종 공격자 IP 배열
$blacklist = @();

#초기화
$list=""

#메인 명령어( 이 스크립트의 코어임.)
#이벤트 실패 로그인 18456 ID 에서 아이피가 있는 message 부분에서 IP만 뽑아낸다.
#list 변수 = 이벤트 실패 로그 아이피 (중복포함)
$ips = get-eventlog Application -Newest $newest | Where-Object {$_.EventID -eq 18456 } | foreach {
$m = $regex2.Match($_.Message); $ip = $m.Groups[1].Value; $ip;
} | Sort-Object | Tee-Object -Variable list | Get-Unique
# ($list | Select-String 211.217.48.254 -SimpleMatch | Measure-Object).count;

foreach ($forIp in $ips) {
#로그인 실패 이벤트 로그 중에는 IP가 없는 것들도 있는 데, 그런 경우
#빈값이 들어오므로 continue로 넘겨준다.
if([string]::IsNullOrEmpty($forIp))
{
#'continue';
continue;
}
if (-not ($blacklist -contains $forIp)) {
$attack_count = ($list | Select-String $forIp -SimpleMatch | Measure-Object).count;
"Found RDP attacking IP on MSSQL: " + $forIp + ", with count: " + $attack_count;
if ($attack_count -ge $deny_count) {$blacklist = $blacklist + $forIp;}
}
}
""
"========$deny_count 회 이상 실패 IP==============="
#방화벽 등록 명령어를 이용해서 자동 차단으로 해도 된다.
$blacklist

 


언제 한번 날 잡아서 완성형으로 만들어야 될 듯...

2016년 10월 22일 토요일

파워쉘로 메일 전송 테스트

$From = "fromaddress@domain.com"
$To = "toaddress@domain.com"
$SMTPServer = "smtp.gmail.com"
$SMTPPort = "587"
$Username = "username@gmail.com"
$Password = "gmailpassword"
$subject = "Email Subject"
$body = "Insert body text here"

$smtp = New-Object System.Net.Mail.SmtpClient($SMTPServer, $SMTPPort);

$smtp.EnableSSL = $true
$smtp.Credentials = New-Object System.Net.NetworkCredential($Username, $Password);
$smtp.Send($From, $To, $subject, $body);

출처

2016년 10월 21일 금요일

파워쉘 실행시 에러

C:\Users\77100606\Downloads\Get-GeoIP.ps1 파일을 로드할 수 없습니다. C:\Users\77100606\Downloads\Get-GeoIP.ps1 파일에 디지털 서명하지 않았습니다. 스크립트가 시스템에서 실행되지 않습니다. 자세한 내용은 "get-help about_signing"을 참조하십시오..
At line:0 char:0

파워쉘 스크립트는 그 권한이 막강하기 때문에 파일마다 디지털 사인은 해야 한다.

그러나 인터넷에 일반사용자 가 사인까지 할리는 만무하다.

해서 그런 스크립트를 싫행 하려면 정책 변경을 해야 한다.
Set-ExecutionPolicy RemoteSigned

Restricted : 파워쉘 실행 정책 기본 값. 명령어 하나씩 실행 가능. 스크립트를 불러와 실행하지 못함
AllSigned : 오직 신뢰된 배포자에 의해 싸인된 스크립트만 실행가능
RemoteSigned : 로컬에서 생성한 스크립트만 실행가능. 다운로드받은 스크립트는 신뢰된 배포자에 의해 싸인된 것만 실행 가능
Unrestricted : 모든 스크립트 실행 가능
ByPass : 아무것도 차단되지 않고 경고나 메시지 없이 실행가능
Undefined : 정책이 적용되지 않음. 기본 정책이 적용됨(Restricted)

출처
출처

2016년 5월 26일 목요일

윈도우 방화벽 해외 IP 차단.

윈도우 방화벽을 이용해서 한국에서의 접속 IP 만 접근 가능 하도록 파워쉘로 만들었다.


특정 포트를 지정해 줘야 한다. 기존에 allow되어 있던 부분은 사용안함 처리 해야 한다.


 


소스는 아래와 같다.


#get-help about_signing 참조하라는 에러 발생시,
#Set-ExecutionPolicy RemoteSigned  실행.


#############Config#################
$countryCode="KR" #차단을 하지 않을 나라의 CountryCode
$geoIPcsvPath="c:\GeoIPCountryWhoisPaid.csv"
#$geoIPcsvPath="\GeoIPCountryWhois.csv" #ISE에서 실행시 찾지 못함.
$ruleName="allowCountry"
$allowPort="3389,1433"
#############Config#################


$geoData=Import-Csv $geoIPcsvPath -header sIP, eIP, cc |  where-object {$_.cc –eq $countryCode} 
$geoDataTotal=$geoData.Count
$remoteIP=""


######  룰이 있는 지 체크 ########
function ruleExistsChk ($ruleName)
{
    $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 $ruleName}
    if(!$RuleCHK){
    #$deny_rule_name + " 룰이 생성되어 있지 않습니다."; exit; 
    #허용하는 룰 생성.
    netsh advfirewall firewall add rule name="$ruleName" localport="$allowPort" protocol=TCP localip=any dir=in action=allow profile="any" interfacetype="any"
    }
}
######  룰이 있는 지 체크 ########


$count=1
foreach ($geoIP in $geoData)
{
    #$remoteIP+=@($geoIP.sIP+"-"+$geoIP.eIP+",") #배열로 저장.
     $remoteIP+=$geoIP.sIP+"-"+$geoIP.eIP+","
     try {

        
         #remoteAddr가 한개의 룰에 약 300개 이상이면 등록이 안됨. 안전하게 200으로 설정.
        if(($count%200) -eq 0)
        {
            $makeRuleName=$ruleName+$countryCode+$count
            ruleExistsChk($makeRuleName)
            netsh advfirewall firewall set rule name=$makeRuleName new remoteip="$remoteIP"
            $remoteIP=""
        }elseif($geoDataTotal -eq $count){
            $makeRuleName=$ruleName+$countryCode+$count
            ruleExistsChk($makeRuleName)
            netsh advfirewall firewall set rule name=$makeRuleName new remoteip="$remoteIP"
            $remoteIP=""
        }

    }catch {
      Write-Warning "Error occured: $_"
    }
     $count++

}


GeoIPCountryWhois.csv을 이용한 나라별 윈도우 방화벽 차단 등록.

나라별방화벽차단등록

www.2cpu.co.kr 에서 제작된 중국쪽 ip대역 차단 스크립트를 보게되었다.

실제로 GeoIPCountryWhois.csv 파일에 있는 걸 스크립트로 만든 거라서

GeoIPCountryWhois 파일이 업데이트 되면 다시 수정 해야 하는 번거로움이 있어서

파워쉘 스크립트로 만들었다.

처음에는 vb 로 만들려고 했으나, vb 자체의 자료도 별로 없고, 기존 프로그래밍 언어와 다른 점이 너무 많아서 powershell 로 바꿨다.

요즈음의 왠만한 윈도우 서버는 powershell 을 지원하니 왠만해서는 될 듯하다. 테스트는 안 해봤다.

최신의 GeoIPCountryWhois.csv 파일은 여기서 다운 받을 수 있다.

근데 파일 자체가 최신이 아니다. 2년전 자료이다.

진짜 최신자료는 www.maxmind.com 에서 유료로 받을 수 있다.



소스
#문의는 http://blog.netchk.net/
#############Config#################
$countryCode="CN" #차단할 나라의 CountryCode
#$geoIPcvsPath="c:\GeoIPCountryWhois.csv"
$geoIPcvsPath="\GeoIPCountryWhois.csv"
$ruleName="blockCountry"
#############Config#################


$geoData=Import-Csv $geoIPcvsPath -header sIP, eIP, start, end, cc, cn |  where-object {$_.cc –eq $countryCode} 
$geoDataTotal=$geoData.Count
$remoteIP=""


######  룰이 있는 지 체크 ########
function ruleExistsChk ($ruleName)
{
    $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 $ruleName}
    if(!$RuleCHK){
    #$deny_rule_name + " 룰이 생성되어 있지 않습니다."; exit; 
    netsh advfirewall firewall add rule name="$ruleName" localip=any dir=in action=block profile="any" interfacetype="any"
    }
}
######  룰이 있는 지 체크 ########


$count=1
foreach ($geoIP in $geoData)
{
    #$remoteIP+=@($geoIP.sIP+"-"+$geoIP.eIP+",") #배열로 저장.
     $remoteIP+=$geoIP.sIP+"-"+$geoIP.eIP+","
     
     #remoteAddr가 한개의 룰에 약 300개 이상이면 등록이 안됨. 안전하게 200으로 설정.
    if(($count%200) -eq 0)
    {
        $makeRuleName=$ruleName+$countryCode+$count
        ruleExistsChk($makeRuleName)
        netsh advfirewall firewall set rule name=$makeRuleName new remoteip="$remoteIP"
        $remoteIP=""
    }elseif($geoDataTotal -eq $count){
        $makeRuleName=$ruleName+$countryCode+$count
        ruleExistsChk($makeRuleName)
        netsh advfirewall firewall set rule name=$makeRuleName new remoteip="$remoteIP"
        $remoteIP=""
    }

     $count++

}

예전 차단하는 스크립트에서도 썼지만 remoteAddress 에 limit 이 걸려 있다.

단일 IP는 약 1000개 인데, IP range는 약 300개 정도이다.

그래서 200개 단위로 rule을 다시 생성한다.



ps. 위의 소스를 이용해서 한국만 허용하고 해외는 모두 차단 하는 스크립트를 만들었는 데, 안된다. 리눅스의 iptable 같은 경우 순서에 따라 적용이 되기 때문에 모든 IP 차단, 한국 IP 허용 으로 하면 된다.

윈도우 방화벽은 순서에 따라 적용되지 않는다. 한국 IP 허용, 모든 IP 차단 해도 안되고, 순서를 바꿔서 등록 해도 역시 안된다.

방법은 있는데, 기존에 등록되어 있는 허용 포트 부분을 모두 지정하는 것이다. 한국 IP 만 등록해 놓은 룰을 적용한 후, local port 를 설정하고, 기존에 적용되어 있던 부분을 삭제 하면 된다.

문제는 포트별로 다른 IP 차단이 안된다는 점. 해외 IP를 전부 등록해야...;;

ps2. 방화벽 규칙에서 여러 룰에서 차단과 허용이 둘다 있으면 차단 시킨다.

https://technet.microsoft.com/ko-kr/library/cc755191(v=ws.10).aspx

2016년 1월 27일 수요일

윈도우 서버 접속 사용자, IP 확인.

윈도우 이벤트 로그를 통한 접속 사용자 확인 하는 파워쉘.

윈도우에서 제공하는 게 있음

logonactivity.ps1

출처

2014년 10월 28일 화요일

현재 접속자 중 해외에서 접속한 사람이 있는 지 확인 하는 파워쉘 스크립트.

이 스크립트를 사용하려면 kisa에서 whois openapi key 발급 받아야 됨.


###################### Config ######################
#kisa 에서 발급받은 api key
#http://whois.kisa.or.kr/kor/whois/openAPI_KeyCre.jsp
$kisaKey = "00000000000000000000"
###################### Config ######################




###### kisa open api를 이용해 한국 아이피인지 체크 ########
function whoisKR ($IpAddress)
{
if(-not $IpAddress) {echo "input ip address"; return}

$countryCode = ""

# Do whois lookup with ARIN on the IP address, do crude error check.
$webclient = new-object System.Net.WebClient
$webclient.Encoding = [System.Text.Encoding]::UTF8
[xml][/xml] $ipxml = $webclient.DownloadString("http://whois.kisa.or.kr/openapi/ipascc.jsp?key=$kisaKey&query=$IpAddress&answer=xml")
if (-not $?) { echo "error" ; return }

$countryCode = $ipxml.whois.countryCode

if($countryCode -ne "KR")
{
return $FALSE #NOT KR
}else{
return $TRUE #KR
}

}
###### kisa open api를 이용해 한국 아이피인지 체크 ########


#whoisKR
#whoisKR "222.122.20.1"
#whoisKR "54.217.151.196"


###### MAIN
###### netstat 를 통해 외부 IP가 한국 꺼인지 아닌 지 체크. ########
###### 한국이 아니면 해당 IP를 deny 룰에 적용. ########
###### 참조 : http://www.lazywinadmin.com/2014/08/powershell-parse-this-netstatexe.html
$ForeignAddressIP = @()

# Get the output of netstat
$data = netstat -nat

# Keep only the line with the data (we remove the first lines)
$data = $data[5..$data.count]

# Each line need to be splitted and get rid of unnecessary spaces
foreach ($line in $data)
{
# Get rid of the first whitespaces, at the beginning of the line
$line = $line -replace '^\s+', ''

# Split each property on whitespaces block
$line = $line -split '\s+'

$temp = ($line[2] -split ":")[0]

#예외처리
switch ($temp)
{
"0.0.0.0" {}
"127.0.0.1" {}
"*"{}
"["{}
default {$ForeignAddressIP += $temp}
}

}


$ForeignAddressIP = $ForeignAddressIP | Sort-Object -unique
foreach( $checkIP in $ForeignAddressIP)
{
#한국이면 true, 아니면 false
if(whoisKR $checkIP)
{
'한국 IP : ' + $checkIP
}else{
'!!!!경고, 한국 IP 아님!!!! : ' + $checkIP
}
'-----------------------'

}

cmd /c pause | out-null

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