• HTTP2指纹识别(一种相对不为人知的网络指纹识别方法)


    HTTP/2 指纹识别

    和Tls指纹类似也是一种 Web 服务器可以依赖指纹来识别哪个客户端。

    例如,它可以识别浏览器类型和版本,或者是否使用了脚本(你是真实浏览器啊还是ScriptBoy?)。

    该方法依赖于 HTTP/2 协议的内部结构,与其更简单的前身 HTTP/1.1 相比,这些内部结构鲜为人知。

    在这篇文章中,我将首先简要介绍 HTTP/2协议,然后详细介绍我们可以协议的哪些参数来识别你究竟谁(what are you)!

    与HTTP/1.1相比

    使用HTTP/1.1协议,客户端向服务器发送文本请求(通常使用 TLS 加密)默认情况下,Chrome 的请求如下所示:

    1. GET / HTTP/1.1
    2. Host: www.wikipedia.org
    3. sec-ch-ua: " Not A;Brand";v="99", "Chromium";v="101", "Google Chrome";v="101"
    4. sec-ch-ua-mobile: ?0
    5. sec-ch-ua-platform: "Windows"
    6. Upgrade-Insecure-Requests: 1
    7. User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.67 Safari/537.36
    8. Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,;q=0.8,application/signed-exchange;v=b3;q=0.9
    9. Sec-Fetch-Site: none
    10. Sec-Fetch-Mode: navigate
    11. Sec-Fetch-User: ?1
    12. Sec-Fetch-Dest: document
    13. Accept-Encoding: gzip, deflate, br
    14. Accept-Language: en-US,en;q=0.9

    User-Agent包含客户端的确切版本,虽然可用于识别客户端。但是很容易被任何 http 库或命令行工具伪造(地球人都知道)!

    HTTP/2 简介

    HTTP/2 是 HTTP 协议的主要修订版,从 2015 年左右开始出现。现在大约一半的网站使用 HTTP/2

    基本上所有流行的网站都默认使用它!

    如何看服务端使用的是否是http2协议呢?

    在chrome上看是这样的

    在Firefox上看是这样的

    HTTP/2 的主要目标是提高性能

    • 多路复用(Multiplexing ) - 多个请求和响应可以同时共享同一个 TCP 连接,从而减少了获取具有大量资源(图像、脚本等)的站点的时间。
    • 优先级(PRIORITY) - HTTP/2 支持对某些请求和响应进行优先级排序。
    • 服务器推送(Server push) - 在 HTTP/2 中,服务器可以在客户端请求资源之前将资源发送给客户端。
    • 插播一条广告:需要开通正版JetBrains全家桶的可以联系我,56元一年,正版授权,官网可查有效期,有需要的加我微信:poxiaozhiai6,备注:902。

    然而,HTTP 协议的应用程序语义没有改变:它仍然由熟悉的请求/响应模型组成,包括 URI、HTTP 方法、HTTP 标头和状态码

    Frames and Streams

    HTTP/2 是一种二进制协议,与文本 HTTP/1.1 不同。HTTP/2 中的消息由帧组成,有十种不同用途的帧。帧始终是流的一部分。

    Stream都是有编号的,从0开始

    如上图:编号为0的Stream包含如下

    • SETTINGS是客户端发送的第一帧,包含 HTTP/2 的特定配置,
    • WINDOW_UPDATE- 增加接收器的窗口大小,下面会讲到

    然后是编号开始递增,代表了客户端给服务端发送的实际请求,如上图为1的Stream:

    • HEADERS 包含 URI、HTTP 方法和客户端的 HTTP 头
    • DATA 包含来请求的资源数据以及服务器的响应

    使用 HTTP/2 进行客户端指纹识别

    研究http2协议的工具

    这里推荐使用nghttpd,它可以很方便的创建一个http2协议的webserver。
    最关键的是,让客户端请求的时候它能够直观的把每一帧都给打印出来(下面会给大家演示)
    我将它安装在wsl的ubuntu机器上,还得自建一个证书,这里我遇到了一点坑。

    下面就是如何使用nghttpd跑h2协议server

    我这里分别使用如下客户端来测试

    • Chrome浏览器
    • Firefox浏览器
    • CURL
    • Python脚本

    1. SETTINGS

    上面介绍到这是客户端发送的第一帧,里面有一些特殊配置

    Chrome

    1. recv SETTINGS frame <length=24, flags=0x00, stream_id=0>
    2. [SETTINGS_HEADER_TABLE_SIZE(0x01):65536]
    3. [SETTINGS_MAX_CONCURRENT_STREAMS(0x03):1000]
    4. [SETTINGS_INITIAL_WINDOW_SIZE(0x04):6291456]
    5. [SETTINGS_MAX_HEADER_LIST_SIZE(0x06):262144]

    Firefox

    1. recv SETTINGS frame <length=18, flags=0x00, stream_id=0>
    2. [SETTINGS_HEADER_TABLE_SIZE(0x01):65536]
    3. [SETTINGS_INITIAL_WINDOW_SIZE(0x04):131072]
    4. [SETTINGS_MAX_FRAME_SIZE(0x05):16384]

    CURL

    1. recv SETTINGS frame <length=18, flags=0x00, stream_id=0>
    2. [SETTINGS_MAX_CONCURRENT_STREAMS(0x03):100]
    3. [SETTINGS_INITIAL_WINDOW_SIZE(0x04):1073741824]
    4. [SETTINGS_ENABLE_PUSH(0x02):0]

    PYTHON

    1. recv SETTINGS frame <length=36, flags=0x00, stream_id=0>
    2. [SETTINGS_HEADER_TABLE_SIZE(0x01):4096]
    3. [SETTINGS_ENABLE_PUSH(0x02):0]
    4. [SETTINGS_INITIAL_WINDOW_SIZE(0x04):65535]
    5. [SETTINGS_MAX_FRAME_SIZE(0x05):16384]
    6. [SETTINGS_MAX_CONCURRENT_STREAMS(0x03):100]
    7. [SETTINGS_MAX_HEADER_LIST_SIZE(0x06):65536]

    很明显,根据测试,在SETTINGS Frame帧里面配置,
    不同的客户端设置的种类和值都是不同的,这使得很容易区分是否是浏览器,
    而且这个配置不容易控制,可以用于指纹识别!

    WINDOW_UPDATE

    HTTP/2 实现了一种流控制机制。
    流量控制为接收方提供了在每个流的基础上调节流量的机制。
    使用WINDOW_UPDATE大小来实现的

    默认窗口大小由SETTINGS帧里面的 SETTINGS_INITIAL_WINDOW_SIZE中的值控制,
    参考上方测试,可以看到 Chrome 使用 6MB (6291456) 而 Firefox 使用 128KB (131072)

    当客户端接收数据时,它可以使用WINDOW_UPDATE框架来调整窗口大小,从而增加其窗口大小。

    Chrome

    1. recv WINDOW_UPDATE frame <length=4, flags=0x00, stream_id=0>
    2. (window_size_increment=15663105)

    Chrome 实际上将连接级窗口大小增加到 15MB (15663105+65535=15MB)

    Firefox

    1. recv WINDOW_UPDATE frame <length=4, flags=0x00, stream_id=0>
    2. (window_size_increment=12517377)

    Firefox 会将其增加到 12MB

    CURL

    1. recv WINDOW_UPDATE frame <length=4, flags=0x00, stream_id=0>
    2. (window_size_increment=1073676289)

    curl使用 32MB

    PYTHON

    1. recv WINDOW_UPDATE frame <length=4, flags=0x00, stream_id=0>
    2. (window_size_increment=16777216)

    PYTHON 会将其增加到 16MB

    所以我们也可以使用该参数用于指纹识别!

    HEADERS

    这个有点意思了

    从广义上讲,HEADERS 包含了 HTTP/1.1 的所有功能,包含了
    URI、方法(GET/POST/等)和客户端的头等!

    下面的几个伪标头的顺序对于每个客户端是不同的。

    • :method
    • :authority
    • :scheme
    • :path

    我们来测试一下

    Chrome

    顺序是:
    m,a,s,p

    Firefox

    顺序是:
    m,p,a,s

    CURL

    顺序是:
    m,p,s,a

    Python

    顺序是:
    m,a,s,p

    这个看似很小的差异,也可以用于指纹识别

    HTTP/2 指纹识别在哪里使用?

    它用于与TLS 指纹识别类似的目的:比如反 DDOS 和反脚本等自动爬虫(提高门槛),只允许真实浏览器等。

    如何让你的server具有提取客户端HTTP2指纹的能力

    ja3是tls指纹的标准,wiresharp也默认带有

    搞http2指纹的目前市面上还没有标准,
    我开源了一款提取tls&http2指纹的中间件(面向aspnetcore的)

    在线测试:

    https://kawayiyi.com/tls

    1. {
    2. "tlsVersion": "Tls12",
    3. "tcpConnectionId": "0HMKCUARI97OU",
    4. "tlsHashOrigin": "771,4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,0-23-65281-10-11-35-16-5-13-18-51-45-43-27-17513-21,29-23-24,0",
    5. "tlsHashMd5": "cd08e31494f9531f560d64c695473da9",
    6. "cipherList": [
    7. "TLS_AES_128_GCM_SHA256",
    8. "TLS_AES_256_GCM_SHA384",
    9. "TLS_CHACHA20_POLY1305_SHA256",
    10. "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
    11. "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
    12. "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
    13. "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
    14. "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256",
    15. "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256",
    16. "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
    17. "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
    18. "TLS_RSA_WITH_AES_128_GCM_SHA256",
    19. "TLS_RSA_WITH_AES_256_GCM_SHA384",
    20. "TLS_RSA_WITH_AES_128_CBC_SHA",
    21. "TLS_RSA_WITH_AES_256_CBC_SHA"
    22. ],
    23. "extentions": [
    24. "server_name",
    25. "extended_master_secret",
    26. "renegotiation_info",
    27. "supported_groups",
    28. "ec_point_formats",
    29. "session_ticket",
    30. "application_layer_protocol_negotiation",
    31. "status_request",
    32. "signature_algorithms",
    33. "signed_certificate_timestamp",
    34. "key_share",
    35. "psk_key_exchange_modes",
    36. "supported_versions",
    37. "compress_certificate",
    38. "extensionApplicationSettings",
    39. "padding"
    40. ],
    41. "supportedgroups": [
    42. "X25519",
    43. "CurveP256",
    44. "CurveP384"
    45. ],
    46. "ecPointFormats": [
    47. "uncompressed"
    48. ],
    49. "proto": "HTTP/2",
    50. "h2": {
    51. "SETTINGS": {
    52. "1": "65536",
    53. "3": "1000",
    54. "4": "6291456",
    55. "6": "262144"
    56. },
    57. "WINDOW_UPDATE": "15663105"
    58. }
    59. }

    如何过http2指纹呢?

    知道了原理,还不好过吗

    总结

    指纹识别在整个网络中变得非常普遍,Http2的指纹相对来说不为人知,但是并不新鲜。

  • 相关阅读:
    ubuntu1804发布kitti数据集的gps资料,imu资料(包含发布图片,点云过程)
    基于安卓android微信小程序的装修家装小程序
    RSA加解密(非对称加密)
    Java学习笔记之基本数据类型转换
    阿里P8大牛整理总结,影响全球250W工程师,两大阿里java开发手册
    SDN | 环境搭建(一)| Ubuntu 16.04 及 Openvswitch安装
    web前端期末大作业:基于HTML+CSS+JavaScript汽车租赁网站(47页)
    【matlab网络通信】tcpserver参数详解
    学习强化学习该具备的技能和环境
    WordArt Designer:基于用户驱动与大语言模型的艺术字生成
  • 原文地址:https://blog.csdn.net/qq_41701956/article/details/126687974