#前言
主要从Nginx反代、Cloudflare CDN和Cloudflare Worker讨论如何隐藏Cobalt Strike Stage uri的特征以及隐藏C2域名和IP的方法。并记录一下部署过程中遇到的坑点。
关于域前置可以参考: Cobalt Strike 绕过流量审计。Cloudflare无法使用域前置,它会校验SNI。
#部署Nginx反向代理及https
如果在Cobalt Strike的C2 malleable配置文件中没有自定义http-stager的uri,那么通过访问默认的uri就能获取到cs的shellcode。加密shellcode的密钥是固定的(3.x 0x69,4.x 0x2e
),所以能解出c2域名等配置信息。下图是nmap扫描插件的扫描结果。
该特征解决方法:
-
修改源码修改加密的密钥(可参考:Bypass cobaltstrike beacon config scan)
-
如果用的是stageless的shellcode(也就是200多k的shellcode),可以直接在malleable配置文件中配置
set host_stage "false"
,或在cs中将stager和stager64给删了。 -
设置iptables,只允许localhost访问CS listener监听的端口。将外部请求通过Nginx转发到localhost上的listener。还可以在Nginx上设置过滤规则来允许特定请求。
#配置nginx.conf
根据CS配置文件进行配置,这里用的是jquery-c2.4.0.profile。(配置Nginx还可通过CS malleable配置文件生成nginx.conf)
在nginx.conf中可以添加对user-agent的校验,只有指定的user-agent才能访问到stage uri。
|
|
#申请免费https证书
使用letsencrypt申请非常方便。使用官方推荐的工具Certbot - Debianstretch Nginx,根据教程几行命令搞定。
注意: 提前在nginx.conf配置文件中设置好server name img.xxx.com
。certbot会自动读取配置文件中的域名,并为它申请证书。生成的证书文件存储在:/etc/letsencrypt/live/img.xxx.com/
目录下。
在nginx配置文件中启用证书。
|
|
#Cobalt Strike 配置证书
-
生成img.xxx.com.store文件
1
openssl pkcs12 -export -in /etc/letsencrypt/live/img.xxx.com/fullchain.pem -inkey /etc/letsencrypt/live/jimg.xxx.com/privkey.pem -out img.xxx.com.p12 -name img.xxx.com -passout pass:123456
1
keytool -importkeystore -deststorepass 123456 -destkeypass 123456 -destkeystore img.xxx.com.store -srckeystore img.xxx.com.p12 -srcstoretype PKCS12 -srcstorepass 123456 -alias img.xxx.com
-
将生成的img.xxx.com.store放到cs目录下,修改teamserver文件最后一行,将cobaltstrike.store修改为img.xxx.com.store和store文件对应的密码。(有必要的话,把端口号也可以改了并设置iptables只允许特定ip访问)
1
java -XX:ParallelGCThreads=4 -Dcobaltstrike.server_port=40120 -Djavax.net.ssl.keyStore=./img.xxx.com.store -Djavax.net.ssl.keyStorePassword=123456 -server -XX:+AggressiveHeap -XX:+UseParallelGC -classpath ./cobaltstrike.jar server.TeamServer $*
-
将keystore加入Malleable C2 profile中
1 2 3 4
https-certificate { set keystore “img.xxx.com.store”; set password “123456”; }
启动cs设置listener
这里https port(bind):
设置的8022(cs会把端口开在8022),在nginx配置文件中的将proxy_pass设置为:https://127.0.0.1:8022。
开启listener之后设置iptables,只允许127.0.0.1访问。这下nmap也就扫不出来了。
|
|
#Cobalt Strike配置CDN
部署cdn是为了隐藏cs服务器的真实IP,以Cloudflare的免费cdn为例,过程也非常简单。
-
添加域名
-
选择免费版本,设置要加速的子域名,并在你的域名服务商处修改域名解析dns为cloudflare的dns。
-
经过cloudflare验证成功后,在进行多地ping,看一下生效没有。
#cloudflare 缓存
cloudflare能开启开发模式,来禁用缓存,但是只有3个小时。可以通过页面规则来永久设置缓存规则。
因为cs配置文件中设置的uri都是js结尾的,所以这里使用*js
来匹配所有uri。
#坑点
配置完cdn后,会发现机器能上线,但是执行命令无回显。这个问题困扰了好半天,一直以为是cloudlflare缓存配置问题,然而禁用缓存后问题依旧存在。最后逐步定位到是cs配置文件的问题。
这里用的是jquery-c2.4.0.profile配置文件。它设置header "Content-Type" "application/javascript; charset=utf-8";
为响应头。修改所有响应头为:header "Content-Type" "application/*; charset=utf-8";
即可正常执行命令回显。
这里的mime-type如果为application/javascript、text/html等,机器执行命令就无法回显。猜测是cdn会检测响应头content-type的值,如果是一些静态文件的mime-type可能就导致这个问题。
#Cloudflare Worker配置
Cloudflare Worker能够执行无服务器函数,免费用户有10万请求/每天的额度。并且能自定义workers.dev的子域。我们可以编写js处理以及转发请求。
js脚本如下(需要设置X-Forwarded-For
头,不然上线的ip是worker的ipv6地址)
|
|
点击保存部署,访问xxx.youtobe-mail.workers.dev
域名,看看是否正常。然后在listener中设置
到此设置完毕,之后通信的请求都是通过xxx.xxx.workers.dev
进行的,隐藏了真实域名和IP。
#参考
- Cobalt Strike 绕过流量审计
- 利用Cloudflare Worker来隐藏C2基础设施 - FreeBuf网络安全行业门户
- 关于Cobalt Strike检测方法与去特征的思考 - 安全内参 | 决策者的网络安全知识库
- CS 合法证书 + Powershell 上线
- GitHub - threatexpress/cs2modrewrite: Convert Cobalt Strike profiles to modrewrite scripts
- malleable-c2/jquery-c2.4.0.profile at master · threatexpress/malleable-c2 · GitHub