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

举报
未闻Code 发表于 2022/02/07 11:00:17 2022/02/07
【摘要】 网站通过 JA3算法,利用一些指纹信息来识别你的请求,无论你是否使用了代理 IP,网站都能识别到你。今天我们首先讲讲在 Golang 下面,如何修改这个指纹。

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

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

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

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)
 }
}

运行效果如下图所示:

12.png

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

13.png

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

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

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)
 }
}

运行效果如下图所示:

15.png

这段代码的关键是: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
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。