前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >一日一技:Golang 如何突破 JA3?

一日一技:Golang 如何突破 JA3?

作者头像
青南
发布2021-09-09 16:37:23
1.7K0
发布2021-09-09 16:37:23
举报
文章被收录于专栏:未闻Code未闻Code

摄影:产品经理

小菜上桌

在之前的文章里面,我们讲到了网站通过 JA3算法,利用一些指纹信息来识别你的请求,无论你是否使用了代理 IP,网站都能识别到你。

今天我们首先讲讲在 Golang 下面,如何修改这个指纹。

我们先来写一段代码,观察在使用了代理以后, Golang 的 JA3指纹依然不变:

代码语言:javascript
复制
package main

import (
 "crypto/tls"
 "fmt"
 "io/ioutil"
 "net/http"
 "net/url"
 "time"
)

func req() {
 proxyUrl, err := url.Parse("http://隧道代理IP:PORT")
 client := &http.Client{
  Transport: &http.Transport{Proxy: http.ProxyURL(proxyUrl),
   TLSClientConfig: &tls.Config{InsecureSkipVerify: false}},
 }
 resp, err := client.Get("https://httpbin.org/ip")
 if err != nil {
  fmt.Println(err)
 }

 defer resp.Body.Close()
 content, err := ioutil.ReadAll(resp.Body)
 if err != nil {
  fmt.Println(err)
 }
 fmt.Println(string(content))
}

func main() {
 for i := 0; i < 10; i++ {
  req()
  time.Sleep(time.Second)
 }
}

运行效果如下图所示:

但是,当我要访问 JA3测试页面的时候,发现返回的签名字符串始终是一样的:

为了解决这个问题,我们可以使用一个第三方的包,叫做: ja3transport[1]

这个包的使用方法如下面代码所示:

代码语言:javascript
复制
package main

import (
 "fmt"
 "github.com/CUCyber/ja3transport"
 tls "github.com/refraction-networking/utls"
 "io/ioutil"
 "net/http"
)


type Browser struct {
 Ja3 string
 UserAgent string
}


func req(browser Browser) {
 config := tls.Config{
  InsecureSkipVerify: true,

 }
 tr, _ := ja3transport.NewTransportWithConfig(browser.Ja3, &config)

 client := &http.Client{
  Transport: tr,
 }
 req, _ := http.NewRequest("GET", "https://ja3er.com/json", nil)
 req.Header.Set("User-Agent", browser.UserAgent)
 resp, err := client.Do(req)
 if err != nil {
  fmt.Println(err)
 }

 defer resp.Body.Close()
 content, err := ioutil.ReadAll(resp.Body)
 if err != nil {
  fmt.Println(err)
 }
 fmt.Println(string(content))
}

func main() {
 ja3List := []Browser{
  {Ja3: "771,4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53-10,0-23-65281-10-11-35-16-5-13-18-51-45-43-27,29-23-24,0",UserAgent: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.2 Safari/605.1.15"},
  {Ja3: "771,4865-4866-4867-49196-49195-52393-49200-49199-52392-49188-49187-49162-49161-49192-49191-49172-49171-157-156-61-60-53-47-49160-49170-10,0-23-65281-10-11-16-5-13-18-51-45-43-21,29-23-24-25,0", UserAgent: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36 Edg/92.0.902.67"},
  {Ja3: "771,4865-4866-4867-49196-49195-49188-49187-49162-49161-52393-49200-49199-49192-49191-49172-49171-52392-157-156-61-60-53-47-49160-49170-10,65281-0-23-13-5-18-16-11-51-45-43-10-21,29-23-24-25,0", UserAgent: "Mozilla/5.0 (iPhone; CPU iPhone OS 13_1_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.1 Mobile/15E148 Safari/604.1"},
 }
 for _, ja3 := range ja3List{
  req(ja3)
 }
}

运行效果如下图所示:

这段代码的关键是:tr, _ := ja3transport.NewTransportWithConfig(browser.Ja3, &config),这一行代码,把我们自定义的 JA3指纹字符串传入进去,这个库在发起请求的时候,修改请求的数据包,用我们自定义的指纹字符串替换原来的默认字符串,从而实现修改 JA3指纹的目的。大家关注上面图中我标记的3个ja3_hash。他们不同了,说明修改 JA3指纹成功。

JA3有自己的生成规则,所以并不能随便乱改。但确实里面有一些地方也可以改。大家可以用测试网站进行测试,看改了以后能不能正确返回不同的 ja3_hash。如果能返回,说明改对了。如果报错了,说明改错了。

当然,最简单的方法是收集尽可能多的不同类别不同型号的浏览器指纹和对应的 User-Agent,然后随机选择一对,轮换使用,这样就可以有效规避网站对 JA3字符串频率的检查。

关于今天用到的ja3transport,如果大家有兴趣可以去看作者写的文章,介绍了这个包的工作原理: Impersonating JA3 Fingerprints.[2]

好了,今天使用 Golang 突破 JA3的方法就介绍到这里。请大家期待后面使用 Python 突破 JA3的方法。

参考文献

[1]

ja3transport: https://github.com/CUCyber/ja3transport

[2]

Impersonating JA3 Fingerprints.: https://medium.com/cu-cyber/impersonating-ja3-fingerprints-b9f555880e42

END

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-08-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 未闻Code 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档