如何隐蔽你的C2

2022-01-20 15:48:14 浏览数 (1)

如何隐蔽你的C2

文章首发于安全客:https://www.anquanke.com/post/id/231448

端口特征修改

证书特征修改

修改服务端证书CobaltStrike.store

修改上线的证书

流量特征修改

SNI域前置

申请配置CDN

配置CS profile文件

开启Listener

生成木马上线

ESNI域前置

ESNI 在红蓝对抗中,如果攻击者不通过手段隐藏C2服务器,这样可能导致C2被溯源以及被反撸。以下内容讲述如何通过手段隐蔽C2。

端口特征修改

CobaltStrike的连接端口默认为50050,这是个很明显的特征。要想修改这个默认端口,我们可以修改teamserver文件,将50050端口改成任意其他端口均可。

证书特征修改

Keytool是一个java数据证书的管理工具,Keytool将密钥 和 证书 存放在一个称为 keystore 的文件中,即.store后缀的文件中。

Keystore是什么?keystore是java的密钥库,用来进行通信加密,如数字签名。keystore就是用来保存密钥对的公钥和私钥。Keystore可理解为一个数据库,可以存放很多个组数据。

每组数据主要包含以下两种数据:

  • 密钥实体 --- 密钥(secret key)又或者私钥和配对公钥(采用非对称加密)
  • 可信任的证书实体 --- 只包含共钥

查看证书文件:keytool -list -v -keystore xx.store

修改证书密码:keytool -storepasswd -keystore xx.store

修改keystore的alias别名:keytool -changealias -keystore xx.store -alias source_name -destalias new_name

修改alias(别名)的密码:keytool -keypasswd -keystore xx.store -alias source_name

keystore

查看CobaltStrike的默认store文件

keytool -list -v -keystore cobaltstrike.store

可以看出CobaltStrike默认的store文件中的Alias name 、Onwer 和 Issuer 的信息,特征都比较明显。

Alias name: cobaltstrike

Onwer: CN=Major Cobalt Strike, OU=AdvancedPenTesting, O=cobaltstrike, L=Somewhere, ST=Cyberspace, C=Earth

Issuer: CN=Major Cobalt Strike, OU=AdvancedPenTesting, O=cobaltstrike, L=Somewhere, ST=Cyberspace, C=Earth

通过直接访问CobaltStrike服务器的端口,也可以看到证书信息。

curl https://192.168.106.5:50050 -v -k

修改服务端证书CobaltStrike.store

服务器端使用的证书CobaltStrike.store,为了掩盖默认SSL证书存在的特征,需要重新创建一个新的不一样的证书 。使用以下命令创建证书:

keytool -keystore cobaltstrike.store -storepass 密码 -keypass 密码 -genkey -keyalg RSA -alias google.com -dname "CN=(名字与姓氏), OU=(组织单位名称), O=(组织名称), L=(城市或区域名称), ST=(州或省份名称), C=(单位的两字母国家代码)"

  • -alias 指定别名
  • -storepass pass 和 -keypass pass 指定密钥
  • -keyalg 指定算法
  • -dname 指定所有者信息

先删除 CobaltStrike 自带的 cobaltstrike.store,然后使用以下命令生成一个新的 cobaltstrike.store 即可!

keytool -keystore cobaltstrike.store -storepass 123456 -keypass 123456 -genkey -keyalg RSA -alias baidu.com -dname "CN=(名字与姓氏), OU=(组织单位名称), O=(组织名称), L=(城市或区域名称), ST=(州或省份名称), C=(单位的两字母国家代码)"

keytool -importkeystore -srckeystore cobaltstrike.store -destkeystore cobaltstrike.store -deststoretype pkcs12

修改上线的证书

cobaltStrike.store 仅仅是服务器端连接的证书。通过https上线使用的证书,不是 cobaltstrike.store,并且,该证书也是默认的!

subject: C=; ST=; L=; O=; OU=; CN=

issuer: C=; ST=; L=; O=; OU=; CN=

查看监听的https端口证书,可以看出证书值都是空的

如果想要修改这个证书,需要修改Malleable C2 profile。详情看官方文档:https://www.cobaltstrike.com/help-malleable-c2

Self-signed Certificates with SSL Beacon 和 Valid SSL Certificates with SSL Beacon 这两个都是用来修改https上线使用的证书的。

  • Self-signed Certificates with SSL Beacon 这里是自己设定的自签名证书。
  • Valid SSL Certificates with SSL Beacon 这里是叫我们使用有效的证书。我们可以使用之前修改过的cobaltstrike.store,也可以使用从其他地方弄过来的证书

我们可以在启动CobaltStrike的时候,指定一个profile文件,然后在文件中配置上线时使用的证书文件即可修改上线时默认的证书。

流量特征修改

流量特征修改使用域前置技术,域前置是一种用于隐藏真实C2服务器IP且同时能伪装为与高信誉域名通信的技术,多用于木马受控端和控制端之间的隐蔽通信。

简言之,利用该技术,可以让受控端以为程序是在和一个高信誉域名通信,但实际上却是在和我们的C2服务器进行通信,效果如下:

SNI域前置

申请配置CDN

正常情况下,第一步我们要做的是先申请一个域名(这个域名的作用是用来配合 CDN 来隐藏我们的C2服务器),然后再申请一个CDN对我们所申请的域名进行加速,在这个过程中CDN会要求我们在域名的解析配置中设置相应的 CNAME。

但由于某云有一个有趣的特点:当 CDN 配置中的源 IP 为自己云服务器时,加速时会跳过对域名的检验,直接与配置中的域名绑定的源服务器IP进行通信。利用该特性,我们不需要去申请域名,也不需要配置该域名的CNAME记录了。换言之,只要我们的C2服务器属于某云的服务器,那么我们就无需申请域名,只需要在申请 CDN 时随便填一个没有人绑定过的域名就行,而且这个域名我们可以填成任何高信誉的域名,例如 test.microsoft.com、wwws.microsoft.com 等。

接下来我们直接去申请 CDN 即可,这里我把域名填为 wwws.microsoft.com。这里端口80和443端口。80端口流量是不加密的,443端口流量是加密的。

这里需要注意的是:

  • 如果是443端口,则后面的 Listener 得是windows/beacon_https/reverse_https
  • 如果是80端口,则后面的 Listener 得是windows/beacon_http/reverse_http

然后下一步即可配置CDN完成

最终结果如下

配置CS profile文件

CDN 申请完成后,就可以开始编辑 Cobalt Strike 要用到的 C2 Profile 文件了,我们直接使用开源项目 Malleable-C2-Profiles 中的 amazon.profile,但需要把其中的 Host 头改成我们自己在 CDN 中绑定的域名,如图:

然后启动CobaltStrike服务端,加载该profile文件

./teamserver C2ip 密码 xx.profile

开启Listener

使用ip作为Hosts

以下HTTPS Host(Stager)

配置完成后如图

打开web日志试图,请求CDN服务器ip然后指定Host头部,可以看到web日志有响应

curl 125.xx.xx.xx -H "Host:wwws.microsoft.com" -v

使用域名作为Hosts

以下HTTPS Host(Stager)

配置完成如图

打开web日志试图,请求CDN服务器ip然后指定Host头部,可以看到web日志有响应

curl xx.xx.com -H "Host:wwws.microsoft.com" -v

生成木马上线

使用各种方式均可上线。这里我们使用Scripted Web Delivery(S)上线

然后在目标机器执行命令上线,可以看到,CS上显示该机器的外部ip为某云的ip,并且该ip是动态变化的。

如果想要上线显示其真正的ip,修改profile文件中的trust_x_forwarded_for为true即可。

在目标机器上执行 netstat -ano 命令查看端口连接,只能看到该机器与某云CDN的ip进行连接,即使封锁了该ip,仍然会与CDN其他ip进行连接,这样就永远无法阻断与C2服务器的连接了

并且使用 wireshark 抓包,可以看到访问的是我们在申请CDN时配置的 wwws.microsoft.com 这个高信任域名。(如下的包得是配置80端口才能抓到,443端口流量加密的抓取不到)

并且不会与我们的C2服务器真实ip进行通信

最终上线流程图

通过比较ip作为Hosts和域名作为Hosts,可以发现两者各有优势。

  • 使用ip作为Hosts:ip是全国各地正常的ip,但是证书不可信
  • 使用域名作为Hosts:证书可信,但是域名是解析到某云CDN的域名,这样容易被发现

ESNI域前置 以下仅限于使用域名作为Hosts,使用ip作为Hosts不用考虑这些。

在HTTP(S)请求中,目标域名通常显示在三个关键位置:DNS查询,TLS(SNI)拓展及HTTP主机头中。通常,这三个地方都会是我们要访问的域名地址,然而,在”Domain Fronting”请求中,DNS查询以及SNI携带了一个域名(前域),而在HTTP host头中携带了另一个域名(隐蔽的,被禁止访问的域名),简单的图例如下:

ESNI

TLS是网络通讯的安全基础(HTTPS)。TLS提供的认证加密使得用户可以确定他们在与谁通讯, 并确保通讯信息不被中间人看到或篡改。虽然TLS可以隐藏用户通讯的内容,但其并不能总是隐藏与用户通讯的对象。比如TLS握手可以携带一个叫做加密服务器名称指示(SNI)的扩展, 这个扩展帮助客户端告诉服务器其想要访问的网站的域名。包括x国在内的审查者利用这一扩展来检查并阻止用户访问特定的网站。

TLS1.3引入了加密SNI(ESNI)。简而言之就是用加密了的SNI阻止中间人查看客户端要访问的特定网站。(更多ESNI的益处请见Cloudflare的介绍文章https://blog.cloudflare.com/encrypted-sni/ )。ESNI有让审查HTTPS流量变得更加困难的潜能; 因为不知道用户使用ESNI访问的网站,审查者要么不封锁任何ESNI连接,要么封锁所有的ESNI连接。

以下是DefCON28大会分享的议题:Domain Fronting is Dead,Long Live Domain Fronting:Using TLS 1.3 to Evade Censors,Bypass Network Defenses,and Blend in With the Noise https://www.youtube.com/watch?v=TDg092qe50g&t=646s

但是目前我们国内使用不了ESNI域前置,因为xx防火墙会把所有ESNI的流量包都给丢弃。

github上的一些ESNI域前置的项目:

  • https://github.com/SixGenInc/Noctilucent
  • https://github.com/Ridter/DomainHiding

参考文章:https://www.anquanke.com/post/id/195011#h2-2

https://mp.weixin.qq.com/s/5MWDXN3eCaw9m-XHDGaXcQ

0 人点赞