一、基本信息
Cobalt Strike是一个著名的框架,它通常被安全专业人员用于攻防演练,因其功能完善,使用灵活,逐渐成为攻击方常用的框架。
Cobalt Strike的植入物,被称为“beacon”,能够使用不同的协议与命令和控制(C2)服务器通信:
HTTP/HTTPs-植入物和C2服务器之间交换的数据被打包在一个HTTP请求中。
SMB-该通道主要用于点对点通信,它使用SMB协议与可能在基于windows的内部网络上看到的常规通信流融合在一起。
TCP-与SMB通道的用途类似,但使用普通TCP套接字。在SMB受到限制或严格监控的情况下,用于横向移动,还可以用于特权提升。
DNS-使用各种DNS查询,Cobalt Strike的beacon可以仅使用DNS与C2服务器通信,优点是名称解析几乎总是被允许的,并且在植入服务器和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 server
socat tcp4-listen:5353,reuseaddr,fork UDP:127.0.0.1:53
# port 5353 will be exposed via an SSH tunnel on the external redirector
ssh ubuntu@redir.c2 -R5353: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 server
socat udp4-listen:53,reuseaddr,fork tcp:localhost:53535
在Cobalt Strike内部创建DNS监听器的问题不在本文讨论范围内,因为这超出了本研究的范围。要了解更多细节,建议查看Steve Borosh的重定向Cobalt Strike DNS beacon或bluescreenofjeff的Red-Team-Infrastructure-Wiki。
得到的通信流如下图所示:
可以通过查询最初为DNS C2配置的主机名来验证设置。如果设置正常工作,DNS响应应该是在DNS idle malleable配置文件选项中配置的,默认情况下它等于“0.0.0.0”:
nslookupmalware.c2
Non-authoritativeanswer:
Name:malware.c2
Address: 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.com
0.0.0.0
dig @70.35.206.199 +short google.com
0.0.0.0
dig @70.35.206.199 +short nonexistent.domain
0.0.0.0
dig @70.35.206.199 +short -t TXT google.com
0.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"记录。这打破了大多数常见库的名称解析逻辑。下面的片段显示了一个示例:
digTXTtest @35.178.76.239
; <<>>DiG 9.10.6 <<>>TXTtest @35.178.76.239
;;globaloptions: +cmd
;;Gotanswer:
;;->>HEADER<<-opcode:QUERY,status:NOERROR,id: 45988
;;flags:qrrdad;QUERY: 1,ANSWER: 1,AUTHORITY: 0,ADDITIONAL: 0
;;WARNING:recursionrequestedbutnotavailable
;;QUESTIONSECTION:
;test.INTXT
;;ANSWERSECTION:
test. 1INA 8.8.8.8
;;Querytime: 97msec
;;SERVER: 35.178.76.239#53(35.178.76.239)
;;WHEN:TueMar 23 10:11:00CET 2021
;;MSGSIZErcvd: 42
为了避免更高级别的解析逻辑,Scapy 库用于伪造原始 DNS 数据包并构建自动扫描程序。下面的片段显示了包发送和响应进行比较的核心功能:
defcheckDNS(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 == ansA1and ansA1 == ansA2and ansA2 !=""and valid_ip(ansA1):
print("[+] Cs Detected: " + ip +" replied with: " + ansTXT)
except Exceptionas e:
pass
这段代码很容易解释,只是将最初的假设转换为实际的Python代码。该脚本的其余功能只是增加了多线程和更好的输出格式,主要的逻辑是上面所示的。
扫描代码针对一小部分数据进行了测试,数据是通过测试版的Shodan获取的,主要是通过JARM 签名,筛选出潜在的Cobalt Strike C2服务器:
所有的结果数据都被下载下来,然后通过Shodan CLI进行解析,以提取IP地址:
#addshodanquery
shodanparse--fieldsip_stre5a2e2e7-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 Strike的DNS服务器类似。可能是误报,也可能是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服务器:
研究人员发现,使用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
参考文献
Bluescreenofjeff - Red Team Infrastructure Wiki
https://github.com/bluscreenofjeff/Red-Team-Infrastructure-Wiki
Steve Borosh - Redirecting Cobalt Strike DNS Beacons
https://medium.com/rvrsh3ll/redirecting-cobalt-strike-dns-beacons-e3dcdb5a8b9b
Cobalt Strike - Simple DNS Redirectors for Cobalt Strike
https://blog.cobaltstrike.com/2021/03/11/simple-dns-redirectors-for-cobalt-strike/
Whiskey-r7 - grab_beacon_config
https://github.com/whickey-r7/grab_beacon_config
Salesforce - JARM
https://engineering.salesforce.com/easily-identify-malicious-servers-on-the-internet-with-jarm-e095edac525a
CoreDNS
https://coredns.io/
本文为CNTIC编译,不代表本公众号观点,转载请保留出处与链接。
联系信息进入公众号后点击“论坛信息”可见。
原文链接:
https://labs.f-secure.com/blog/detecting-exposed-cobalt-strike-dns-redirectors/
原文标题:Detecting exposed Cobalt Strike DNS redirectiors
编译:CNTIC情报组
声明:本文来自国家网络威胁情报共享开放平台,版权归作者所有。文章内容仅代表作者独立观点,不代表安全内参立场,转载目的在于传递更多信息。如有侵权,请联系 anquanneican@163.com。