tls1.3协议实战(一)---client hello和server hello解析

  1、根据公开资料显示,xxxx的聊天通信协议mmtls是基于tls 1.3精简了一些握手的方法后用openssl实现的;官方的介绍在这:https://mp.weixin.qq.com/s/tvngTp6NoTZ15Yc206v8fQ ;为了便于理解、抓住主脉络,我这里整理了整个协议的主干思路,如下:

       

        

  既然是基于tls1.3改造的,为了更好的逆向分析xxxx的通信协议,这里先系统性地学习一下tls1.3协议!tls1.3协议官网地址:https://tools.ietf.org/html/rfc8446 对于新手,纯看文档估计头都大了。为了便于理解,这里通过抓包来窥探tls1.3协议的细节和设计思路!
  2、我这里用chrome 74.0.3729.131,访问google,wireshark抓到包后,随便找一个tls1.3的client hello包,点击右键,选择追踪流->TLS流,能看到完整的tls握手和数据发送的过程;
       

        完整的TLS流如下:

   

   下面挨个分析这些包的作用和重要字段的意义!

  (1)前面3个(195-197)tpc的包:有SYN、ACK等特征,很明显是tcp3次握手的,这里不赘述了;整个TLS的过程,哪怕是0-RTT,都要先经历TCP3次握手,只是不再进行TLS握手,直接发送应用数据
       (2)第198号包明显与众不同了:protocol是tls1.3,info标明了Client Hello,就是client主动找server打招呼,要开始通信了;
                第199号包:server马山给client发确认收到client hello的消息。注意:server为啥要在0.1ms之内回复client,而不是直接发送server hello了? 从下面可以看出,server hello发送延迟到了第281号包,耗时约440ms。这么长时间的延迟,如果不提前给client发送确认包,client可能会认为自己发的hello包丢失,所以server先发个简单的ACK,让client知道已经收到了他的hello包,继续耐心等待!
       第281号包:server给client发送server hello的包,同时标明“change cipher spec”,告诉client后续通信用对称密钥加密了!细心的读者可能发现问题了:server在199号包给client发送了确认收到client hello的消息,但在第281号包才把server hello发给client,这期间操作系统已经发送了82个包,间隔大约440ms,这个耗时在公网通信中非常长了,为啥会延迟这么大了? 这里卖个关子,请继续往下看!
   (3)从第282个包开始,server开始发送application data(猜测应该是网页相关的数据,比如html、js、图片、音视频等文件),距离其发送server hello仅延迟0.1ms;从这里可以看出,client和server互相发送application data,仅耗费1-RTT,这也是tls1.3比tls1.2改进的地方(xxxx使用的mmtls协议采用的就是1-RTT的ECDH在client和server之间互相交换公钥后生成了对称密钥);后面所有的包都是application data和ACK确认包(标明收到了对方的application数据)! 接下来又有问题了:HKDF、PSK、AES-GCM这些算法都在哪体现的了?( ̄▽ ̄)",下面挨个介绍通信中核心的数据以及原理!
 
  3、(1)client hello 包:前面的3层:链路层、ip层、tcp层这里不再赘述,重点学习tls层的字段和含义
  •  老规矩,主动向server打招呼的时候先做个自我介绍:这个是handshake握手包,版本是1.0(我暂时也不知道为什么是这个),这个包的长度是512字节;(注意: tcp协议的缺点之一:必须明文指定包长度!接收方按照指定的长度读取数据。windows下有个 CVE-2020-16898 "Bad Neighbor "  https://www.cnblogs.com/theseventhson/p/14004712.html  就是因为内核驱动没处理好接受的数据包长度导致蓝屏;这个地方还有可能利用整数溢出漏洞,进而导致缓冲区溢出)
  

   接下来是核心的handshake protocol解析,如下:字段有很多,我们挨个看

         

     前面3个handshake type、length、version都是常规的介绍,看英文不解释都能懂!从第4个开始:

  •  random:client随机生成一个32byte的数发给server。通常,在通信中以访给另一方发随机数的作用有:1)防止重放攻击  2)后续用于完整性校验,这里也不例外   3)生成encrypt-key,正式开始加密应用层的数据;
  •  session ID:双方通信的一般套路都是“非对称算法协商密钥,对称算法加密数据”。服务器生成session id,存放本次session协商好的对称密钥。下次通信时,客户端带上session id,server就知道用哪个对称密钥继续加密数据了。不过session id有些缺陷(id一般都存在单个服务器,但客户端的数据一般都是反向代理、负载均衡等转发到内部某个server的,这些反向代理、负载均衡是不知道session id属于哪个server),已经被session ticket替代;
  • cipher suites:client列举自己支持的加密套件,可以看出前面一般是非对称加密算法,协商对称算法密钥的。后面都是加密应用数据的对称算法;后续server会根据自己的实际情况选择合适的加密套件;这里稍微解释一下这些加密套件的基础算法,比如:0xc02b,ECDHE,是双方用来协商对称密钥的椭圆曲线算法;ECDSA是客户端验证服务端的签名算法;AES_128_GCM_SHA256是128bit的对称加密算法,同时带了数据校验功能,可有效识别传输的数据是否被篡改!

          

  •  extension:有好多分项,都有不同的含义,先看第一个:说明server name。这里访问的是gstatic,貌似是google的广告联盟站点。我并没有访问这个,估计是访问google时自带的;

        

  •  supported groups:由于安全性和效率问题,tls1.3已经不再使用RSA,而是椭圆曲线。不同的椭圆曲线对应不同的曲线形状,会产生不同的公钥;同样,不同的基点G也会导致产生不同的公钥,所以这里有4种不同的椭圆曲线参数供client选择;

  

  • session ticket:作用和session id类似,上面已经解释过了。这里由于还是client hello阶段,所以这个字段暂时没有值;保留字段,带上空值,也可以向服务器标明client支持session ticket功能

   

  •  application layer protocol negotiation:协商tls上层的应用层协议,这里采用的是http协议

       

  •  key share:这个是重点!tls1.3支持1-RTT,比tls1.2效率提升一倍,原因就在这里了:在client hello里面,client列举出了自己支持的加密套件,并把所有的非对称加密算法的公钥都一并带上(虽说这里只有1种,我怀疑是浏览器的问题)。server收到后可以直接根据接受的ECDHE和client的公钥生成自己的公钥和对称密钥

        

  •  PSK exchange models:psk_dhe_ke=1,这里双方约定用非对称加密方法ECDHE协商一个对称密钥,或则直接从之前协商出来的密钥参数中得出一个密钥(psk_ke);

      

  •  supported version:支持的tls版本,这里大概是为了兼容老版本,从tls1.0到1.3都支持

      

  •  pre-shared key:访问googke另一个分站点的时候,抓到了PSK的字段,如下:(1)psk本质也是一串ID,这里有226byte,生成方式见本文上方的那张图,最早是server和client通过tls成功握手后把key和其他一些信息通过HMAC转换后发给client;client后续访问可以直接带上这个PSK,就不用再做密钥协商,节约时间;(2)这里还有个obfuscated ticket age: 1874391131,转成年月日的格式就是2029-05-25 16:12:11,这是PSK的生存时间,过期就用不了了

            

  注意几个容易混淆的概念:

  • key_share:椭圆曲线中双方互换公钥来生成对称加密的私钥; pre_shared_key:是预共享秘钥认证机制PSK生成的对称秘钥,PSK也是一种身份认证机制;
  • psk其实即使Session ticket外加一些检验的东西,相当于ticket的强化版!

  上面介绍了那么多extension,有4个extension是必须的:psk_key_exchange_modes、pre_shared_key、key_share、supported_versions;

 

  (2)server hello:先来看前面遗留的第一个问题:为啥client hello之后server先发一个ack给client,再发server hello了?而不是直接发个server hello?

   

   server hello要根据client的加密套件、公钥继续算出自己公钥和私钥(32byte=258bit),这种big num的计算是相当耗时的(这里花了约440ms)。如果server在收到client hello后不马上回复ACK,而是等计算出自己公钥和私钥再回复client,搞不好client会认为server已经超时挂掉,所以server先发个ACK,让client知道他的hello包已经被收到

  和分析client hello包一样,接下来挨个分析重要字段的含义:

  • 还是标明这个包的作用是handshake,长度122字节,版本是1.2(也不知道为啥不标注1.3)......

  

  •  Random: 32byte的随机数,作用和之前client发给server的随机数一样,1)防止重放    2)后续用于消息完整性校验,防止被篡改   3)生成encrypt-key,正式开始加密应用层的数据;

          

  •  session id:32byte,作用在client那里已经解释了

   

  •   Cipher Suite:client在client hello包里面列举了其能支持的加密套件,这里server在里面选择了这个加密套件;后续双方就用AES_GCM来做对称加密

        

  •   Extensions:最重要的莫过于key_share了。对称加密算法是AES_GCM,那么密钥又是啥了? 就是通过椭圆曲线计算出来的;Client在hello包里已经给server发送了他的公钥,server也要把自己的公钥发给client,双方才能计算出对称加密的密钥,所以server这里选择了x25519(这个其实是client选择的,server只能遵从)

        

  • Change Cipher Spec:告诉client,后续咋们通信时改变现在的加密方式,即改成对称密钥加密通信数据

      

    剩下的问题又来了:wireshark就解析到了0xba这个位置,从0xbb到0x58e=1422的位置,还有1234byte并未解析,这些又都是什么数据了?纵观整个协议的握手过程,截至目前看到的都是handshake密钥交换阶段,record传输加密数据的阶段都在哪了? 

        4、总结:

  (1) 刚开始学的时候,对session id、ticket、psk理解不够透彻,很多概念的解释看的云里雾里,这里系统性对比和总结这3个概念的区别,希望对读者有所帮助;这些概念或事物的宗旨很简单:对称加密的密钥是经过多个RTT协商而来的,耗时非常长,对服务器CPU算力的消耗也不小,来之不易,需要好好保存,下次通信时如果能继续复用就太好了,下面3个本质上都是保存对称加密密钥的方法

    

   (2)整个过程涉及到client和server双方互换公钥和生成对称密钥。期间只有client验证server,并没有server验证client,这里有个缺陷:如果黑客冒充client(这个不难,比如随机更换源IP,导致server认为是来自不同client的包),随机生成各种公钥(甚至都不用随机生成,而是直接写死),server接收到client的公钥后要需要耗费算计去计算对称密钥。如果黑客伪造的client达到一定数量,理论上可以导致server的CPU耗尽,无法再接受正常client的链接请求,这也是常见的DOS攻击之一!

 

参考:

1、https://blog.csdn.net/SkyChaserYu/article/details/105840504  tls1.3抓包分析

2、https://time.geekbang.org/comment/nice/111287  session id、session ticket、psk三者区别和联系

3、https://halfrost.com/https_tls1-3_handshake/ 直观感受tls握手流程

4、https://jasonlees.netlify.app/article/tcpip-4-ssl-tls-3/   TCP/IP系列(4)-SSL/TSL详解(3)

5、https://cshihong.github.io/2019/05/09/SSL%E5%8D%8F%E8%AE%AE%E8%AF%A6%E8%A7%A3/  SSL协议详解

 

posted @ 2021-04-04 22:19  第七子007  阅读(12458)  评论(0编辑  收藏  举报