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

025.指纹浏览器-WebGPU指纹+出售成品

一、WebGPU是什么

  • WebGPU 是一种新的 Web 标准,旨在提供一个具备现代硬件加速能力的图形和计算接口,用于网络应用。
  • WebGPU存在的目的是,允许Web网页应用用户设备上的GPU,从而实现更加高效和强大的图形渲染和计算性能。

二、什么是WebGPU指纹

  • 通过收集如GPU型号、驱动版本、支持的图形特性等信息,hash而成的指纹信息。
  • WebGPU指纹唯一性并不太高,还有很多浏览器是不支持webGPU,所以WebGPU指纹的风控等级较低

三、获取浏览器的WebGPU指纹

  • 有攻才有防,先看看网站是如何通过js获取你的WebGPU指纹的。
  • 将下面的代码复制到F12控制台,就可以获取显示你的WebGPU指纹了
async function checkWebGPUSupport() {
    if (!navigator.gpu) {
        console.log("当前浏览器不支持WebGPU");
        return;
    }

    const adapter = await navigator.gpu.requestAdapter();
    if (!adapter) {
        console.log("当前浏览器不支持WebGPU");
        return;
    }

    const device = await adapter.requestDevice();
    // console.log("GPU Device:", device);

    // 请求设备支持的扩展
    const extensions = Array.from(adapter.features.values());
    console.log("支持的扩展:", extensions);

    // 获取硬件限制信息并手动序列化
    const limits = {};
    for (const key in device.limits) {
	    console.log("key", key)
        limits[key] = device.limits[key];
    }
    console.log("硬件限制信息:", limits);

    // 序列化和哈希处理
    const serializedData = JSON.stringify({
        extensions: extensions,
        limits: limits
    });
    console.log('serializedData', serializedData);
	
    // 使用SHA-256计算哈希
    const hashBuffer = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(serializedData));
    const hashArray = Array.from(new Uint8Array(hashBuffer));
    const hashHex = hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
    
    console.log("hash后得到的webGPU指纹:", hashHex);
}

await checkWebGPUSupport();

  • 输出:
ffa2f3d7b37fd10b2c2eb8c7bb973462443ec1d10040191a399c68fab4d812ee

四、编译随机webGPU指纹

不用注意:这里依旧是全网独一份。

  • 第一篇文章写了如何编译chromium,假设你已经编译成功了。
  • 找到源码 /third_party/blink/renderer/modules/webgpu/gpu_supported_limits.cc
1.头部加上(随便加在一个#include后面)
#include "base/command_line.h"
2.我们注释掉这里的最后一行
#define SUPPORTED_LIMITS(X)                    \
  X(maxTextureDimension1D)                     \
  X(maxTextureDimension2D)                     \
  X(maxTextureDimension3D)                     \
  X(maxTextureArrayLayers)                     \
  X(maxBindGroups)                             \
  X(maxBindGroupsPlusVertexBuffers)            \
  X(maxBindingsPerBindGroup)                   \
  X(maxDynamicUniformBuffersPerPipelineLayout) \
  X(maxDynamicStorageBuffersPerPipelineLayout) \
  X(maxSampledTexturesPerShaderStage)          \
  X(maxSamplersPerShaderStage)                 \
  X(maxStorageBuffersPerShaderStage)           \
  X(maxStorageTexturesPerShaderStage)          \
  X(maxUniformBuffersPerShaderStage)           \
  X(maxUniformBufferBindingSize)               \
  X(maxStorageBufferBindingSize)               \
  X(minUniformBufferOffsetAlignment)           \
  X(minStorageBufferOffsetAlignment)           \
  X(maxVertexBuffers)                          \
  X(maxBufferSize)                             \
  X(maxVertexAttributes)                       \
  X(maxVertexBufferArrayStride)                \
  X(maxInterStageShaderComponents)             \
  X(maxInterStageShaderVariables)              \
  X(maxColorAttachments)                       \
  X(maxColorAttachmentBytesPerSample)          \
  X(maxComputeWorkgroupStorageSize)            \
  X(maxComputeInvocationsPerWorkgroup)         \
  X(maxComputeWorkgroupSizeX)                  \
  X(maxComputeWorkgroupSizeY)                  \
  X(maxComputeWorkgroupSizeZ)                  \
  //X(maxComputeWorkgroupsPerDimension)

这里注释的maxComputeWorkgroupsPerDimension其实是个函数,注释掉是因为我们要给它重新定义一个。

3. 随便一个函数后面追加:
unsigned  GPUSupportedLimits::maxComputeWorkgroupsPerDimension() const {
  base::CommandLine* base_command_line = base::CommandLine::ForCurrentProcess();
  int seed;
  if (base_command_line->HasSwitch("fingerprints")) {
      std::istringstream(base_command_line->GetSwitchValueASCII("fingerprints")) >> seed; 
  }else{
      auto now = std::chrono::system_clock::now();
      std::time_t now_time_t = std::chrono::system_clock::to_time_t(now);
      seed = static_cast<int>(now_time_t);
  }
  return seed % 128;
}

可以看到,这里的原理就是webGPU里的maxComputeWorkgroupsPerDimension属性设置成了返回随机数。其他属性集帅们按需照搬。

4.编译
ninja  -C  out/Default chrome
  • 找到out/Default chrome下新编译的执行文件chrome.exe执行
  • 再次看看webGPU指纹,是不是每次访问都变成随机了。

五、在线指纹验证网站:

  • https://browserleaks.com/webgpu
  • https://abrahamjuliot.github.io/creepjs/

六、广告时间

  • 集帅们的支持是我还在继续更新的动力。
  • 再次推广下自编译的指纹浏览器,集帅可以直接购买。链接: https://dwz.cn/KOweICeK
成品功能:
  • canvas指纹
  • plugins指纹
  • webGL指纹
  • webRTC禁用
  • audio指纹
  • ClientRects指纹
  • tls/ja4指纹
  • fonts指纹
  • webGPU指纹
  • 可绕过cdp检测
  • 可绕过常见无头检测
  • 浏览器屏幕信息
  • 浏览器版本和UserAgent
  • creepjs跑分为 D-
成品参数:
  • 启动chrome时,传入参数--fingerprints=123123123(正整数),则指纹固定不变。当正整数更换,则获得一个新指纹。
  • 启动chrome时,不传--fingerprints,则每个访问请求的指纹全部随机生成。

(附加)

  • 适配的chromedriver.exe
  • 启动chrome时,传入参数--noimage的话,从底层彻底抹除图片的访问请求。

注意:指纹浏览器编译版本为124,只用于爬虫,目前只有windows的,会有视频,声音无法播放的情况


http://www.kler.cn/a/281952.html

相关文章:

  • ks 小程序sig3
  • 十五届蓝桥杯赛题-c/c++ 大学b组
  • 自动化运维-检测Linux服务器CPU、内存、负载、IO读写、机房带宽和服务器类型等信息脚本
  • Nacos 配置中心变更利器:自定义标签灰度
  • 前端基础(四十一):实时获取麦克风音量
  • python语言基础-5 进阶语法-5.2 装饰器-5.2.2 简单装饰器
  • git-命名规范
  • GPT应用-如何用GPT4.0写一份专业的ppt
  • vue全局参数
  • upload-labs(Pass-18 ~ Pass-21)
  • 0x03 ShowDoc 文件上传漏洞(CNVD-2020-26585)复现
  • 乾元通渠道商中标大理市自然灾害应急能力提升项目
  • MSSQL 手工注入(第一关)
  • 数学建模之数据分析【八】:数据预处理之数据格式化
  • Objective-C 动态调用秘籍:NSInvocation 的魔法
  • 使用matplotlib可视化dataframe:让你的数据更生动有趣
  • 【采集软件】抖音根据关键词批量采集搜索结果工具
  • 使用Hutool操作Excel的时候出现的问题(压缩比问题)
  • 计算机毕业设计选题推荐-保险业务管理系统-Java/Python项目实战
  • 使用canal增量同步ES索引库数据
  • AI模型应该追求全能还是专精
  • 【hot100篇-python刷题记录】【跳跃游戏】
  • 设计模式 7 桥接模式
  • 【Redis】Redis编程技巧
  • (十八)Flink CEP 详解
  • Spring数据访问层管理 ▎集成MyBatis ▎AOP ▎事务管理 ▎SpringWeb配置