FRP 分析与改造
source link: https://qftm.github.io/2022/12/10/frp-modify/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
FRP 因其功能丰富,红队攻击者常将其用在内网渗透中,但是 FRP 在实际红蓝对抗中存在很多特征,导致被蓝队发现并溯源。
下面通过对 FRP 0.45.0 版本进行分析,提取特征并进行规避。
客户端执行流程分析
客户端入口:cmd/frpc/main.go
命令行参数处理使用的是 cobra 库,初始化,其中cfgFile默认值是./frpc.ini
rootCmd,判断cfgDir,进入runClient(cfgFile)
加载配置文件
解析配置文件,读取配置文件内容给content,UnmarshalClientConfFromIni进行第一次解析赋值给cfg、content备份的buffer给LoadAllProxyConfsFromIni进行第二次解析
UnmarshalClientConfFromIni主要解析ini文件common项
LoadAllProxyConfsFromIni主要解析ini文件所有的proxy代理项
解析完所有的ini文件配置,开始真正启动服务 startService(cfg, pxyCfgs, visitorCfgs, cfgFilePath)
跟进startService,NewService建立服务,svr.Run开始运行
Run()函数内svr.login()尝试登陆到frps服务端,返回conn和session
login()函数,首先检测TLSEnable是否开启,后面开始建立TCP连接,用建立好的连接,发了个0x17的字符,代表等下要建立tls加密传输
最后发送登录信息给服务端
流量特征修改
基础通信分析
客户端frpc common基础配置
[common]
server_addr = 8.219.248.226
server_port = 2086
[plugin_socks5]
type = tcp
remote_port = 7070
plugin = socks5
plugin_user = admin
plugin_passwd = 123456
frpc启动时,如果客户端[common]
未指定协议protocol
,则默认使用TCP协议
TCP三次握手建立连接后,开始向服务端发送认证信息
o{"version":"0.45.0","os":"darwin","arch":"arm64","privilege_key":"cacaf2489774a4c69abe80dc57ac5486","timestamp":1671416534,"pool_count":1}
服务端frps接收客户端认证信息,并启动代理插件监听
服务端也会通过TCP协议返回一些信息 version、run_id
10{"version":"0.45.0","run_id":"0fa0b38623bbd1bc"}
客户端显示认证成功的信息和代理情况
在其他主机上配置代理测试访问,当frps收到代理转发请求后,frps服务端会将代理信息(代理插件名、地址、端口、认证等)及代理转发请求数据传送给frpc客户端
基础流量特征
上面客户端连接认证及代理转发过程分析,通过在frpc客户端抓包分析,其中流量特征主要包括两点
- 客户端连接认证时,双方三次握手建立TCP通信后传递的一些特定格式的登陆信息
- 客户端代理转发请求时,收到服务端传递的一些特定格式的代理信息
上述特征清理,可开启TLS加密TCP通信内容。
从 v0.25.0 版本开始,frpc 和 frps 之间支持通过 TLS 协议加密传输。通过在 frpc.ini 的 common 中配置 tls_enable = true
来启用此功能。
[common]
server_addr = 8.219.248.226
server_port = 2086
tls_enbale = true
[plugin_socks5]
type = tcp
remote_port = 7070
plugin = socks5
plugin_user = admin
plugin_passwd = 123456
重新启动frpc客户端,此时双方建立连接后的通信TCP数据流内容已加密
测试frpc客户端代理转发服务端代理请求情况,可看到TCP数据流内容已加密
除了使用tls_enable = true
外,还可继续使用use_encryption = true
、use_compression = true
进行二次处理。
TLS特征
当开启TLS加密通信内容时,由于 frp 为了端口复用,建立 TLS 连接的第一个字节默认为 0x17,导致开启TLS流量特征明显。
客户端建立TLS发起第一个数据包Client Hello
之前,默认会发送一个一字节大小的TCP通信数据
修改TLS默认字节,定位源码pkg/util/net/tls.go
、pkg/util/net/dial.go
,修改如下5处
测试效果,默认一字节0x17
变为自定义五字节0x11 0x23 0x66 0x46 0x15
配置文件优化
frpc客户端启动需要指定frpc.ini配置文件,默认frpc配置文件为frpc.ini,同时frpc启动后frpc.ini会保留在目标机子上。
那么,针对frpc配置文件的优化主要包含两点
- 配置文件的文件名及后缀可自定义
- frpc运行自删除配置文件
针对frpc运行自删除配置文件,在cmd/frpc/sub/root.go里面进行修改,第一步,在init()函数中添加frpc启动参数
rootCmd.PersistentFlags().BoolVarP(&delCfgFile, "delete", "d", false, "delete config file of frpc")
第二步,在startService()函数中添加判断delCfgFile参数是否开启,如果开启则删除frpc配置文件
if delCfgFile {
errs := os.Remove(cfgFile)
if errs != nil {
log.Warn("delete config file of frpc fail\n")
} else {
log.Info("delete config file of frpc success\n")
}
}
CDN域前置
frpc域前置CDN一般结合websocket协议使用,自frp0.21.0及之后支持websocket协议(仅支持ws协议,不支持wss协议)。
WebSocket
测试域前置,客户端frpc common配置
[common]
server_addr = 101.42.233.208
server_port = 2086
protocol = websocket
[plugin_socks5]
type = tcp
remote_port = 7070
plugin = socks5
plugin_user = admin
plugin_passwd = 123456
frpc启动时,如果客户端协议为websocket则会通过先发送http请求进行ws协议切换
然后通过websocket协议向服务端发送认证信息
o\000\000\000\000\000\000\000�{"version":"0.45.0","os":"darwin","arch":"arm64","privilege_key":"aa879aa8dbec993816aa42a498c19069","timestamp":1669782153,"pool_count":1}
wireshark字符串搜索Display filter
可以搜索Websocket内的字符串,搜索语句为 data-text-lines contains "darwin"
服务端frps接收客户端认证信息
服务端也会通过ws协议返回一些信息 version、run_id
1\000\000\000\000\000\000\0000{"version":"0.45.0","run_id":"a7bca8b1e7386bdb"}
客户端显示认证成功的信息
上面客户端连接认证过程分析,通过在frpc客户端抓包分析,其中流量特征主要包括两点
- 客户端连接认证服务端时ws协议切换发起的特定http uri请求(/~!frp)
- 双方建立WebsSocket通信后传递的一些特定格式的登陆信息
第一处特征清理,修改frp建立WebSocket时请求的路径
修改常量FrpWebsocketPath,重新编译
第二处特征清理,开启TLS加密WebSocket通信内容
网上有人改版frp websocket适配CDN,新增配置 websocket_domain 为了满足在国内云厂商CDN上抢注的可信域名(server_addr=api.baidu.com.dnsv1cdn.cn、websocket_domain=api.baidu.com,websocket_domain为Http包内的Host头),目前国内云厂商都需要验证域名所属和备案已无法抢注。
WebSocket Secure
Web Socket 使用 TLS 即可实现等同 Web Socket Secure 效果。
References
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK