Skip to content

Concept

IoM中需要知道的概念

通讯

Spite是整个IoM通讯的最小单元

flowchart TD
    Client -- gRPC 调用 --> Server
    Server -- 生成spite --> Listener
    Implant -- 等待连接 --> Listener
    Listener -- Pack&Encrypt --> Implant

Spite 是在server/listener ↔ implant 之间进行数据交换的载体. 所有的需要与交互implant的操作都需要构造Spite结构体.

Spite基于protobuf实现, 具体定义请见: proto仓库 下的 implant.proto

message Spite {
  string name = 1;  // 用来寻找implant中的module
  uint32 task_id = 2; // task_id
  bool  async = 3;    // deprecated
  uint64 timeout = 4; // deprecated
  uint32 error = 5;   // malefic本体错误码
  Status status = 6;  // task状态

  oneof body {        // module需要的部分
    Empty empty = 10;  
    Block block = 11;
    AsyncACK async_ack = 13;
    SysInfo sysinfo = 20;
    Register register = 21;
    Ping ping = 22;
    Suicide suicide = 23;
    Request request = 24;
    Response response = 25;
    LoadModule  load_module = 31;
    Modules  modules = 32;
    LoadAddon load_addon = 35;
    Addons addons = 36;
    ExecuteAddon execute_addon = 37;
    ExecuteBinary execute_binary = 42;
    LsResponse ls_response = 101;
    ...
  }
}

所有与module交互的协议都在这里定义. 并且预留了一些通用的message 用来解决新增module时需要频繁修改proto的问题.

Listener

IoM中的Listener与其他C2中的概念略有不同. Listener是独立于Server的, 可以部署在任意的服务器上, 通过grpc提供的stream与server进行全双工实时通讯.

Listener与Server的彻底解耦是IoM的核心设计理念之一, Listener可以是多种形态的,任意伪装的, 位于任意位置的. 这是下一代C2的进化方向之一.

graph LR
    MSF["MSF\n监听在本机"] --> Cobaltstrike["Cobaltstrike\n监听在Server"] --> IoM["IoM\n可以在任意服务器上监听"]

listener有四个主要组件

  • listener , 管理pipeline以及与server交互.
  • pipeline, 与implant交互的管道, 每个listener可以有任意个websilte或者pipeline
  • forworder, 每个pipeline都会创建一个forworder, 通过forwarder将数据转发至server
  • parser/generator, 将来自implant/webshell的数据解析为Spite; 将Spite解析为implant/webshell能识别的二进制数据
  • cryptor 流式加密解密器

pipeline

数据管道

pipeline 是listener与外部implant/webshell交互的数据管道.

pipleline的形态有很多, 例如:

  • tcp/tls , 监听tcp端口, 接受来自implant的数据, 当前的默认配置
  • bind, 主动发起请求的管道, 用来与bind模式的implant交互
  • pulse, 专门为pulse实现的pipeline, 因为pulse尽可能减少体积, 无法实现完整的tcp/tls功能.
  • website , 类似CS的host功能
  • http/https (🛠️), 监听http服务
  • rem (🛠️) ,流量服务, 预计会在v0.0.4 上线
  • payload generator (🛠️), 用来与webshell主动交互的pipeline

cryptor (unstable)

v0.0.3 初步支持了自定义加密算法.

type Cryptor interface {  
    Encrypt(reader io.Reader, writer io.Writer) error  
    Decrypt(reader io.Reader, writer io.Writer) error  
    Reset() error  
}

这个Cryptor将直接作用于Conn(与rem相同的设计), 会对全包进行加密解密. 因此只支持流式加密算法.

目前实现了两种常见的流式加密算法:

  • XOR
  • AES-CFB

密码学不安全

这两种算法都是对称的, 且没有前向后向密码学安全的特性.

parser (unstable)

v0.0.3 初步实现了自定义 Parser

parser用来控制最终生成的数据包格式.

server/listener/client之间的交互都通过spite实现, 但在最终发送到目标的数据包可以是任意格式的.

接口如下:

type PacketParser interface {  
    PeekHeader(conn *peek.Conn) (uint32, uint32, error)  
    ReadHeader(conn *peek.Conn) (uint32, uint32, error)  
    Parse([]byte) (*implantpb.Spites, error)  
    Marshal(*implantpb.Spites, uint32) ([]byte, error)  
}

Parse 用来实现二进制数据到Spites的映射. Marshal实现Spites到二进制数据的映射. ReadHeader与PeekHeader 尝试用作协议识别, 通过先解密一定长度的header数据, 来自动判定协议类型.

Important

parser, pipeline, cryptor 是相互解耦的, 可以任意两者之间互相组装的.

Server

https://github.com/chainreactors/malice-network/tree/master/server

server与listener在v0.0.2后合并了二进制文件

为了减少在安装与使用上的步骤, 从v0.0.2开始, 使用同一个二进制文件发布. 只需要使用不同的配置文件, 就能开启server或listener, 或同时开启server与listener

server是数据处理的核心, client/listener 都会通过grpc与server进行交互, implant则是通过 listener上的pipeline间接与server进行交互.

所有的数据都在server中维护, 在client/listener中只会保留只读副本.

server维护了一组状态集合(内存中只会保留当前存活的, 历史数据保存于数据库中):

  • clients , 正在连接的所有的用户
  • listeners, 正在连接的所有listener
  • jobs, 所有的pipeline, 包括(tcp, website等)
  • event, 将会轮询所有用户, 将event广播至每个用户
  • sessions, 存活的implant, session还为每个implant维护了一些子状态集

并且通过server上的grpc实现对这些状态的增删改查, 事件通知, listener交互等等

session

session是其中较为复杂的结构, 保存了implant的所有信息.

session内部还维护了多个子状态集

  • 基本信息, 例如操作系统, 进程信息等
  • task, 所有正在执行的任务
  • connection, 逻辑上的连接状态
  • cache, 数据缓存, 通用保存一定大小的历史数据
  • module, implant可用的模块
  • addon, implant中已加载的组件

rootrpc

为了方便管理, 我们添加了一个仅server安装程序本地(127.0.0.1)可使用的rpc.

这个rpc可以用来添加删除用户, 生成新的证书.

可以在rootrpc手册 中查看使用教程

Implant

目前只提供了一个implant, 即malefic, malefic详细文档 - malefic, 主程序, 包含了beacon/bind两种模式的完整功能 - mutant, 用来实现自动化配置malefic的各种条件编译与特性, 以及生成shellcode, srdi等 - pulse, 最小化的shellcode模板, 对应CS的artifact, 能编译出只有4kb的上线马, 非常适合被各种loader加载 - prelude, 多段上线的中间阶段, 可以在这里按需配置权限维持, 反沙箱, 反调试等功能.

IoM计划提供一整套互相解耦的implant解决方案, 实现各个阶段各种需求不同的二进制文件生成.

在设计目标中, implant实际上还有更多的内容, 但受限于精力, 我们暂时只将已实现的, 或短期内将实现的功能进行简单的介绍. 后续将随着开发进度逐步补全.

Client

在v0.0.2 IoM彻底重构了client, 现在client有了一些独特的新特性.

在implant中, 已经能动态加载 dll, exe, clr, powershell, bof, shellcode, module七种类型的格式. 对应到client中. 我们通过多个维度的动态拓展的能力将其组合起来.

client现在支持的动态执行二进制程序(fileless)的命令有:

  • execute-assembly, 执行CLR程序, 例如C#,VB编译出来的二进制程序, 支持bypass ASMI,ETW
  • execute-exe, 通过牺牲进程反射执行任意语言编译出来的exe程序, 支持参数欺骗, 进程注入, sideload
  • inline-exe, 在当前进程内执行exe
  • execute-dll, 类似execute-exe, 通过牺牲进程反射执行dll程序, 同样支持参数欺骗, 进程注入, sideload
  • inline-dll 类似inline-exe
  • execute-shellcode, 类似execute-exe
  • inline-shellcode, 类似inline-exe
  • powershell, unmanaged powershell,
  • bof, 执行.o程序
  • load-module , 动态加载模块
  • execute-addon, 执行已经加载到implant内存中的程序

与之对应的是一系列管理这些执行能力的插件:

  • mal, IoM支持的插件语言带来的拓展能力, 当前支持lua, 能动态注册命令, 或添加新的能力
  • addon, 用来防止执行较大体积的二进制文件中反复从服务器发送的问题, 可以在内存中保存二进制程序, 下次使用只需要直接发送参数即可.
  • module, 动态加载的implant module.
  • alias sliver中的alias, 主要用来管理CLR与UDRL的DLL程序
  • extension, sliver中的extension, 主要用来管理BOF与sliver特定格式的dll
  • armory, sliver的插件包管理工具

现在的client像是一个发射架, 可以支持几乎能找到全部的拓展格式的fileless执行. 并通过多种方式去自定义自己的军火库.

OPSEC模型

红队视角的OPSEC模型

通过四个维度的评判, 参考CVSS的分级标准。

评分越高越安全 分为:

  • 低(0-3.9)操作极其容易被检测, 明显痕迹, 造成恶性(失去立足点, 系统崩溃等)后果
  • 中(4.0-6.9) 操作可能被检测,痕迹可控, 后果可控
  • 高(7.0-8.9) 操作基本不可能不检测, 痕迹较小或无痕迹, 被检测也不会有明显后果
  • OPSEC(9.0-10)分, 这个级别的操作被称为OPSEC. 几乎不可能被检测, 没有痕迹, 不会造成后果.

暴露度

被EDR/NDR或任意设备检测到的暴露程度

  • 是否有新进程创建
  • 是否有新线程创建
  • 是否有新文件创建
  • 是否有新网络连接创建
  • 是否需要调用系统api

痕迹

被追踪还原操作痕迹的成功率

  • 是否可以删除相关操作日志
  • 是否可以删除相关文件

检测可能性

  • 现有检测机制是否有可能追踪
  • 在操作系统内部是否有可能被追踪
  • 实现相关检测手段复杂性

后果

  • 操作失败可能带来的后果
  • 是否影响长期潜伏
  • 是否影响驻留时间