014.修改chromium源码-修改webGL指纹(二)

修改chromium源码-修改webGL指纹(二)

一、webGL指纹是什么

  • 之前介绍过webGL指纹和常见网站绕过webGL指纹,插眼传送

二、为啥有的webGL指纹-二期

  • 上期我们通过修改gl的参数,getSupportedExtensions()函数返回值列表的顺序,绕过部分网站的指纹检测。
  • 但还有些网站通过webGL生成图形来获取指纹,我们就需要再出一期了。
  • 还有就是:上期指纹检测未通过browserscan这个网站。

三、获取浏览器的webGL指纹(通过生成图像)

  • 有攻才有防,先看看网站是如何通过js获取你的webGL指纹的。
  • 将下面的代码复制到F12控制台,就可以获取显示你的webGL指纹了。

async function sha256(message) {// 把字符串转换为Uint8Arrayconst msgBuffer = new TextEncoder().encode(message);// 计算散列值const hashBuffer = await crypto.subtle.digest('SHA-256', msgBuffer);// 转换为数组const hashArray = Array.from(new Uint8Array(hashBuffer));// 转换为16进制字符串const hashHex = hashArray.map(b => b.toString(16).padStart(2, '0')).join('');return hashHex;
}function getWebGLFingerprint() {var canvas = document.createElement('canvas');var gl = canvas.getContext("webgl") || canvas.getContext("experimental-webgl");// 设置清除颜色为黑色,不透明gl.clearColor(0.0, 0.0, 0.0, 1.0);// 清除颜色缓冲区gl.clear(gl.COLOR_BUFFER_BIT);// 创建顶点着色器var vsSource = `attribute vec4 aVertexPosition;void main(void) {gl_Position = aVertexPosition;}`;var vertexShader = gl.createShader(gl.VERTEX_SHADER);gl.shaderSource(vertexShader, vsSource);gl.compileShader(vertexShader);// 创建片段着色器var fsSource = `void main(void) {gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);}`;var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);gl.shaderSource(fragmentShader, fsSource);gl.compileShader(fragmentShader);// 创建着色器程序var shaderProgram = gl.createProgram();gl.attachShader(shaderProgram, vertexShader);gl.attachShader(shaderProgram, fragmentShader);gl.linkProgram(shaderProgram);gl.useProgram(shaderProgram);// 定义三角形的顶点var vertices = new Float32Array([0.0,  1.0,  0.0,-1.0, -1.0,  0.0,1.0, -1.0,  0.0]);// 创建顶点缓冲区对象var vertexBuffer = gl.createBuffer();gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);// 将缓冲区对象绑定到着色器变量var vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition");gl.enableVertexAttribArray(vertexPositionAttribute);gl.vertexAttribPointer(vertexPositionAttribute, 3, gl.FLOAT, false, 0, 0);// 绘制三角形gl.drawArrays(gl.TRIANGLES, 0, 3);// 读取渲染结果并生成指纹//var pixels = new Uint8Array(gl.drawingBufferWidth * gl.drawingBufferHeight * 4);//gl.readPixels(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight, gl.RGBA, gl.UNSIGNED_BYTE, pixels);//return pixels;var res = canvas.toDataURL()return res
}sha256(getWebGLFingerprint()).then(hash => console.log(hash));

可以看到:获取图像数据有2种方式,关键函数是readPixels()toDataURL()

四、修改源码的readPixels()函数

  • 打开源码文件 \third_party\blink\renderer\modules\webgl\webgl_rendering_context_base.cc
1.找到下面的代码
void WebGLRenderingContextBase::ReadPixelsHelper(GLint x,GLint y,GLsizei width,GLsizei height,GLenum format,GLenum type,DOMArrayBufferView* pixels,int64_t offset) {if (isContextLost())return;
2.替换为
int getRandomIntForFoo12Modern() {static std::mt19937 generator(static_cast<unsigned long>(time(NULL))); // 静态以确保只初始化一次std::uniform_int_distribution<int> distribution(0, 9);return distribution(generator);
}void WebGLRenderingContextBase::ReadPixelsHelper(GLint x,GLint y,GLsizei width,GLsizei height,GLenum format,GLenum type,DOMArrayBufferView* pixels,int64_t offset) {if (isContextLost())return;//追加2行width = width - getRandomIntForFoo12Modern();height = height - getRandomIntForFoo12Modern();

注意:这里我们通过裁剪了部分像素来实现改变ReadPixelsHelper方法的返回值

五、修改源码的toDataURL()函数

  • 打开源码文件 \third_party\blink\renderer\core\html\canvas\html_canvas_element.cc
1.头部加上(随便加在一个#include后面)
#include <algorithm> 
#include <random>    
#include <chrono>   
2.找到下面的代码

String HTMLCanvasElement::toDataURL(const String& mime_type,const ScriptValue& quality_argument,ExceptionState& exception_state) const {if (ContextHasOpenLayers(context_)) {exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,"`toDataURL()` cannot be called with open layers.");return String();}if (!OriginClean()) {exception_state.ThrowSecurityError("Tainted canvases may not be exported.");return String();}double quality = kUndefinedQualityValue;if (!quality_argument.IsEmpty()) {v8::Local<v8::Value> v8_value = quality_argument.V8Value();if (v8_value->IsNumber())quality = v8_value.As<v8::Number>()->Value();}String data = ToDataURLInternal(mime_type, quality, kBackBuffer);TRACE_EVENT_INSTANT(TRACE_DISABLED_BY_DEFAULT("identifiability.high_entropy_api"),"CanvasReadback", "data_url", data.Utf8());return data;
}

注意:最新源码可能和当前代码有略微差异,但基本逻辑是一样。要做的是给返回值后面加空格

3.替换为
String HTMLCanvasElement::toDataURL(const String& mime_type,const ScriptValue& quality_argument,ExceptionState& exception_state) const {if (ContextHasOpenLayers(context_)) {exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,"`toDataURL()` cannot be called with open layers.");return String();}if (!OriginClean()) {exception_state.ThrowSecurityError("Tainted canvases may not be exported.");return String();}double quality = kUndefinedQualityValue;if (!quality_argument.IsEmpty()) {v8::Local<v8::Value> v8_value = quality_argument.V8Value();if (v8_value->IsNumber())quality = v8_value.As<v8::Number>()->Value();}String data = ToDataURLInternal(mime_type, quality, kBackBuffer);TRACE_EVENT_INSTANT(TRACE_DISABLED_BY_DEFAULT("identifiability.high_entropy_api"),"CanvasReadback", "data_url", data.Utf8());//这里追加几行std::srand(std::time(nullptr));int randomNum = std::rand() % 100 + 1;std::string spaces(randomNum, ' ');data = data + String(spaces);//LOG(ERROR) << "data:('" << data << "') data";return data;
}

注意:data返回的是base64字符串,我们随机给后面加多个空格,这样不但不影响函数的功能,hash的也就是乱的了。

4.编译
ninja  -C  out/Default chrome

browserscan这个站要是知道的话,一定会想:这些人怎么这么坏~~

六、在线指纹验证网站:

  • https://abrahamjuliot.github.io/creepjs/
  • https://www.browserscan.net/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/30939.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C语言变量、指针的内存关系

1. type p ? 表示从内存地址p开始&#xff0c;开辟一段内存&#xff0c;内存大小为类型type规定的字节数&#xff0c;然后把等号右边的值写入到这段内存中。 因此&#xff0c;这块内存起点位置是p&#xff0c;结束是ptype字节数-1。 2. type* p ?表示从内存地址p开始&…

Unity3d 游戏暂停(timeScale=0)引起的deltaTime关联的系列问题解决

问题描述 游戏暂停的功能是通过设置timeScale0实现的&#xff0c;不过在暂停游戏的时候&#xff0c;需要对角色进行预览和设置&#xff0c;为了实现这个功能&#xff0c;是通过鼠标控制相机的操作&#xff0c;为了使相机的操作丝滑&#xff0c;获取鼠标操作系数乘以Time.delta…

Opencv学习项目3——pytesseract

上一次我们使用pytesseract.image_to_data(img)来检测文本&#xff0c;这次我们来只检测数字 项目演示 可以看到&#xff0c;我们只检测了数字其他的并没有检测出来 代码实现 前面两次介绍了opencv的画矩形和设置文本&#xff0c;这次就直接用了&#xff0c;不太明白的可以看…

数据资产与用户体验优化:深入挖掘用户数据,精准分析用户需求与行为,优化产品与服务,提升用户体验与满意度,打造卓越的用户体验,赢得市场认可

一、引言 在数字化时代&#xff0c;数据已经成为企业最宝贵的资产之一。通过深入挖掘和分析用户数据&#xff0c;企业能够精准把握用户需求和行为&#xff0c;从而优化产品与服务&#xff0c;提升用户体验和满意度。这不仅有助于企业在激烈的市场竞争中脱颖而出&#xff0c;还…

Java基础 - 练习(四)打印九九乘法表

Java基础练习 打印九九乘法表&#xff0c;先上代码&#xff1a; public static void multiplicationTable() {for (int i 1; i < 9; i) {for (int j 1; j < i; j) {// \t 跳到下一个TAB位置System.out.print(j "" i "" i * j "\t"…

Linux 多进程情况下文件读写加锁

文件读取加锁: #include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <unistd.h> #include <sys/stat.h> #include <sys/file.h> #define LOCK_FILE "/root/priv/cjson/test.lock" #define DA…

在php中的序列化与反序列化

序列化与反序列化的定义&#xff1a; 序列化是指把对象转化为可传输的字节序列过程&#xff0c;而反序列化是指把字节序列还原为对象的过程。序列化和反序列化是数据持久化和网络传输中常用的技术手段&#xff0c;它们使得数据可以在不同平台、不同系统之间进行有效的存储和通信…

HTML 中怎样优化图像加载以提高网页性能?

优化图像加载可以提高网页性能&#xff0c;以下是一些常见的优化方法&#xff1a; 缩小图像尺寸&#xff1a;使用合适的图像尺寸可以减小文件大小&#xff0c;加快加载速度。可以使用图像编辑工具将图像调整到适合网页显示的尺寸。 压缩图像文件&#xff1a;使用图像压缩工具可…

戏剧之家杂志戏剧之家杂志社戏剧之家编辑部2024年第14期目录

文艺评论 南戏瓯剧跨文化传播研究 陈晓东;高阳;许赛梦; 3-7 论互联网时代的戏剧传播与批评——以西法大剧社和南山剧社为例 邬慧敏; 8-10 “左手荒诞&#xff0c;右手温情”——《西西弗神话》在戏剧《第七天》中的接受探究 赵稳稳; 11-13 戏剧研讨《戏剧之家》投稿…

[SAP ABAP] 数据类型

1.基本数据类型 示例1 默认定义的基本数据类型是CHAR数据类型 输出结果: 示例2 STRING数据类型用于存储任何长度可变的字符串 输出结果: 示例3 DATE数据类型用于存储日期信息&#xff0c;并且可以存储8位数字 输出结果: 提示Tips&#xff1a;日期和时间类型的变量可以直接进…

网络安全筑基篇——SQL注入

目录 前言 什么是SQL&#xff1f; 什么是SQL注入&#xff1f; SQL注入的危害有哪些&#xff1f; SQL注入有哪些类型&#xff1f; SQL注入的一些思路 首先得判断SQL注入是否存在 判断SQL注入点 判断数据库的一个类型 SQL注入的防范措施 前言 本文可能有些许的难以理解…

openh264 帧级码率控制源码分析

openh264 码率控制结构 关于 openh264 码率控制整体结构&#xff0c;可以参考&#xff1a;openh264 码率控制原理框架。 openh264 帧级码率控制介绍 函数关系图&#xff1a;从图可以看出&#xff0c;帧级码控的核心函数就是WelsRcPictureInitGom、WelsRcPictureInfoUpdateGo…

DAB-DETR

论文地址&#xff1a; https://arxiv.org/pdf/2201.12329 文章通过前人的经验得出&#xff0c;导致 DETR 训练速度慢的原因很大可能是因为 decoder 中 cross attention 这个模块&#xff0c;由上面的对比可以看出其与 self attention 的区别主要就在于query的不同。文章猜想两个…

LC15.三数之和、LC22括号生成

LC15.三数之和 给你一个整数数组 nums &#xff0c;判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i ! j、i ! k 且 j ! k &#xff0c;同时还满足 nums[i] nums[j] nums[k] 0 。请 你返回所有和为 0 且不重复的三元组。 注意&#xff1a;答案中不可以包含重复的…

【Python办公自动化之Word】

python办公⾃动化之-Word python-docx库 文章目录 python办公⾃动化之-Word1、安装python-docx库2、⽂档的结构说明3、基本操作语法3.1 打开⽂档3.2加⼊不同等级的标题3.3 添加⽂本3.4 设置字号插曲1&#xff1a;实战演示3.5 设置中⽂字体3.6 设置斜体3.7 设置粗体3.8⾸⾏缩进…

H3C防火墙抓包(图形化)

一.报文捕获 &#xff0c;然后通过wireshark查看报文 二.报文示踪 &#xff0c; 输入源目等信息&#xff0c; 查看报文的详情

使用Docker Compose运行Nginx

使用Docker Compose运行Nginx可以更方便地管理和配置多个容器。以下是步骤&#xff1a; 1. 安装Docker Compose 首先&#xff0c;确保已经安装了Docker和Docker Compose。如果没有安装&#xff0c;可以参考官方文档进行安装&#xff1a;Docker Compose安装指南 2. 创建项目目…

mongodb 集群安装

整体架构图&#xff1a; 1. 配置域名 Server1&#xff1a; OS version: CentOS Linux release 8.5.2111 hostnamectl --static set-hostname mongo01 vi /etc/sysconfig/network # Created by anaconda hostnamemong01 echo "192.168.88.20 mong1 mongo01.com mongo…

返回给前端数据的封装

返回格式如下&#xff1a; { "code": 200/400, "msg": "成功"/"失败", "total": n, "data": [ {}&#xff0c;{}]} 1.在common中新增Result 类&#xff0c;代码如下 package com.xxx0523.common; import lombo…

kylin-v10sp2-Babelfish for PostgreSQL

环境准备 x86_linux_kylin v10 sp2 1、依赖 yum makecache yum install -y uuid-devel 2、源代码 下载支持babelfish的pg&#xff0c;也是babelfish社区维护更新 cd /opt#pg源码&#xff0c;支持babelfish版 git clone https://github.com/babelfish-for-postgresql/post…