rakshasa开源地址
https://github.com/Mob2003/rakshasa
rakshasa是一个用Go编写的程序,旨在创建一个能够实现多级代理,内网穿透网络请求。它可以在节点群中任意两个节点之间转发tcp请求和响应,同时支持socks5代理,http代理,并可引入外部http、socks5代理池,自动切换请求ip。
节点之间使用内置证书的TLS加密TCP通信,再叠加一层自定义秘钥的AES加密。该程序可在所有Go支持的平台上使用,包括Windows和Linux服务器。
- 主控端 具有全部功能,能控制所有节点,包括其他主控节点。
- 被控端 只能连接到其他节点,并接收主控端的指令。
最初设计 Rakshasa 时,并没有区分主控端和被控端。这在执行 VPN 和代理操作时非常方便。
然而,在渗透测试场景下,节点往往部署在不安全的设备和网络中。这就可能导致节点所在的设备被攻破,攻击者通过该节点对您的节点群进行反渗透。因此,Rakshasa 需要能够控制节点权限。
一开始,我们考虑了多种解决方案,包括登录验证、连接验证等。但发现这些方法对现有代码的修改过于庞大且耗时。经过简短的思考和面向百度谷歌编程后,决定采用 RSA 非对称加密来处理这个问题。
RSA 加密的特点是分为公钥和私钥。在安全系统中,不安全程序使用公钥,而安全程序使用私钥。
因此,被控端和主控端的最大区别在于,主控端拥有私钥,而被控端没有私钥。
在rakshasa 中,私钥被定义在了 cert/tls.go 文件中,但没有赋值。在编译主控端之前,将私钥写入 private.go 文件。这样编译出的程序会自带私钥。在编译被控端时,删除 private.go 文件,生成的程序就不包含私钥了。具体的编译代码可以参考 build.go 文件。
有了公钥和私钥后,就需要实现权限区分。
被控端没有私钥。它需要连接其他节点进行转发,但不能解密。因此,有两个关键信息不能加密:IP 地址和 UUID。如果 IP 地址被加密,被控端如何进行下一级连接?消息转发和消息控制基于 UUID。如果将 UUID 加密,被控节点也会变成盲目。因此,被控端需要对除 IP 地址和 UUID 之外的其他信息进行加密,并且被控端无法对这些信息进行解密,确保被控端不会反过来控制其他节点。
主控端拥有私钥。Go 语言自带的库无法实现私钥加密和公钥解密功能,因此采用了第三方库来实现私钥加密。代码中对所有关键主控消息进行了加密,包括但不限于启动 Socks5 正反代理,HTTP 代理,TCP 正反向代理等功能。
有些同学发现,被控节点启动 Socks5 代理和 HTTP 代理并没有报错。这是因为 Socks5 代理和 HTTP 代理启动时并不需要对方同意,而是在本地直接开启。在使用时才会请求对方节点。这时您会发现,尽管 HTTP 代理已经启动,但无法访问网络。
最后附上rakshasa各个版本的区别
fullnode | node | fullnode_lite | node_lite | |
---|---|---|---|---|
连接其他节点 | √ | √ | √ | √ |
启动本地socks5代理 | √ | √ | √ | √ |
启动本地http代理 | √ | √ | √ | √ |
启动多层代理 | √ | × | √ | × |
远程shell | √ | × | √ | × |
其他远程功能 | √ | × | √ | × |
交互式CLI | √ | √ | × | × |
check_proxy | √ | √ | × | × |