本文中,我们将使用Bro入侵检测软件(IDS)作为客户端指纹探测技术工具。
众所周知,在最初的TLS握手过程(特别常用于浏览器中的HTTPS协议)中,会交换一条名为“ClientHello”的消息;在这条消息中,客户端列举了所支持的密码组件(即所谓的密码套件)。
例如,使用Wireshark协议解析软件来分析Linux系统中的Firefox50.1.0浏览器所发送的一条“ClientHello”消息,如下图所示。
有一些网站可以告诉我们所用浏览器的TLS协议特征,比如 Qualys SSL Labs SSL Client Test。
有趣的是,不同的TLS客户端往往使用不同的密码套件集合。比如,对于wget命令而言:
其握手数据报文(“ClientHello”消息)如下图所示。
如图可知,wget命令发送了68个不同的密码套件(而之前的Firefox浏览器发送了15个),而且两者的次序也不同。
因此,除了其他参数(比如同时存在于消息中的,所用的TLS协议版本),密码套件的数目及次序为我们提供了客户端的指纹。
Firefox浏览器和Chrome浏览器有不同的指纹;同样,Tor客户端(不用于断点续传)的指纹不同于Python脚本,微软WEB请求APIs,或者Delphi编程实现的RAT,等等。
事实上,我们可以利用其识别非授权程序,或者检测是否有恶意软件,为了操控或者窃密活动而潜伏伪装成用于组织内部的HTTPS浏览器。
走进Bro软件
要解析ClientHello消息并不是复杂的事情;可以使用p0f插件(参考文章:https://idea.popcount.org/2012-06-17-ssl-fingerprinting-for-p0f/)和专用工具比如FingerprintTLS(参考文章:https://blog.squarelemon.com/tls-fingerprinting/)。正如所料,Bro IDS软件也可以解析TLS协议;我们可以在文件/usr/local/bro/share/bro/base/protocols/ssl/consts.bro中找到所用的若干常量。
TLS协议版本幻数和对应的名字映射如下:
同样,在文件略微偏后的位置处,能看到不同的密码套件和cipher_desc数据结构:
如前文(网址:https://www.securityartwork.es/2017/01/11/bro-ids-tips-and-tricks/)所述,当一个感兴趣的事件发生时,Bro软件捕获一个对应于ClientHello消息的事件,如下所示(定义于文件/usr/local/bro/share/bro/base/bif/plugins/Bro_SSL.events.bif.bro):
至此,我们已经备齐了所有用于执行指纹识别的材料;脚本框架如下所示:
事件原型中的ciphers向量所存放的索引,可用于访问消息中的不同密码套件,同时我们可以用cipher_desc结构表将它们映射到对应的文本字符串。我们使用join_string_vec()函数(类似于Perl,Python或者其他语言的join()函数/方法)来以逗号分隔的方式显示它们。若将脚本保存到文件log_cipher_suites.bro,则我们在之前所捕获的文件tls.pcap上应用该脚本来实现一次快速测试。具体命令与输出如下所示:
可以看出,Firefox浏览器使用TLSv1.2协议发送了15个密码套件。
日志记录框架
执行print命令,则当Bro软件作为守护进程运行时所有信息将被存储到stdout.log文件中;然而,如果我们想要将输出发送到另一个文件中,或者发送到Elasticsearch搜索引擎呢?为此,Bro软件提供了日志记录框架。其用法非常简单,一学就会;-)
要讲之前的“测试”脚本改造成最终版本,首先我们需要创建一个名为TlsFingerprint的模块,命令如下:
然后,我们需要定义两个变量,它们将被模块导出到Bro软件的其他部分;简便起见,将其命名为LOG和Info。具体代码如下:
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)