当前位置: 首页 > news >正文

Python爬虫TLS

TLS指纹校验原理和绕过

浏览器可以正常访问,但是用requests发送请求失败。

后端是如何监测得呢?为什么浏览器可以返回结果,而requests模块不行呢?

https://cn.investing.com/equities/amazon-com-inc-historical-data

1.指纹校验案例

1.1 案例:ascii2d

https://ascii2d.net/

import requestsres = requests.get(url="https://ascii2d.net"
)print(res.text)
<!DOCTYPE html>
<html lang="en-US"><head><title>Just a moment...</title><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /></head>...
</html>

1.2 案例:investing

https://cn.investing.com/equities/amazon-com-inc-historical-data

import requestsres = requests.get(url="https://cn.investing.com/equities/amazon-com-inc-historical-data",headers={'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.93 Safari/537.36',}
)
res.encoding = 'utf-8'
print(res.text)

1.3 案例:yuanrenxue

import requestsres = requests.get(url="https://match.yuanrenxue.cn/api/match/19?page=1"
)print(res.text)

2.TLS指纹

如今几乎所有平台通信都是基于Https的协议,而无论基于什么工具去发送Https请求时,都需要基于TLS/SSL先建立两端安全的通信(握手),建立后再进行数据传输。

TLS的握手阶段,客户端会向服务端发送 Client Hello 数据包,在数据包内的JA3就是指纹信息(基于电脑的TLS版本+内置算法等计算出来的字符串),并且该值不会随着请求头修改、代理等发生变化。所以,某个网站的后台就会去读取TLS客户端的JA3指纹,如果是非正常指纹,禁止访问。例如:

  • requests请求

    requests==2.31.0
    urllib3==2.0.7
    
    [JA3 Fullstring: 771,4866-4867-4865-49196-49200-159-52393-52392-52394-49195-49199-158-49188-49192-107-49187-49191-103-49162-49172-57-49161-49171-51-157-156-61-60-53-47-255,0-11-10-16-22-23-49-13-43-45-51-21,29-23-30-25-24,0-1-2][JA3: bc29aa426fc99c0be1b9be941869f88a]固定,所以后端API可以禁止此指纹。
    
  • 浏览器请求

    [JA3 Fullstring: 771,4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,11-18-27-35-16-51-10-23-5-43-65281-65037-0-17513-13-45,29-23-24,0][JA3: 5ae2fe79293ec63d585f3f987cf69d01]谷歌浏览器的JA3会变化。
    

扩展:有些网站专门收录ja3黑名单。

https://sslbl.abuse.ch/ja3-fingerprints/
https://sslbl.abuse.ch/blacklist/sslblacklist.csv
https://github.com/salesforce/ja3/blob/master/lists/osx-nix-ja3.csv
https://ja3er.com/getAllUasJson
https://ja3er.com/getAllHashesJson

2.1 查看指纹

想要快速查看自己的TSL指纹信息:https://tls.browserleaks.com/json

import requestsres = requests.get('https://tls.browserleaks.com/json')
print(res.text)

其他网站还有:

https://tls.browserleaks.com/json
https://tls.peet.ws/
https://tls.peet.ws/api/all

2.2 Wireshark

基于Wireshark抓包并筛选出Client Hello数据包,去内部查看:

1.下载安装

下载并安装Wireshark https://www.wireshark.org/download.html

2.抓网卡

打开Wireshark,选择要抓包监测的网卡,选择你上网使用的那个网卡。

3.筛选IP

筛选目标IP ip.dst_host==146.56.195.149

4.数据包

用浏览器或用requests发送请求,就可以监测到网络请求,然后找到 Client Hello数据包,就可以看到相关指纹信息。

2.3 ja3

[JA3 Fullstring: 771,4866-4867-4865-49196-49200-159-52393-52392-52394-49195-49199-158-49188-49192-107-49187-49191-103-49162-49172-57-49161-49171-51-157-156-61-60-53-47-255,0-11-10-16-22-23-49-13-43-45-51-21,29-23-30-25-24,0-1-2][JA3: bc29aa426fc99c0be1b9be941869f88a]

关于加密相关的值:

  • JA3 是对 JA3 Fullstring进行md5加密的结果。

  • JA3 Fullstring是由五段组成

    JA3 gathers the decimal values of the bytes for the following fields in the Client Hello packet; - SSL Version,- Accepted Ciphers- List of Extensions- Elliptic Curves- Elliptic Curve Formats
    It then concatenates those values together in order, using a "," to delimit each field and a "-" to delimit each value in each field.JA3 为客户端发送的clienthello 数据包中的以下字段收集字节的十进制值: SSL Version, Accepted Ciphers, List of Extensions, Elliptic Curves, and Elliptic Curve Formats(SSL 版本、接受的密码、扩展列表、椭圆曲线和椭圆曲线格式)。然后它将这些值按顺序连接在一起,使用“,”分隔每个字段,使用“-”分隔每个字段中的每个值。https://github.com/salesforce/ja3
    
    SSLVersion, Cipher, SSLExtension, EllipticCurve, EllipticCurvePointFormat
    
    第1个值:771                                   表示SSL版本,即:TLS 1.2(0x0303),0x0303转换为10进制就是771第2个值:4866-4867-4865-49196-49200-159-52393-52392-52394-49195-49199-158-49188-49192-107-49187-49191-103-49162-49172-57-49161-49171-51-157-156-61-60-53-47-255        表示TLS客户端支持的加密套件。第三个值:0-11-10-16-22-23-49-13-43-45-51-21    表示支持的 TLS 扩展第四个值:29-23-30-25-24                        表示支持的支持的椭圆曲线(ECC加密算法)第五个值:0-1-2                                 表示支持的椭圆曲线格式
    

1.SSLVersion

771

将0x0303转换为10进制就是771

2.Cipher

4866-4867-4865-49196-49200-159-52393-52392-52394-49195-49199-158-49188-49192-107-49187-49191-103-49162-49172-57-49161-49171-51-157-156-61-60-53-47-255

将算法套件的十六进制表示,转换成十进制,然后再凭借起来。

3.SSLExtension

0-11-10-16-22-23-49-13-43-45-51-21

SSL中所有的扩展对应的数字

4.EllipticCurve

29-23-30-25-24

将supported_groups对应的十六进制转换成十进制。

5.EllipticCurvePointFormat

0-1-2

ec_point_formats转换转换十进制。

3.突破指纹

理解TLS中ja3生成机制后,绕过的思路也就有了:requests请求时,改变 ja3 string得内容,生成合法的的ja3指纹

3.1 【PY】requests【案例3】

requests在发送请求时,内部依赖urllib3实现。

pip install urllib3==1.26.15
pip install urllib3==1.26.16
pip install urllib3==2.0.7

自定义 ciphers实现生成非默认ja3

方式1:

import requests
import urllib3urllib3.util.ssl_.DEFAULT_CIPHERS = ":".join([# "ECDHE+AESGCM",# "ECDHE+CHACHA20",# "DHE+AESGCM",# "DHE+CHACHA20",# "ECDH+AESGCM",# "DH+AESGCM",# "ECDH+AES","DH+AES","RSA+AESGCM","RSA+AES","!aNULL","!eNULL","!MD5","!DSS",
])res = requests.get(url="https://tls.browserleaks.com/json",headers={'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.93 Safari/537.36',}
)
res.encoding = 'utf-8'
print(res.text)

方式2:

import requests
from requests.adapters import HTTPAdapter
from requests.packages.urllib3.util.ssl_ import create_urllib3_contextclass MineAdapter(HTTPAdapter):CIPHERS = ":".join(["ECDHE+AESGCM","ECDHE+CHACHA20","DHE+AESGCM","DHE+CHACHA20","ECDH+AESGCM","DH+AESGCM","ECDH+AES","DH+AES","RSA+AESGCM","RSA+AES","!aNULL","!eNULL","!MD5","!DSS",])def init_poolmanager(self, *args, **kwargs):context = create_urllib3_context(ciphers=self.CIPHERS)kwargs['ssl_context'] = contextreturn super().init_poolmanager(*args, **kwargs)def proxy_manager_for(self, *args, **kwargs):context = create_urllib3_context(ciphers=self.CIPHERS)kwargs['ssl_context'] = contextreturn super().proxy_manager_for(*args, **kwargs)session = requests.Session()
session.headers.update({'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.93 Safari/537.36',
})
session.mount("https://", MineAdapter())res = session.get("https://tls.browserleaks.com/json")
res.encoding = 'utf-8'
print(res.text)

用此方法,可以过案例3的TLS校验机制,例如:

import requests
import urllib3urllib3.util.ssl_.DEFAULT_CIPHERS = ":".join([# "ECDHE+AESGCM",# "ECDHE+CHACHA20",# "DHE+AESGCM",# "DHE+CHACHA20",# "ECDH+AESGCM",# "DH+AESGCM",# "ECDH+AES","DH+AES","RSA+AESGCM","RSA+AES","!aNULL","!eNULL","!MD5","!DSS",
])res = requests.get(url="https://match.yuanrenxue.cn/api/match/19?page=1",headers={'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.93 Safari/537.36',}
)
res.encoding = 'utf-8'
print(res.text)

注意:Python层得TLS是基于底层openssl对外提供的方法,而openssl暴漏给Python只能通过修改 ciphers 来修改ja3指纹,无法支持修改 SSLExtension, EllipticCurve, EllipticCurvePointFormat

3.2 【PY】curl_cffi【案例1+2+3】

https://pypi.org/project/curl-cffi/#description

  • curl是一个可以发送网络请求的工具。
  • curl-impersonate是一个基于curl基础上进行开发的一个工具,可以完美的模拟主流的浏览器。
  • curl_cffi,是套壳curl-impersonate,让此工具可以更方便的应用在Python中。
pip install curl-cffi
from curl_cffi import requestsres = requests.get(# url="https://ascii2d.net/",# url="https://cn.investing.com/equities/amazon-com-inc-historical-data",url="https://match.yuanrenxue.cn/api/match/19?page=1",headers={'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.93 Safari/537.36',},impersonate="chrome101",
)
print(res.text)

3.3 【Go】CycleTLS 【案例1+2+3】

关于Golang环境和基础入门教程可以参考:

课件:https://www.5xclass.cn/wiki/detail/4/0/
视频:https://www.bilibili.com/video/BV1u5411W79w/

github上有一个基于Golang开发的开源模块CycleTLS ,可以更靠近底层去实现定制ja3指纹,直接自定义ja3 fullstring

https://github.com/Danny-Dasilva/CycleTLS

go get github.com/Danny-Dasilva/CycleTLS/cycletls 
package mainimport ("github.com/Danny-Dasilva/CycleTLS/cycletls""log"
)func main() {client := cycletls.Init()// https://ascii2d.net/// https://cn.investing.com/equities/amazon-com-inc-historical-data// https://match.yuanrenxue.cn/api/match/19?page=1response, err := client.Do("https://tls.browserleaks.com/json", 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)
}

相关文章:

Python爬虫TLS

TLS指纹校验原理和绕过 浏览器可以正常访问&#xff0c;但是用requests发送请求失败。 后端是如何监测得呢&#xff1f;为什么浏览器可以返回结果&#xff0c;而requests模块不行呢&#xff1f; https://cn.investing.com/equities/amazon-com-inc-historical-data 1.指纹校…...

【Linux AnolisOS】配置Linux固定ip地址。然后在Windows上连接使用linux中docker容器里的redis和nacos。

1.关于将虚拟机ip地址更改为静态地址 &#xff0c;跟着下面这个视频搞的&#xff0c;不想看文章的可以看视频。 第四章-07-配置Linux固定IP地址哔哩哔哩bilibili 当用的centos9 视频里让我们打开网络配置文件 vim /etc/sysconfig/network-scripts/ifcfg-ens33 但是我打开时…...

IDEA中查询Maven项目的依赖树

在Maven项目中&#xff0c;查看项目的依赖树是一个常见的需求&#xff0c;特别是当你需要了解项目中直接或间接依赖了哪些库及其版本时。你可以通过命令行使用Maven的dependency:tree插件来做到这一点。这个命令会列出项目中所有依赖的树状结构。 打开idea项目的终端&#xff…...

【Ubuntu】GPU显存被占用,但显示没有使用GPU的进程

文章目录 一、问题描述二、解决方案2.1 寻找问题进程2.2 尝试杀死相关进程2.3 投放核弹&#xff0c;一键全杀2.4 再次查看GPU使用情况 参考资料 一、问题描述 今天使用服务器的时候发现gpu被占了很多内存&#xff0c;但是使用 nvidia-smi 命令并没有发现占这么多显存的进程&am…...

【并发编程】Java并发编程核心包

1、简介 java.util.concurrent 是 Java 并发编程的核心包&#xff0c;提供了丰富的工具和框架来支持多线程编程、并发任务执行、线程安全集合、同步机制等。 2、线程池Thread Pool 线程池是并发编程中最重要的工具之一&#xff0c;用于管理和复用线程&#xff0c;避免频繁创…...

Unity 淡入淡出

淡入&#xff08;Fade in&#xff09;&#xff1a;类似打开幕布 淡出&#xff08;Fade out&#xff09;&#xff1a;类似关上幕布 方案一 使用Dotween&#xff08;推荐&#xff09; using DG.Tweening; using UnityEngine; using UnityEngine.UI;public class Test : MonoB…...

完整的 LoRA 模型训练步骤:如何使用 Kohya_ss 进行 LoRA 训练

完整的 LoRA 模型训练步骤&#xff1a;如何使用 Kohya_ss 进行 LoRA 训练 一、环境配置1. 安装 Python 和虚拟环境2. 克隆 Kohya_ss 仓库3. 安装依赖4. 启动 GUI lora训练1. 准备数据 图片处理打标签2. 配置 LoRA 训练2.2 配置图片文件夹和输出目录 训练解决方法&#xff1a; 使…...

视觉分析之边缘检测算法

9.1 Roberts算子 Roberts算子又称为交叉微分算法&#xff0c;是基于交叉差分的梯度算法&#xff0c;通过局部差分计算检测边缘线条。 常用来处理具有陡峭的低噪声图像&#xff0c;当图像边缘接近于正45度或负45度时&#xff0c;该算法处理效果更理想。 其缺点是对边缘的定位…...

git输错用户名或者密码

git push时候跳出window弹窗&#xff0c;输入用户名和密码&#xff0c;如果错误&#xff0c;会有如下情况&#xff1a; $ git push -u origin “master” remote: [session-6c466aa6] rain: Incorrect username or password (access token) fatal: Authentication failed for ‘…...

【Unity Shader编程】之图元装配与光栅化

执行方式&#xff1a;自动完成 图元装配自动化流程 顶点坐标存入装配区 → 按绘制模式连接顶点 → 生成完整几何图元 示例&#xff1a;gl.drawArrays(gl.TRIANGLES, 0, 3)自动生成三角形 会自动自动裁剪超出屏幕范围&#xff08;NDC空间外&#xff09;的三角形&#xff0c;仅保…...

以ChatGPT为例解析大模型背后的技术

目录 1、大模型分类 2、为什么自然语言处理可计算&#xff1f; 2.1、One-hot分类编码&#xff08;传统词表示方法&#xff09; 2.2、词向量 3、Transformer架构 3.1、何为注意力机制&#xff1f; 3.2、注意力机制在 Transformer 模型中有何意义&#xff1f; 3.3、位置编…...

网页版的俄罗斯方块

1、新建一个txt文件 2、打开后将代码复制进去保存 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>俄…...

Linux运维_Dockerfile_打包Moby-26.1.4编译dockerd环境

Linux运维_Dockerfile_打包Moby-26.1.4编译dockerd环境 Dockerfile 是一个文本文件, 包含了构建 Docker 镜像的所有指令。 Dockerfile 是一个用来构建镜像的文本文件, 文本内容包含了一条条构建镜像所需的指令和说明。 通过定义一系列命令和参数, Dockerfile 指导 Docker 构…...

数据中心储能蓄电池状态监测管理系统 组成架构介绍

安科瑞刘鸿鹏 摘要 随着数据中心对供电可靠性要求的提高&#xff0c;蓄电池储能系统成为关键的后备电源。本文探讨了蓄电池监测系统在数据中心储能系统中的重要性&#xff0c;分析了ABAT系列蓄电池在线监测系统的功能、技术特点及其应用优势。通过蓄电池监测系统的实施&#…...

layui.table.exportFile 导出数据并清除单元格中的空格

Layui在执行数据导出的时候&#xff0c;会出现部分数据单元格中有空格的情况,下面的方法可以去除掉单元格中的空格,供大家参考&#xff01;&#xff01; function table_export(id,title) {//根据传入tableID获取表头var headers $("div[lay-id" id "] .layu…...

vue-指令

前端开发Vue的指令 Vue.js 提供了丰富的指令系统&#xff0c;用于扩展HTML的功能和行为。这些指令可以分为内置指令和自定义指令两大类。以下是对Vue.js中常见指令的详细解释和示例&#xff1a; 1. 内置指令 1.1 插值表达式 用法&#xff1a;{{ expression }}示例&#xff…...

跟着李沐老师学习深度学习(十三)

现代循环神经网络 循环神经网络中梯度异常在实践中的意义引发了一些问题&#xff1a; 早期观测值影响重大&#xff1a;早期观测值对预测所有未来观测值极为重要&#xff0c;如序列中第一个观测值包含校验和&#xff0c;需在序列末尾辨别其是否正确&#xff0c;若无特殊机制存…...

鸿蒙与跨端迁移的重要性

鸿蒙操作系统&#xff08;HarmonyOS&#xff09;是由华为公司开发的一款面向未来的全场景分布式操作系统。它旨在提供一个统一的平台&#xff0c;支持各种设备之间的无缝协作和数据共享&#xff0c;从而为用户提供更加连贯和高效的体验。在鸿蒙的生态系统中&#xff0c;跨端迁移…...

成员函数定义后面加const是什么功能:C++中const成员函数的作用

成员函数定义后面加const是什么功能&#xff1a;C中const成员函数的作用 前言C中const成员函数的作用总结 前言 在PX4的代码中的位置控制模块中&#xff0c;有这样一个成员函数 void getAttitudeSetpoint(vehicle_attitude_setpoint_s &attitude_setpoint) const;该函数的…...

QSNCTF-WEB做题记录

第一题&#xff0c;文章管理系统 来自 <天狩CTF竞赛平台> 描述&#xff1a;这是我们的文章管理系统&#xff0c;快来看看有什么漏洞可以拿到FLAG吧&#xff1f;注意&#xff1a;可能有个假FLAG哦 1&#xff0c;首先观察题目网站的结构和特征 这个一个文件管理系统&#x…...

设计模式和设计原则回顾

设计模式和设计原则回顾 23种设计模式是设计原则的完美体现,设计原则设计原则是设计模式的理论基石, 设计模式 在经典的设计模式分类中(如《设计模式:可复用面向对象软件的基础》一书中),总共有23种设计模式,分为三大类: 一、创建型模式(5种) 1. 单例模式(Sing…...

【Java学习笔记】Arrays类

Arrays 类 1. 导入包&#xff1a;import java.util.Arrays 2. 常用方法一览表 方法描述Arrays.toString()返回数组的字符串形式Arrays.sort()排序&#xff08;自然排序和定制排序&#xff09;Arrays.binarySearch()通过二分搜索法进行查找&#xff08;前提&#xff1a;数组是…...

CentOS下的分布式内存计算Spark环境部署

一、Spark 核心架构与应用场景 1.1 分布式计算引擎的核心优势 Spark 是基于内存的分布式计算框架&#xff0c;相比 MapReduce 具有以下核心优势&#xff1a; 内存计算&#xff1a;数据可常驻内存&#xff0c;迭代计算性能提升 10-100 倍&#xff08;文档段落&#xff1a;3-79…...

Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility

Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility 1. 实验室环境1.1 实验室环境1.2 小测试 2. The Endor System2.1 部署应用2.2 检查现有策略 3. Cilium 策略实体3.1 创建 allow-all 网络策略3.2 在 Hubble CLI 中验证网络策略源3.3 …...

Spring Boot+Neo4j知识图谱实战:3步搭建智能关系网络!

一、引言 在数据驱动的背景下&#xff0c;知识图谱凭借其高效的信息组织能力&#xff0c;正逐步成为各行业应用的关键技术。本文聚焦 Spring Boot与Neo4j图数据库的技术结合&#xff0c;探讨知识图谱开发的实现细节&#xff0c;帮助读者掌握该技术栈在实际项目中的落地方法。 …...

Unit 1 深度强化学习简介

Deep RL Course ——Unit 1 Introduction 从理论和实践层面深入学习深度强化学习。学会使用知名的深度强化学习库&#xff0c;例如 Stable Baselines3、RL Baselines3 Zoo、Sample Factory 和 CleanRL。在独特的环境中训练智能体&#xff0c;比如 SnowballFight、Huggy the Do…...

Python Ovito统计金刚石结构数量

大家好,我是小马老师。 本文介绍python ovito方法统计金刚石结构的方法。 Ovito Identify diamond structure命令可以识别和统计金刚石结构,但是无法直接输出结构的变化情况。 本文使用python调用ovito包的方法,可以持续统计各步的金刚石结构,具体代码如下: from ovito…...

Linux系统部署KES

1、安装准备 1.版本说明V008R006C009B0014 V008&#xff1a;是version产品的大版本。 R006&#xff1a;是release产品特性版本。 C009&#xff1a;是通用版 B0014&#xff1a;是build开发过程中的构建版本2.硬件要求 #安全版和企业版 内存&#xff1a;1GB 以上 硬盘&#xf…...

MyBatis中关于缓存的理解

MyBatis缓存 MyBatis系统当中默认定义两级缓存&#xff1a;一级缓存、二级缓存 默认情况下&#xff0c;只有一级缓存开启&#xff08;sqlSession级别的缓存&#xff09;二级缓存需要手动开启配置&#xff0c;需要局域namespace级别的缓存 一级缓存&#xff08;本地缓存&#…...

git: early EOF

macOS报错&#xff1a; Initialized empty Git repository in /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/.git/ remote: Enumerating objects: 2691797, done. remote: Counting objects: 100% (1760/1760), done. remote: Compressing objects: 100% (636/636…...