使用 URL Toolbox 时,您无法“躲避”莱文斯坦博士





5.00/5 (1投票)
在我们上一篇关于解析的博文中,我们详细介绍了如何将完全限定域名或 URL 传递给 URL Toolbox,并收到一组解析得很好的字段,其中包括查询字符串、顶级域、子域。今天,我们将对这些字段进行一些分析算术。
这是“使用 Splunk 进行狩猎:基础知识”系列的第十部分。 我的私人 SPL 专家大卫·沃伊夫又发表了一篇关于我喜欢的主题的精彩文章。我希望你们都喜欢。- 瑞安·科瓦尔
在我们上一篇关于解析的博文中,我们详细介绍了如何将URL Toolbox传递给完全限定域名或 URL,并收到一组解析得很好的字段,其中包括查询字符串、顶级域、子域等等!今天,我们将对这些字段进行一些复杂的分析算术。如果您还没有阅读上一篇博文“UT_parsing Domains Like House Slytherin”,请先去查看一下,然后再回到这里……我们会等您。
.
..
…
好的,您回来了!
那么,“复杂的分析算术”是什么意思呢?具体来说,就是利用之前提到的字段,如domain和ut_domain,并尝试使用香农和莱文斯坦计算来找出值的随机性,或者它们与合法域(或其他字符串)的关联程度。
一如既往,我们喜欢在狩猎时先提出假设。让我们从使用电子邮件事件开始,并假设攻击者试图通过发送来自域名与合法域名(通常称为“拼写抢注”)非常相似的钓鱼邮件来欺骗用户。为了检测这些恶意域名变体,我们将使用字符串之间的莱文斯坦距离。
莱文斯坦距离
莱文斯坦距离最早由弗拉基米尔·莱文斯坦于 1965 年提出。该距离基本上是将一个字符串转换为另一个字符串所需的更改次数。如果一个字符串是“hello!”,另一个是“hallo!”,则距离为 1,因为“e”将被替换为“a”。
有了这个背景,让我们看一个 URL Toolbox 的例子。
index=email mail from | stats count by Sender | rex field=Sender "\@(?<domain_detected>.*)" | stats sum(count) as count by domain_detected | where domain_detected!="mycompany.com" | eval list="mozilla" | `ut_parse_extended(domain_detected, list)` | eval company_domain="mycompany.com" | `ut_levenshtein(ut_domain, company_domain) ` | eval ut_levenshtein= min(ut_levenshtein) | where ut_levenshtein < 3
在这个例子中,我们拥有域名“mycompany.com”,有人试图通过从名为“mycampany.com”的域名发送电子邮件来欺骗我们!搜索的前五行提取域名并针对该域名运行`ut_parse_extended(2)`宏(我相信您还记得,我们在上一篇博文中介绍了这一点)。搜索的新部分针对新提取的ut_domain字段运行`ut_levenshtein(1)`宏,并将其与我们的合法域名进行比较。如上图所示,该距离为一,我们的规则很容易检测到。我调查过的大多数客户都使用 1-2 的阈值进行警报;如果超过 2,您可能会收到大量误报。
同样的技术可以用于任何数据源。让我们修改我们的假设,假设收到钓鱼邮件的用户不会注意到他们点击的链接中的拼写抢注。这里有一个例子,针对“mycompany.com”域名的这种情景。
index=pan_logs sourcetype=pan:threat url=* | stats count by url | eval list="mozilla" | `ut_parse_extended(url, list)` | stats sum(count) as count by ut_domain | where ut_domain!="mycompany.com" | eval company_domain="mycompany.com" | `ut_levenshtein(ut_domain, company_domain)` | eval ut_levenshtein= min(ut_levenshtein) | where ut_levenshtein < 3
我把与我们第一个示例相同的命令涂成了灰色——要查看完全不同的数据集,我们唯一需要的更改是更改源类型并解析 URL。
URL Toolbox 还支持多值字段,这使我们能够检测试图欺骗我们的子域的使用,并允许我们监控多个域名(因为每个组织都有多个域名)。这个搜索有点长,但值得!这与 Splunk Security Essentials 中“具有相似域名的电子邮件”标题下的搜索非常相似,如果您愿意,可以在那里查看。
让我们继续我们关于网络钓鱼邮件的原始假设,但将其范围扩大到包括多个域和子域。
index=email mail from | stats count by Sender | rex field=Sender "\@(?<domain_detected>.*)" | stats sum(count) as count by domain_detected | eval domain_detected=mvfilter(domain_detected!="mycompany.com" AND domain_detected!="company.com" AND domain_detected!="mycompanylovestheenvironment.com") | eval list="mozilla" | `ut_parse_extended(domain_detected, list)` | foreach ut_subdomain_level* [eval orig_domain=domain_detected, domain_detected=mvappend(domain_detected, '<<FIELD>>' . "." . ut_tld)] | eval domain_names_analyzed=mvappend(domain_detected, ut_domain), company_domains_used = mvappend("mycompany.com", "company.com", "mycompanylovestheenvironment.com") | `ut_levenshtein(domain_names_analyzed, company_domains_used) ` | eval ut_levenshtein= min(ut_levenshtein) | where ut_levenshtein < 3 | fields - domain_detected ut_* | rename orig_domain as top_level_domain_in_incoming_email count as num_occurrences ut_levenshtein as Levenshtein_Similarity_Score
搜索过程类似于单域名搜索,但增加了处理多值字段的逻辑。
香农熵
好的,让我们从莱文斯坦转到香农熵检测。香农熵是以克劳德·香农博士的名字命名的,他于 1948 年提出了信息熵的概念。信息熵的基本要点是它允许我们确定字符串中存在的随机性量。例如,google.com 的熵得分为 2.65,而 c32DyQG9dyYtuB471Db.com 的熵得分为 4.2!使用这种技术使我们能够寻找算法生成的域名。
在这个例子中,我从一个假设开始:我们网络中的恶意软件使用随机域名与其他恶意基础设施进行通信。
index=pan_logs sourcetype=pan:threat url=* | stats count values(src_ip) as src_ip by url | `ut_parse_extended(url, list)` | stats sum(count) as count values(src_ip) by ut_domain | `ut_shannon(ut_domain)` | search ut_shannon>3
在我们的搜索中,我们着重于识别 URL,执行统计计算以获取按 URL 计数,然后使用 URL Toolbox 宏 `ut_parse_extended(2)` 解析出域。解析域后,我们使用 `ut_shannon(1)` 宏计算每个域的熵分数。计算熵后,我们再执行一些额外的统计计算并格式化以供查看。
在上面的示例中,我们查找熵大于 3 的任何域。这个截止值在每个数据集中都会有所不同,根据需要进行调整,直到您得到较低的误报。
扩展我们刚刚创建的搜索,我们可以假设攻击者会通过 DNS 尝试窃取数据。为了帮助我们,我们将通过添加更多统计数据来优化我们的搜索。此查询在 SplunkLive! 2016 期间展示,允许我们通过工具 dnscat2(或 dnscat)检测数据窃取。dnscat2 会询问攻击者拥有的域名,然后对文件进行加密、压缩和分块。为了窃取数据,它会在该域名内生成大量随机子域名(被窃取的数据)的 DNS 请求。由于攻击者拥有该域名并监听请求,他们可以成功捕获并在其服务器上重新创建数据。无需防火墙漏洞,NGFW 检测也不可能,因为它看起来像是来自您的 DNS 服务器的 DNS 流量!
让我们看看如何使用 stats 命令来查找这种数据。
index=bro sourcetype=bro_dns | `ut_parse(query)` | `ut_shannon(ut_subdomain)` | eval sublen=length(ut_subdomain) | stats count avg(ut_shannon) as avg_sha avg(sublen) as avg_sublen stdev(sublen) as stdev_sublen by ut_domain | search avg_sha>3 avg_sublen>20 stdev_sublen<2
我指控!我们像往常一样,首先解析查询。我们计算子域的熵,然后开始根据子域和熵生成计数、平均值和标准差。一旦计算完成,就可以轻松过滤结果并排序查看。
虽然我们花了很多时间在域名上,但重要的是要理解我们可以将相同的熵技术应用于 Splunk 中的任何字段,包括本地操作系统上的文件名。我们可以假设攻击者正在使用随机文件路径从用户配置文件启动进程
sourcetype=win*security EventCode=4688 New_Process_Name=*\Users\* | `ut_shannon(New_Process_Name)` | stats values(ut_shannon) as "Shannon Entropy Score" by New_Process_Name, host | rename New_Process_Name as Process, host as Endpoint
这里有一点需要注意——香农熵的有用性随着字符串长度的增加而降低。我们正在努力在 Splunk Enterprise 中构建基于机器学习的随机性检测。如果您有兴趣进行 Beta 测试,请联系我们!
您可能会想,如果我们可以对文件使用香农熵,那么我们是否可以对文件使用莱文斯坦?当然可以——莱文斯坦可以用于拼写抢注进程!我可能会假设攻击者会通过启动与合法 Windows 进程(如 explorer.exe、iexplore.exe、svchost.exe 或 services.exe)非常相似的文件名来向管理员隐藏进程。
sourcetype=win*security EventCode=4688 | rex field=New_Process_Name "(?<filename>[^\\\\/]*$)" | stats values(host) as hosts dc(host) as num_hosts values(Image) as Images by filename | eval goodfilenames=mvappend("svchost.exe","iexplore.exe","ipconfig.exe","explorer.exe") | `ut_levenshtein(filename, goodfilenames)` | where min(ut_levenshtein) < 3 AND min(ut_levenshtein) > 0
哇。
现在,这不算太糟糕,不是吗?几个不同的例子说明了如何使用 `ut_shannon(1)` 和 `ut_levenshtein(1)` 仅用数学来发现恶意行为。
如果所有这些都让您感到非常兴奋,并且您想要更多,我们将为您留下最后一个探索领域。Cedric Le Roux 最近发布了另一个应用程序,名为 JellyFisher。JellyFisher 的灵活性不如 URL Toolbox——不支持多值字段或缓存——但它确实增加了新的算法选择,包括 Damerau-Levenshtein。这类似于 Levenshtein,但稍微好一点的是,交换两个字符(例如“l”和“p”来创建 slpunk.com)只算作距离一。这意味着可以更有效地检测攻击者的恶意行为!如果您好奇,请查看文档并尝试一些新的用例。
下次再见,祝您狩猎愉快! :-)
有关香农熵的更多示例,请查看 Ryan Kovar 和 Sebastien Tricaud 的这些博客