基于Web浏览器的设备指纹相关知识整理

本文最后更新于2019年3月2日,已超过 1 年没有更新,如果文章内容失效,还请反馈给我,谢谢!

=Start=

缘由:

在做数据安全的过程中需要准确的数据以支持进一步的分析,传统的IP、UserAgent太简单,不具备对抗性和唯一性(但一般情况下也还OK,并没有那么不堪,因为大部分都还是正常用户)。最好的情况肯定是通过安装的agent去获取更准确、更全面的信息,但如果没有条件的话,只能退而求其次,选用基于Web浏览器的指纹了。

这里整理一下收集整理到的和Web指纹相关的资料,方便后续要用的时候查阅和参考。

正文:

参考解答:

# 什么是“指纹”?

说到“指纹”可能大家都知道是手指头的纹理,而且每个人的指纹都是唯一的。 如果你时常接触信息安全领域的一些资料,也会听到“指纹”这个形象的说法(比如:操作系统指纹、网络协议栈指纹、等等)。IT 领域提到的“指纹”一词,其原理跟“刑侦”是类似的——“当你需要研究某个对象的类型/类别,但这个对象你又无法直接接触到。这时候你可以利用若干技术来获取该对象的某些特征,然后根据这些特征来猜测/判断该对象的类型/类别

# “指纹”和隐私的关系

在启用cookie(或是需要登录)的情况下,对于网站而言,你是没什么隐私可言的(但这属于你知晓相关情况,以相关信息换取便利和个性化服务,也不是所有的网站都会利用获取的数据对你做偏好分析,虽然这种做法现在很普遍……);

但在“指纹”这种情况下,你是无法知道网站是否有在客户端(以某种方式)保存了什么信息,它不会被用户发觉,用户也无法清除,所以在启用了“指纹”的情况下,你也是没有什么隐私可言的。

# 什么是“指纹”的“信息量”?

在 IT 领域有各种各样的特征可以用来充当“指纹”。这时候就需要判断,用哪个特征做指纹,效果更好。为了讨论这个问题,就得扫盲一下“指纹的信息量”。 为了帮助大伙儿理解,先举一个例子: 假设你要在学校中定位某个人,如果你光知道此人的性别,你是比较难定位的(只能排除 1/2 的人);反之如果你不知道性别,但是知道此人的生日,就比较容易定位(可以排除掉大约 364/365 的人,只剩大约 1/365 的人)。为什么?因为“生日”比“性别”更加独特,所以“生日”比“性别”能够提供更多的信息量。 从这个例子可以看出:某个特征越独特,则该特征的信息量越大;反之亦然。信息量越大的特征,就可以把对象定位到越小的范围。

一些浏览器信息的「信息量」:

Variable Entropy (bits)
plugins 15.4
fonts 13.9
user agent 10.0
http accept 6.09
screen resolution 4.83
timezone 3.04
supercookies 2.12
cookies enabled 0.353
# 多个“指纹”的综合定位

如果能同时获取【互不相关】的若干个指纹,就可以大大增加定位的精确性。比如要在某个公司里面定位某人,如果你知道此人的“生日”和“生肖”,那么就可以达到 1/4380(1/4380 = 1/12 * 1/365) 的定位精度。因为综合定位之后,比例之间是【乘法】的关系,所以范围就被急剧缩小了。 为什么要特别强调“互不相关”呢?假如你同时知道的信息是“生日”和“星座”,那么定位的精度依然是 1/365——因为生日的信息已经包含了星座的信息。所以,只有那些相互独立的特征(所谓的相互独立,数学称为“正交”),在综合定位的时候才可以用【乘法】。

# 什么是“浏览器的指纹”?

当你使用浏览器访问某个网站的时候,浏览器【必定会暴露】某些信息给这个网站。为什么强调“必定”呢?因为这些信息中,有些是跟 HTTP 协议相关的(本章节说的 HTTP 协议是广义的,也包括 HTTPS)。只要你基于 HTTP 协议访问网站,浏览器就【必定】会传输这些信息给网站的服务器。 再啰嗦一下:HTTP 协议是 Web 的基石。只要你通过浏览器访问 Web,必定是基于 HTTP 协议的。因此,Web 网站的服务器必定可以获取到跟你的浏览器相关的某些信息(具体是哪些信息,下面会说到)。

# “浏览器指纹”如何暴露隐私?

简单来说就是,cookie是主动暴露(为了获得更好的服务),而且有规避的办法(例如:浏览器的隐身模式);「浏览器指纹」属于「被动暴露」,隐蔽性更强,因而很难进行有效规避。

# 浏览器指纹技术分类

1、常见浏览器指纹(以AmIUnique模型为例);

属性 来源 例子
User agent HTTP header Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.118 Safari/537.36
Accept HTTP header text/html,applicationxhtmlxml,applicationxml;q=0.9,image/webp,/;q=0.8
Content encoding HTTP header gzip, deflate, sdch
Content language HTTP header en-us,en;q=0.5
List of plugins JavaScript Plugin 1: Chrome PDF Viewer. Plugin 2: Chrome Remote Desktop Viewer. Plugin 3: Native Client.Plugin 4: Shockwave Flash..
Cookies enabled JavaScript yes
Use of local/session storage JavaScript yes
Timezone JavaScript -60 (UTC+1)
Screen resolution and color depth JavaScript 1920x1200x24
List of fonts Flash plugin Abyssinica SIL,Aharoni CLM,AR PL UMing CN,AR PL UMing HK,AR PL UMing TW…
List of HTTP headers HTTP headers Referer,X-Forwarded-For,Connection,Accept,Cookie,Accept-Language,Accept-Encoding,User-Agent,Host
Platform JavaScript Linux x86_64
Do Not Track JavaScript yes
Canvas JavaScript vext quiz
WebGL Vendor JavaScript NVIDIA Corporation
WebGL Renderer JavaScript GeForce GTX 650 Ti/PCIe/SSE2
Use of an ad blocker JavaScript no

2、Canvas指纹及WebGL指纹;

HTML5中的Canvas元素允许脚本进行2D形状和文本的渲染。通过这种方式,我们可以让一个程序输出打印图案两次,使用不同文字和颜色来观察他们的区别(当样本库足够大时,定位精度就足够高)。

WebGL 指纹则可以通过 WEBGL_debug_renderer_info 接口,获得产品名和供应商名,从而起到指纹的作用和效果。

3、新浏览器指纹技术;

除了上面已有的一些常规特征之外,还有一些特征/指标可以纳入参考:

  • CPU内核数量
  • 系统支持的语言(writing scripts)
  • AudioContext

被称为第三代指纹追踪技术的核心,则是识别设备后面的人。通过人的习惯、人的行为等等来对人进行归并,此项技术比较复杂。

4、Cookie驻留技术;

严格意义上来讲,这其实这不能算是一种新的指纹技术,因为它的原理就是将数据写入浏览器各个维度,获取的时候再从各个维度中读出来,只要其中一个有数据就可以将数据取出。比较强大的地方在于:1.存储的维度非常多,寻常用户难以清理;2.取数据的时候会将清除的数据重新恢复,名副其实的僵尸cookie。

# 常见的开源浏览器指纹项目

## AmIUnique

## fingerprint.js

## fingerprint2.js

## clientjs

## evercookie

 

参考链接:

=END=

声明: 除非注明,ixyzero.com文章均为原创,转载请以链接形式标明本文地址,谢谢!
https://ixyzero.com/blog/archives/4329.html

《基于Web浏览器的设备指纹相关知识整理》上的13个想法

  1. Web客户端追踪(下)—浏览器指纹追踪
    https://mp.weixin.qq.com/s/0ly_H296o73TmOYPUMl5EQ
    `
    一、典型追踪技术
    1. 浏览器指纹追踪
    1) 基本指纹(基本指纹是任何浏览器都具有的特征标识,比如硬件类型(Apple)、操作系统(Mac OS)、用户代理(User agent)、系统字体、语言、屏幕分辨率、浏览器插件 (Flash, Silverlight, Java, etc)、浏览器扩展、浏览器设置 (Do-Not-Track, etc)、时区差(Browser GMT Offset)等众多信息,这些指纹信息“类似”人类的身高、年龄等,有很大的冲突概率,只能作为辅助识别。)
    2) 高级指纹
    ①、Canvas指纹
    ②、AudioContext指纹
    3) 硬件指纹
    4) 综合指纹

    2. 跨浏览器指纹
    3. WebRTC

    二、防客户端追踪措施
    1. 浏览器设置
    2. 插件
    `
    浏览器指纹真的有效吗?
    https://mp.weixin.qq.com/s/MesxZ4aWPxVi3DWGpaDr2w

  2. `
    根据 UserAgent 中的关键字判断操作系统的类型(要注意的是SQL中最好不要出现分号;避免语法错误):

    case
    when locate(‘Windows NT’,ua) > 0 THEN ‘win’
    when locate(‘Macintosh’,ua) > 0 THEN ‘mac’
    when locate(‘iPhone’,ua) > 0 THEN ‘iphone’
    when locate(‘iPad’,ua) > 0 THEN ‘ipad’
    when locate(‘Android’,ua) > 0 THEN ‘android’
    when locate(‘Linux x86_64’,ua) > 0 THEN ‘linux’
    when locate(‘Java/’,ua) > 0 THEN ‘java’
    else ‘others’
    END AS platform
    `
    https://stackoverflow.com/questions/9693574/user-agent-extract-os-and-browser-from-string
    Hive自己定义函数的使用——useragent解析
    https://www.cnblogs.com/mengfanrong/p/5125607.html

  3. SameSite=None: Known Incompatible Clients
    https://www.chromium.org/updates/same-site/incompatible-clients
    `
    这里想提的点不是 Chrome 80 的 SameSite 机制,而是Google提供的一个提取解析UserAgent的正则:

    // Regex parsing of User-Agent string. (See note above!)

    bool isIosVersion(int major, string useragent):
    string regex = “\(iP.+; CPU .*OS (\d+)[_\d]*.*\) AppleWebKit\/”
    // Extract digits from first capturing group.
    return useragent.regexMatch(regex)[0] == intToString(major)

    bool isMacosxVersion(int major, int minor, string useragent):
    string regex = “\(Macintosh;.*Mac OS X (\d+)_(\d+)[_\d]*.*\) AppleWebKit\/”
    // Extract digits from first and second capturing groups.
    return (useragent.regexMatch(regex)[0] == intToString(major)) &&
    (useragent.regexMatch(regex)[1] == intToString(minor))

    bool isSafari(string useragent):
    string safari_regex = “Version\/.* Safari\/”
    return useragent.regexContains(safari_regex) &&
    !isChromiumBased(useragent)

    bool isMacEmbeddedBrowser(string useragent):
    string regex = “^Mozilla\/[\.\d]+ \(Macintosh;.*Mac OS X [_\d]+\) ”
    + “AppleWebKit\/[\.\d]+ \(KHTML, like Gecko\)$”
    return useragent.regexContains(regex)

    bool isChromiumBased(string useragent):
    string regex = “Chrom(e|ium)”
    return useragent.regexContains(regex)

    bool isChromiumVersionAtLeast(int major, string useragent):
    string regex = “Chrom[^ \/]+\/(\d+)[\.\d]* ”
    // Extract digits from first capturing group.
    int version = stringToInt(useragent.regexMatch(regex)[0])
    return version >= major

    bool isUcBrowser(string useragent):
    string regex = “UCBrowser\/”
    return useragent.regexContains(regex)

    bool isUcBrowserVersionAtLeast(int major, int minor, int build, string useragent):
    string regex = “UCBrowser\/(\d+)\.(\d+)\.(\d+)[\.\d]* ”
    // Extract digits from three capturing groups.
    int major_version = stringToInt(useragent.regexMatch(regex)[0])
    int minor_version = stringToInt(useragent.regexMatch(regex)[1])
    int build_version = stringToInt(useragent.regexMatch(regex)[2])
    if major_version != major:
    return major_version > major
    if minor_version != minor:
    return minor_version > minor
    return build_version >= build
    `

  4. 设备指纹乱象——跨平台deviceid打通
    https://mp.weixin.qq.com/s/9RwrrmmhzRXm7P12aFsNUA
    `
    从甲方的角度考虑,他们确实需要用一个唯一ID来标识这个设备,无论是是APP还是网页,这个需求是一个刚需。于是乎,某乙方厂商就鼓吹能做跨平台deviceid打通,在POC时占尽了优势。分析其APP SDK的代码,APP在后台加载webview执行一段web设备指纹的js。可以发现所谓的APP-浏览器和小程序-浏览器deviceid打通需求,最终都是统一到了跨浏览器(webview) deviceid。

    那么问题来了,如何做到跨浏览器deviceid的呢?众所周知,javascript能采集到的字段本身唯一性就比较差,因此deviceid主要依赖于canvas。而不同的浏览器canvas是不一样的,userAgent也不一样,就连ssl cipher也不一样,因此需要去寻找浏览器不相关的硬件指标,比如webgl、系统版本、屏幕大小、ip等等。最终能够达到的最佳效果,也就是相同型号的设备无论是何种浏览器deviceid都一致,或者相同ip的设备无论是何种浏览器deviceid都一致。换言之,是在丧失部分唯一性的前提下,提升了deviceid的稳定性。POC过程中,测试设备有限,很难遇到deviceid碰撞的情况,只有在大规模设备测试的情况下才会发现问题。

    最后就陷入了POC功能完全满足,上线以后各种问题的怪圈。留下一群不知如何是好的甲方风控策略人员。

    风控产品好与不好的评判标准,是看最终能否对完整流程的风控起到价值。
    `
    浏览器插件与设备指纹
    https://mp.weixin.qq.com/s/OBcX1P_-j78uNMRwyXk8Nw

  5. 可以使用页面引入的js获取电脑的硬件信息吗(js get computer hardware information)?
    Get a visitor’s System Hardware information?
    https://stackoverflow.com/questions/45772255/get-a-visitors-system-hardware-information
    `
    In short, no.

    PHP runs on the server and only has access to it and data sent to it.

    Javascript runs on the client but is sandboxed and has no direct access to the hardware layer (just limited information about the GPU).

    All services that do offer this kind of “scanning” (nVidia, etc) – use a downloadable application that scans the hardware for that platform then returns the result to the web service.

    So you can do it, but you would need some additional software that can run on the client machine that can access the data you require.
    ==

    简单来说就是——不行。

    PHP运行在server端,只有server端上以及发送给他的数据的操作权限。

    JavaScript运行在client端,但是是运行在沙盒中的,因此没有硬件层的直接访问权限(除了关于GPU的有限信息之外)。

    所有提供此类扫描功能的服务都是通过——使用一个可下载的应用来扫描,然后将扫描结果回传至server端来实现的。
    `

    MAC addresses in JavaScript
    https://stackoverflow.com/questions/3385/mac-addresses-in-javascript
    `
    不行,做不到。如果你能够直接用JavaScript做这件事,这将是一个隐私/安全漏洞。
    `

  6. 你好,你的浏览器信息量表格中,各个变量的熵值是怎么的来的呢?

发表评论

电子邮件地址不会被公开。 必填项已用*标注