python、go、node的ja3指纹实现

一.初识

1.什么是ja3相信大家都有所耳闻,这里就不做太多概述,简单来讲就是就是基于tls/ssl协议的客户端指纹特征识别技术。

2.绕过ja3的四种方法

  • 1.访问ip指定host绕过waf
  • 2.代理中转请求(go版本有实现可以去了解下)
  • 3.更换request工具库
  • 4.魔改requests

3.tls检测网站

  • akamai 1.75
  • akamai2.0
  • Cloudflare(5秒盾)

这里我们讲解各语言版本的实现,详细了解ja3的可以移步到一下文章。

参考1

参考2

参考3

二.语言实现——(案例猿人学19题)
  • python

    一.pyhttpx

import pyhttpx
sess= pyhttpx.HttpSession()
url = f"https://match.yuanrenxue.com/api/match/19?page=1"
response = sess.get(url,headers=Headers)

​ 二. Pycurl(pycurl是curl的一个python版本)

import pycurl, json
from io import BytesIO

Class getAll():
	def __init__(self):
		self.pyc=pycurl.Curl()
		self.buffer=BytesIO()
	
	def getoutPut():
		self.pyc.setopt(pycurl.URL, 'http://some-url')
		#跳过验证
		self.pyc.setopt(pycurl.SSL_VERIFYHOST,0)
		self.pyc.setopt(pycurl.SSL_VERIFYPEER,0)
		self.pyc.setopt(pycurl.POST,1)
		self.pyc.setopt(pycurl.WRITEDATA,self.buffer)
		self.pyc.setopt(pycurl.HTTPHEADER, ['content-type: 		   	     				application/json','content-type:multipart/form-data'])
		data = json.dumps({"name": "abc", "path": "def", "target": "ghi"})
		self.pyc.setopt(pycurl.POSTFIELDS, data)
		self.pyc.perform()
		self.pyc.close()
		print(self.buffer.getvalue().decode('utf-8'))

​ 三.魔改open_ssl

from requests.adapters import HTTPAdapter
from requests.packages.urllib3.util.ssl_ import create_urllib3_context

ORIGIN_CIPHERS = ('ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+HIGH:'
'DH+HIGH:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+HIGH:RSA+3DES')


class DESAdapter(HTTPAdapter):
    def __init__(self, *args, **kwargs):
        """
        A TransportAdapter that re-enables 3DES support in Requests.
        """
        CIPHERS = ORIGIN_CIPHERS.split(':')
        random.shuffle(CIPHERS)
        CIPHERS = ':'.join(CIPHERS)
        self.CIPHERS = CIPHERS + ':!aNULL:!eNULL:!MD5'
        super().__init__(*args, **kwargs)
        
        
    def init_poolmanager(self, *args, **kwargs):
        context = create_urllib3_context(ciphers=self.CIPHERS)
        kwargs['ssl_context'] = context
        return super(DESAdapter, self).init_poolmanager(*args, **kwargs)

    def proxy_manager_for(self, *args, **kwargs):
        context = create_urllib3_context(ciphers=self.CIPHERS)
        kwargs['ssl_context'] = context
        return super(DESAdapter, self).proxy_manager_for(*args, **kwargs)
        
import requests
headers = {'User-Agent': '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'}
s = requests.Session()
s.headers.update(headers)
 
for _ in range(5):
    s.mount('https://ja3er.com', DESAdapter())
    resp = s.get('https://ja3er.com/json').json()
    print(resp)

提示:cycletls是一个针对go和node的ja3实现

项目地址:cycletls

  • go(cycletls)

    1.安装:go get github.com/Danny-Dasilva/CycleTLS/cycletls

    2.使用

package main

import (
	"github.com/Danny-Dasilva/CycleTLS/cycletls"
	"log"
)

func main() {

	client := cycletls.Init()

	response, err := client.Do("https://match.yuanrenxue.com/api/match/19?page=1", cycletls.Options{
		Body:      "",
		Ja3:       "771,4865-4867-4866-49195-49199-52393-52392-49196-49200-49162-		 49161-49171-49172-51-57-47-53-10,0-23-65281-10-11-35-16-5-51-43-13-45-28-		  21,29-23-24-25-256-257,0",
	    UserAgent: "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:87.0) 			    	 Gecko/20100101 Firefox/87.0",
	}, "GET")
	if err != nil {
		log.Print("Request Failed: " + err.Error())
	}
	log.Println(response)
}
  • node(cycletls)

    1.安装:npm install cycletls

    2.使用

const initCycleTLS = require('cycletls');
// Typescript: import initCycleTLS from 'cycletls';

(async () => {
  // Initiate CycleTLS
  const cycleTLS = await initCycleTLS();

  // Send request
  const response = await cycleTLS('https://match.yuanrenxue.com/api/match/19?page=1', {
    body: '',
    ja3: '771,4865-4867-4866-49195-49199-52393-52392-49196-49200-49162-49161-	  	  49171-49172-51-57-47-53-10,0-23-65281-10-11-35-16-5-51-43-13-45-28-21,29-23-     24-25-256-257,0',
    userAgent: 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:87.0) Gecko/20100101       Firefox/87.0',
    timeout: 2,
    // proxy: 'http://username:password@hostname.com:443'
  }, 'get');

  console.log(response);

  // Cleanly exit CycleTLS
  cycleTLS.exit();

})();

效果

在这里插入图片描述

三.结语

好了,上面列举的这些ja3指纹工具实现相信能够应付绝大多是情况,兄弟们可以自行测试效果,如果遇到更多的情况,还得详细的分析,去进行魔改测试。

### 使用Python实现JA4指纹提取 JA4 (JARM and JA3’s cousin) 是一种用于识别TLS客户端特征的技术。通过分析TLS握手过程中特定字段,可以创建唯一的指纹来标识不同的浏览器或设备。 为了使用Python实现JA4指纹提取,主要依赖于`scapy`库解析网络数据包以及处理TLS协议细节[^1]: ```python from scapy.all import * import struct def extract_ja4(packet): try: if packet.haslayer(TLSClientHello): ch = packet[TLSClientHello] # 版本号 version = f"{ch.version:#06x}" # 扩展列表 cipher_suites = ':'.join(f'{cs:#06x}' for cs in struct.unpack('!'+ 'H' * (len(ch.cipher_suites)//2), bytes(ch.cipher_suites))) extensions = [] for ext in ch.extensions: ext_type = f"{ext.type:#06x}" if hasattr(ext, 'data'): data_hex = ''.join([f'{b:02X}' for b in ext.data]) extension_entry = f"{ext_type}-{data_hex}" extensions.append(extension_entry) ja4_string = ",".join([ version, cipher_suites, '-'.join(extensions), ]) return ja4_string except Exception as e: pass return None # 测试函数 if __name__ == "__main__": packets = rdpcap("example.pcap") # 替换为实际抓取的数据包文件路径 for pkt in packets: result = extract_ja4(pkt) if result is not None: print(result) ``` 上述脚本定义了一个名为 `extract_ja4()` 的方法,该方法接收一个Scapy Packet对象作为输入参数并尝试从中抽取必要的信息构建JA4字符串表示形式。此过程涉及读取TLS Client Hello消息中的版本号、密码套件和支持的扩展程序等内容,并按照指定格式组合成最终的结果串。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ks_coder

你的鼓励将是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值