简介
CobaltStrike,曾经的渗透工具之王,正在受到新兴工具Sliver的挑战。Sliver是一个用Golang编写的跨平台通用植入框架,旨在替代CobaltStrike。它由BishopFox公司的Joe DeMesy和Ronan Kervella在2019年summercon会议上提出并设计,具有稳定、高性能和安全的通信载荷。作为一个开源且跨平台的工具,它可供安全组织或个人进行测试使用。Sliver推出后受到欢迎,其github仓库在短时间内获得了4k的star数,并已被勒索集团DEV-0237等组织使用。预计不久的将来,这个新兴的后渗透工具将会大放异彩。Sliver自2019年开始到如今已有三年时间,版本更新十分频繁,这也代表该工具正逐步走向成熟阶段。
Sliver自2019年开始到如今已有三年时间,版本更新十分频繁,这也代表该工具正逐步走向成熟阶段;
服务端、客户端以及有效载荷均支持Windows、Linux及Android等三种流行系统和架构,且服务端和客户端通信采用mtls加密通信,防止被检测;
载荷使用mTLS, WireGuard, HTTP(S)以及 DNS等多协议保护对外通信,并使用TCP和SMB等进行内网通信;
Windows下存在进程迁移/注入、文件操作、注册表操作和内存命令执行等多种控制功能;
以下将简述该工具的使用及与CobaltStrike等老牌后渗透工具进行对比,看一看Sliver的优缺点。
2 Sliver介绍及使用
Sliver是作为跨平台植入和协作使用的目的设计而成,根据其官方所述,Sliver的原理控制图如下图所示(笔者略有增加)。
可以发现,Sliver同CobaltStrike一样均采用服务器进行核心控制,转发客户端和被控机的通信消息,稍显不同的是,Sliver的服务器也可直接对被控机进行控制。
2.1 安装协作
Sliver官方提供了不同客户端及服务端的安装文件,包括windows、linux和macos系统,基本覆盖了流行系统,做到了大部分平台适配,下载地址为https://github.com/BishopFox/sliver/releases。如下图所示:
原则上服务端及客户端均可以使用对应的安装包进行安装运行,且安装包安装不需要额外的环境配置,但是由于windows服务器存在功能限制,Sliver官方建议服务端使用linux或macos的服务器进行配置。而CobaltStrike限于使用java打包,服务端与客户端的运行依赖于java环境,而客户端则需要布置在具有图形界面的服务器上。
在实用性上,CobaltStrike依赖于java环境跨平台,Sliver则使用go语言在指定平台进行编译跨平台,Sliver的服务端及客户端兼容性均略高,也省去了安装环境的必要。
笔者这里使用kali虚拟机当作服务器,ip地址为192.168.83.166,运行服务端文件,运行界面如下图:
开启Multiplayer Mode模式,可以存在不同系统下的多客户端共同管理。首先需要在服务端创建相关配置文件,然后客户端使用并开启相关配置,如下图所示:
该配置文件为校验信息,使用ECC非对称加密算法实现登录通信,如下图所示:
然后拷贝该配置文件到客户端,只需要运行对应的客户端文件,并导入配置然后运行即可。这里使用的客户端分别是win10系统(ip:192.168.83.164)以及linux系统下自身(ip:192.168.83.165),如下图所示:
通过服务端生成的配置信息可以看出,服务端与客户端通信验证方式为ECC非对称加密算法。CobaltStrike客户端是向Teamserver(CobaltStrike服务端)发送指定的java通信打包的登陆密码即可登录,存在爆破的可能性,而且由于登录返回信息与正常流量存在差异,对于暴露在外的服务器可以进行全网扫描探测,所以不得不对CobaltStrike进行二次开发以规避风险。而Sliver只有获取相应私钥才能与之服务端进行通信,安全性会得到很大的保障。
2.2 载荷制作
Sliver将生成的载荷称之为Implants,这与CobaltStrike工具中生成的stageless和stager拉取的stage (beacon)功能一致,均属于第二阶段的有效载荷,也是稳定控制被控机的有效载荷。
2.2.1 植入方式
Sliver在植入载荷方式同CobaltStriket以及Meterpreter一样均有两种方式,非阶段式与阶段式植入,由于非阶段式的载荷与阶段式下载的载荷一致,所以主要关注阶段式即可,如下表所示:
Sliver | CobaltStriket | Meterpreter | |
分阶段 | 1.stager(Meterpreter)+ Implant 2.url download(*.woff)+ Implant | stager+ beacon | stager+ stage |
控制载荷 | Implant | beacon(Reflective自加载) | stage(Reflective自加载) |
优点 | 下载的Implant可以使用非对称算法加密,下载后无法进行解密 | 体积小 | 体积小 |
缺点 | 下载路径为任意名称+.woff,后期可能会被作检测,且文件体积较大 | 下载及解密算法已知 | 下载及多重解密算法已知 |
对于需要限制载荷长度的环境下,Sliver使用两种方式进行分阶段注入。可以采用Meterpreter框架生成stager,下图为Sliver生成stager过程。
可以看到生成的stager是Meterpreter框架下未加密的的x64位的stager,将stager在内存中运行即可下载运行Sliver的Implants。
而且Sliver也支持自定义下载方式,即使用指定的url路径进行获取Implant,且支持使用AES加密下载的Implants文件,如下图所示:
可以使用任意名称拼接woff后缀下载Implants载荷,如下图所示:
2.2.2 载荷类型
2.2.2.1 系统分类
在使用CobaltStrike工具时,有一个很大的缺点就是生成的载荷只能上线Windows主机,其他系统类型则需要插件(如CrossC2)辅助,配置上线过程相当麻烦,Sliver在此基础上进行了一定程度的拓展,Meterpreter则是基本支持了所有系统以及脚本和Web类的代码生成功能。以下是Sliver、 CobaltStriket和Meterpreter生成载荷运行系统的类型对比表,可以发现Sliver基本覆盖流行系统,除此之外Sliver还包含shellcode、 service以及可执行文件,不需要像Meterpreter生成的载荷一样进行二次加工,便利性大大提高。
Sliver | CobaltStrike | Meterpreter | |
windows | √ | √ | √ |
linux | √ | × | √ |
macos | √ | × | √ |
Android | × | × | √ |
… |
2.2.2.2 通信分类
在使用CobaltStrike中会根据被控机的特点使用不同的通信方式以达到上线目的,其中根据使用场景分为出网通信以及内网通信两种方式,内网通信需要建立在出网通信成功的基础才能运行,出网通信载荷在内网通信载荷中充当流量转发的桥梁,这里内网通信不做引述。
CobaltStrike | 出网 | HTTP(S) | 通过HTTP(S)协议,并结合cdn转发技术或者御前置技术隐藏真实C2 |
DNS | 使用DNS解析内容传递数据,在只有DNS协议换环境下使用,且较为隐蔽 | ||
内网 | SMB | 目标机器须开启445端口,使用命令管道控制 | |
Bind TCP | 使用TCP协议,可更改端口 |
Sliver的通信方式包含了多种方式进行通信。其中内网通信方式与CobaltStrike相同。而外网通信则新增加的通信方式有MTLS(相互身份验证协议)和WireGuard(VPN协议),这两种通信方式都十分隐蔽,不容易被流量设备发现。
值得注意的是,Sliver开发了一个多协议多ioc控制功能,即可以使用多种通信方式不同的ioc进行控制,避免生成的单一通信或者ioc连接失败。通信协议顺序优先级由高到低依次为MTLS -> WG -> HTTP(S)-> DNS。
多通信如下图:
多ioc随机--连接如下图:
2.2.2.3 模式分类
另外的,Sliver设计的Implants具备两种模式:beacon模式和session模式,区别在于beacon模式属于异步通信方式,即执行累计的任务后,定期连接服务端返回数据,该模式与CobaltStrike的通信方式相同,而session模式则进行持久连接,前者通信更加隐蔽,后者执行命令响应速度更快。当前Implants可由beacon模式切换至session模式,反之的功能官方尚未实现。
2.3 载荷上线
2.3.1 开启监控
与CobaltStrike和Meterpreter相同,Sliver投放载荷前需要对载荷中ioc以及端口进行监控,值得注意的是需要根据对应的协议去开启不同的监控,这点Sliver官方并未详细说明,否则无法上线,如下图所示:
2.3.2 投递载荷
作为后渗透工具,CobaltStrike具有官方默认的载荷投递方式,包括钓鱼攻击、邮件攻击或者利用漏洞模板等直接投递木马。
而Sliver没有相关默认的投递载荷方式,需要使用者自己编写相关代码进行投递,笔者直接复制生成的木马在windows(ip:192.168.83.163)和系统为linux(ip:192.168.83.167)的被控机直接运行。
使用use指令观察被控机上线情况,发现存在上线的session或者beacon。
使用use [uuid]选择对被控机进行控制,下图分别是对windows系统和Linux系统进行相关指令控制。
查看相关控制指令如下图所示,发现按照功能分为window特殊指令和常规指令,但linux的Implant中没有特殊指令。
Sliver载荷基本功能对比如下表所示,与CobaltStrike对比发现目前功能仍相对较少,尤其是一些权限提取及数据获取方面稍显不足。
但Sliver也做出了一些新的有意思的功能,比如migrate功能。migrate功能为进程迁移,可以将自身转移到同等权限的其他进程下。
相关样本由于是双击打开,所以父进程是explore.exe,准备转移的进程为calc.exe,pid为2136。
执行migrate命令进行转移,可以看到calc.exe产生了流量,但进程树没有发生变化,起到了很好的隐藏效果。
3 Sliver分析及调试
以上简述了关于Sliver的基本使用情况,接下来将通过源码介绍Sliver的核心功能实现方法及防范措施。
3.1 环境准备
3.1.1 调试方法
3.1.1.1 server/client调试
原理:使用delve远程调试sliver-go-v1.18.5源码。
环境准备:ubuntu20.04,vscode,go1.18.5.linux-amd64, sliver-go-v1.18.5(版本一一对应)。
1.首先安装go以及delve工具,配置相应go环境变量,以及安装好Sliver的静态数据(完整成功运行Sliver源码下的go-assets.sh文件)
2.设置.vscode文件下的配置文件,包括task.json、launch.json和setting.json文件。
task.json |
{ "label": "Run Debug Server", "type": "shell", "command": "dlv", "args": [ "debug", "--build-flags=\\"-tags osusergo,netgo,cgosqlite,sqlite_omit_load_extension,server -ldflags="-X github.com/bishopfox/sliver/client/version.Version=0.0.0 -X github.com/bishopfox/sliver/client/version.CompiledAt=Never -X github.com/bishopfox/sliver/client/version.GithubReleasesURL=https://api.github.com/repos/BishopFox/sliver/releases -X github.com/bishopfox/sliver/client/version.GitCommit=debug -X github.com/bishopfox/sliver/client/version.GitDirty=Dirty -X github.com/bishopfox/sliver/client/assets.DefaultArmoryPublicKey=RWSBpxpRWDrD7Fe+VvRE3c2VEDC2NK80rlNCj+BX0gz44Xw07r6KQD9L -X github.com/bishopfox/sliver/client/assets.DefaultArmoryRepoURL=https://api.github.com/repos/sliverarmory/armory/releases"\\"", "--headless", "--listen=:2345", "--api-version=2", "--log", "github.com/bishopfox/sliver/server" ], "presentation": { "echo": true, "reveal": "always", "focus": true, "showReuseMessage": false, "clear": true, "panel": "new", }, "problemMatcher": [ "$go" ] } |
launch.json |
{ "version": "0.2.0", "configurations": [ { "name": "Debug Server", "type": "go", "request": "attach", "mode": "remote", "remotePath": "${workspaceFolder}", "port": 2345, "host": "127.0.0.1", "trace": "log" }, ] } |
setting.json (linux amd64环境) |
{ "go.toolsEnvVars": { "GOOS": "linux", "GOARCH": "amd64" } } |
3.运行指定变量生成编译文件,下为server调试代码,如果需要client调试,需要更改x相关位置为client。
dlv debug --build-flags="-tags osusergo,netgo,cgosqlite,sqlite_omit_load_extension,server -ldflags="-X github.com/bishopfox/sliver/client/version.Version=1.1.2 -X github.com/bishopfox/sliver/client/version.CompiledAt=Never -X github.com/bishopfox/sliver/client/version.GithubReleasesURL=github.com -X github.com/bishopfox/sliver/client/version.GitCommit=aabbcc -X github.com/bishopfox/sliver/client/version.GitDirty=Dirty"" --headless --listen=:2345 --api-version=2 --log github.com/bishopfox/sliver/server dlv debug --build-flags="-tags osusergo,netgo,cgosqlite,sqlite_omit_load_extension,client -ldflags="-X github.com/bishopfox/sliver/client/version.Version=1.1.2 -X github.com/bishopfox/sliver/client/version.CompiledAt=Never -X github.com/bishopfox/sliver/client/version.GithubReleasesURL=github.com -X github.com/bishopfox/sliver/client/version.GitCommit=aabbcc -X github.com/bishopfox/sliver/client/version.GitDirty=Dirty"" --headless --listen=:2345 --api-version=2 --log github.com/bishopfox/sliver/client |
4.在主目录下生成了指定的调试文件:
5.在server/client的main.go文件中的main函数下断点,F5进行调试,以下为调试成功界面:
3.1.1.2 mplant调试
结合对源码的分析,可以看出生成Implant时Sliver会通过输入的配置文件对模板源码进行一定的删减修改,然后会在~/.sliver/slivers生成指定的源码,如下图所示:
其中生成源码对比模板源码如下图所示,因此调试时需要对指定的生成源码进行调试才能成功。
1.类似server/client调试配置好基本环境。
2.设置.vscode文件下的配置文件即launch.json文件。
launch.json |
{ "version": "0.2.0", "configurations": [ { "name": "Debug Implant", "type": "go", "request": "attach", "mode": "remote", "port": 2345, "host": "127.0.0.1", "trace": "log" }, ] } |
3.运行指定变量生成编译文件,下为Implant调试代码,监听源端口需要与launch.json保持一致。
dlv exec --api-version 2 --headless --listen 127.0.0.1:2345 --accept-multiclient ./implant |
4.在Sliver的sliver.go文件中的main函数下断点,F5进行调试,以下为调试成功界面:
3.1.2 目录功能
(1)Client/:主要提供客户端功能,其中server对session的控制也使用client的功能。
ncommand/:client的控制台命令,接收event消息并进行分配。
(2)mplant/:主要包含生成Implant植入的模板源码,然后根据配置输入的不同,修改删减模板源码然后编译生成载荷。
nsliver/:模板源码,根据配置信息删减编译生成Implant源码,然后进行编译混淆等措施。
(3)protobuf/:使用grbc协议在serevr及client间传递消息。
nclientpb/: client消息发送到server。
nsliverpb/: server消息发送到client。
(4)server/:主要进行监控session服务以及多用户服务。
nconfig/: 配置文件解析器。
ngenerate/:生成载荷。
nrpc/:远程过程调用实现,通过使用RPC的API调用客户端相关的二进制文件代码。
3.2 源码解析
3.2.1 client上线
Siver使用gRPC框架来搭建server/clinet控制系统,并使用Token进行校验,gRPC是一个高性能、通用的开源RPC框架,其由Google主要面向移动应用开发并基于HTTP/2协议标准而设计,基于ProtoBuf(Protocol Buffers)序列化协议开发,且支持众多开发语言。以下分别从server/clinet源码进行解析。
clinet上线功能首先需要server开启multiplayer模式,否则无法连接,服务端监听客户端上线端口默认为31337(可以修改);
server开启Token安全验证,并开启监听,使用event循环接受信息;