01Cobalt Strike反制综述
参考文档:https://forum.butian.net/share/708
Cobalt Strike
近些年来被称之为多人线上运动神器,在目前攻防大背景下,由Cobalt Strike
展开的红蓝对抗技术不断积累,其中域前置技术、修改特征等手段来躲避各种流量检测工具,而Cobalt Strike
的特征识别也成为网络空间测绘引擎重点关照的点,而且各种威胁情报中,对于Cobalt Strike
的特征标记也最常见。如果在我们实战攻防中,遇到了红队使用Cobalt Strike
来钓鱼等操作时,我们如何在短时间内扰乱红队,甚至将红队的Cobalt Strike
服务器宕机,又或者是红队使用了域前置技术,短时间内无法溯源的情况下,如何能够扳回一局?本文参考了大量的文章,一起来学习复现一下如何从一个木马到反制红队Cobalt Strike
服务器。
本文参考了大量的文章,一起来学习复现一下如何从一个木马到反制红队Cobalt Strike
服务器。
02本文说明
测试Cobalt Strike
版本:4.3
注意:本文时常跨度较长,文章中部分图可能无法完全对接文字,但是方法都是一模一样的,本文针对的都是内网环境测试,下文如未做特殊说明,cs
版本均为4.3
。
03CS简单版上线分析
在Cobalt Strike没有使用域前置的情况下,进行测试。
在攻击的时候,使用最简单的Beacon HTTP
模式:
生成一个exe
文件,然后运行在Windows7
虚拟机中,并准备抓包分析:
监听vnic0
这张卡,可以监控到虚拟机win7
的流量:
双击之后,上线成功,也抓到了流量:
暂停抓包,开始分析:
使用的攻击机ip地址为:10.30.7.240因为使用的是HTTP的beacon,所以在这里使用命令进行过滤:ip.addr == 10.30.7.240 && http在这里如果在实战中,是没法知道cs服务端的ip地址的,在这里可以关闭虚拟机的浏览器,确保没有http服务的时候,直接使用http过滤是一样的:
过滤方法:ip.addr == 10.30.7.240 && http
过滤方法:http
由此可以看到,当前过滤得到的结果是一样的。
追踪第三条数据可以看到一个cookie
信息:
GET /IE9CompatViewList.xml HTTP/1.1 Accept: */* Cookie: Mkq5CSB3bIJnuXwR+A3nCJjQn2c1vYk6XjIUcDQJQao3hqnTIng4zRWayhxpey74n9uBA8mVcRMdrr2LHPqtfOI9Uuysz5v9ACTTydHE5/x6h/tW2MB+J8jonn4Xtl2aaSlPXrmG+njwN1EOTkucrza6bCPdx0WHFLElFtotcZU= User-Agent: Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0; MASP) Host: 10.30.7.240 Connection: Keep-Alive Cache-Control: no-cache HTTP/1.1 200 OK Date: Fri, 24 Dec 2021 08:31:51 GMT Content-Type: application/octet-stream Content-Length: 0
在这里用一个脚本复现下:
# -*- encoding: utf-8 -*- # Time : 2021/12/24 16:52:07 # Author: crow import requests url = 'http://10.30.7.240:80/IE9CompatViewList.xml' header = { 'Accept':'*/*', 'Cookie': 'Mkq5CSB3bIJnuXwR+A3nCJjQn2c1vYk6XjIUcDQJQao3hqnTIng4zRWayhxpey74n9uBA8mVcRMdrr2LHPqtfOI9Uuysz5v9ACTTydHE5/x6h/tW2MB+J8jonn4Xtl2aaSlPXrmG+njwN1EOTkucrza6bCPdx0WHFLElFtotcZU=', 'User-Agent': 'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0; MASP)', 'Host': '10.30.7.240', 'Connection': 'Keep-Alive', 'Cache-Control': 'no-cache' } res = requests.get(url,headers= header) # print(res.url) print('-'*20) print(res.text) # 无返回 print('-'*20) print(res.headers) # {'Date': 'Fri, 24 Dec 2021 09:04:53 GMT', 'Content-Type': 'application/octet-stream', 'Content-Length': '0'} # print('-'*20) # print(res.status_code)
在cs
界面将原来的机器清除,运行之后,cs
上线。
在这里知道那个cookie
是非对称RSA
加密过的,如果想解密,需要一个私钥Private Key
才能解密。
Cookie: Mkq5CSB3bIJnuXwR+A3nCJjQn2c1vYk6XjIUcDQJQao3hqnTIng4zRWayhxpey74n9uBA8mVcRMdrr2LHPqtfOI9Uuysz5v9ACTTydHE5/x6h/tW2MB+J8jonn4Xtl2aaSlPXrmG+njwN1EOTkucrza6bCPdx0WHFLElFtotcZU=
关于私钥获取在下一节。
04Private Key与Public Key
现在以上帝视角在Cobalt Strike
服务器上进行解密:
java -cp "cobaltstrike.jar" DumpKeys.java
此时,注意:
环境要在JDK11
版本下运行。还要把这个java
文件放置在CS服务器的CS文件夹下,与“cobaltstrike.jar
“同一个目录下。(参考:https://forum.butian.net/share/708)
Private Key: MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAMyLIY+FyD/7cPtjZZYgjYVbuRYiF9VkGGrF6yKXl093vLDY9osCXiXOpas96nOApW13O5pet1MD1sMBCEDqTYCWC0qF0+cQDcpc22EIiQk185uMkBx0DuSPsuLo533FCWLtThHE9II7bcOe4jb3AorUv/2SrxAXkXwS6+MrwuQNAgMBAAECgYEArgRATSZ4M1brzDPIHW0cebSLRrVCqZ062LwBS7DEXit0MNClD6a4ClpAv+sxJ4rvMq4Z2z9xoALIF6ctKm0r+RBQJrjHC9IIzKF3+a5+lOKIFdVF2WtSN1L9Njn0of2W/IMlg95U21krq8gZU+7lsISoSGmlWxuiT5xLVSKPWVECQQDl4L5w8XWbUbn+HkXPUpddLVQr7eax9YIPYEZUp9bDAbuwusFp+POug7dMZPFAJ+GkPnfsbsl9Pv+qwr6LXgovAkEA48llmeGPEzD8gZzJWya+rxRxFG+GzQKUq8FVRM2/kjJJ8n9DVbVWQAovDYoOAozdxzYk6IGsN0TvfjRW8KGygwJBAOAmZYx75dGtv06q9idSwYV5zbmIIIsmecvEdM/XWPKNnhaWBELxHavtg65aP2Pvf3ZH82f4H0ChTWuUuXfsGsECQFYLWanLHnStaHS9eQJJnHYeTqjdiBohA2/t0/vtjJP5Ex3bHOBfY3lFX4jJwYkNFSmPNlntwdQO4jjWJJE5Q2kCQFYa/PNGTjYiVikgo5OuB6JQfITp8Ny9v0fKP0LNhmBSjkbKSRz74pA/63eb3NI7+CuB2dJUA9ZuwkkMBwjY5yg= Public Key: MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDMiyGPhcg/+3D7Y2WWII2FW7kWIhfVZBhqxesil5dPd7yw2PaLAl4lzqWrPepzgKVtdzuaXrdTA9bDAQhA6k2AlgtKhdPnEA3KXNthCIkJNfObjJAcdA7kj7Li6Od9xQli7U4RxPSCO23DnuI29wKK1L/9kq8QF5F8EuvjK8LkDQIDAQAB
在这里就取到了私钥,有了私钥之后可以在线解密:
解密网站:https://the-x.cn/cryptography/Rsa.aspx
(我没有解密成功,注意base64和hex编码等问题),在这放一张解密成功的:
在这里是可以看到上线的主机的若干信息的。
当然,也可以使用https://github.com/Apr4h/CobaltStrikeScan
中的工具直接解析Beacon
的配置和payload
:
使用方法,当木马运行之后,直接在运行木马的机器中,使用命令行中运行该exe
文件:
CobaltStrikeScan.exe -p
在实际情况中,无法取得私钥的,但是在有公钥的情况下或许就可以直接上线机器,详细分析请见下节。
05beacon解密分析
5.1 上线流程分析
5.1节引用参考:https://www.secpulse.com/archives/165561.html
攻击者利用CS Server生成新的Beacon监听(包括一对非对称公私钥)并生成Stager;
攻击者投递Stager到受控主机;
受控主机在Exploit阶段执行小巧的Stager;
受控主机根据Stager UrI请求特征向Beacon Staging Server下载体积较大更复杂的Stage到本地,Beacon Staging Server会校验UrI的合法性;
Stage解密并解析Beacon配置信息(比如公钥PublicKey、C2 Server信息);
Stage通过公钥PublicKey加密主机的元数据并发送至C2 Server;
C2 Server用私钥解密数据获取主机元数据。
从上述流程中,我们能Get到2个核心点:
- Stager Uri校验算法
- Beacon配置的解密算法
5.2 流程分析
在上述执行上线的操作里面,一共过滤出了4
个包,其中最关键的就是前3
个:
上线的时候先投递一个小巧的Stager Payload,然后通过Stager 去Beacon Staging Server的某个URI下载完整的Stage(也就是体积更大功能更复杂的Payload),并将其注入内存。这个URI作为特征也可以用来识别CS服务器,做网络测绘。CS中Stager URI校验算法,就是生成4位的随机校验码,将校验码拼接到URI后面即可请求到Stage的代码。
以上两段参考至:https://forum.butian.net/share/708
在这里面提到生成4位的随机校验码,使用的算法是Stager URI
校验算法checksum8
,这个算法的代码部分如下:图片参考:https://www.cnblogs.com/donot/p/14226788.html
由代码可知,当前的checksum8
算法执行方法:
从a-z、A-Z、0-9
字母中,随机使用选择四个字符,在这四个字符计算ASCII
码的值后求和取模,如果结果等于92
的为32位
的,等于93
为64位
的,代码如下:
# -*- encoding: utf-8 -*- # Time : 2021/12/28 16:15:11 # copy Author: crow # 脚本内容参考:https://mp.weixin.qq.com/s/BLM8tM88x9oT4CjSiupE2A # https://www.freebuf.com/articles/network/258138.html import requests import random,time def generate_checksum(input): trial = '' total = 0 while total != input: total = 0 trial = ''.join(random.choice("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789") for i in range(4)) # print(trial) for i in range(4): # tmp = trial[i:i+1] # print('total的值', total) # print('tmp的值:',tmp) # print('ord的值:',ord(tmp)) # print('除后的值:', ord(tmp) % 256) # time.sleep(2) total = (total + ord(trial[i:i+1])) % 256 # print(total) print('64位的stage:',trial) return total # print(total) for j in range(0,6): # generate_checksum(92) # 32位 generate_checksum(93) # 64位
在这里运行每次生成的4
个字符都是不唯一的,但是结果都是符合checksum8
算法的,因此在这里只要是端口对应,直接拼接即可下载stage
文件。