In my previous company Exchange OWA is ' t published to the internet, so this blog described my first time encountering hacker Trying to hack my new company ' s Active directory passwords. Based on it, I wrote a powershell script running on each CAS servers to use 4625 events identify hacker ' s source IP and BL Ock it.
Environment is Windows Exchange 2013
First of all, some points need to be noticed,
Normally, there is more than 1 CAS servers in production Exchange environment, so the script must is setup on each of the M.
Event ID is 4625, it message contains source IP address and account names.
You probably need to enable auditing first, otherwise probably no 4625 would be logged.
Here is the procedure,
After the script triggered, it'll capture events in Security logs for past minutes, filter out all 4625 events; ea Ch by each, script analysis XML data of event and gets the source IP and target AD account; Use IP as the "key", AD accounts as the "Value", store data in a hash table; At last, script loop every IP address in hash table and block IP address which exceed defined threshold and send warning E Mail to admins.
#Enter script ' s parent directoryset-location (Get-item ($MyInvocation. mycommand.definition)). Directoryname#the time script should back to trace Logs$minutestoback = 10$date = Get-date$strdate = $Date. ToString (' yyyy- Mm-dd ') $End _time = $Date $start_time = $Date. AddMinutes (-$MinutesToBack) #Two log files, script only send logs for past Inutes content$strlogfile = "${strdate}.txt" $strLogFile _e = "${strdate}_e.txt" Set-content-path $strLogFile _e-value $ null# from Fw_whitelist.txt is the IP WhiteList, there always some exceptions$whitelist = @ (Get-content-path ' fw_whitelist.txt '-erroraction:silentlycontinue)
#Define threshold to add in firewall, means total failure authencations, means AD accounts de-duplicated, if one I P address exceeds both values, it'll be in firewall (except those in whitelist) $t _4625_FW = @ (50, 10)
#email Sending Part$mail_from = "$ ($env: COMPUTERNAME) @xxxx. yyyy" $Mail _to = ' [email protected] ', ' [email protected] ' $ Mail_subject = ' Warning email Subject ' $Mail _smtpserver = ' SMTP server address '
The script is based on 4625 events, so I just hardcoded 4625 in script
ps:why use Get-winevent? Cause it has a method to get XML data of one event, I don ' t need to care about locale/language, etc.
#logging some informationadd-log-path $strLogFile _e-value "Catch logs after: $ ($Start _time. ToString (' HH:mm:ss ') "-Type infoadd-log-path $strLogFile _e-value" Catch logs before: $ ($End _time. ToString (' HH:mm:ss ') "-Type Info#get logs from past defined minutes$4625 = @ (get-winevent-filterhashtable @{logname = ' Security '; Id = 4625; StartTime = $Start _time; EndTime = $End _time;} -erroraction:silentlycontinue) #output the number of 4625add-log-path $strLogFile _e-value "Total 4625 logs count: [$ ($4625.count)] " -type Info
The loop each event, the convert to XML data and get IP and the AD account name, the store in Hashtable,
# http://schemas.microsoft.com/win/2004/08/events/event# Index 5 = targetusername# index = ipaddress$s_4625 = @{}f Oreach ($e in $4625) { $xmlData = $IP = $Account = $null $xmlData = [XML] $e. TOXML () $IP = $( if ($xmlData. event.eventdata.data[19]. ' #text '-imatch ' ^\s*$ ') { ' NULL ' } else {$xmlData. event.eventdata.data[19]. ' #text '. Trim () }) $Account = $(if ($xmlData. event.eventdata.data[5]. ' #text '-imatch ' ^\s*$ ') {' NULL '} else {$xmlData. event.eventdata.data[5]. ' #text '. Trim () }) $s _4625.$ ($IP) + = @ ($Account)}
Loop each IP in Hashtable, compare with predefined threshold, adding to firewall or does some other actions.
foreach ($IP in $s _4625. Keys) {$tmp = @ ($s _4625. $IP | Group-object | Sort-object Count-Descending) Add-log-path $strLogFile _e-value "in Past [${minutestoback}] minutes [Ip][total][ad accounts][top 5]:[$IP ][$ ($s _4625. $IP. Count)][$ ($tmp. Count)][$ ($tmp [0..4] |%{$_. Name, $_. Count-join ': '})] "- Type Info if ($s _4625. $IP. Count-ge $t _4625_fw[0]-and $tmp. Count-ge $t _4625_fw[1 ]) {$tmp. Name | Add-content-path "$IP. Log"-encoding Default if ($WhiteList-notcontains $IP ) {$Mail = $tr UE New-netfirewallrule-displayname "Scriptauto_$ip"-profile any-action block-remoteaddress $IP-Direction Inbou ND- erroraction:silentlycontinue if (!$? ) {add-log-path $strLogFile _e-value ' Adding to Firewall failed,cause: '- Type Error add-log-path $strLogFile _e-val UE $Error [0]- type Error} else {add-log-path $strLogFile _e-value "[$IP] added to firewall"- type War Ning}} else {add-log-path $strLogFile _e-value "[$IP] is in whitelist"- Type Info}} else {Add-log -path $strLogFile _e-value "[$IP] not exceed threshold"- Type Info}} / span>
Send out Email notification if necessary,
If ($Mail) { try { send-mailmessage-from $Mail _from-to $Mail _to-subject $Mail _subject-smtpserver $ Mail_smtpserver-body ((get-content $strLogFile _e-encoding Default)-join "' t ' n")-Encoding UTF8 } catch< c7/>{ add-log-path $strLogFile _e-value "Failed to send mail, cause: $ ($Error [0])"-Type Error }}get-conten T-path $strLogFile _e | Add-content-path $strLogFileadd-log-path $strLogFile _e-value ' completed '-type Info
triggered by Task Scheduler every minutes, based on your environment and exprience define the threshould, it works.
Use PowerShell script against password hacking over OWA