在暗影中潜行-CS服务器隐匿(二)

前言

在上一篇文章中,总结了互联网上一些常见的Cobalt Strike特征修改以及服务器的隐藏方法。在本篇进行了进一步的补充总结,包含:重定向器的设置、DNS监听器的隐藏以及简单修改Cobalt Strike来防止团队服务器的泄露。


1 重定向器

重定向器是隐蔽攻击基础设施中的关键组件,用于混淆后端基础架构,并可用于混淆或迷惑正在调查的事件响应者,当我们的重定向器服务器被封禁时,我们真正的 Cobalt Strike 团队服务器的 IP 仍然可用。

1.1 Dumb Pipe重定向器

Dumb Pipe重定向器会混淆CS服务器的真实IP地址,适合于快速启动环境,但由于该重定向不对流量执行任何条件的过滤,所以较容易被防守方深入溯源。

1.1.1 iptables

iptables是Linux的防火墙工具,它可以将某个端口上的任何传入流量NAT到远程主机的指定端口。

以root权限运行以下命令将443端口的TCP流量重定向到CS服务器的443端口,其中为CS服务器IP。

1
2
3
4
5
6
iptables -I INPUT -p tcp -m tcp --dport 443 -j ACCEPT
iptables -t nat -A PREROUTING -p tcp --dport 443 -j DNAT --to-destination <REMOTE-HOST-IP-ADDRESS>:443
iptables -t nat -A POSTROUTING -j MASQUERADE
iptables -I FORWARD -j ACCEPT
iptables -P FORWARD ACCEPT
sysctl net.ipv4.ip_forward=1

1.1.2 socat

socat是用来创建相同类型的流量重定向工具。

以下命令将443端口的流量重定向到CS服务器的443端口,其中为CS服务器IP。

1
socat TCP4-LISTEN:443,fork TCP4:<REMOTE-HOST-IP-ADDRESS>:443

如果重定向大量流量,socat重定向器可能会出现一些问题。

1.2 过滤型重定向器

虽然Dumb Pipe重定向器可以快速启动,但过滤型重定向器提供了几乎无穷无尽的方法来阻止防守方来调查我们的CS服务器。

1.2.1 Apache mod_rewrite

安装Apache并开启模块。

1
2
3
4
apt-get install apache2
a2enmod ssl rewrite proxy proxy_http
a2ensite default-ssl.conf
service apache2 restart

在Apache2的配置文件中,找到Directory将None改为ALL。

1
2
3
4
5
<Directory /var/www/>
Options Indexes FollowSymLinks
AllowOverride None
Require all granted
</Directory>

编辑 SSL 站点配置(默认位于/etc/apache2/sites-enabled/default-ssl.conf),设置SSLCertificateFile、SSLCertificateKeyFile为SSL证书路径,并在文件中加入以下配置。

1
2
3
4
5
6
7
8
# Enable SSL
SSLEngine On
# Enable Proxy
SSLProxyEngine On
# Trust Self-Signed Certificates generated by Cobalt Strike
SSLProxyVerify none
SSLProxyCheckPeerCN off
SSLProxyCheckPeerName off

在完成了以上配置后,接下来要根据C2配置文件来编写位于网站根目录(默认为/var/www/html/)下的.htaccess文件。

mod_rewrite规则语法:

1
2
3
4
5
6
7
8
#启用重写引擎
RewriteEngine On
#如果请求的 %URI 是“/payload.exe”或“/landingpage.html”(带有可选的尾部斜杠),则 [忽略大小写];
RewriteCond %{REQUEST_URI} ^/(payload\.exe|landingpage\.html)/?$ [NC]
#将整个请求更改 为从远程主机的 IP提供原始请求路径,并保持用户的地址栏相同(隐藏后端服务器的 IP)。
RewriteRule ^.*$ http://REMOTE-HOST-IP %{REQUEST_URI} [P]
#如果不满足上述条件,将整个请求更改为 http://example.com/并从原始请求中删除所有查询字符串。不判断之后的规则并重定向用户,更改地址栏。
RewriteRule ^. *$ http://example.com/? [L,R=302]

也可以直接利用Python脚本(https://github.com/threatexpress/cs2modrewrite)根据C2配置文件生成.htaccess文件。

1
python3 cs2modrewrite.py -i havex.profile -c https://[CS服务器地址] -r https://[www.xxxx.com] > /var/www/html/.htaccess

正常上线。

image-20220517144813521

直接访问域名会跳转至其他地址。

image-20220517145627672

1.2.2 Nginx

Nginx的重定向在上篇的“Nginx反向代理隐藏端口”部分有过说明,不再赘述。

1.2.3 Caddy

Caddy一个强大的、企业级的、开源的 Web 服务器,且带有用 Go 编写的自动HTTPS。

安装caddy,根据官方文档,Ubuntu安装方法如下:

1
2
3
4
5
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo apt update
sudo apt install caddy

根据自己的CS配置文件进行caddy配置文件的编写。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
(cs_proxy_upstream) {
#caddy只处理以/include/开头的请求,根据CS配置文件来配置
handle /include/* {
# 阻止访问的UA列表
@ua_denylist {
header User-Agent curl*
}

# 阻止访问的IP列表
@ip_denylist {
remote_ip 8.8.8.8/32
}
header {
-Server
+X-Robots-Tag "noindex, nofollow, nosnippet, noarchive"
+X-Content-Type-Options "nosniff"
}
# 在阻止访问的UA列表的IP访问是返回403,可设为其它
respond @ua_denylist "Forbidden" 403 {
close
}

# 在阻止访问的IP列表的IP访问是返回403,可设为其它
respond @ip_denylist "Forbidden" 403 {
close
}

# 反向代理到CS服务器,且配置X-Forwarded-For头
reverse_proxy https://CS服务器地址:443 {
header_up Host {upstream_hostport}
header_up X-Forwarded-Host {host}
header_up X-Forwarded-Port {port}
}
}
}

配置完成后caddy run运行caddy。

正常上线,在CS配置文件中设置trust_x_forwarded_for为true可通过x-forwarded获取上线主机出口IP,而不是重定向器IP。

image-20220518110402419

image-20220518110947921

2 DNS over HTTPS

DoH (DNS over HTTPS)即使用安全的 HTTPS 协议运行 DNS ,主要目的是增强用户的安全性和隐私性。通过使用加密的 HTTPS 连接,第三方将不再影响或监视解析过程。因此,将无法查看请求的 URL 并对其进行追踪。

在使用DNS监听器控制受害主机时,会产生大量DNS请求,流量异常易被发现。

image-20220512140036137

2.1 配置TitanLdr

安装由Kyle Avery fork的TitanLdr工具:

https://github.com/kyleavery/TitanLdr

此TitanLdr可以指定多个DoH服务器,每次回调时,Beacon都会从服务器列表中随机选择一个。可以在/hooks/DnsQuery_A.c文件的第116行修改DoH服务器列表。

image-20220512163411509

可用的DoH服务器可从该wiki中

https://github.com/curl/curl/wiki/DNS-over-HTTPS

寻找(不局限于此),修改完成后需要构建程序来使用该工具,需要安装NASM和MinGW来完成构建。

以Ubuntu 20.04为例:

1
2
3
4
5
6
7
从NSAM官网下载稳定版NASM软件包
# wget https://www.nasm.us/pub/nasm/releasebuilds/2.14.02/nasm-2.14.02.tar.gz
# tar -xvf nasm-2.14.02.tar.gz
# cd nasm-2.14.02
# ./configure
# make
# make install

安装完成后可通过nasm -version来查看是否安装成功

image-20220512164218506

MinGW可通过 apt install mingw-w64 直接安装

image-20220512164807586

全部安装完成后,执行make进行构建

image-20220512165010714

可能会因Python3缺少module报错,pip install 缺少的module,重新 make 进行构建即可

image-20220512165501364

2.2 使用TitanLdr

准备一个域名解析到Cobalt Strike服务器,并配置NS记录

image-20220512165906344

将Titan.cna通过脚本管理器导入到Cobalt Strike中,即可使用DoH,配置DNS监听器

image-20220512160957443

Beacon运行后,可以看到只发出了一个DNS请求来解析DoH服务器的地址,之后的流量都经过了HTTPS的加密。

image-20220512160926328

image-20220512160819534

3 修改Cobalt Strike客户端

3.1 准备

3.1.1 反编译

通过IDEA中自带的反编译工具java-decompiler反编译CobaltStrike

该工具位于IDEA安装目录的\plugins\java-decompiler\lib文件夹下

01-IDEA反编译插件

在目录下创建用来放反编译后源码的文件夹,此处我创建了个名为cs的文件夹

1
java -cp java-decompiler.jar org.jetbrains.java.decompiler.main.decompiler.ConsoleDecompiler -dgs=true cobaltstrike.jar cs/

如果出现了下图的报错,则说明Java版本低了

02-Java版本低

JDK编译器版本及其对应的class文件版本序号:

JDK编译器版本 class文件版本序号
JDK8 52.0
JDK9 53.0
JDK10 54.0
JDK11 55.0
JDK12 56.0

所以这里要使用11以上版本的Java来执行,才可以正常反编译(这里我使用的Java17)

03-反编译

经过漫长的等待后,得到一个jar,解压后就是我们所需要的CS源码了

04-反编译结束

05-反编译结束1

3.1.2 建立IDEA项目

​ 这里为了方便代码的修改和查看,所以我选择通过IDEA来继续进行,也可以直接编辑要修改的java文件,用命令行直接编译为class文件,再拖进原来的jar包中。

在IDEA中新建一个项目

06-创建IDEA新项目0

07-创建IDEA新项目1

08-创建IDEA新项目2

项目名称看自己喜好自定义命名

在项目目录下创建一个文件夹(例如lib)用来存放反编译前的jar文件,并将反编译后的文件解压至项目目录

09-项目目录配置

在项目结构-项目设置的模块中导入这个jar包

10-项目结构

11-项目设置模块

12-选择jar 13-导出模块

完成后点击应用

配置工件,从项目结构-项目设置-工件中的+号添加JAR-来自具有依赖项的模块

15-添加工件

这里需要选择主类,主类选择aggressor.Aggressor

16-选择主类

可以通过反编译的源码中META-INF的MANIFEST.MF文件看到Main-Class即主类

14-入口

17-配置完成

至此IDEA的配置全部完成

当我们需要修改哪个文件就将文件重构复制至src目录中,再进行相应的修改

18-复制源码

19-复制到src目录下

修改源码完成后,在菜单栏的构建一栏中选择构建工件

20-构建工件21-构建

等待其构建完成后,会在项目目录下生成一个out目录,修改完成的jar在其artifacts目录下

22-等待构建完成

23-生成jar

这时我们直接打开jar会弹出报错

24-打开报错

直接一步到位,cmd运行或写入bat文件运行

1
java -XX:ParallelGCThreads=4 -XX:+AggressiveHeap -XX:+UseParallelGC -Xms512M -Xmx1024M -jar ZBCCS.jar $*

运行后会报错缺少cobaltstrike.auth文件

25-缺少文件

将原来的文件拖入即可

26-复制文件

更简单的方法就是将生成的修改后的jar改名为cobaltstrike.jar(原来的名字)放回原来的目录以替换原来的文件使用

27-正常运行

成功正常运行

3.2 修改

​ 在修改前要做好备份,以防止出现错误后Cobalt Strike无法正常使用。

3.2.1 修改登录

​ 可以通过修改源码中的标识数,来防止别人通过脚本暴力破解得到teamserver的密码。在修改后即便对方得到了正确密码,但是其客户端标识数与修改后的服务端不同,所以很难直接连接到我们的teamserver。

28-1-爆破成功

28-2-爆破成功


修改ssl目录下的SecureSocket.java和SecureServerSocket.java中的标识数

28-3-securesocket

29-secureserversocket

以及dns目录下AsymmetricCrypto.java中的标识数

29-1-AsymmetricCrypto

修改后,通过IDEA的构建工件生成新的jar

这时我们使用未修改的客户端尝试连接,会返回显示连接错误

30-正常客户端无法登陆

服务端显示:身份验证协议无效(旧客户端?)

32-服务端提示

只有使用修改后的客户端才可以正常连接服务端

31-正常登录


3.2.2 修改配置文件异或密钥

​ 在上篇文章中提到可以通过Nmap的grab_beacon_config扫描出监听器信息。

36-nmap扫描

​ 也可以通过访问链接下载文件,再由CobaltStrikeParser工具(GitHub地址:https://github.com/Sentinel-One/CobaltStrikeParser)解出文件内容

33-破解配置文件

​ 查看这两种脚本的源码,可以发现它们都是通过异或密钥(3.x为0x69,4.x为0x2E)来解密出相应信息的

37-beacon_config_0x2E

38-beacon_config_0x2E


将Beacon目录下的BeaconPayload.java文件中的0x2E修改为其他值(这里显示为46,46的十六进制为0x2E),修改后构建工件

39-修改0X2E

用CrackSleeve(GitHub地址:https://github.com/izj007/CrackSleeve)来解密jar中的dll文件

1
2
编译文件: javac -encoding UTF-8 -classpath cobaltstrike.jar CrackSleeve.java
解密: java -classpath cobaltstrike.jar;./ CrackSleeve decode

43-解密dll

解密后用IDA来编辑dll,以beacon.dll文件为例

通过IDA的查找字节功能查找0x2E

44-IDA查找

找到xor开头的一行,双击跳转

45-查找xor

在菜单栏的Edit—Patch program—Change byte… 修改字节

46-进入修改字节

将2E改为其他的值

47-修改字节

在菜单栏Edit—Patch program—Apply patches to input file… 保存修改

48-应用保存

需要修改的文件除了beacon.dll外还有beacon.x64.dll、dnsb.dll、dnsb.x64.dll、pivot.dll、pivot.x64.dll、extc2.dll以及extc2.x64.dll。

全部修改完成后通过CrackSleeve再加密回去,加密的密钥就使用对应版本的密钥

1
java -classpath cobaltstrike.jar;./ CrackSleeve encode

49-加密

全部完成后将dll文件放入cobaltstrike.jar的sleeve文件夹下,至此修改完成

50-尝试上线

HTTP以及HTTPS上线正常

通过Nmap的grab_beacon_config扫描,从cs的web日志中看到Nmap对cs服务端成功发起了请求,但未能扫出监听器信息

52-Nmap扫描结果

通过访问链接下载文件,再由CobaltStrikeParser解文件内容,也未能解出

54-解失败


总结

本文主要对上篇总结进行了补充。一个隐匿的攻击基础设施是红队的重要组成部分,隐匿的方法也不仅仅局限于本文提供的方法,只有不断的探索或学习大佬们的新隐匿方法,才能让我们的攻击基础设施更加完善。

参考链接

https://www.blackhillsinfosec.com/dns-over-https-for-cobalt-strike/

https://bluescreenofjeff.com/2018-04-12-https-payload-and-c2-redirectors/

https://bluescreenofjeff.com/2016-06-28-cobalt-strike-http-c2-redirectors-with-apache-mod_rewrite/

https://github.com/threatexpress/cs2modrewrite

https://github.com/kyleavery/TitanLdr

https://github.com/Sentinel-One/CobaltStrikeParser

https://mp.weixin.qq.com/s/fhcTTWV4Ddz4h9KxHVRcnw

https://github.com/ca3tie1/CrackSleeve

本文提及的工具仅供学习使用,禁止用于非法用途,本文不承担任何责任