红队C2数据通信之TLV模型
红队C2数据通信之TLV模型
TLV也即Type-length-value,这种一种具有固定格式的数据通信模型,简称为TLV,我们这里只讲讲在红队C2开发中的使用。
格式
每个TLV数据包结构大概如下图:

其中第一个字节type,指定了这个数据包中所需要传输的数据的类型,你可以自己设定比如0xa,代表string类型,0xb 代表int类型。
第二个字段是一个int类型值,length,指定了数据的长度,当你接收到一个数据包到时候,你要解析获取其中的数据,获取多少呢?这个字段的作用就在这。
第三个字段就是我们的数据本身了,没有额外的标识,这个地方数据一般都是序列化后的数据,比如一个字符串的二进制字节数据。
一般我们如果使用C语言,可以定义一个类似如下的结构体:
struct TLV {
uint8_t type; // 1 字节类型
int length; // 长度,int 类型
std::vector<uint8_t> value; // 值,字节数组
TLV(uint8_t t, const std::vector<uint8_t>& v)
: type(t), length(static_cast<int>(v.size())), value(v) {}
}; // by gpt应用
C2当中一般在进行命令传输以及结果回显获取中,通过tlv可以很好的规范化数据,一般我们获取被控机器的基本信息,比如获取机器用户名,机器名,ip地址,我们就可以把获取到的数据封装成单个的tlv数据包,再结合起来。

其实像这个地方,你还可以把它再放入到一个更大的TLV数据中,因为我们C2通信有心跳数据,也有命令执行结果的数据,可以把他们分别再放在不同的 TLV 中再加以区分。
使用TLV也同时方便后续的扩展,因为C2开放的本质其实就是开发网络通信,假如你的项目别人接手了,或者说别人想拓展一些功能,但是通信还是沿用你的,使用tlv就很方便易懂,效率也很高,代码可读性啥的都会很好。
使用TLV也完全不会影响通信的加解密,你可以整个数据包加密,也可以对其中的数据字段做加密都是可以的。
rasta-mouse有一个项目,用于提供一种C2通信规范:
https://github.com/rasta-mouse/OST-C2-Spec
这个某种程度上也是TLV的一种应用,将各种任务进行标记独立,并封装在格式化数据包中,这个项目做的比较细化,对每个命令都做了细化单独处理,比如文件的读写删除等等,也可以在此基础上修改,找到符合自己的一种通信规范。