互联网|对红队利器Cobalt Strike一个历史遗留漏洞的研究( 四 )
config = self.data.read().split(" ")
self.bid = config[0]
self.pid = config[1]
self.ver = config[2]
self.intz = config[3]
self.comp = config[4]
self.user = config[5]
self.is64 = config[6]
if config[7] == "1":
self.barch = "x64"
else:
self.barch = "x86"
return
self.charset = self.readShort("
self.charset_oem = self.readShort("
self.bid = self.readInt()
self.pid = self.readInt()
self.port = self.readShort()
b = self.readByte()
if self.flag(b, 1):
self.barch = ""
self.pid = ""
self.is64 = ""
elif self.flag(b, 2):
self.barch = "x64"
else:
self.barch = "x86"
self.is64 = int(self.flag(b, 4))
self.high_integrity = self.flag(b, 8)
self.ver, self.intz, self.comp, self.user, self.proc = self.data.read().split(" ")
当解析器在解密的元数据blob上运行时 , 将产生以下输出:
本文插图
元数据解析
现在 , 我们有足够的信息来生成和加密我们自己的元数据 。
对称加密
Cobalt Strike使用CBC模式下的AES-256和HMAC-SHA-256进行任务加密 。 对于存在该漏洞的Cobalt Strike版本 , 该版本已包含在试用版中 , 但是从3.6版开始 , 在未经许可的Cobalt Strike版本中不再启用此功能 。 这意味着 , 对于受害者使用的某些Cobalt Strike破解版或试用版 , 网络通信将以明文形式发送 。 但是 , 当我们查看3.6之前的版本时 , 始终启用任务加密 。
解析完元数据后 , Team Server将通过检查元数据中指定的AES密钥是否已经为BeaconID值注册(也从元数据中进行了解析)来检查该Beacon是否是新的Beacon 。
如果先前未为BeaconID注册任何AES密钥 , 则它将继续并为Beacon会话设置AES密钥 。 这是通过获取解密的Beacon元数据的前16个字节来实现的 。 通过计算SHA256总和以创建256位密钥 , 将其前半部分(8个字节)用于导出AES密钥 。 下半部分用作HMAC密钥也是如此 。 你可能已经在上面的输出中注意到了这些解析 。 这些密钥可用于任务加密和解密 。
以下Python脚本显示了AES加密/解密的工作方式 。
import hashlib
import hmac
import binascii
import base64
import sys
import struct
from Crypto.Cipher import AES
HASH_ALGO = hashlib.sha256
SIG_SIZE = HASH_ALGO().digest_size
class AuthenticationError(Exception):
pass
def compare_mac(mac, mac_verif):
if len(mac) != len(mac_verif):
print "invalid MAC size"
return False
result = 0
for x, y in zip(mac, mac_verif):
result |= ord(x) ^ ord(y)
return result == 0
def decrypt(encrypted_data, iv_bytes, signature, shared_key, hmac_key):
if not compare_mac(hmac.new(hmac_key, encrypted_data, HASH_ALGO).digest()[0:16], signature):
raise AuthenticationError("message authentication failed")
cypher = AES.new(shared_key, AES.MODE_CBC, iv_bytes)
data = http://news.hoteastday.com/a/cypher.decrypt(encrypted_data)
return data
def readInt(buf):
return buf[4:], struct.unpack(">L", buf[0:4])[0]
推荐阅读
- 互联网|上线半年收获6700万用户,这款聚焦下沉用户的陌生人社交APP是怎么做到的?
- 互联网|5G商用一周年,华为云向互联网企业大抛绣球
- 互联网|中台产品经理实战(14):中台与SaaS、微服务关系
- 互联网|行业观察 | 你所不知道的5G消息
- 互联网|多名知名人物推特被黑,拜登奥巴马都“中招”,比尔盖茨也在其内
- 互联网|发放高利贷,还要窃取用户信息?这些金融APP在秀“道德底线”
- 互联网|东莞先知:数字智能,先觉“先知”
- 云计算|从互联网到AI崛起,上海能弯道超车吗?
- 行业互联网,5G|江苏有线顺利完成园区5G信号开通测试
- 行业互联网,AI人工智能|城市教育大脑以“ AI+ 大数据”为核心 , 引领教育变革