CobaltStrike逆向学习系列(3):Beacon C2Profile 解析
这是[信安成长计划]的第 3 篇文章
关注微信公众号[信安成长计划]
0x00 目录
0x01 Controller 端分析
0x02 Beacon 端分析
0x03 展示图
在上一篇文章中完成了 Stageless Beacon 生成的分析,接下来就是对 Beacon 的分析了,在分析上线之前先将 C2Profile 的解析理清楚,因为 Beacon 中大量的内容都是由 C2Profile 决定的。
而且,目前 C2Profile 也是被作为检测 CobaltStrike 的一种手段,只有在理解了它的实现原理,才能真正明白检测原理和绕过方法。
0x01 Controller 端分析
直接跟到 beacon/BeaconPayload.java,看 exportBeaconStage 方法
对于前面值的获取暂时不管,直接看重点,是如何添加的,因为最后是直接把 settings 转 byte 数组,然后混淆后 Patch 的,所以就重点看一下 settings 都干了什么事
看一眼 settings 的设置,可以很明显的发现四个方法 addShort、addInt、addString、addData
但是可以发现 addString 根本上调用的就是 addData,所以重点就是 addShort、addInt、addData 三个方法
再回头看一下前面在调用时候的情况,后面的参数是需要添加进去的内容、长度,但在第一个参数位置还有一些不明白含义的数字,这个序号是在 Beacon 端解析 C2Profile 的时候需要用到的,在后面来进行解释。
在分析这三个关键方法的时候,还有三个 final 类型的值需要注意一下,到这里也就可以猜个八九不离十了,C2Profile 一定是用某个字节的值来表示数据类型,然后将对应的数据存储在后面
所以来整体看一下这三个方法,首先将序号添加进来;接着 addShort 添加了 1,addInt 添加了 2,addData 添加了 3,这刚好就是上面所定义的几个值;然后 addShort 添加了 2,addInt 添加了 4,addData 添加了 长度值,所以推测,这个位置应该是后面数据的长度;最后他们都将数据添加在了后面
所以整体的结构应该是
0x02 Beacon 端分析
在理 C2Profile 的时候,顺便把解析前的一些内容一起分析一下,在之前分析 Beacon 生成的时候,已经分析过了,实际执行的 Beacon 是由一个 Loader 加载执行的,所以在实际运行的时候,运行的是 Loader,我们在 CreateThread 下断,然后在线程函数中下断也就跟到了熟悉的 PE 头,这里也就是之前说的引导头
首先,它通过计算偏移的方式调用了 ReflectiveLoad
跟进去后,可以发现 ReflectiveLoad 最后调用 DLLMain 的时候传递的 fdwReason 为 1,同时在 return 的时候,也将 DLLMain 的地址 return 回来了
继续往下跟,可以发现它再次调用了 DLLMain,并且传递的 fdwReason 为 4
接下来就该分析真正核心的 beacon.dll 在 DLLMain 中干了什么事,经过分析发现,当 fdwReason 为 1 时,实际执行的是解析 C2Profile 的操作,当 fdwReason 为 4 时,才是真正的功能执行,很明显,这里我们更关心的是解析 C2Profile 的操作
跟进分析,先申请了一片 0x800 的内存用于存储,接着有一个很明显的操作,将一片内存异或,这些都与之前分析生成时候的逻辑一致
AAAABBBBCCCCDDDD 的内存特征
4096 的内存大小
0x2E 的异或操作
接着设置了一个结构体,将 C2Profile 的地址存两份,将其大小也存两份,这个结构体在后面解析的时候会用到
之后就是循环解析,并在最后的时候将这片区域抹零
首先在最开始的时候取了 Short 类型,并且这个函数也是结束解析的关键,首先判断一下结构当中的 Size,如果小于 2,直接 return 0,也就是说所有的都解析完了,这个 0 也就刚好在外层结束了整个解析的流程
转换字节序,取两个字节,这个值也就是之前所说的 index,然后将位置偏移加二,总大小减二,返回 index
然后按照刚才的逻辑可以取出 type 和 size
接着将 index*16,并将 type 存储到对应的位置,到这里 index 的作用也就明确了,是用来指定存储的偏移位置的,这样做就相当于内存对齐一样,在查找的时候是非常方便的
接着便是根据 type 类型来决定执行操作了
获取 Short 与 Int 的都是一样的,就不细说了,重点说一下 Ptr 类型的
先根据 size 申请了一片内存空间,并将地址存储在了对应的位置上,然后去解析
如果剩余大小小于 Ptr 要取的大小,说明有问题,直接 return;然后与之前一样,将所存储的这个结构体的位置偏移后移,将大小进行对应的减小,最后将数据的地址 return 回来
最后使用内存拷贝的方式将数据拷到所申请的内存当中
所以最终在 Beacon 中所使用的样子是这样的
0x03 展示图
所以 Controller Patch 到 Beacon 中的 C2Profile 与 Beacon 在运行时所使用的 C2Profile 长的并不是一样的
Controller
Beacon
CobaltStrike逆向学习系列(3):Beacon C2Profile 解析的更多相关文章
- CobaltStrike逆向学习系列(5):Bypass BeaconEye
这是[信安成长计划]的第 5 篇文章 关注微信公众号[信安成长计划] 0x00 目录 0x01 BeaconEye 检测原理 0x02 Bypass 1 0x03 Bypass 2 0x04 效果图 ...
- CobaltStrike逆向学习系列(11):自实现 Beacon 检测工具
这是[信安成长计划]的第 11 篇文章 关注微信公众号[信安成长计划] 0x00 目录 0x01 检测原理 0x02 检测方案 0x03 存在的问题 0x04 解决方案 0x05 示例代码 0x06 ...
- CobaltStrike逆向学习系列(2):Stageless Beacon 生成流程分析
这是[信安成长计划]的第 2 篇文章 关注微信公众号 [信安成长计划] 0x00 目录 0x01 Patch Beacon 0x02 Patch Loader 0x03 文件对比 0x04 流程图 C ...
- CobaltStrike逆向学习系列(4):Beacon 上线协议分析
这是[信安成长计划]的第 4 篇文章 关注微信公众号[信安成长计划] 0x00 目录 0x01 Beacon 发送 0x02 TeamServer 处理 0x03 流程图 0x04 参考文章 在上一篇 ...
- CobaltStrike逆向学习系列(7):Controller 任务发布流程分析
这是[信安成长计划]的第 7 篇文章 关注微信公众号[信安成长计划] 0x00 目录 0x01 Controller->TeamServer 0x02 TeamServer->Beacon ...
- CobaltStrike逆向学习系列(6):Beacon sleep_mask 分析
这是[信安成长计划]的第 6 篇文章 关注微信公众号[信安成长计划] 0x00 目录 0x01 C2Profile 分析 0x02 set userwx "true" 0x03 s ...
- CobaltStrike逆向学习系列(8):Beacon 结果回传流程分析
这是[信安成长计划]的第 8 篇文章 关注微信公众号[信安成长计划] 0x00 目录 0x01 Beacon 接收与处理 0x02 结果回传 Beacon 在接受完命令并执行后,会将数据加密回传给 T ...
- CobaltStrike逆向学习系列(15):CS功能分析-BOF
这是[信安成长计划]的第 15 篇文章 0x00 目录 0x01 BOF功能分析 0x02 BOF功能执行 0x03 写在最后 其实在看过 RDI 与 DotNet 功能执行之后,BOF 的执行基本就 ...
- CobaltStrike逆向学习系列(10):TeamServer 启动流程分析
这是[信安成长计划]的第 10 篇文章 关注微信公众号[信安成长计划] 0x00 目录 0x01 基本校验与解析 0x02 初始化 0x03 启动 Listeners 在之前的分析中,都是针对 Cob ...
随机推荐
- X-Forwarded-for漏洞解析
首先了解X-Forwarded-for(简称:XFF) X-Forwarded-for:简称XFF,它代表客户端,也就是HTTP的请求真实的IP,只有在通过了HTTP代理或者负载均衡器时才会添加该项. ...
- 【pwn】DASCTF Sept 九月赛
[pwn]DASCTF Sept 月赛 1.hehepwn 先查看保护,栈可执行,想到shellcode 这题需要注意shellcode的写法 拖入ida中分析 一直以为iso scanf不能栈溢出, ...
- ComboBox行高
//行高至少大于20 public static void SetComboBoxLineHeight(ComboBox list, int itemHeight) { list.DropDownSt ...
- python闭包函数&装饰器
一.函数引用 函数可以被引用 函数可以被赋值给一个变量 def hogwarts(): print("hogwarts") # hogwarts() # 函数调用 print(ho ...
- 【海淘域名】GoDaddy账户被锁定后的解决方法
转载自[美国海淘网]http://www.usahaitao.com/Experience/Detail_2886.html 通过ICANN申诉顺利的从国内无良奸商(35互联与商务中国,小编的域名 ...
- i-Urban Renovation使用3D Tiles可视化鸟取县Munakata建筑状态
Cesium中文网:http://cesiumcn.org/ | 国内快速访问:http://cesium.coinidea.com/ 日本的鸟取县,使用i-Urban Renovation appl ...
- 定位new
常规的new是分配内存,然后调用相应的构造函数,而定位new是在已经分配内存的上面调用构造函数: // ConsoleApplication7.cpp : 定义控制台应用程序的入口点. #includ ...
- AOP-基本概念
AOP(概念) 1,什么是AOP (1)面向切面(方面)编程 :利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率. (2)通 ...
- 开源办公套件DzzOffice安装教程
DzzOffice开源办公套件 DzzOffice是一套开源办公套件,适用于企业.团队搭建自己的 类似"Google企业应用套件"."微软Office365"的 ...
- Typecho博客支持emoji表情设置
介绍 大家在typecho博客写文章时,很多人都喜欢使用emoji表情(比如这些图标)但是typecho的数据库类型默认不支持emoji编码,因为Emoji是一种在Unicode位于u1F601-u1 ...