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

相关文章

opencv图像处理之指纹验证的实现

《opencv图像处理之指纹验证的实现》本文主要介绍了opencv图像处理之指纹验证的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学... 目录一、简介二、具体案例实现1. 图像显示函数2. 指纹验证函数3. 主函数4、运行结果三、总结一、

Python实现无痛修改第三方库源码的方法详解

《Python实现无痛修改第三方库源码的方法详解》很多时候,我们下载的第三方库是不会有需求不满足的情况,但也有极少的情况,第三方库没有兼顾到需求,本文将介绍几个修改源码的操作,大家可以根据需求进行选择... 目录需求不符合模拟示例 1. 修改源文件2. 继承修改3. 猴子补丁4. 追踪局部变量需求不符合很

Linux修改pip和conda缓存路径的几种方法

《Linux修改pip和conda缓存路径的几种方法》在Python生态中,pip和conda是两种常见的软件包管理工具,它们在安装、更新和卸载软件包时都会使用缓存来提高效率,适当地修改它们的缓存路径... 目录一、pip 和 conda 的缓存机制1. pip 的缓存机制默认缓存路径2. conda 的缓

Linux修改pip临时目录方法的详解

《Linux修改pip临时目录方法的详解》在Linux系统中,pip在安装Python包时会使用临时目录(TMPDIR),但默认的临时目录可能会受到存储空间不足或权限问题的影响,所以本文将详细介绍如何... 目录引言一、为什么要修改 pip 的临时目录?1. 解决存储空间不足的问题2. 解决权限问题3. 提

Linux文件名修改方法大全

《Linux文件名修改方法大全》在Linux系统中,文件名修改是一个常见且重要的操作,文件名修改可以更好地管理文件和文件夹,使其更具可读性和有序性,本文将介绍三种在Linux系统下常用的文件名修改方法... 目录一、引言二、使用mv命令修改文件名三、使用rename命令修改文件名四、mv命令和rename命

Spring 中 BeanFactoryPostProcessor 的作用和示例源码分析

《Spring中BeanFactoryPostProcessor的作用和示例源码分析》Spring的BeanFactoryPostProcessor是容器初始化的扩展接口,允许在Bean实例化前... 目录一、概览1. 核心定位2. 核心功能详解3. 关键特性二、Spring 内置的 BeanFactory

mybatis-plus 实现查询表名动态修改的示例代码

《mybatis-plus实现查询表名动态修改的示例代码》通过MyBatis-Plus实现表名的动态替换,根据配置或入参选择不同的表,本文主要介绍了mybatis-plus实现查询表名动态修改的示... 目录实现数据库初始化依赖包配置读取类设置 myBATis-plus 插件测试通过 mybatis-plu

Linux下修改hostname的三种实现方式

《Linux下修改hostname的三种实现方式》:本文主要介绍Linux下修改hostname的三种实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录linux下修改ho编程stname三种方式方法1:修改配置文件方法2:hFvEWEostnamectl命

Git如何修改已提交人的用户名和邮箱

《Git如何修改已提交人的用户名和邮箱》文章介绍了如何修改Git已提交人的用户名和邮箱,包括注意事项和具体步骤,确保操作正确无误... 目录git修改已提交人的用户名和邮箱前言第一步第二步总结git修改已提交人的用户名和邮箱前言需注意以下两点内容:需要在顶层目录下(php就是 .git 文件夹所在的目

修改若依框架Token的过期时间问题

《修改若依框架Token的过期时间问题》本文介绍了如何修改若依框架中Token的过期时间,通过修改`application.yml`文件中的配置来实现,默认单位为分钟,希望此经验对大家有所帮助,也欢迎... 目录修改若依框架Token的过期时间修改Token的过期时间关闭Token的过期时js间总结修改若依