CobaltStrike逆向学习系列(2):Stageless Beacon 生成流程分析
字数 2261 2025-08-29 08:30:36

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

1. Stageless Beacon概述

CobaltStrike的Beacon生成分为两种类型:

  • Stage Beacon:分阶段加载,最终文件较小,需要从网络中拉取后续阶段
  • Stageless Beacon:无阶段加载,最终文件较大,包含所有功能

本文重点分析Stageless Beacon的生成流程,使用的payload示例为windows/beacon_http/reverse_http

2. Stageless Beacon生成流程

2.1 初始处理阶段

  1. 用户点击生成时,进入WindowsExecutableStageDialog.dialogAction方法
  2. 根据界面选择的输出类型决定生成文件后缀
  3. 弹出文件保存对话框
  4. 用户选择保存位置后,进入dialogResult方法处理Patch操作

2.2 Patch Beacon核心流程

2.2.1 准备工作

  1. 获取当前选择的Listener名称和架构(x86/x64)
  2. 进入关键方法export

2.2.2 export方法处理

  1. 根据选择的payload决定调用哪个处理函数
  2. 根据架构选择核心功能DLL(Beacon文件)

执行两个关键处理:

  • exportBeaconStage:处理C2Profile相关内容
  • pe.process:处理PE格式、ReflectiveLoad和引导头

2.2.3 exportBeaconStage处理

  1. 根据Beacon路径读取相应文件
  2. 解析C2Profile:
    • 这是BeaconEye、CobaltStrikeScan等工具检测的根本依据
    • 解析逻辑是检测与绕过的关键点
  3. 处理完成后:
    • 将数据转换为特定格式的byte数组
    • 设置总大小为4096字节,不足部分用随机字符填充
    • 调用beacon_obfuscate进行混淆(逐字节异或)
  4. 将处理后的内容Patch到Beacon中

2.2.4 PE处理(pe.process)

分为两个主要步骤:

  1. pre_process

    • 从C2Profile中取出与PE相关的项
    • 通过PEEditor进行基本处理
  2. post_process

    • 添加ReflectiveLoad和引导头
    • 使用PEParser解析Beacon(注意:作者实现的解析类存在一些小BUG)
ReflectiveLoad处理细节
  1. 获取导出函数ReflectiveLoad的偏移

  2. Patch引导头:

    • 利用PE头中的原始数据字节作为指令
    • 覆盖不重要的PE结构
    • 在堆栈平衡前提下执行自定义功能
    • 通过偏移跳转执行ReflectiveLoad函数
  3. 调用getReflectiveLoaderFunction添加ReflectiveLoad函数:

    • CobaltStrike使用自定义实现的ReflectiveLoad,非公开的RDI项目
    • 提供三份备用方案,区别在于内存分配函数:
      • HeapAlloc
      • VirtualAlloc
      • MapViewOfFile
  4. 将ReflectiveLoad和引导头放到对应位置

2.3 Patch Loader阶段

CobaltStrike不会直接保存处理后的Beacon,而是:

  1. 根据选择的文件类型选择对应的Loader:

    • Stageless使用的Loader名称中包含"big"
    • Stage使用的Loader名称不包含"big"
  2. 调用_patchArtifact方法:

    • 处理基本信息
    • 随机生成数值用于异或整个Beacon
  3. Patch操作:

    • 找到Patch点(1024个'A'的位置)
    • 构造Patch内容:
      • Patch+16的位置(4字节)
      • Beacon总长度(4字节)
      • 异或加密Key(4字节)
      • GetModuleHandleA地址(4字节)
      • GetProcAddress地址(4字节)
      • 异或后的Beacon
    • 第一个存储位置指向GetProcAddress地址
  4. 执行Patch并返回

  5. 写入文件完成生成

3. 文件对比分析

3.1 beacon.x64.dll分析

  1. 直接搜索可找到Patch点
  2. 导出函数附近可见一串90 CC占位(NOP INT3指令)

3.2 生成文件对比

对比生成的Beacon与artifact64big.exe可验证上述流程。

4. 关键点总结

  1. C2Profile处理

    • 是检测工具的主要依据
    • 了解其解析逻辑可实现检测绕过或更精确的检测
  2. ReflectiveLoad实现

    • CobaltStrike使用自定义实现
    • 三种内存分配方案提供灵活性
  3. 引导头技术

    • 利用PE头数据作为指令
    • 覆盖不重要PE结构实现功能
  4. Loader Patch机制

    • 使用特定位置的占位符进行Patch
    • 包含关键API地址和加密信息
  5. 架构差异

    • 处理流程会根据x86/x64架构选择不同资源

5. 检测与对抗思路

  1. 检测点

    • C2Profile特定格式和结构
    • ReflectiveLoad的特征
    • 引导头的特殊实现方式
    • Loader中的Patch模式
  2. 绕过思路

    • 修改C2Profile的存储和混淆方式
    • 自定义ReflectiveLoad实现
    • 改变引导头的实现逻辑
    • 调整Loader的Patch机制
  3. 增强检测

    • 深入分析C2Profile解析逻辑
    • 识别自定义ReflectiveLoad的特征
    • 检测PE头异常使用情况
    • 监控Loader中的特定Patch模式
CobaltStrike逆向学习系列(2):Stageless Beacon生成流程分析 1. Stageless Beacon概述 CobaltStrike的Beacon生成分为两种类型: Stage Beacon:分阶段加载,最终文件较小,需要从网络中拉取后续阶段 Stageless Beacon:无阶段加载,最终文件较大,包含所有功能 本文重点分析Stageless Beacon的生成流程,使用的payload示例为 windows/beacon_http/reverse_http 。 2. Stageless Beacon生成流程 2.1 初始处理阶段 用户点击生成时,进入 WindowsExecutableStageDialog.dialogAction 方法 根据界面选择的输出类型决定生成文件后缀 弹出文件保存对话框 用户选择保存位置后,进入 dialogResult 方法处理Patch操作 2.2 Patch Beacon核心流程 2.2.1 准备工作 获取当前选择的Listener名称和架构(x86/x64) 进入关键方法 export 2.2.2 export方法处理 根据选择的payload决定调用哪个处理函数 根据架构选择核心功能DLL(Beacon文件) 执行两个关键处理: exportBeaconStage :处理C2Profile相关内容 pe.process :处理PE格式、ReflectiveLoad和引导头 2.2.3 exportBeaconStage处理 根据Beacon路径读取相应文件 解析C2Profile: 这是BeaconEye、CobaltStrikeScan等工具检测的根本依据 解析逻辑是检测与绕过的关键点 处理完成后: 将数据转换为特定格式的byte数组 设置总大小为4096字节,不足部分用随机字符填充 调用 beacon_obfuscate 进行混淆(逐字节异或) 将处理后的内容Patch到Beacon中 2.2.4 PE处理(pe.process) 分为两个主要步骤: pre_process : 从C2Profile中取出与PE相关的项 通过PEEditor进行基本处理 post_process : 添加ReflectiveLoad和引导头 使用PEParser解析Beacon(注意:作者实现的解析类存在一些小BUG) ReflectiveLoad处理细节 获取导出函数 ReflectiveLoad 的偏移 Patch引导头: 利用PE头中的原始数据字节作为指令 覆盖不重要的PE结构 在堆栈平衡前提下执行自定义功能 通过偏移跳转执行ReflectiveLoad函数 调用 getReflectiveLoaderFunction 添加ReflectiveLoad函数: CobaltStrike使用自定义实现的ReflectiveLoad,非公开的RDI项目 提供三份备用方案,区别在于内存分配函数: HeapAlloc VirtualAlloc MapViewOfFile 将ReflectiveLoad和引导头放到对应位置 2.3 Patch Loader阶段 CobaltStrike不会直接保存处理后的Beacon,而是: 根据选择的文件类型选择对应的Loader: Stageless使用的Loader名称中包含"big" Stage使用的Loader名称不包含"big" 调用 _patchArtifact 方法: 处理基本信息 随机生成数值用于异或整个Beacon Patch操作: 找到Patch点(1024个'A'的位置) 构造Patch内容: Patch+16的位置(4字节) Beacon总长度(4字节) 异或加密Key(4字节) GetModuleHandleA地址(4字节) GetProcAddress地址(4字节) 异或后的Beacon 第一个存储位置指向GetProcAddress地址 执行Patch并返回 写入文件完成生成 3. 文件对比分析 3.1 beacon.x64.dll分析 直接搜索可找到Patch点 导出函数附近可见一串 90 CC 占位(NOP INT3指令) 3.2 生成文件对比 对比生成的Beacon与 artifact64big.exe 可验证上述流程。 4. 关键点总结 C2Profile处理 : 是检测工具的主要依据 了解其解析逻辑可实现检测绕过或更精确的检测 ReflectiveLoad实现 : CobaltStrike使用自定义实现 三种内存分配方案提供灵活性 引导头技术 : 利用PE头数据作为指令 覆盖不重要PE结构实现功能 Loader Patch机制 : 使用特定位置的占位符进行Patch 包含关键API地址和加密信息 架构差异 : 处理流程会根据x86/x64架构选择不同资源 5. 检测与对抗思路 检测点 : C2Profile特定格式和结构 ReflectiveLoad的特征 引导头的特殊实现方式 Loader中的Patch模式 绕过思路 : 修改C2Profile的存储和混淆方式 自定义ReflectiveLoad实现 改变引导头的实现逻辑 调整Loader的Patch机制 增强检测 : 深入分析C2Profile解析逻辑 识别自定义ReflectiveLoad的特征 检测PE头异常使用情况 监控Loader中的特定Patch模式