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

2024-06-21 09:44

本文主要是介绍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/

这篇关于014.修改chromium源码-修改webGL指纹(二)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1080879

相关文章

Python函数的基本用法、返回值特性、全局变量修改及异常处理技巧

《Python函数的基本用法、返回值特性、全局变量修改及异常处理技巧》本文将通过实际代码示例,深入讲解Python函数的基本用法、返回值特性、全局变量修改以及异常处理技巧,感兴趣的朋友跟随小编一起看看... 目录一、python函数定义与调用1.1 基本函数定义1.2 函数调用二、函数返回值详解2.1 有返

java 恺撒加密/解密实现原理(附带源码)

《java恺撒加密/解密实现原理(附带源码)》本文介绍Java实现恺撒加密与解密,通过固定位移量对字母进行循环替换,保留大小写及非字母字符,由于其实现简单、易于理解,恺撒加密常被用作学习加密算法的入... 目录Java 恺撒加密/解密实现1. 项目背景与介绍2. 相关知识2.1 恺撒加密算法原理2.2 Ja

Nginx屏蔽服务器名称与版本信息方式(源码级修改)

《Nginx屏蔽服务器名称与版本信息方式(源码级修改)》本文详解如何通过源码修改Nginx1.25.4,移除Server响应头中的服务类型和版本信息,以增强安全性,需重新配置、编译、安装,升级时需重复... 目录一、背景与目的二、适用版本三、操作步骤修改源码文件四、后续操作提示五、注意事项六、总结一、背景与

Android实现图片浏览功能的示例详解(附带源码)

《Android实现图片浏览功能的示例详解(附带源码)》在许多应用中,都需要展示图片并支持用户进行浏览,本文主要为大家介绍了如何通过Android实现图片浏览功能,感兴趣的小伙伴可以跟随小编一起学习一... 目录一、项目背景详细介绍二、项目需求详细介绍三、相关技术详细介绍四、实现思路详细介绍五、完整实现代码

SQL Server修改数据库名及物理数据文件名操作步骤

《SQLServer修改数据库名及物理数据文件名操作步骤》在SQLServer中重命名数据库是一个常见的操作,但需要确保用户具有足够的权限来执行此操作,:本文主要介绍SQLServer修改数据... 目录一、背景介绍二、操作步骤2.1 设置为单用户模式(断开连接)2.2 修改数据库名称2.3 查找逻辑文件名

Oracle修改端口号之后无法启动的解决方案

《Oracle修改端口号之后无法启动的解决方案》Oracle数据库更改端口后出现监听器无法启动的问题确实较为常见,但并非必然发生,这一问题通常源于​​配置错误或环境冲突​​,而非端口修改本身,以下是系... 目录一、问题根源分析​​​二、保姆级解决方案​​​​步骤1:修正监听器配置文件 (listener.

Linux中修改Apache HTTP Server(httpd)默认端口的完整指南

《Linux中修改ApacheHTTPServer(httpd)默认端口的完整指南》ApacheHTTPServer(简称httpd)是Linux系统中最常用的Web服务器之一,本文将详细介绍如何... 目录一、修改 httpd 默认端口的步骤1. 查找 httpd 配置文件路径2. 编辑配置文件3. 保存

8种快速易用的Python Matplotlib数据可视化方法汇总(附源码)

《8种快速易用的PythonMatplotlib数据可视化方法汇总(附源码)》你是否曾经面对一堆复杂的数据,却不知道如何让它们变得直观易懂?别慌,Python的Matplotlib库是你数据可视化的... 目录引言1. 折线图(Line Plot)——趋势分析2. 柱状图(Bar Chart)——对比分析3

Nginx 413修改上传文件大小限制的方法详解

《Nginx413修改上传文件大小限制的方法详解》在使用Nginx作为Web服务器时,有时会遇到客户端尝试上传大文件时返回​​413RequestEntityTooLarge​​... 目录1. 理解 ​​413 Request Entity Too Large​​ 错误2. 修改 Nginx 配置2.1

Python对PDF书签进行添加,修改提取和删除操作

《Python对PDF书签进行添加,修改提取和删除操作》PDF书签是PDF文件中的导航工具,通常包含一个标题和一个跳转位置,本教程将详细介绍如何使用Python对PDF文件中的书签进行操作... 目录简介使用工具python 向 PDF 添加书签添加书签添加嵌套书签Python 修改 PDF 书签Pytho