这是[信安成长计划]的第 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 解析的更多相关文章

  1. CobaltStrike逆向学习系列(5):Bypass BeaconEye

    这是[信安成长计划]的第 5 篇文章 关注微信公众号[信安成长计划] 0x00 目录 0x01 BeaconEye 检测原理 0x02 Bypass 1 0x03 Bypass 2 0x04 效果图 ...

  2. CobaltStrike逆向学习系列(11):自实现 Beacon 检测工具

    这是[信安成长计划]的第 11 篇文章 关注微信公众号[信安成长计划] 0x00 目录 0x01 检测原理 0x02 检测方案 0x03 存在的问题 0x04 解决方案 0x05 示例代码 0x06 ...

  3. CobaltStrike逆向学习系列(2):Stageless Beacon 生成流程分析

    这是[信安成长计划]的第 2 篇文章 关注微信公众号 [信安成长计划] 0x00 目录 0x01 Patch Beacon 0x02 Patch Loader 0x03 文件对比 0x04 流程图 C ...

  4. CobaltStrike逆向学习系列(4):Beacon 上线协议分析

    这是[信安成长计划]的第 4 篇文章 关注微信公众号[信安成长计划] 0x00 目录 0x01 Beacon 发送 0x02 TeamServer 处理 0x03 流程图 0x04 参考文章 在上一篇 ...

  5. CobaltStrike逆向学习系列(7):Controller 任务发布流程分析

    这是[信安成长计划]的第 7 篇文章 关注微信公众号[信安成长计划] 0x00 目录 0x01 Controller->TeamServer 0x02 TeamServer->Beacon ...

  6. CobaltStrike逆向学习系列(6):Beacon sleep_mask 分析

    这是[信安成长计划]的第 6 篇文章 关注微信公众号[信安成长计划] 0x00 目录 0x01 C2Profile 分析 0x02 set userwx "true" 0x03 s ...

  7. CobaltStrike逆向学习系列(8):Beacon 结果回传流程分析

    这是[信安成长计划]的第 8 篇文章 关注微信公众号[信安成长计划] 0x00 目录 0x01 Beacon 接收与处理 0x02 结果回传 Beacon 在接受完命令并执行后,会将数据加密回传给 T ...

  8. CobaltStrike逆向学习系列(15):CS功能分析-BOF

    这是[信安成长计划]的第 15 篇文章 0x00 目录 0x01 BOF功能分析 0x02 BOF功能执行 0x03 写在最后 其实在看过 RDI 与 DotNet 功能执行之后,BOF 的执行基本就 ...

  9. CobaltStrike逆向学习系列(10):TeamServer 启动流程分析

    这是[信安成长计划]的第 10 篇文章 关注微信公众号[信安成长计划] 0x00 目录 0x01 基本校验与解析 0x02 初始化 0x03 启动 Listeners 在之前的分析中,都是针对 Cob ...

随机推荐

  1. Solon 开发,二、注入或手动获取Bean

    Solon 开发 一.注入或手动获取配置 二.注入或手动获取Bean 三.构建一个Bean的三种方式 四.Bean 扫描的三种方式 五.切面与环绕拦截 六.提取Bean的函数进行定制开发 七.自定义注 ...

  2. web刷题记录 极客大挑战2019Knife upload buy a flag

    极客2019Knife webshell就是以asp.php.jsp或者cgi等网页文件形式存在的一种代码执行环境,主要用于网站管理.服务器管理.权限管理等操作.使用方法简单,只需上传一个代码文件,通 ...

  3. Linux下进程线程,Nignx与php-fpm的进程线程方式

    1.进程与线程区别 进程是程序执行时的一个实例,即它是程序已经执行到课中程度的数据结构的汇集.从内核的观点看,进程的目的就是担当分配系统资源(CPU时间.内存等)的基本单位. 线程是进程的一个执行流, ...

  4. vue学习15-自定义组件model使用

    <!DOCTYPE html> <html lang='en'> <head> <meta charset='UTF-8'> <meta http ...

  5. Java 将PDF转为HTML时保存到流

    本文介绍如何通过Java后端程序代码将PDF文件转为HTML,并将转换后的HTML文件保存到流.在实现转换时,可设置相关转换属性,如:是否嵌入SVG.是否嵌入图片等.下面是实现转换的方法和步骤: 1. ...

  6. py调用shell

    py调用shell

  7. CKKS Part5: CKKS的重缩放

    本文翻译于 CKKS EXPLAINED, PART 5: RESCALING,主要介绍CKKS方案中最重要的技术- rescaling,重缩放技术 介绍 在CKKS的前一篇文章 CKKS Part4 ...

  8. HBase安装教程

    一.版本介绍 linux : CentOS7 Hadoop : 2.7.6 zookeeper : 3.4.6 hbase : 1.4.6 jdk : jdk1.8.0_171 三个节点的主机名分别为 ...

  9. JVM学习十二 - (复习)JVM内存结构

    JVM 内存结构 Java 虚拟机的内存空间分为 5 个部分: 程序计数器 Java 虚拟机栈 本地方法栈 堆 方法区 JDK 1.8 同 JDK 1.7 比,最大的差别就是:元数据区取代了永久代.元 ...

  10. JVM学习八-(复习)年轻代、老年代、永久代

    Java 中的堆是 JVM 所管理的最大的一块内存空间,主要用于存放各种类的实例对象,如下图所示: 在 Java 中,堆被划分成两个不同的区域:新生代 ( Young ).老年代 ( Old).新生代 ...