如何用Powershell制作垃圾邮件监控隔离工具

363 阅读3分钟
本文阅读对象为Office365 Exchange管理员,鉴于作者水平有限,如有错误,欢迎指正

所需知识

  • Exchange Online 后台管理机制 【传输规则,隔离区,过滤器等】
  • Powershell

背景

由于钓鱼邮件日益猖獗,新型钓鱼邮件(图片,二维码,附件加密文件)层出不穷。我们需要在EOP提供的防护基础之上,更及时的对邮件标题,正文,发件人域名做分析统计,从而更好的去完成钓鱼邮件防护。

现实场景

三月企业内部收到大量退税邮件,标题为“重要通知,请尽快完成退税”,公司要求对所有这类垃圾邮件进行处理。

作为管理员的您,应该如何处理?

  • 无脑版:拦截发件人,把发件人IP拉黑。
  • 粗暴版:用传输规则来对邮件主题为“重要通知”的全部放入隔离区。
  • 粗暴进化版:用传输规则,将非本公司域名发送的邮件主题为“重要通知”的全部邮件放入隔离区。
  • 粗暴进化黄牛版:用传输规则,将非本公司域名发送的邮件主题为“重要通知”的全部邮件放入隔离区。每一个小时查看隔离区,手动进行邮件释放。

作为管理员的您,怎么更好的完成隔离邮件工具?

  1. 事后拦截不如事前预防,(当然事后拦截,可以保证不重复踩坑。)
  2. 隔离区的邮件需要按域名归类分析。
  3. 利用分析好的域名报告,创建白黑名单,并生成白黑名单底稿,确保白名单的邮件不被拦截,黑名单的不被释放,且拦截不会重复出现在报告中。
  4. 手动检查隔离区,释放被错误拦截的邮件
  5. 统计每天释放,拦截的邮件数量,做到心中有数。

需要哪些工具?

image.png

工具流程[3个规则+2个报告]

作者偷懒,白名单规则和关键词拦截规则整合到了一起,实际为2规则+2HTML报告

垃圾邮件流程.png

代码实现流程如下:

邮件命中关键词->关键词拦截的域名是什么【内容参考隔离区域报告样例】->确定拦截无误(人工确认)->手工加传输规则(内容参考“关键字隔离”样例) ->代码读trannsport rule,把新增加的域名写到黑名单文件【内容参考白黑名单txt样例】 ->生成每日邮件拦截报告拦截邮件总数部分【内容参考隔离区邮件每日分类统计报告】

邮件命中关键词->关键词拦截的域名是什么【内容参考隔离区域报告样例】->确定需要释放可(人工确认)->手工释放邮件->手工加传输规则((内容参考“关键字隔离”样例exception部门)) ->代码读传输规则,把新增加的域名写到白名单文件) ->生成每日邮件拦截报告释放邮件总数部分【内容参考隔离区邮件每日分类统计报告】

核心组件

传输规则 ---样例

关键字拦截

image.png

黑名单

image.png

隔离日报

白黑名单txt & 隔离区邮件每日分类统计报告

image.png

隔离区域名报告

image.png

核心代码

`` 感谢各位阅读,欢迎提供宝贵意见

#获取所有隔离区邮件
$pages = 1000
$traces = @()
$FinalReports = @()
$page = 1
do{    
    $traces = Get-QuarantineMessage  -StartReceivedDate $StartTime.AddDays(-1) -EndReceivedDate $StartTime  -PageSize 1000 -Page $page |?{$_.ReleaseStatus -ne 'RELEASED'}
    if($traces.count -eq 0){
        Write-EOPLog "We only have $page page records"
        break
    }
    $page ++
    $FinalReports += $traces
}while($page -lt $pages)


#$fileName = $Logdate + '-MessageTraceHistory' + '.csv'
Write-EOPLog "Check how many domains & mails count for each domain were blocked."
$DomainDetails = $FinalReports |%{$_.SenderAddress.split('@')[1]}|group |select Count,Name
#$Domains = $DomainDetails |select -ExpandProperty Name

#对比白黑名单,去掉重复域名,发送邮件
Write-Host "compare domain info with black list & whitelist domains"
$attachment = "C:\TEMP\QuarantineMessages.CSV"
$FinalReports |Select-Object Subject,MessageId,SenderAddress,RecipientAddress,PolicyName,PolicyType,ReleaseStatusDirection,ReleaseStatus |Export-Csv $attachment -Encoding UTF8 -NoTypeInformation
$AllowDomains =  Get-Content C:\QuarantineDomain\QuarantineWhiteList.TXT
$BlockDomains =  Get-Content C:\QuarantineDomain\QuarantineBlackList.TXT


$IssueDomains = @($DomainDetails |?{$AllowDomains -notcontains $_.Name -and $BlockDomains -notcontains $_.Name})
if($IssueDomains.COUNT -ne 0){
    $body = Format-HtmlTable $IssueDomains -keywords_color @{"Count"=$($CommonColor['Blue'])}
    Send-MailMessage -Subject "($($FinalReports.count)) mails were blocked, Please check their doamin properties" -Body $body  -Attachments $attachment -From <O365> -to <O365MailAddress> -Encoding UTF8 -SmtpServer PARTNER.OUTLOOK.CN
}



#Pre-loading
##==============================================================================================================
if ($MyInvocation.MyCommand.Path -ne $null)
{
    $Script:basePath = Split-Path $MyInvocation.MyCommand.Path
    $Script:scriptname = Split-Path $MyInvocation.MyCommand.Path -Leaf
}
else
{
    $Script:basePath = "."
}


# Initialize HTML table
$className = $scriptName.Split('.')[0].ToUpper()
$HtmlBody = "<TABLE Class=$className border='1' cellpadding='0'cellspacing='0' style='Width:900px'>"
$HtmlBody += "<TR style=background-color:$($CommonColor['LightBlue']);font-weight:bold;font-size:17px>`
                <TD colspan='6' align='center' style=color:$($CommonColor['White'])>Qurantine Message Report</TD></TR>"
##===============================================================================================================

$transportRules = Get-TransportRule
$QuarantineTR = $transportRules |?{$_.Name -eq 'Quarantine-Keyword'}
$WLDomains =  $QuarantineTR.ExceptIfSenderDomainIs
Write-EOPLog "$($WLDomains.count) domains were whitelisted"

$bak = $json.ReportPath.WhiteList + ".Bak"
Copy-Item $json.ReportPath.WhiteList $bak -Force
$HisWLs  = Get-content $json.ReportPath.WhiteList
$DeltaWL = $WLDomains |?{$HisWLs -notcontains $_}
Write-EOPLog "$($DeltaWL.count) domains were found not in history whitelist, add them into history list"
$HisWLs += $DeltaWL
Set-Content $json.ReportPath.WhiteList -Value $HisWLs 


Write-EOPLog "Check QuarantineMessages for date $logdate"

$pages = 1000
$traces = @()
$TotalQMs = @()
$page = 1
do{    
    $QMs =  @(Get-QuarantineMessage -StartReceivedDate  $StartTime.AddDays(-1)  -EndReceivedDate $StartTime -Page $page)
    if($QMs.count -eq 0){
        Write-EOPLog "$page page records were found"
        break
    }
    $page ++
    $TotalQMs += $QMs
}while($page -lt $pages)
 
$ReleasedQMS = @($TotalQMs |?{$_.ReleaseStatus -eq 'RELEASED'})
Write-EOPLog "$($ReleasedQMS.count)/$($TotalQMs.count)  mails were released"


Write-EOPLog "Check how many domains were blocked"
$BlockTRs = $transportRules |?{$_.Name -eq 'BlockDomains'}
$BlockDomains =  $BlockTRs.SenderDomainIs
Write-EOPLog "$($BlockDomains.count) were blocked"


#auto update history whitelist domain list
$bak = $json.ReportPath.BlackList + ".Bak"
Copy-Item $json.ReportPath.BlackList $bak -Force
$HisBDs  = Get-content $json.ReportPath.BlackList
$DeltaBL = $BlockDomains |?{$HisBDs -notcontains $_}
Write-EOPLog "$($DeltaBL.count) domains were found not in history whitelist, add them into history list"
$HisBDs += $DeltaBL
Set-Content $json.ReportPath.BlackList -Value $HisBDs 
#Update History Record of block domains


#export all history data
#Save history data

$data = [pscustomobject]@{"Date" = $Logdate; "TotalQMs"=$TotalQMs.count; "ReleasedQMS"=$ReleasedQMS.count; "BlockDomains" = $BlockDomains.count; "WLDomains" = $WLDomains.count}
$HisdataFolder = Split-Path $json.ReportPath.BlackList -Parent
$data |Export-Csv $HisdataFolder\QuanrentineData.csv -NoTypeInformation -Append -Encoding UTF8


# PostBody 
##==============================================================================================================

#QM  report         
$HtmlBody += "<TR font-weight:bold;font-size:18px>`
                <TD colspan='1.5' align='center' )>TotalQMs</TD>
                <TD colspan='1.5' align='center' )>ReleasedQMS</TD><TD colspan='1.5' align='center'>BlockDomains</TD><TD colspan='1.5' align='center'>WLDomains</TD></TR>"

$HtmlBody += "<TR font-weight:bold;font-size:18px>`
                <TD colspan='1.5' align='center' )>$($TotalQMs.count)</TD><TD colspan='1.5' align='center'>$($ReleasedQMS.count)</TD>`
                <TD colspan='1.5' align='center'>$($BlockDomains.Count)</TD><TD colspan='1.5' align='center'>$($WLDomains.count)</TD></TR>"

$HtmlBody += "</table>"