探测Cobalt Strike DNS重定向服务

  • A+
所属分类:安全文章
一、基本信息


Cobalt Strike是一个著名的框架,它通常被安全专业人员用于攻防演练,因其功能完善,使用灵活,逐渐成为攻击方常用的框架。 

Cobalt Strike的植入物,被称为“beacon”,能够使用不同的协议与命令和控制(C2)服务器通信:

  • HTTP/HTTPs-植入物和C2服务器之间交换的数据被打包在一个HTTP请求中
  • SMB-该通道主要用于点对点通信,它使用SMB协议与可能在基于windows的内部网络上看到的常规通信流融合在一起。
  • TCP-SMB通道的用途类似,但使用普通TCP套接字。在SMB受到限制或严格监控的情况下,用于横向移动,还可以用于特权提升。
  • DNS-使用各种DNS查询,Cobalt Strikebeacon可以仅使用DNSC2服务器通信,优点是名称解析几乎总是被允许的,并且在植入服务器和C2服务器之间没有直接通信,因为DNS解析将使用默认的名称服务器进行。
  • Custom-使用记录良好的外部C2协议,该机制可使用户自定义通信方式,可不依赖于Cobalt Strike的默认信道。一个有名的例子是F-Secure的C3框架。

这项研究通过主动探测,对使用DNS作为通信通道的Cobalt Strike服务器进行指纹识别。尽管研究方法会有些不同,但结果将类似于JARM对受Cobalt Strike限制的HTTP/HTTPs请求。


二、DNS重定向


在开始实际的探测之前,了解Cobalt Strike的标准DNS服务器是如何部署的是很重要的。“重定向器"的概念是为了进一步强化攻击基础结构、分离被攻击的组件和实际 C2 服务器所暴露的内容而引入的, 这为使用者提供了更大的灵活性,可防止暴露在互联网上的控制服务器在攻击期间被发现。事实上,更换一个新的重定向器可能需要数小时,而重建一个新的C2服务器可能会对操作产生更大的影响。

通常,标准的Cobalt Strike DNS重定向器是使用socat或iptables创建的。事实上,官方文档建议将其作为创建基于DNS的重定向器的首选工具。

例如,下面的命令能够为DNS创建一个简单的重定向:

# socat will listen on TCP 5353 and redirect to cobalt strike's DNS serversocat tcp4-listen:5353,reuseaddr,fork UDP:127.0.0.1:53
# port 5353 will be exposed via an SSH tunnel on the external redirectorssh [email protected] -R 5353:127.0.0.1:5353
# on the redirector, socat will listen on 53 and forward the data to the SSH tunnel, that eventually will reach the C2 serversocat udp4-listen:53,reuseaddr,fork tcp:localhost:53535

在Cobalt Strike内部创建DNS监听器的问题不在本文讨论范围内,因为这超出了本研究的范围。要了解更多细节,建议查看Steve Borosh的重定向Cobalt Strike DNS beacon或bluescreenofjeff的Red-Team-Infrastructure-Wiki。

得到的通信流如下图所示:

探测Cobalt Strike DNS重定向服务

可以通过查询最初为DNS C2配置的主机名来验证设置。如果设置正常工作,DNS响应应该是在DNS idle malleable配置文件选项中配置的,默认情况下它等于“0.0.0.0”:

nslookup malware.c2
Non-authoritative answer:Name: malware.c2Address: 0.0.0.0

 “0.0.0.0”,如前所述,是 Cobalt Strike的默认值。


三、探测阶段


F-Secure进行的研究是基于以下声明:

无论接收到什么查询,只要它不是C2通信的一部分,Cobalt Strike的DNS监听器将使用dns_idle字段中定义的值进行应答。

事实上,beacon将dns_idle作为检查新任务的重要部分。但有一个问题,默认的 DNS 服务器也会使用该值回复其他域的所有其他查询。

假设DNS服务器总是以相同的IP地址回应所有的查询,这可能是Cobalt Strike存在的一个指示器。当然,这种方法也不是没有假阳性,研究的一部分是量化这种机制的真实度。

 

可以通过启动的Cobalt Strike服务器验证真实度:

dig @70.35.206.199 +short amazon.com0.0.0.0
dig @70.35.206.199 +short google.com0.0.0.0
dig @70.35.206.199 +short nonexistent.domain0.0.0.0
dig @70.35.206.199 +short -t TXT google.com0.0.0.0

domain0.0.0.0dig @70.35.206.199 +short -t TXT google.com0.0.0.0

可以看到,服务器用默认dns_idle值"0.0.0.0"回复了所有查询,即使更改了默认值,这种方法也会起作用,因为所有查询仍将返回相同的值。有趣的是,即使查询的不是 “A” 记录,Cobalt Strike仍然返回了"A"记录。这打破了大多数常见库的名称解析逻辑。下面的片段显示了一个示例:

dig TXT test @35.178.76.239
; <<>> DiG 9.10.6 <<>> TXT test @35.178.76.239;; global options: +cmd;; Got answer:;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 45988;; flags: qr rd ad; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0;; WARNING: recursion requested but not available
;; QUESTION SECTION:;test. IN TXT
;; ANSWER SECTION:test. 1 IN A 8.8.8.8
;; Query time: 97 msec;; SERVER: 35.178.76.239#53(35.178.76.239);; WHEN: Tue Mar 23 10:11:00 CET 2021;; MSG SIZE rcvd: 42

为了避免更高级别的解析逻辑,Scapy 库用于伪造原始 DNS 数据包并构建自动扫描程序。下面的片段显示了包发送和响应进行比较的核心功能:

def checkDNS(name):    ip = name    try:         ans = sr1(IP(dst=ip)/UDP(sport=RandShort(), dport=53)/DNS(rd=1,qd=DNSQR(qname="google.com",qtype="TXT")), verbose=False, timeout=0.5)        ansTXT = ans[DNSRR][0].rdata        ans = sr1(IP(dst=ip)/UDP(sport=RandShort(), dport=53)/DNS(rd=1,qd=DNSQR(qname="amazon.com",qtype="A")), verbose=False, timeout=0.5)        ansA1 = ans[DNSRR][0].rdata        ans = sr1(IP(dst=ip)/UDP(sport=RandShort(), dport=53)/DNS(rd=1,qd=DNSQR(qname="google.com",qtype="A")), verbose=False, timeout=0.5)        ansA2 = ans[DNSRR][0].rdata        if ansTXT == ansA1 and ansA1 == ansA2 and ansA2 != '' and valid_ip(ansA1):            print("[+] Cs Detected: " + ip  + " replied with: " + ansTXT)    except Exception as e:        pass

这段代码很容易解释,只是将最初的假设转换为实际的Python代码。该脚本的其余功能只是增加了多线程和更好的输出格式,主要的逻辑是上面所示的。

扫描代码针对一小部分数据进行了测试,数据是通过测试版的Shodan获取的,主要是通过JARM 签名,筛选出潜在的Cobalt Strike C2服务器:

探测Cobalt Strike DNS重定向服务


所有的结果数据都被下载下来,然后通过Shodan CLI进行解析,以提取IP地址:

# add shodan queryshodan parse --fields ip_str e5a2e2e7-e029-4b10-a5f8-63687aa7a09c.json.gz > cobalt.txt 

初始数据集的结果为阳性的,具有多个匹配项:

python scan.py ~/Downloads/cs-dns.txt[+] Cs Detected: 24.252.133.75 replied with: 10.0.0.1[+] Cs Detected: 193.202.92.36 replied with: 193.202.92.36[+] Cs Detected: 194.204.33.130 replied with: 127.53.53.53[+] Cs Detected: 194.62.33.31 replied with: 192.168.33.31[+] Cs Detected: 5.8.16.29 replied with: 72.5.65.111[+] Cs Detected: 37.191.180.47 replied with: 37.191.180.47[+] Cs Detected: 35.178.76.239 replied with: 8.8.8.8[+] Cs Detected: 85.27.174.244 replied with: 85.27.174.244[+] Cs Detected: 70.35.206.199 replied with: 0.0.0.0[+] Cs Detected: 209.9.227.212 replied with: 209.9.227.212[+] Cs Detected: 175.176.185.229 replied with: 103.60.101.170[+] Cs Detected: 179.191.84.68 replied with: 10.0.0.1


四、互联网调查


在一定程度上,研究的下一步是将分析范围扩展到整个互联网。为了获得所需的结果,有必要对所有暴露端口53/UDP的主机进行全网扫描,最后决定使用Project Sonar的数据集,而不是手动进行扫描,该数据集已经收集了所需的信息,这使得可以将扫描范围从数十亿个ip缩小到大约700万条记录。考虑到检测基于UDP的协议,选择“Project Sonar”的数据集非常有必要,因为UDP协议通常较慢,并且不如TCP可靠。


对数据集扫描会产生大约1400个结果,研究人员认为这个数量过多,需要再根据Cobalt Strike C2服务器的其他特征,进一步辅助验证。比如:

  • 开放端口50050

  • 在HTTP/S请求中是404状态码,并且内容长度为0,这是Cobalt Strike的明显特征

  • 有一个匹配的JARM签名

  • 对于启用分阶段模式的控制服务器,可通过特定HTTP请求,获取到beacon配置

  • 回复“0.0.0.0”,这是“dns_idle”的默认值

上述过程的结果如下:

  • 24台服务器开启了50050端口

  • 49台服务器返回了,Cobalt Strike的默认HTTP响应

  • 27台服务器启用了分阶段模式,使研究人员获取到了beacon配置

  • 91个服务器回复“0.0.0.0”

  • “07d14d16d21d21d07c42d41d00041d24a458a375eef0c576d23a7bab9a9fb1”是16个服务器的JARM签名,表明是Cobalt Strike攻击


在 1400 个结果中,由于匹配到上面特征中的一个或多个,122 个极有可能是Cobalt Strike服务器。使用extremely useful Nmap script进一步调查beacon配置后,注意到使用 8.8.8.8 作为dns_idle的重复模式:

{   "x64":{      "md5":"26dca1f00735af2e11d856cdbc239a72",      "sha1":"0f964782e58ac43ab0433b7cbb007295eed1bcd1",      "time":1616664618025.3,      "config":{         "Port":80,         "Beacon Type":"0 (HTTP)",         "Polling":50000,         "Pipe Name":"",         "User Agent":"Mozilla\/5.0 (compatible; MSIE 9.0; Windows Phone OS 7.5; Trident\/5.0; IEMobile\/9.0; LG; LG-E906)",         "Jitter":15,         "Header 1":"",         "Method 2":"POST",         "Spawn To x86":"%windir%\\syswow64\\rundll32.exe",         "C2 Server":"[REDACTED],\/_\/scs\/mail-static\/_\/js\/",         "Method 1":"GET",         "Spawn To x64":"%windir%\\sysnative\\rundll32.exe",         "Max DNS":255,         "Header 2":"",         "HTTP Method Path 2":"\/mail\/u\/0\/",         "DNS Sleep":0,         "DNS Idle":"8.8.8.8"      },      "sha256":"ce4d2de8d28423bc975b7792b69722e8b8e01c01c723f43e494709062fcdb550"   },   "x86":{      "md5":"d836ddfcb06c1959d002fabd70aff8fd",      "sha1":"7d8c5d34da8a0ece4fcda322a1c814b285d4b8f8",      "time":1616664587530.2,      "config":{         "Port":80,         "Beacon Type":"0 (HTTP)",         "Polling":50000,         "Pipe Name":"",         "User Agent":"Mozilla\/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident\/4.0; BTRS125526)",         "Jitter":15,         "Header 1":"",         "Method 2":"POST",         "Spawn To x86":"%windir%\\syswow64\\rundll32.exe",         "C2 Server":"[REDACTED],\/_\/scs\/mail-static\/_\/js\/",         "Method 1":"GET",         "Spawn To x64":"%windir%\\sysnative\\rundll32.exe",         "Max DNS":255,         "Header 2":"",         "HTTP Method Path 2":"\/mail\/u\/0\/",         "DNS Sleep":0,         "DNS Idle":"8.8.8.8"      },      "sha256":"52029626c23dc2cd60f65e0bfa087021f0ee4d96ed0259a6e03cd7ff2fd471ac"   }}

研究人员决定将该值作为另一个特征,最终统计出Cobalt Strike服务器的总数为135个。剩余的服务器分为以下类别:

  • 假阳性,我们发现一些家用路由器版本的行为方式与Cobalt StrikeDNS服务器类似。可能是误报,也可能是CS服务器。

  • Cobalt Strike DNS服务器改变了默认dns_idle值,没有在同一IP地址上托管HTTP服务器。

  • DNS水坑和蜜罐。尽管已经做出了努力来避免这种情况,但一些DNS服务器的行为方式可能与Cobalt Strike类似。

注:完整的扫描结果将在这篇博文发布后发布,同时还有扫描程序的源代码。


五、Red团队案例


研究人员进行这项研究的根本原因是DNS重定向器是愚蠢的,这意味着它将DNS请求毫无逻辑地转发给Cobalt Strike。例如,如果研究人员看一下基于HTTP的重定向器的发展,会发现使用socat或iptables很快就被抛弃了,取而代之的是更好的替代方案,如使用mod rewrite的Apache或Nginx。

问题是研究人员还没有看到同样的方法应用于DNS重定向器,一个可能的解决方案是创建一个智能重定向器,它能够根据请求的域名将DNS请求代理到特定的DNS服务器:

探测Cobalt Strike DNS重定向服务

研究人员发现,使用CoreDNS等开源DNS服务器解决了这个问题。事实上,使用如下所示的“Corefile”,也可以避免这种琐碎的检测:

. {  forward . 9.9.9.9}malware.c2 {    forward . malware.c2:5353}. {  forward . 9.9.9.9}malware.c2 {    forward . malware.c2:5353}

CoreDNS 可以部署在暴露在互联网上的 VPS 上,并充当"智能"重定向器。此配置将仅代理Cobalt Strike对"malware.c2"域的请求,其他一切都将使用"9.9.9.9"公共解析器解决。


 六、结论


这项研究展示了一种可以用来追踪暴露在互联网上的Cobalt Strike服务器方法,可以用来丰富威胁情报数据,以实现更好的检测。

对于使用Cobalt Strike或其他支持DNS的C2框架的red 团队和渗透测试人员,研究人员提供了一种方法,可以使用开源工具构建更好、更智能的DNS重定向器。


注:关于CobaltStrike TLS流量分析可以参考https://mp.weixin.qq.com/s/9xklwpHl-vhXen1luQslSg


参考文献

  1. Bluescreenofjeff - Red Team Infrastructure Wiki
    https://github.com/bluscreenofjeff/Red-Team-Infrastructure-Wiki
  2. Steve Borosh - Redirecting Cobalt Strike DNS Beacons
    https://medium.com/rvrsh3ll/redirecting-cobalt-strike-dns-beacons-e3dcdb5a8b9b
  3. Cobalt Strike - Simple DNS Redirectors for Cobalt Strike
    https://blog.cobaltstrike.com/2021/03/11/simple-dns-redirectors-for-cobalt-strike/
  4. Whiskey-r7 - grab_beacon_config
    https://github.com/whickey-r7/grab_beacon_config
  5. Salesforce - JARM
    https://engineering.salesforce.com/easily-identify-malicious-servers-on-the-internet-with-jarm-e095edac525a
  6. CoreDNS
    https://coredns.io/




为CNTIC编译,不代表本公众号观点,转载请保留出处与链接。

联系信息进入公众号后点击“论坛信息”可见。

原文链接:
https://labs.f-secure.com/blog/detecting-exposed-cobalt-strike-dns-redirectors/
原文标题:Detecting exposed Cobalt Strike DNS redirectiors
编译:CNTIC情报组


探测Cobalt Strike DNS重定向服务

本文始发于微信公众号(国家网络威胁情报共享开放平台):探测Cobalt Strike DNS重定向服务

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: