用powershell脚本自动阻止OWA爆破AD账户密码

This artical will also be published in English: http://www.cnblogs.com/LarryAtCNBlog/p/4820327.html

以前所在的公司OWA什么的都不对外开放倒是从来没有经历过利用Exchange OWA的AD账户密码爆破行为,入职了一个新的公司后OWA对公网开放使用,结果引来了不少的攻击。于是乎做了一个powershell的脚本,数据源基于Exchange CAS上的security日志,用计划任务每10分钟检查一次,超过阀值的则扔进CAS的防火墙block掉。

环境是Windows 2012 / Exchange 2013

另外,需要注意如下几点,

首先CAS服务器一般都不止一台,而且做了NLB,因此脚本要放在每台CAS上都设置执行,

其次验证错误的日志ID号为4625,Message里包括了详细信息如源IP,账户名什么的,

再次CAS服务器上需要开启日志审核,否则可能没有该日志被记录下来。

流程先描述一下,

脚本运行后从Security日志中抓取过去10分钟的条目,过滤出所有4625的条目;逐条对每条4625日志循环,从日志的XML数据中提取出被验证的账户和验证源IP,以IP为key,账户为值,记录于哈希表中;最后对哈希表中的的IP做循环将超过阀值的IP加入防火墙block掉,发出邮件告警。

#进入脚本所在目录
Set-Location (Get-Item ($MyInvocation.MyCommand.Definition)).DirectoryName

#要追踪多长时间之前的日志,和计划任务也要对应好
$MinutesToBack = 10

$Date = Get-Date
$strDate = $Date.ToString(‘yyyy-MM-dd‘)

$End_time = $Date
$Start_time = $Date.AddMinutes(-$MinutesToBack)

#定义两个日志文件,邮件告警时仅会发送过去10分钟的日志内容
$strLogFile = "${strDate}.txt"
$strLogFile_e = "${strDate}_e.txt"

Set-Content -Path $strLogFile_e -Value $null

#从FW_WhiteList.txt读取白名单的IP地址,总归会有些例外,例外的IP地址以每行的形式写在该文本中
$WhiteList = @(Get-Content -Path ‘FW_WhiteList.txt‘ -ErrorAction:SilentlyContinue)
#定义加入防火墙的阀值,50代表验证的密码错误次数,10代表账号去掉重复之后的账户数目,两个值都被超过就会被加入防火墙,白名单中的例外
$t_4625_fw = @(50, 10)
#没什么好说的,邮件告警部分
$Mail_From = "$($env:COMPUTERNAME)@xxxx.yyyy"
$Mail_To = ‘[email protected]‘, ‘[email protected]xxxx.yyyy‘
$Mail_Subject = ‘邮件标题‘

$Mail_SMTPServer = ‘SMTP地址‘

由于日志是直接以4625来判断,我也就直接把4625直接写死在了脚本中。

这里为会什么要用Get-WinEvent呢?因为它有一个方法获取日志的xml格式数据,处理起来有通用的方法,不用管地区语言之类的,

#日志信息
Add-Log -Path $strLogFile_e -Value "Catch logs after : $($Start_time.ToString(‘HH:mm:ss‘))" -Type Info
Add-Log -Path $strLogFile_e -Value "Catch logs before: $($End_time.ToString(‘HH:mm:ss‘))" -Type Info

#从Eventlog中抓过去一段时间的日志
$4625 = @(Get-WinEvent -FilterHashtable @{LogName = ‘Security‘; Id = 4625; StartTime = $Start_time; EndTime = $End_time;} -ErrorAction:SilentlyContinue)
#输出4625日志数目
Add-Log -Path $strLogFile_e -Value "Total 4625 logs count : [$($4625.Count)]" -Type Info

对每条日志循环处理,转换为xml后取出IP和账户名存在hash table中,

# http://schemas.microsoft.com/win/2004/08/events/event
# index 5 = TargetUserName
# index 19 = IpAddress
$s_4625 = @{}
foreach($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)
}

将Hash table中的key也就是IP做循环,以之前定义的阀值相对比后做加入防火墙的操作,

foreach($IP in $s_4625.Keys)
{
    $tmp = @($s_4625.$IP | Group-Object | Sort-Object Count -Descending)
    Add-Log -Path $strLogFile_e -Value "过去[${MinutesToBack}]分钟[IP地址][错误量][账户][前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 = $true
            New-NetFirewallRule -DisplayName "ScriptAuto_$IP" -Profile Any -Action Block -RemoteAddress $IP -Direction Inbound -ErrorAction:SilentlyContinue
            if(!$?)
            {
                Add-Log -Path $strLogFile_e -Value ‘加入firewall失败,原因:‘ -Type Error
                Add-Log -Path $strLogFile_e -Value $Error[0] -Type Error
            }
            else
            {
                Add-Log -Path $strLogFile_e -Value "[$IP]加入防火墙" -Type Warning
            }
        }
        else
        {
            Add-Log -Path $strLogFile_e -Value "[$IP]在白名单中" -Type Info
        }
    }
    else
    {
        Add-Log -Path $strLogFile_e -Value "[$IP]未超过阀值" -Type Info
    }
}

最后如果有必要发出邮件的话就通过smtp发出,

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
    {
        Add-Log -Path $strLogFile_e -Value "Failed to send mail, cause: $($Error[0])" -Type Error
    }
}

Get-Content -Path $strLogFile_e | Add-Content -Path $strLogFile
Add-Log -Path $strLogFile_e -Value ‘Completed‘ -Type Info

计划任务中设置每10分钟跑一次,根据自己环境和经验设置好阀值,最近想通过OWA爆破密码的IP也是各种被封掉,效果还是明显的。

时间: 2024-10-24 15:28:49

用powershell脚本自动阻止OWA爆破AD账户密码的相关文章

同时新建AD账号、邮箱、添加通讯组的powershell脚本

根据公司的需要,写了一个同时新建AD账号.邮箱.添加通讯组的powershell脚本,首先需要编辑csv文件,格式如下: 代码如下,加入了重名判断.添加到组延迟6秒运行.失败后重现尝试4次功能: Import-Module ActiveDirectory $erroractionpreference = "SilentlyContinue" #判断是否有重名账号存在 $f = $False Import-Csv -Path D:\newuser\Info.csv | foreach {

如何让powershell脚本可以在计划任务中自动执行

今天在测试PS脚本的时候,,突然想到,让脚本每天定时自动执行,因为以前有做过Bat的经验,就想,这个还不简单,直接在windows的计划任务中创建任务不就可以了吗?于是就动手测试了,结果发现悲剧了,PS1后缀的脚本无法直接在计划任务中执行好吧,只能找度娘出马了,于是找了这种方法,自己记录一下1:我这边在我的电脑上写了一个简单的获取服务的脚本,之后保存为services.ps1这样的名称        get-service  | where{$_.status -eq "running"

PowerShell脚本授权最佳实践

[TechTarget中国原创] Windows PowerShell已成为微软在Windows Server上提供的首选管理界面.因为深度整合到Windows Server操作系统,PowerShell表面看上去可以不受任何限制做任何事情.然而,实际上能做得并没有那么多. Windows Server最好用的功能之一就是可以运行脚本.PowerShell脚本允许代码重复使用,并支持运行复杂的命令序列,这是其他方式无法实现的. PowerShell脚本的编写者必须关注的一个大问题就是授权.Pow

Day11.开发脚本自动部署及监控

1.编写脚本自动部署反向代理.web.nfs:要求:I.部署nginx反向代理三个web服务,调度算法使用加权轮询: II.所有web服务使用共享存储nfs,保证所有web都对其有读写权限,保证数据一致性: 2.编写监控脚本,监控nginx,nfs存活状态,内存使用率检测,异常则发送报警邮件 准备发送邮件的工具: 监控脚本的编写: 继续编写刚才的脚本编写,加入邮件功能 3.编写计划任务,定时运行监控脚本,完成监控操作

开发脚本自动部署及监控

1.编写脚本自动部署反向代理.web.nfs: #!/bin/bash yum install epel-release -y yum install nginx -y ps aux |grep nginx |grep -v 'grep' if [ $? -ne 0 ] then systemctl start nginx fi sed -ri '/^http/a upstream xzhweb\{' /etc/nginx/nginx.conf sed -ri '/^upstream/a ser

Shell脚本-----自动备份Mysql数据库

脚本的整体思路 1.定义需要的变量 2.利用for循环备份需要备份的库,并以库名-当天日期.sql命名,并记录相关日志 3.建立备份当天的日期的目录,向备份的Sql文件移动到该目录 4.压缩打包该目录,以节省空间,打包成功后删除该目录 5.备份目录只备份七天的数据库,第八天删除第一天的备份,目录只会存在连续七天的备份文件 6.查找备份目录下的.log日志文件,超过七天的删除 #!/bin/bash mysql_bin=/usr/local/tdoa/mysql/bin/mysqldump use

powershell脚本自动检核DAG

经常检查DAG复制是Exchange邮箱管理员日常任务之一,以前每天上去看也挺烦的,尤其数据库比较多的情况下.下图就是"好心"的台北同事经常提醒我检查,我的天,这要是通过EMC看还不累死.还CC我领导,搞的人怪没面子的. 几条需要注意: 一.此脚本放在exchange任一台主机运行即可. 二.Add-PSSnapin Microsoft.Exchange.Management.PowerShell.E2010 添加Exchange管理模块 三.用Get-MailboxDatabase

iOS开发进阶 - 使用shell脚本自动打包上传到fir.im上-b

用fir.im测试已经好长时间了,感觉每次打包上传都很麻烦,想着是不是可以用脚本自动打包,在网上搜了一下确实有,下面总结一下如何使用脚本自动打包上传到fir.im,以及打包过程中遇到的问题和解决办法 相关资料和下载 首先是打包脚本的下载地址,这个是我找到的比较全的一个,里面有很多不同功能的shell脚本,亲测好用,传送门:https://github.com/heyuan110/BashShell?spm=5176.100239.blogcont5028.4.kFcLtR 还有关于fir指令的一

云服务程序在启动的时候执行Powershell脚本

如果在云服务程序启动时候,需要执行Powershell脚本,我们需要将脚本嵌入到程序中,并且编写一个cmd来执行这个脚本,具体如下: 1.编写测试的Powershell脚本:每隔10分钟 检测dns $TimeStart = Get-Date $TimeEnd = $timeStart.addminutes(1440) $name = "cnppmedia.blob.core.chinacloudapi.cn." $result = "d:\nslookuplog.txt&q