一篇文章带你读懂 TLS Poison 攻击(一)


一篇文章带你读懂 TLS Poison 攻击(一)

STATEMENT

声明

由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,雷神众测及文章作者不为此承担任何责任。

雷神众测拥有对此文章的修改和解释权。如欲转载或传播此文章,必须保证此文章的完整性,包括版权声明等全部内容。未经雷神众测允许,不得任意修改或者增减此文章内容,不得以任何方式将其用于商业目的。


一篇文章带你读懂 TLS Poison 攻击(一)

NO.1 前言

本篇文章是《一篇文章带你读懂 XXX 攻击》系列的第二篇文章,主要讲述了 TLS Poison 攻击对应的三种攻击方式、一些可能算是“新”的 DNS Rebinding 技巧以及一些关于 IP 选择探索等内容。

使用《一篇文章带你读懂 XXX 攻击》的标题既是为了督促自己把一个攻击尽可能多的细节尽可能地搞懂,也是为了提升自己的写作能力以及表述水平。本文旨在帮助大家了解学习 TLS Poison 攻击,希望能够通过一篇文章让大家读懂 TLS Poison 攻击。但是,仅仅是网络协议便涉及到很多内容,仅靠本文是不可能完全读懂的,本文的内容也并非完全正确,所以也希望大家抱着怀疑的态度合理对文章提出质疑。

本文主要是对 Black Hat USA 2020 - When TLS Hacks You 议题的整理与复盘,该攻击是一种利用 TLS 协议特性结合客户端实现缺陷达到攻击内网应用的攻击方式,可以达到任意写入 Memcached 等内网服务的攻击效果,进而配合其他漏洞造成 RCE 等危害。

这是去年在 black hat USA 被提出的一项攻击方式,但作者在提出这个攻击方式后,由于种种因素,他放出来的 demo 并不能直接使用,所以我在对该项的研究复现中整理了很多攻击细节,以及一些可以拓展的地方,还有一些关于计算机科学知识的探索。

本文主要分成三部分,第一部分主要简单讲述一些必要的背景知识,第二部分会详细记录三种攻击方式的实现步骤,第三部分会讲述一些关于在复现过程中的一些思考以及相关探索的内容。如果还有后续的进展,我也会同步到自己的个人博客上,欢迎关注,以及前来交流:https://blog.zeddyu.info/

如果对该篇文章有任何疑问或质疑,欢迎来信:

echo emVkZHl1Lmx1QGdtYWlsLmNvbQ==|base64 -d

欢迎对协议安全等内容感兴趣的同学一起交流学习!

PS: 如无特殊说明,整个实验背景均基于 Ubuntu 20.04 LTS ,curl 7.68.0 build with OpenSSL/1.1.1f  ,后文提到的 IPv6 均指的是  IPv4-mapped IPv6 addresses 这类地址


由于内容较多,原文将会被分成四节文章在该平台上进行发布,本篇为该文章的第一节。


一篇文章带你读懂 TLS Poison 攻击(一)

NO.2 背景


- TLS Overview

传输层安全性协议(英语:Transport Layer Security,缩写:TLS)及其前身安全套接层(英语:Secure Sockets Layer,缩写:SSL)是一种安全协议,目的是为互联网通信提供安全及数据完整性保障。网景公司(Netscape)在1994年推出首版网页浏览器-网景导航者时,推出HTTPS协议,以SSL进行加密,这是SSL的起源。IETF将SSL进行标准化,1999年公布TLS 1.0标准文件(RFC 2246)。随后又公布TLS 1.1(RFC 4346,2006年)、TLS 1.2(RFC 5246,2008年)和TLS 1.3(RFC 8446,2018年)。在浏览器、电子邮件、即时通信、VoIP、网络传真等应用程序中,这个协议被广泛使用。许多网站,如Google、Facebook 等也以这个协议来创建安全连线,发送资料,目前已成为互联网上保密通信的工业标准。

Netscape 开发了名为安全套接字层(Secure Socket Layer,SSL)的上一代加密协议,TLS 由此演变而来。TLS 1.0 版的开发实际上始于 SSL 3.1 版,但协议的名称在发布之前进行了更名,以表明它不再与 Netscape 关联。由于这个历史原因,TLS 和 SSL 这两个术语有时会互换使用。

该协议由两层组成:TLS 记录协议(TLS Record)和 TLS 握手协议(TLS Handshake)。

因为本文侧重点并非 TLS 本身的加密算法流程,所以会忽略很多密码算法流程,只提其中对我们后续攻击相关的部分,对密码算法部分感兴趣的读者可以自行搜索了解。

TLS Handshake

TLS 握手是启动使用 TLS 加密的通信会话的过程。在 TLS 握手期间,两个通信方交换消息以相互确认,彼此验证,确立它们将使用的加密算法,并就会话密钥达成共识。它定义了消息的格式和交换的顺序。这些可以根据客户端和服务器的需求而变化,也就是说,有几种可能的程序来建立连接。初始交换的结果是TLS连接成功(双方都准备好用TLS传输应用数据)或发出警报消息。

每当用户通过 HTTPS 导航到网站,并且浏览器首先开始查询网站的源站服务器时,都会进行 TLS 握手。每当其他任何通信使用 HTTPS(包括 API 调用和 HTTPS 上的 DNS 查询)时,也会发生 TLS 握手。通过 TCP 握手打开 TCP 连接后,将发生 TLS 握手。

在 TLS 握手过程中,客户端和服务器一同执行以下操作:

· 指定将要使用的 TLS 版本(TLS 1.0、1.2、1.3 等)

· 决定将要使用哪些密码套件

· 通过服务器的公钥和 SSL 证书颁发机构的数字签名来验证服务器的身份

· 生成会话密钥,以在握手完成后使用对称加密

· 检查是否需要恢复会话

TLS 握手是由客户端和服务器交换的一系列数据报或消息。TLS 握手涉及多个步骤,因为客户端和服务器要交换完成握手和进行进一步对话所需的信息。TLS 握手的确切步骤将根据所使用的密钥交换算法的类型以及双方支持的密码套件而有所不同,RSA 密钥交换算法最为常用。但是并非所有 TLS 握手均使用非对称加密(公钥和私钥),并非全都会在生成会话密钥的过程中使用私钥,例如 Diffie-Hellman 握手等,这里不做过多介绍。

TLS Record

TLS Record 协议使用握手过程中创建的密钥来确保应用数据的安全。记录协议负责保护应用数据的安全,并验证其完整性和来源。它管理以下内容:将传出的消息分为可管理的块、重新组合传入的消息、压缩外发报文块和解压接收报文块(可选)、将信息验证码(Message Authentication Code, MAC)应用到外发信息并使用 MAC 验证接收信息、加密外发报文和解密接收报文。当 TLS Record 协议完成后,外发加密数据被传到传输控制协议(TCP)层进行传输。

- TLS 1.2

TLS 1.2 HankShake

由于历史原因,TLS 的前身 SSL 已经被废弃;现行趋势中,主流 TLS 版本为 1.2 ,并且 1.2 版本 对于 1.1 版本的改动相对于本文重点来说并不重要,并且现在处于推广 1.3 版本的时代,我们这里从 TLS 1.2 开始讲起。

1. Client hello: 客户端发送 ClientHello 消息,指定它支持的最高 TLS 协议版本、一个随机数、一个建议的密码套件列表和建议的压缩方法。如果客户端试图执行恢复握手,它可能会发送一个会话 ID 。如果客户端可以使用应用层协议协商,它可能包括一个支持的应用协议列表,例如 HTTP/2 。

2. Server hello: 服务器以 ServerHello 消息作出响应,包含从客户端提供的选择中选择的协议版本、随机数、密码套件和压缩方法。为了确认或允许恢复握手,服务器可以发送一个会话 ID 。选择的协议版本应该是客户端和服务器都支持的最高版本。例如,如果客户端支持 TLS 1.1 版本,服务器支持 1.2 版本,则应选择 1.1 版本;不应选择 1.2 版本。

3. (Optional) Certificate: 服务器向客户端发送证书或证书链。证书链通常以服务器的公钥证书开始,并以证书颁发机构的根证书结束。该消息是可选的,但是在需要服务器身份验证时使用。

4. (Optional) Certificate request: 如果服务器必须对客户端进行身份验证,则它将向客户端发送证书请求。在Internet应用程序中,很少发送此消息。

5. (Optional) Server key exchange: 如果来自证书的公钥信息不足以进行密钥交换,则服务器会向客户端发送服务器密钥交换消息。例如,在基于Diffie-Hellman(DH)的密码套件中,此消息包含服务器的DH公钥。

6. Server hello done: 服务器告诉客户端它已经完成了其初始协商消息。

7. (Optional)Certificate: 如果服务器从客户端请求证书,则客户端将发送其证书链,就像服务器之前所做的一样。

  Note: 只有少数Internet服务器应用程序要求客户端提供证书。

8. Client key exchange: 客户端生成用于创建用于对称加密的密钥的信息。对于 RSA ,客户端随后使用服务器的公共密钥对该密钥信息进行加密并将其发送到服务器。对于基于 DH 的密码套件,此消息包含客户端的 DH 公钥。

9. (Optional) Certificate verify: 如前所述,当客户端出示证书时,此消息由客户端发送。其目的是允许服务器完成对客户端进行身份验证的过程。使用此消息时,客户端使用加密哈希函数发送其进行数字签名的信息。当服务器使用客户端的公共密钥解密此信息时,服务器便能够对客户端进行身份验证。

10. Change cipher spec: 客户端发送一条消息,告知服务器更改为加密模式。

11. Finished: 客户端告诉服务器已准备好开始安全数据通信。

12. Change cipher spec: 服务器发送一条消息,告知客户端更改为加密模式。

13. Finished: 服务器告诉客户端它已准备好开始安全数据通信,握手到此结束。

14. Encrypted data: 客户端和服务器使用对称加密算法和在客户端问候和服务器问候期间协商的加密哈希函数,以及使用客户端在客户端密钥交换期间发送给服务器的秘密密钥进行通信。此时可以重新协商握手。

15. Close Messages: 在连接结束时,双方都会发送 close_notify Alert 报文,以通知对等方该连接已关闭。

大致流程如下图所示:

一篇文章带你读懂 TLS Poison 攻击(一)

对于不同的密钥算法,还会产生稍微不一致的流程,这里并不作为重点,所以我们就不再展开描述了。

TLS 1.2 Session Resumption Overview

完整的 TLS 握手产生的额外延时和计算成本让所有需要安全通信的应用程序牺牲了很多性能代价,为了帮助降低部分成本, TLS 提供了一种机制恢复会话机制,用来恢复或共享多个连接之间的相同协商的秘钥数据。会话恢复是一个重要的优化部署,简略的握手消除了一个完整的 TLS 握手往返耗时,大大降低了双方的计算成本。在 TLS 1.2 中, TLS Session Resumption 可以采用 Session ID 和会话票机制来实现。除性能上的优势外,恢复的会话还可以用于单点登录,因为它保证了原始会话和任何恢复的会话都来自同一个客户端。

TLS 1.2 Session Resumption - Session ID

在这种机制中,服务器在与客户端初次握手时,服务器会随机分配一个 Session ID。客户端和服务器将这个会话ID与会话密钥和连接状态一起存储。为了恢复会话,客户端将存储的会话ID与第一个协议消息(ClientHello)一起发送给服务器。如果服务器识别到了连接并愿意恢复会话,它就会用相同的会话ID来回复,重新建立各自的会话。这样就可以快速建立安全的连接,而且由于我们重用了之前协商好的会话数据,所以不会损失安全性。

Client 在一开始发送 ClientHello 消息中, ClientHello 消息中包括一个可变长度的 Session ID。如果为空则表示是一个新的会话,也就是客户端与服务端第一次握手,Server 在返回 ServerHello 时就会发送一个 Session ID ,此时内容为 Server 产生,当协商握手完成后,Session ID 就变得有效,并一直存在,直到由于超过有效时间或因为在与会话相关的连接上遇到服务器错误而被删除。如果不为空,该值就表示客户端希望重用该会话的安全参数,Server 会检查它的会话缓存以进行匹配,如果匹配成功,并且 Server 愿意在指定的会话状态下重建连接,它将会发送一个带有相同会话 ID 值的 ServerHello 消息,这时 Client 和 Server 必须都发送 ChangeCipherSpec 消息并且直接发送 Finished 消息,一旦重建立完成,Client 和 Server 可以开始交换应用层数据。如果一个会话 ID 不匹配,Server 会产生一个新的会话 ID,然后 TLS Client 和 Server 需要进行一次完整的握手。

      Client                                                Server
ClientHello --------> ServerHello [ChangeCipherSpec] <-------- Finished [ChangeCipherSpec] Finished --------> Application Data <-------> Application Data
Figure 2. Message flow for an abbreviated handshake


在 RFC 5246 中,对 SessionID 做出了规定,其长度为 0-32 位:

opaque SessionID<0..32>


同时 RFC 建议 Session ID的寿命上限为24小时,因为获得master_secret的攻击者可能会冒充被入侵的一方,直到相应的 Session ID 失效。

整个重用过程我们可以从下图比较直观的看到:

一篇文章带你读懂 TLS Poison 攻击(一)

客户端首先发送了一个 Client Hello 消息给服务端,并且其 Session ID 为空,这时候 Server 响应了 Server Hello 当中就会返回一个 32 字节长度的 Session ID。现在客户端和服务器的 TLS 会话缓存中都存储了 Session ID,其值为 56bcf9f6ea40ac1bbf05ff7fd209d423da9f96404103226c7f927ad7a2992433。这样做的好处就是,在下一次TLS连接请求中,客户端不需要再经历完整的TLS握手。

一篇文章带你读懂 TLS Poison 攻击(一)

客户端只需在其 Client Hello 消息中发送之前从 Server 那里得知的 Session ID ,然后 Server 确认这个 Session ID 在它的 TLS 会话缓存之后,它们就会进行所谓的 Abbreviated TLS Handshake 。在这次 TLS 握手过程中不会交换证书或密钥信息,之前协商好的密钥会被重新使用,这样就完成了一次 TLS Session Resumption 。

TLS 1.2 Session Resumption - Session Ticket

然而,Session ID 机制的一个实际限制是要求服务器为每个客户端创建和维护一个会话缓存。这就导致了服务器上的几个问题,每天可能会有成千上万甚至上百万个独特的连接;每一个打开的TLS连接都会消耗内存,需要 Session ID 缓存和删除策略,以及对于有许多服务器的热门网站的部署挑战,理想情况下,这些网站应该使用共享的 TLS Session 缓存以获得最佳性能。因此,对于任何多服务器的部署,Session ID 都需要一些仔细的思考和系统架构,以确保会话缓存的良好运行。

为了解决服务器端部署 TLS 会话缓存的这一问题,引入了 Session Ticket (RFC 5077)替换机制,它取消了服务器保留每个客户端会话状态的要求。取而代之的是,如果客户端表示支持会话票,服务器可以包含一个会话票记录,其中包括所有用只有服务器知道的秘密密钥加密的协商会话数据。然后,该会话票由客户端存储,并且可以包含在后续会话的握手消息中。因此,所有的会话数据只存储在客户端,但票据仍然是安全的,因为它是用只有服务器知道的密钥加密的。

会话票机制被称为无状态恢复机制。无状态恢复机制的主要改进是取消了服务器端的会话缓存,简化了部署,要求客户端在每次与服务器的新连接时提供会话票据,直到票据过期。

TLS SessionTicket 是一个扩展,其基于 RFC4366 (https://tools.ietf.org/html/rfc4366。Ticket 的格式是一个 opaque 的结构,用于携带特定会话的状态信息。RFC 推荐的 Session Ticket 结构如下:

struct {  uint32 ticket_lifetime_hint;  opaque ticket<0..2^16-1>;} NewSessionTicket;
struct { opaque key_name[16]; opaque iv[16]; opaque encrypted_state<0..2^16-1>; opaque mac[32];} ticket;


这个扩展可以在 ClientHello 和 ServerHello 中发送。如果客户端拥有一个想要用来恢复会话的 ticket,那么它就会在 ClientHello 中的 SessionTicket 扩展中包含这个 ticket。如果客户端没有票据,并且准备在 NewSessionTicket 握手消息中接收票据,那么它必须在 SessionTicket 扩展中包含一个长度为零的 Session Ticket 。如果客户端不准备在 NewSessionTicket 握手消息中接收票据,则必须不包含 SessionTicket 扩展,除非客户端发送通过其他方式从服务器收到的非空票据。

         Client                                               Server
ClientHello (empty SessionTicket extension)--------> ServerHello (empty SessionTicket extension) Certificate* ServerKeyExchange* CertificateRequest* <-------- ServerHelloDone Certificate* ClientKeyExchange CertificateVerify* [ChangeCipherSpec] Finished --------> NewSessionTicket [ChangeCipherSpec] <-------- Finished Application Data <-------> Application Data
Figure 1: Message Flow for Full Handshake Issuing New Session Ticket


如上流程图所示,客户端通过在 ClientHello 消息中包含一个 SessionTicket TLS 扩展名来表示它支持这种机制,此时 SessionTicket 为空,服务器将发送一个空的SessionTicket 扩展来表示它将使用 NewSessionTicket 握手消息发送一个新的 Session Ticket,该消息是在服务器成功验证客户端的 Finished 消息后,在ChangeCipherSpec 消息之前的 TLS 握手期间发送。在得到 Session Ticket 后,Client 将该 Session Ticket 与主密和其他与当前会话相关的参数一起缓存。

         Client                                                Server         ClientHello         (SessionTicket extension)      -------->                                                          ServerHello                                      (empty SessionTicket extension)                                                     NewSessionTicket                                                   [ChangeCipherSpec]                                       <--------             Finished         [ChangeCipherSpec]         Finished                      -------->         Application Data              <------->     Application Data
Figure 2: Message Flow for Abbreviated Handshake Using New Session Ticket


当客户端希望恢复会话时,它在 ClientHello 消息中的 SessionTicket 扩展中包含该票据。然后服务器对收到的票据进行解密,验证票据的有效性,从票据的内容中检索会话状态,并使用这个状态来恢复会话。如果服务器成功验证了客户端的票据,那么就可以在 ServerHello 之后加入 NewSessionTicket 握手消息来续订票据。

我们可以通过实例来进一步了解这个机制:

一篇文章带你读懂 TLS Poison 攻击(一)

客户端首先通过在 Client Hello 消息中添加 SessionTickets TLS Extension 来表明它支持无状态会话恢复(绿色部分), Server 还会通过发送包含有空的 SessionTicket TLS Extension 的 Server Hello 消息给 Client ,表示 Server 支持 SessionTicket TLS Extension(红色部分)。

一篇文章带你读懂 TLS Poison 攻击(一)

在握手完成之前,也就是 Finished 之前,Server 会发送一个名为 New Session Ticket 的新 TLS 消息,其中包含加密的会话信息(如主密、使用的密码等),Server 可以在稍后使用它专门为此生成的唯一密钥进行解密。从这一点开始,Client 会将 Session Ticket 保存在它的 TLS 缓存中,直到下一次它在 Session Ticket过期之前都可以使用它与之前的 Server 恢复 TLS 会话。

一篇文章带你读懂 TLS Poison 攻击(一)

现在,当 Client 想要重新使用之前的会话时,它在 Client Hello 消息的 SessionTicket TLS Extension 中发送了 Session Ticket,此时我们所注意到,客户端也创建了一个新的会话 ID ,用于以下目的:

· 服务器回复相同的 Session ID 表示 Server 接受 Session Ticket ,并将重用该 Session 。

· 服务器回复空的/不同的 Session ID :Server 决定进行完全握手,原因是可能是 Session Ticket 过期了,或者它正在恢复原来的会话。PS:这样的 Session ID 并不存储在 Server 上,否则会破坏无状态会话重用的目的。这是一次性使用,只是为了向 Client 表示 Server 接受了他们发送的session ticket。

在上述的例子中,Server 成功接受并重用了 TLS 会话,我们可以确认进行了一个 Abbreviated TLS 握手,并且在服务器的 Server Hello 消息中,Server 回复了客户端发送的相同 Session ID 。这就是一个简单的基于 Session Ticket 机制的 Session Resumption ,服务端不需要在本地存储会话信息,因此与有状态的会话恢复相比,它是一个更具扩展性的选择。

- TLS 1.3

TLS 1.3 Overview

TLS 1.3 可以说是 TLS 1.2 的升级版本,它在 RFC 8446 中定义,于 2018 年 8 月发表。我们这里简要的介绍几个我们比较关心的改动:

· 减少握手等待时间,将握手时间从 2-RTT 降低到 1-RTT,并且增加 0-RTT 模式。

· 废除 Session ID 和 Session Ticket 会话恢复方式,统一通过 PSK 的方式进行会话恢复,并在 NewSessionTicket 消息中添加过期时间和用于混淆时间的偏移值。

在握手时相对于 TLS 1.2 发生了比较明显的改动:

· 与 TLS 1.2 握手类似,TLS 1.3 握手以 Client Hello 消息开始,但有一个重要的变化就是客户端发送支持的加密套件列表,并猜测服务器可能选择的密钥协议协议,也会发送它对该特定密钥协议协议的密钥共享。

· Server 在回复 Server Hello 时,服务器回复它所选择的密钥协议协议,其中也包括服务器的密钥共享、证书以及 Server Finished 。

· 现在,客户端检查服务器证书,生成密钥,并发送 Client Finished ,之后就可以发送加密数据了。

这样一来,TLS 1.3 握手就节省了整整一个来回和数百毫秒的时间,比 TLS 1.2 握手有了很大的改进。RFC 8446 提供的简要流程图如下:

 Client                                           Server
Key ^ ClientHelloExch | + key_share* | + signature_algorithms* | + psk_key_exchange_modes* v + pre_shared_key* --------> ServerHello ^ Key + key_share* | Exch + pre_shared_key* v {EncryptedExtensions} ^ Server {CertificateRequest*} v Params {Certificate*} ^ {CertificateVerify*} | Auth {Finished} v <-------- [Application Data*] ^ {Certificate*}Auth | {CertificateVerify*} v {Finished} --------> [Application Data] <-------> [Application Data]
+ Indicates noteworthy extensions sent in the previously noted message.
* Indicates optional or situation-dependent messages/extensions that are not always sent.
{} Indicates messages protected using keys derived from a [sender]_handshake_traffic_secret.
[] Indicates messages protected using keys derived from [sender]_application_traffic_secret_N.
Figure 1: Message Flow for Full TLS Handshake


TLS 1.2 与 1.3 简要的握手对比如下图所示:

一篇文章带你读懂 TLS Poison 攻击(一)

TLS 1.3 Session Resumption - PSK

按照上文所说,TLS 1.3 用通过预共享密钥(Pre-Shared Key, PSK)恢复会话的概念取代了 1.2 当中的 Session ID 和 Session Ticket 。在最初的握手之后,服务器向客户端发送一个 PSK 标识。PSK 内容取决于服务器,可能包含一个数据库查询密钥或一个自我加密和自我认证的票据。客户端将此PSK身份与自己的会话密钥一起存储。其中, RFC 8446 定义的 PSK 结构如下所示:

  struct {          opaque identity<1..2^16-1>;          uint32 obfuscated_ticket_age;      } PskIdentity;
opaque PskBinderEntry<32..255>;
struct { PskIdentity identities<7..2^16-1>; PskBinderEntry binders<33..2^16-1>; } OfferedPsks;
struct { select (Handshake.msg_type) { case client_hello: OfferedPsks; case server_hello: uint16 selected_identity; }; } PreSharedKeyExtension;


在随后的握手中,客户端在给服务器的 ClientHello 消息中提供这个 PSK ,服务器根据 PSK 的内容对票据进行解密,并使用包含的会话密钥和连接状态来恢复会话,或者服务器使用包含的查找密钥在自己的数据库中查找会话密钥和连接状态。RFC 8446 提供了一个 Session Resumption 的流程图如下:

          Client                                               Server
Initial Handshake: ClientHello + key_share --------> ServerHello + key_share {EncryptedExtensions} {CertificateRequest*} {Certificate*} {CertificateVerify*} {Finished} <-------- [Application Data*] {Certificate*} {CertificateVerify*} {Finished} --------> <-------- [NewSessionTicket] [Application Data] <-------> [Application Data]

Subsequent Handshake: ClientHello + key_share* + pre_shared_key --------> ServerHello + pre_shared_key + key_share* {EncryptedExtensions} {Finished} <-------- [Application Data*] {Finished} --------> [Application Data] <-------> [Application Data]
Figure 3: Message Flow for Resumption and PSK

1. 客户端向服务器发送一个带有 key_share 扩展的 ClientHello 消息。该扩展列出了客户端支持的密钥交换加密方法。

2. 服务器用一个带有 key_share 扩展名的 ServerHello 消息进行响应,这个扩展包含了它要用于密钥交换的加密方法,并且服务器将其参数一同发送给客户端。

3. 服务器和客户端都交换认证消息。

4. 服务器向客户端发送 NewSessionTicket 消息,其中包含一个 PSK ,客户端可以通过在 ClientHello 消息的 pre_shared_key 扩展中包含这个 PSK ,用于未来的握手。

5. 客户端和服务器现在可以交换加密的应用数据。

6. 在未来的握手中,客户端向服务器发送一个包含 key_share 和 pre_shared_key 扩展名的 ClientHello 消息。pre_shared_key 扩展包含 NewTicketSession 消息中发送的 PSK 。

7. 服务器用包含 pre_shared_key 和 key_share 扩展名的 ServerHello 消息作出响应。pre_shared_key 扩展包含服务器同意使用的 PSK ,并将其参数发送给客户端。

8. 服务器和客户端互相发送 Finished 消息,之后客户端和服务器可以交换加密的应用数据。

我们可以通过一个简单的例子来直观感受一下 TLS 1.3 基于 PSK 的握手过程:

一篇文章带你读懂 TLS Poison 攻击(一)

如上图所示,Client 第一次与 Server 握手发送 Client Hello 消息时,只包含了 key_share 拓展,Server 也做出响应的回应,使用包含 key_share 拓展的消息进行回应。

一篇文章带你读懂 TLS Poison 攻击(一)

复制弹窗的命令,放到靶机中运行。Client 在第二次发送 Client Hello 消息时,带上了之前 Server 在 NewSessionTicket 发送的 pre_shared_key ,将其作为拓展发送至 Server ,随后 Server 响应 Server Hello 消息时,也使用 pre_shared_key 作为拓展响应,这样就完成了基于 PSK 的 Session Resumption

一篇文章带你读懂 TLS Poison 攻击(一)

可能有同学会问为什么我们看不到类似 TLS 1.2 当中直接有一个 NewSessionTicket 呢?我们可以仔细回顾一下上面的 RFC 流程图,Server 返回的 NewSessionTicket 消息有个中括号,而这里的中括号表示的是使用从 [sender]_application_traffic_secret_N 导出的密钥保护的信息,所以我们使用 wireshark 无法直接看到其中的内容,但是其中我们使用 opnssl 时候能够更明显的看到 Server 发过来的 TLS Session Ticket ,如图所示,也就是我们 Client 在进行恢复会话时所携带的 PSK ,在使用 openssl 进行恢复会话时,就会提示我们已经恢复了会话。这样就完成了一次 Session Resumption。

TLS 1.3 Session Resumption - 0-RTT

虽然 TLS 1.3 最大的亮点之一是 0-RTT ,但是我们这里不做详细的分析,因为我们可以从下面的 RFC 8446 提供的流程图看出来,虽然增加了一个 early_data ,但是对于本篇文章来说并不是重点,他依然使用了 pre_shared_key ,所以对于上文基于 PSK 的会话恢复模式来说基本一致,这里就不做过多分析,感兴趣的同学可以自行搜索了解。

         Client                                               Server
ClientHello + early_data + key_share* + psk_key_exchange_modes + pre_shared_key (Application Data*) --------> ServerHello + pre_shared_key + key_share* {EncryptedExtensions} + early_data* {Finished} <-------- [Application Data*] (EndOfEarlyData) {Finished} --------> [Application Data] <-------> [Application Data]
+ Indicates noteworthy extensions sent in the previously noted message.
* Indicates optional or situation-dependent messages/extensions that are not always sent.
() Indicates messages protected using keys derived from a client_early_traffic_secret.
{} Indicates messages protected using keys derived from a [sender]_handshake_traffic_secret.
[] Indicates messages protected using keys derived from [sender]_application_traffic_secret_N.
Figure 4: Message Flow for a 0-RTT Handshake


- SSRF

服务器端请求伪造 (Server-Side Request Forgery, SSRF) 是一种由攻击者构造形成由服务端发起请求的一个安全漏洞。一般情况下,SSRF攻击的目标是从外网无法访问的内部系统。(正是因为它是由服务端发起的,所以它能够请求到与它相连而与外网隔离的内部系统)

SSRF 形成的原因大都是由于服务端提供了从其他服务器应用获取数据的功能且没有对目标地址做过滤与限制。比如从指定URL地址获取网页文本内容,加载指定地址的图片,下载等等。

一篇文章带你读懂 TLS Poison 攻击(一)

- DNS Rebinding

DNS重新绑定是计算机攻击的一种形式。在这种攻击中,恶意网页会导致访问者运行客户端脚本,攻击网络上其他地方的计算机。攻击者注册一个域名(如attacker.com),并在攻击者控制下将其代理给DNS服务器。服务器配置为很短响应时间的TTL记录,防止响应被缓存。当受害者浏览到恶意域时,攻击者的DNS 服务器首先用托管恶意客户端代码的服务器的 IP 地址作出响应。例如,他们可以将受害者的浏览器指向包含旨在在受害者计算机上执行的恶意 JavaScript 或 Flash 脚本的网站。

恶意客户端代码会对原始域名(例如attacker.com)进行额外访问,这些都是由同源政策所允许的。但是,当受害者的浏览器运行该脚本时,它会为该域创建一个新的 DNS 请求,并且攻击者会使用新的 IP 地址进行回复。例如,他们可以使用内部 IP 地址或互联网上某个目标的IP地址进行回复。

一篇文章带你读懂 TLS Poison 攻击(一)



到目前为止,我们简单地讲述完了一些必要的背景知识,在后续的文章当中,我将会详细讲述记录三种攻击方式的实现步骤,以及一些关于在复现过程中的一些思考以及相关探索的内容。



一篇文章带你读懂 TLS Poison 攻击(一)

RECRUITMENT

招聘启事

安恒雷神众测SRC运营(实习生)
————————
【职责描述】
1.  负责SRC的微博、微信公众号等线上新媒体的运营工作,保持用户活跃度,提高站点访问量;
2.  负责白帽子提交漏洞的漏洞审核、Rank评级、漏洞修复处理等相关沟通工作,促进审核人员与白帽子之间友好协作沟通;
3.  参与策划、组织和落实针对白帽子的线下活动,如沙龙、发布会、技术交流论坛等;
4.  积极参与雷神众测的品牌推广工作,协助技术人员输出优质的技术文章;
5.  积极参与公司媒体、行业内相关媒体及其他市场资源的工作沟通工作。

【任职要求】 
 1.  责任心强,性格活泼,具备良好的人际交往能力;
 2.  对网络安全感兴趣,对行业有基本了解;
 3.  良好的文案写作能力和活动组织协调能力。


简历投递至 

bountyteam@dbappsecurity.com.cn

设计师(实习生)

————————

【职位描述】
负责设计公司日常宣传图片、软文等与设计相关工作,负责产品品牌设计。

【职位要求】
1、从事平面设计相关工作1年以上,熟悉印刷工艺;具有敏锐的观察力及审美能力,及优异的创意设计能力;有 VI 设计、广告设计、画册设计等专长;
2、有良好的美术功底,审美能力和创意,色彩感强;

3、精通photoshop/illustrator/coreldrew/等设计制作软件;
4、有品牌传播、产品设计或新媒体视觉工作经历;

【关于岗位的其他信息】
企业名称:杭州安恒信息技术股份有限公司
办公地点:杭州市滨江区安恒大厦19楼
学历要求:本科及以上
工作年限:1年及以上,条件优秀者可放宽


简历投递至 

bountyteam@dbappsecurity.com.cn

安全招聘

————————

公司:安恒信息
岗位:Web安全 安全研究员
部门:战略支援部
薪资:13-30K
工作年限:1年+
工作地点:杭州(总部)、广州、成都、上海、北京

工作环境:一座大厦,健身场所,医师,帅哥,美女,高级食堂…

【岗位职责】
1.定期面向部门、全公司技术分享;
2.前沿攻防技术研究、跟踪国内外安全领域的安全动态、漏洞披露并落地沉淀;
3.负责完成部门渗透测试、红蓝对抗业务;
4.负责自动化平台建设
5.负责针对常见WAF产品规则进行测试并落地bypass方案

【岗位要求】
1.至少1年安全领域工作经验;
2.熟悉HTTP协议相关技术
3.拥有大型产品、CMS、厂商漏洞挖掘案例;
4.熟练掌握php、java、asp.net代码审计基础(一种或多种)
5.精通Web Fuzz模糊测试漏洞挖掘技术
6.精通OWASP TOP 10安全漏洞原理并熟悉漏洞利用方法
7.有过独立分析漏洞的经验,熟悉各种Web调试技巧
8.熟悉常见编程语言中的至少一种(Asp.net、Python、php、java)

【加分项】
1.具备良好的英语文档阅读能力;
2.曾参加过技术沙龙担任嘉宾进行技术分享;
3.具有CISSP、CISA、CSSLP、ISO27001、ITIL、PMP、COBIT、Security+、CISP、OSCP等安全相关资质者;
4.具有大型SRC漏洞提交经验、获得年度表彰、大型CTF夺得名次者;
5.开发过安全相关的开源项目;
6.具备良好的人际沟通、协调能力、分析和解决问题的能力者优先;
7.个人技术博客;
8.在优质社区投稿过文章;


岗位:安全红队武器自动化工程师
薪资:13-30K
工作年限:2年+
工作地点:杭州(总部)

【岗位职责】
1.负责红蓝对抗中的武器化落地与研究;
2.平台化建设;
3.安全研究落地。

【岗位要求】
1.熟练使用Python、java、c/c++等至少一门语言作为主要开发语言;
2.熟练使用Django、flask 等常用web开发框架、以及熟练使用mysql、mongoDB、redis等数据存储方案;
3:熟悉域安全以及内网横向渗透、常见web等漏洞原理;
4.对安全技术有浓厚的兴趣及热情,有主观研究和学习的动力;
5.具备正向价值观、良好的团队协作能力和较强的问题解决能力,善于沟通、乐于分享。

【加分项】
1.有高并发tcp服务、分布式等相关经验者优先;
2.在github上有开源安全产品优先;
3:有过安全开发经验、独自分析过相关开源安全工具、以及参与开发过相关后渗透框架等优先;
4.在freebuf、安全客、先知等安全平台分享过相关技术文章优先;
5.具备良好的英语文档阅读能力。


简历投递至

bountyteam@dbappsecurity.com.cn

岗位:红队武器化Golang开发工程师

薪资:13-30K
工作年限:2年+
工作地点:杭州(总部)

【岗位职责】
1.负责红蓝对抗中的武器化落地与研究;
2.平台化建设;
3.安全研究落地。

【岗位要求】
1.掌握C/C++/Java/Go/Python/JavaScript等至少一门语言作为主要开发语言;
2.熟练使用Gin、Beego、Echo等常用web开发框架、熟悉MySQL、Redis、MongoDB等主流数据库结构的设计,有独立部署调优经验;
3.了解docker,能进行简单的项目部署;
3.熟悉常见web漏洞原理,并能写出对应的利用工具;
4.熟悉TCP/IP协议的基本运作原理;
5.对安全技术与开发技术有浓厚的兴趣及热情,有主观研究和学习的动力,具备正向价值观、良好的团队协作能力和较强的问题解决能力,善于沟通、乐于分享。

【加分项】
1.有高并发tcp服务、分布式、消息队列等相关经验者优先;
2.在github上有开源安全产品优先;
3:有过安全开发经验、独自分析过相关开源安全工具、以及参与开发过相关后渗透框架等优先;
4.在freebuf、安全客、先知等安全平台分享过相关技术文章优先;
5.具备良好的英语文档阅读能力。

简历投递至

bountyteam@dbappsecurity.com.cn



END

一篇文章带你读懂 TLS Poison 攻击(一)
一篇文章带你读懂 TLS Poison 攻击(一)
一篇文章带你读懂 TLS Poison 攻击(一)

长按识别二维码关注我们




版权归原作者所有,如若转载,请注明出处:https://www.ciocso.com/article/528.html

发表评论

登录后才能评论