热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

看我如何检测密码抓取神器Mimikatz的执行

 前言此前,我阅读了CyberWarDog的威胁主动出击(Threat Hunting)文章,并且还偶然发现并仔细阅读了他的“寻找内存中的Mimikatz”系列文章。其中,用于构建签名的方法似乎非常简

 

前言

此前,我阅读了CyberWarDog的威胁主动出击(Threat Hunting)文章,并且还偶然发现并仔细阅读了他的“寻找内存中的Mimikatz”系列文章。其中,用于构建签名的方法似乎非常简单,并且在对恶意工具的分析过程中,已经解决了寻找入口的这一障碍。

用于检测Mimikatz的方法被称为分组(Grouping),具体来讲,是获取一组特殊的Artifacts,并且识别多个特殊的Artifacts同时出现的时间。在本文中,我们将参考CyberWarDog的方法,来探讨如何使用SysmonELK Stack对密码抓取神器Mimikatz进行检测与告警。

我们假设你已经拥有一个ELK Stack,并且配置了ElastAlert集成。这样,就可以在几分钟的时间里迅速将HELK搭建成功(ElastAlert后续会与其合并)。

一开始,我认为这并不是一个完美的解决方案。其思路很简单,如果在同一个主机中,有5DLL1秒钟之内被接连访问,那么就发出告警。然而,很不巧,ElastAlert没有内置这个功能,同样Python也没有。

 

Sysmon配置

我使用的Sysmon配置是Ion-Storm Sysmon Config,源文件位于: https://github.com/ion-storm/sysmon-config/blob/master/sysmonconfig-export.xml 。默认情况下,正确的事件将会被转发。其中的第571-579行如下:


cOndition="is">C:WindowsSystem32WinSCard.dll

cOndition="is">C:WindowsSystem32cryptdll.dll

cOndition="is">C:WindowsSystem32hid.dll

cOndition="is">C:WindowsSystem32samlib.dll

cOndition="is">C:WindowsSystem32vaultcli.dll

cOndition="is">WMINet_Utils.dll

cOndition="contains">Temp

最开始,我们需要写一个脚本,来进行一些逻辑上的验证。我试图让Python工具尽可能模块化,这样我们就可以轻松地对其他事件“分组”进行告警。

我们将要检测的5DLL是:

Cryptdll.dll

Hid.dll

Samlib.dll

Vaultcli.dll

Winscard.dll

在这里,还存在误报的一种可能性,如果恰巧这些DLL1分钟之内被正常访问,那么同样会产生告警。

 

告警脚本

在运行ELK Stack的服务器上,我们首先创建py-alert.py并编辑:

sudo
nano /bin/py-alert.py

py-alert.py的源代码如下:

#!/usr/bin/python
 
import sys
from argparse import ArgumentParser
import datetime
import requests
import subprocess
import os
time = datetime.datetime.now().strftime("%H:%M-%y-%m-%d")
def print_banner():
    print('''npy-alert.py is a tool written to
expand the functionality of ElastAlert
    Author: Jordan Potti
    Twitter: @ok_bye_nown'''
    )
 
def main():
    global arguments
    parser = ArgumentParser()
    parser.add_argument("-T",
dest="action",required=True,help="Action Type: Send Alert (S) or
Data Write (D)")
    parser.add_argument("-a",
dest="detection",required=True,help="Alert Name")
    parser.add_argument("-c",
dest="host",required=False,help="Host to record")
    parser.add_argument("-S",
dest="slack",required=False,help="Slack Web Hook")
    parser.add_argument("-t",
dest="tripped",required=False,help="Number or Hosts needed to
alert")
 
    if len(sys.argv) == 1:
        print_banner()
        parser.error("No arguments
given.")
        parser.print_usage
        sys.exit()
 
    arguments = parser.parse_args()
    outfile = '/tmp/'+arguments.detection
    if arguments.action == 'D':
        with open (outfile, "a+") as
out_file:
           
out_file.write(arguments.host+"n")
 
    if arguments.action == 'S':
        command = "head -50 %s | sort |
uniq -c | gawk '$1>=%s{print $2}'" %(outfile,arguments.tripped)
        print(command)
        output = os.popen(command).read()
        if output != '':
            output = str(output)
            output = output.replace('b'','')
            output = output.replace('\n','')
            out_file = open(outfile, 'w')
            out_file.write("Host: " +
output)
            out_file.write("Alert Type:
" + arguments.detection+"n")
            out_file.write("Time: " +
time)
            out_file = open(outfile, 'r')
            webhook_url = arguments.slack
            slack_data =
{"text":out_file.read()}
            slack_data = str(slack_data)
            slack_data =
"payload="+slack_data
            respOnse= requests.post(
                webhook_url, data=slack_data,
                headers={'Content-Type':
'application/x-www-form-urlencoded'})
            if response.status_code != 200:
                raise ValueError('Request to
slack returned an error %s, the response is: %s' % (response.status_code,
response.text))
            os.remove(outfile)
 
main()

然后,执行该Python脚本:

sudo chmod 755 /bin/py-alert.py

该脚本可以处理我们的全部逻辑,并负责发送Slack Notification告警通知。借助这些选项,我们可以对任何事件组合进行告警。

 

配置告警规则

接下来,将我们的单个规则添加到告警规则目录中。

可以从GitHub获取到我们的规则:

git clone https://github.com/jordanpotti/ElastAlertGrouper.git

随后,将规则文件复制到ElastAlert规则目录中:

sudo cp ElastAlertGrouper/alert_rules/* /etc/elastalert/alert_rules/

现在,在规则目录中就已经有了6条新规则。当指定DLL被加载时,相应的规则将被匹配到,随后立即发出告警。

以下为samlib.yaml的源代码:

es_host:
localhost
es_port:
9200
name:
"samlib"
realert:
    minutes: 0
index:
winlogbeat-*
filter:
-
query:
    wildcard:
        event_data.ImageLoaded:
"*samlib*"
type:
any
alert:
    - command
command:
["/bin/py-alert.py","-T","D","-a","Mimikatz","-c","%(computer_name)s"]

如你所见,我们配置了典型的告警规则选项,并且会在event_data.ImageLoaded中查询samlib。当告警被触发时,会使用如下命令调用我们的Python脚本:

python3
/bin/py-alert.py –T D –a Mimikatz –o /tmp/mimikatz –c $ComputerName

其中的参数-T用于指定脚本将要采取的动作,由于我们这里只是将主机名写入文件,所以我们要使用“Document”或者“D”选项。

其中的参数-a是告警类型,在这里是Mimikatz

其中的参数-c是从告警事件中获取的主机名。

上面的设置针对所有DLL告警事件。因此,当Mimikatz在系统中运行时,输出文件中将会有5个主机名被写入。

 

配置捕获Mimikatz的规则

接下来,让我们来看看Mimikatz的规则:

es_host:
localhost
es_port:
9200
name:
"Mimikatz"
index:
elastalert_status
realert:
    minutes: 0
type:
cardinality
cardinality_field:
rule_name
max_cardinality:
4
filter:
-
terms:
    rule_name:
        - winscard
        - cryptdll
        - hid
        - samlib
        - vaultcli
-
term:
    alert_sent: true
timeframe:
    seconds: 1
alert:
    - command
command:
["python3","/bin/py-alert.py",
"-T","S","-S","SLACKWEBHOOK","-a","Mimikatz","-t","5"]

此告警使用了另外一个索引。实际上,ElastAlert有它自己的索引,在每次告警时都会对其进行查询。因此,我们现在可以查看这个索引,来确认5DLL的告警是不是在1秒之内被接连触发的。这一过程只需要通过对DLL规则进行筛选就可以完成,并且它只返回那些alert_sent标志设置为true的内容,并且只在1秒之内识别出5个结果的时候才发出告警。

此时,我们需要生成一个Slack Web Hook,并使用我们的Web钩子替换“SLACKWEBHOOK”。

其中,告警功能的实现同样是通过调用一个Python脚本:

python3
/bin/py-alert.py –T S –S SLACKWEBHOOK –a Mimikatz –t 5

其中的参数-T代表要执行的操作,在这里,我们要执行“Send”操作。

其中的参数-S需要配置为我们的Slack Web Hook

其中的参数-a代表需要对哪些检测到的类型进行告警。

其中的参数-t代表次数,我们只在输出文件中有5个或者更多特定的主机名时才会产生告警。

最后一部分是最重要的,其中的这个数字应该是我们“分组”中的规则数量。

 

测试过程

接下来,我们运行Mimikatz

立即收到了相关告警:

 

总结

有一点需要特别强调,上述内容已经在实验室的环境中进行了测试,而我们实验室的环境中只有几个终端主机。如果需要在生产环境中进行部署,可能需要根据终端的数量进行相应的调整。

关于如何手动部署的更深入指导,请参考我们实验室的文章:https://cyberwardog.blogspot.com/2017/02/setting-up-pentesting-i-mean-threat_98.html

如果在过程中遇到任何问题,欢迎随时通过Twitter https://twitter.com/ok_bye_now或电子邮件admin@jordanpotti.com与我联系。

我们在本文中涉及到的脚本,并不保证一定能在所有人的环境中成功实现,需要以此为参考进行相应的调整。大家知道,不要盲目信任网络上的脚本,需要加以自行判断。


推荐阅读
author-avatar
mobiledu2502861197
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有