Go实现支持多种协议的抓包工具——Shermie-Proxy

前言

常见的抓包工具有Fiddler、Charles等,我自己用Go基于Tcp协议实现一个代理抓包工具shermie-proxy,支持同时监听多种协议的数据,支持对数据进行自定义修改,代码我都写了注释,如果有对网络编程感兴趣的同学,可以康康。

涉及的知识

  • Ca证书:根证书、中间证书的生成和下发
  • 单向认证、双向认证、Tls握手过程
  • Ws、Wss协议
  • Http、Https协议
  • Socket5协议
  • 协议转换

支持的协议:

  • 支持一个端口同时监听Http、Https、Ws、Wss、Socket5、Tcp几种协议
  • 支持注册消息事件,对消息进行修改、裁剪再发送

使用方法

func init() {
     // 初始化日志
     Log.NewLogger().Init()
     // 初始化根证书
     err := Core.NewCertificate().Init()
     if err != nil {
         Log.Log.Println("初始化根证书失败:" + err.Error())
         return
     }
}
func main() {
    port := flag.String("port", "9090", "listen port")
    nagle := flag.Bool("nagle", true, "connect remote use nagle algorithm")
    proxy := flag.String("proxy", "0", "tcp prxoy remote host")
    flag.Parse()
    if *port == "0" {
      Log.Log.Fatal("port required")
      return
    }
    // 启动服务
    s := Core.NewProxyServer(*port, *nagle, *proxy)
    // 注册http客户端请求事件函数
    s.OnHttpRequestEvent = func(request *http.Request) {

    }
    // 注册http服务器响应事件函数
    s.OnHttpResponseEvent = func(response *http.Response) {
      contentType := response.Header.Get("Content-Type")
      var reader io.Reader
      if strings.Contains(contentType, "json") {
      reader = bufio.NewReader(response.Body)
      if header := response.Header.Get("Content-Encoding"); header == "gzip" {
      reader, _ = gzip.NewReader(response.Body)
     }  body, _ := io.ReadAll(reader)
      Log.Log.Println("HttpResponseEvent:" + string(body))
     }}
    // 注册socket5服务器向客户端推送消息事件函数
    s.OnSocket5ResponseEvent = func(message []byte) {
      Log.Log.Println("Socket5ResponseEvent:" + string(message))
    }
    // 注册socket5客户端向服务器推送消息事件函数
    s.OnSocket5RequestEvent = func(message []byte) {
      Log.Log.Println("Socket5RequestEvent:" + string(message))
    }
    // 注册ws服务器向客户端推送消息事件函数
    s.OnWsRequestEvent = func(msgType int, message []byte, clientConn *Websocket.Conn, resolve Core.ResolveWs) error {
      Log.Log.Println("WsRequestEvent:" + string(message))
      return clientConn.WriteMessage(msgType, message)
    }
    // 注册ws客户端向服务器推送消息事件函数
    s.OnWsResponseEvent = func(msgType int, message []byte, tartgetConn *Websocket.Conn, resolve Core.ResolveWs) error {
      Log.Log.Println("WsResponseEvent:" + string(message))
      return resolve(msgType, message, tartgetConn)
    }
    _ = s.Start()
}

效果

动态图片放在github上了,有可能无法显示。

  • Https代理

  • Wss代理

仓库

地址:github.com/kxg3030/shermie-proxy, 喜欢的话请用你发财的小手点个star

本作品采用《CC 协议》,转载必须注明作者和本文链接
失色天空
本帖由系统于 1年前 自动加精
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
讨论数量: 38

麻烦再出个UI,fiddler everywhere 太贵了我买不起

1年前 评论
DonnyLiu

支持!出个教程吧

1年前 评论
失色天空 (楼主) 1年前

有证书验证的的怎么转

1年前 评论
失色天空 (楼主) 1年前

Core\ProxyHttp.go:226:33: sslConn.ReadLastTimeBytes undefined (type *tls.Conn has no field or method ReadLastTimeBytes)

1年前 评论
巴黎不下雪的冬季 1年前
失色天空 (楼主) 1年前
巴黎不下雪的冬季 1年前
土哥 1年前
失色天空 (楼主) 1年前

ide是什么皮肤啊?

1年前 评论
失色天空 (楼主) 1年前
kinyou

用户目录下面的gopath下面没有这个 src/crypto/tls/conn.go 文件怎么破 ?

1年前 评论
失色天空 (楼主) 1年前

对标 mitmproxy 吗,后期可以考虑一下实现 ui 界面,扩展一下插件机制,能够做到拦截请求与改写响应。

1年前 评论
失色天空 (楼主) 1年前

这个可以抓直播的留言与进入直播的用户吧? :grin:

1年前 评论

我这边为什么没有效果

1年前 评论

我这边为什么没有 动图的那种效果 ?请教 我是还需要做点什么吗

1年前 评论
失色天空 (楼主) 1年前
limit86 (作者) 1年前
失色天空 (楼主) 1年前
limit86 (作者) 1年前
limit86 (作者) 1年前
limit86 (作者) 1年前
失色天空 (楼主) 1年前
limit86 (作者) 1年前
失色天空 (楼主) 1年前
limit86 (作者) 1年前
失色天空 (楼主) 1年前

提几个建议~

  1. go编码风格推荐:gocn.github.io/styleguide/docs/01-...
  2. 协议分析功能可以插件化
  3. 可以看看S.O.L.I.D面向对象设计

这个项目潜力很大

1年前 评论
失色天空 (楼主) 1年前

目前编译成dll c++调用 目前不能多开实例 可以多开吗

1年前 评论
失色天空 (楼主) 1年前

编译成dll dll中如何回调c++函数 目前试验了传送整型和字符串没问题,回调函数还差口气,调用了没反应

1年前 评论

这个怎么让其关闭呢

8个月前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!