0x9bc2
Raw Socket留下的坑, 自定义网络层协议实现木马通信
实现细节
server
和agent
都需要高权限运行, 因为使用了原始套接字(raw socket)
server
使用原始套接字监听监听0x9b
IP协议号agent
发送协议号为0x9b
的原始IP数据包
我们将使用socket2
和etherparse
crate实现核心功能
server
核心代码
// 创建0x9b协议号的原始套接字
let sock = Socket::new(Domain::IPV4, Type::RAW, Some(Protocol::from(155)))?;
// 创建堆区缓冲区
let mut data = Box::new([MaybeUninit::new(0u8); 65535]);
// 接收数据, 并得到agent的SockAddr结构
let (n, agent) = sock.recv_from(&mut *data)?;
// 切片数据
let data = &self[..n];
// 创建迭代器, 过滤出所有有效数据, 并收集成Vec<u8>
let data: Vec<u8> = data
.iter()
.filter_map(|r| Some(unsafe { r.assume_init() }))
.collect();
// 提取出IPv4协议下的数据
let (_, data) = Ipv4Header::from_slice(data.as_slice())?;
agent
核心代码
// 创建stdlib net下的SocketAddrV4, 指向服务器IP
let server = SocketAddrV4::new("127.0.0.1".parse()?, 0);
// 将创建的stdlib net SocketAddrV4结构转为socket2 SockAddr
let server = SockAddr::from(server);
// 创建0x9b协议号的原始套接字
let sock = Socket::new(Domain::IPV4, Type::RAW, Some(Protocol::from(155)))?;
// 向`server`发送原始数据包
self.sock.send_to(b"online", &server)?;
自定义协议number收发数据是这次实验的核心
但是距离稳定可用的武器, 还欠缺一些基本优化
比如实现丢包重发, 消息同步等等
思考
在网络环境很严格的场景下, 目前大多数可能使用ICMP协议进行通信, 但是这个协议如果太多, 太密集, 很可能一些设备会发出告警
这种情况下, 使用自定义的网络层协议进行数据传输吧, 可能很好的解决目前的痛点, 实现隐蔽性
这个的前提是安全设备会对无法识别的协议进行放行, 如此情况下自定义网络层协议的通信对很多安全设备可能就称得上隐形
因为网络设备不分析无法识别的协议, 也同时不会对这一类无法分析的数据进行展示, 所以在流量监控页面是无感的
在我实际测试中, 测试过一个企业端点安全设备, 是世界知名老牌安全公司企业级产品
该设备直接禁止任何无法识别的网络层协议进行通信
不过不是所有安全软件都敢这样做
企业级的设备敢这么做是因为大多数企业的服务器不需要这些功能, 包括任何形势的进程注入都敢直接拒绝
从原理上说, 杀毒软件, 安全设备可以检测到所有的进程注入行为, 但是很多安全软件作为一个产品来说, 作为一个商品来说, 并放不开手脚
这是本质的问题, 所有即使杀软检测到进程注入行为, 也不敢直接阻止此行为, 在无法确认大概率是木马病毒的情况下
很多企业级终端设备, 在这方面放得比较开, 比如我测试过的那个, 一是因为安全公司有实力, 能保证不影响到用户
二是因为客户都是企业, 手脚放得比较开, 大部分企业用户服务器就是跑个WEB程序罢了, 用不到, 也不应该用到敏感功能
所以, 上面我测试的时候, 自定义的网络层数据包直接阻止了, 根本懒得检测是否是合法与非法
其实企业的安全设备就应该这样, 手脚放开, 然后在自己文档里面把因为手脚放开可能会出现的问题列举出来, 用户需要, 再针对某个功能精细的控制
就像rust语言一样, 默认module里所有都设置成私有, 就算把module设置成公有, module下的函数, 结构体还是私有, 就算把结构体设置成公有, 结构体下的字段还是私有, 需要再设置
这就是细腻化控制, rust这样做, 也是为了安全
思考完安全设备, 安全软件的情况, 再思考下, 上面阻止自定义网络层协议的情况可以绕过吗
可以的
已定义的协议号
虽然作为企业安全设备, 把所有未定义的协议直接阻止, 但是已定义的协议安全设备还敢眼睛不眨就阻止吗
我还想到一个细微的点, 在内网情况下, 可以直接发送以太网帧, 进行通信
这样我们只需要MAC地址就能通信, 便可在上层再伪造其他协议, 将源IP和目标IP都伪造成127.0.0.1, 实现更加隐蔽的内网通信
我觉得这样会更隐蔽, 但是没有太多必要, 所以我不是顶尖APT
高手就是把所有能用的, 能做的, 能利用的都做到极致
下次实现内网的数据链路层通信
自定义网络层协议木马, 其实还有很大的利用面, 现实中不会有太多公司会直接阻止 即使全世界安全软件都直接阻止, 那也可以用在没有安全软件的情况下, 实现最高隐蔽性
把能做的, 做到极致