首页
社区
课程
招聘
[原创]mmtls的分析研究与总结
2020-3-5 12:08 25502

[原创]mmtls的分析研究与总结

2020-3-5 12:08
25502

前言

mmtls是基于1.3的tls协议简化修改而来,根据某公司的描述,这种安全可行,用于短连接的安全模式,也给了其他的公司启发,一方面,使用https在越狱root环境下,也容易被窥探,所以开发一种通用而安全的短连接加密协议,确实有些必要,我们想看看到底是如何实现的,所以抓个包,hook下数据来看看。

(不太清楚在这样的氛围下,能不能讨论这个,所以我决定先写一部分,要是可以继续说,再写后半部分,大家参考这种实现,实现出自己的通用加密传输协议)

关于mmtls的介绍可以阅读这篇文章

官方介绍

我们如何入手分析呢?

1.抓包

抓包显然是没有办法看到啥的,不过我们只关心短连接,所以我们需要一个环境来触发短连接的mmtls初始化,而且我们只关心mmtls,并不关心其他的信息,所以,我们可以利用一个早期版本,理由是,早期版本可以屏蔽掉长连接,而强制使用短连接。

2.算法

显然我们应该先对算法,有一些了解,甚至我们应该先阅读一下github上的tls1.3的实现,这样我们才能对tls1.3的答题轮廓有些印象,在我们逆向分析的过程中,省去很多的麻烦,所以我们应该先了解以下算法,包括以下算法的原理和使用。
  • ECDH(ecdh主要用于秘钥协商,签名验证)
  • AESGCM(aes gcm 带校验的aes加密算法,相比于之前的aes cbc要更安全)
  • hkdf扩展(hkdf扩展是用来扩展秘钥的)
  • sha256(哈希算法,基本上用于验证数据)
  • hmac(签名)

Hook

为了便于分析,我们会一次把以上的算法进行hook一次,弄清数据的来龙去脉,这也是分析协议最关键的技巧,跟着数据走,以数据为核心,来进行逆向,不用太在意到底是经过了那些算法,我们只需关心,数据在哪里变化了。所以我选取了PC版本26231,找出上面算法的hook地址,找算法地址其实不复杂,因为基于openssl的算法,搜关键字啥的就行了。为了方便大家对照,我在这里公布地址的列表:
  • BuildWriteBuffer 0xA17B3A (发送数据)
  • GenEcdhPublicKey 0xA475AC
  • GenEcdhPublicKey 0xA475AC
  • GenEcdhPriKey 0xA475C8
  • ClientChannelReceive 0xA18FFD
  • AesGcmCrypterCrypt 0xA6124B
  • AesGcmCrypterCryptFinish 0xA61434
  • OpenSslCryptoUtilHkdfExpand 0xA47827
  • OpenSslCryptoUtilHkdfExpandFinish 0xA478BC
  • OpenSslCryptoUtilEcdh 0xA4816B
  • OpenSslCryptoUtilEcdhFinish 0xA482CF
  • OpenSslCryptoUtilSHA256Update 0xA489A0
  • OpenSslCryptoUtilSHA256Final 0xA48A65
  • OpenSslCryptoUtilSHA256FinalFinish 0xA48B07
  • OpenSslCryptoUtilHMacSHA256 0xA4810D
  • OpenSslCryptoUtilHMacSHA256Finish 0xA4815F

启动注入研究Log

  1. 由于mmtls的必须启动注入,所以需要在dll被load进来就开始注入,这可以利用OD很方便,之后我们可以看到一些日志。


    这里生成了两对ECDH秘钥对,参照官方解释,应该是一对用于加密,一对用于签名校验,因为放弃了原有的tls证书链形式签名校验,可能就采用这种方式来做签名。
  2. 之后看发送数据
    首先可以看到这里对发送的数据进行了一次SHA256计算,之后便发送了,而发送数据从结构上来看应该是tls的clientHello包,但是好像结构并不能完全与之对应,从数据上大致可以分为以下几块:
    • 总大小(00 00 00 D0)
      • 可能是版本(01 03 f1)
      • 内容大小
      • 随机数32
      • 时间戳
      • 一大串不知道啥
      • ECDHPUB1
      • ECDHPUB2
      • 序列号
  3. 看看Serverhello
    Serverhello比较符合tls的规范0x16为协商过程,所以我们将数据
    进行了切割,大体分为四个块,接下来分别以这四个块进行讲解,看看我们理解上的tls1.3与mmtls有什么区别,从文章来理解,砍掉了算法选择,RTT-1就可以协商完成。
  • 第一个数据块
    • 上面可以看到第一个数据块,返回了服务器的pubkey,用于跟我们之前的prikey进行一次ecdh协商然后得出一个32大小的数据。
    • 之后进行一次HKDF的秘钥扩展生成56大小的数据,根据文章描述,应该是对这56的数据进行分开,此时的数据,则为服务器和客户端的共同加解密数据,但是这个数据并不是最终的固定秘钥,而是协商过程用于加解密数据的秘钥。秘钥按照(16 12 16 12)进行分解,作为AES GCM的 key 跟IV,这样便可以进行后续的解密操作。
  • 第二个数据块
    现在就开始解密第二个数据块了,key iv nonce都比较清晰,同理可以解密出来第三部分第四部分。
  • 解密第三个数据块
    第三个块解密出来的数据包含PSK data,以便于后续的直接PSK模式请求。
  • 解密第四个数据块
    第四个数据块包含server finish,服务器返回的数据就完全了,根据server finish可以做一些校验,判断数据是否有错误。
  1. 发送Client Finish
    协商完成以后,客户端要发送client finish的报文,告诉服务器客户端以及完成了解密和协商。
    用第一块数据hdkf扩展出来的加密key iv进行加密即可但是这里的IV做了异或自增加,为了防止重攻击,服务器应该解密之后自增长,这样重复请求就无法解密。
  2. 扩展出业务秘钥
    到这里就和application.data.key.expansion一起扩展出来了真正的业务请求秘钥,现在就是安全的传输模式了。

    总结

    https的流量劫持从这篇文章我们其实了解到,从http时代的流量劫持到https时代都没有彻底解决,以前运营商恶心,现在证书信任依然是个很大的问题,所以我们如果能从mmtls的实现里面,对tls1.3进行改动,应该可以实现一套比较通用的安全传输协议层,而且基本上也与业务无关。

[CTF入门培训]顶尖高校博士及硕士团队亲授《30小时教你玩转CTF》,视频+靶场+题目!助力进入CTF世界

最后于 2020-3-6 11:03 被大魔头编辑 ,原因: 更新
收藏
点赞6
打赏
分享
最新回复 (27)
雪    币: 34
活跃值: (37)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
双峰山 2020-3-5 15:27
2
1
照着GitHub的tls1.3实现就行了,几个细微差别而已。
雪    币: 2011
活跃值: (2275)
能力值: ( LV4,RANK:55 )
在线值:
发帖
回帖
粉丝
evilbeast 1 2020-3-6 02:21
3
0
可以
雪    币: 2011
活跃值: (2275)
能力值: ( LV4,RANK:55 )
在线值:
发帖
回帖
粉丝
evilbeast 1 2020-3-6 02:26
4
0
好文
雪    币: 83
活跃值: (1037)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
killpy 2 2020-3-6 06:49
5
1
mark
雪    币: 1333
活跃值: (301)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
酷鸟 2020-3-6 11:40
6
0
好文 期待后续
雪    币: 20
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
kongkong447 2020-3-26 15:58
7
1
秘钥按照(16 12 16 12)进行分解,作为AES GCM的 key 跟IV
这个看分解  是 (16 16 12 12)
091DDD18   0D7C99F0
091DDD1C   00000010
091DDD20   0D7C9A00
091DDD24   00000010
091DDD28   0D7C9A10
091DDD2C   0000000C
091DDD30   0D7C9A1C
091DDD34   0000000C
雪    币: 160
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
孤山飞雪 2020-4-12 11:43
8
0
jingang728627,v,等联系
雪    币: 2867
活跃值: (2598)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
KongKong20 2020-5-5 10:03
9
0
请教下怎样:屏蔽掉长连接,而强制使用短连接?
找了资料,说是__RunConnect,尝试了修改socekt为-1,还是会再次调用长连接。
往上层找MakesureLonglinkConneted,没找到开始调用的地方。
雪    币: 33
活跃值: (1681)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
大魔头 2020-5-6 20:27
10
0
KongKong20 请教下怎样:屏蔽掉长连接,而强制使用短连接? 找了资料,说是__RunConnect,尝试了修改socekt为-1,还是会再次调用长连接。 往上层找MakesureLonglinkConneted ...
新版本是不让屏蔽了的
雪    币: 2867
活跃值: (2598)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
KongKong20 2020-5-8 09:27
11
0
大魔头 新版本是不让屏蔽了的
我这边用的是一样的老版本:2.6.2.31。
clientHello包长也不是 0x0d,反而大很多0x161,其他字段对得上,就中间的未知多了很多东西
雪    币: 234
活跃值: (289)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
Altai001 2020-5-24 22:46
12
0

5

最后于 2020-7-7 21:40 被Altai001编辑 ,原因: 重新组织下语言
雪    币: 234
活跃值: (289)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
Altai001 2020-6-13 11:53
13
0

--

最后于 2020-6-15 11:05 被Altai001编辑 ,原因: 不恰当言论
雪    币: 2867
活跃值: (2598)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
KongKong20 2020-6-15 10:58
14
0
Altai001 我知道为什么了,我的也是0x161,仔细再读一篇MMTLS的介绍就知道了 哈哈哈
携带了PSK数据?
雪    币: 234
活跃值: (289)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
Altai001 2020-6-15 11:00
15
0


最后于 2020-7-6 13:07 被Altai001编辑 ,原因: 不符合规范
雪    币: 234
活跃值: (289)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
Altai001 2020-6-15 11:02
16
0
KongKong20 携带了PSK数据?
对的,这个应该是0-RTT PSK协商
雪    币: 33
活跃值: (1681)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
大魔头 2020-6-15 11:27
17
0
KongKong20 我这边用的是一样的老版本:2.6.2.31。[em_78] clientHello包长也不是 0x0d,反而大很多0x161,其他字段对得上,就中间的未知多了很多东西
那是第一次协商完成以后,本地缓存了加密的PSK,所以下次就直接发送psk就可以协商了
雪    币: 2867
活跃值: (2598)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
KongKong20 2020-6-15 11:48
18
0
Altai001 对的,这个应该是0-RTT PSK协商
感谢感谢~
雪    币: 2867
活跃值: (2598)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
KongKong20 2020-6-15 11:49
19
0
大魔头 那是第一次协商完成以后,本地缓存了加密的PSK,所以下次就直接发送psk就可以协商了
感谢感谢~
雪    币: 234
活跃值: (289)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
Altai001 2020-6-23 14:51
20
0

.

最后于 2020-7-6 13:06 被Altai001编辑 ,原因: 不符合规范
雪    币: 22
活跃值: (37)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
sagittaquas 2020-7-14 10:25
21
1
我不是搞逆向的,不过个人觉得mmtls没必要研究,不是未来方向,而且它假设了应用层能够谨慎的使用它(就好像微信发文件时,在其明文数据结构中包含了该文件的本地文件名一样。应用层的粗心大意造成了很多安全问题)。
未来协议的典型需求是: 低延迟,高带宽利用率,高并发,物理网络切换不切换会话等等。防范的主要是 攻击,破解。需要平衡的是各种厂商的正常需求,比如流量监控等。
因此,dtls,gquic,iquic这些才值得研究。当然,作为现有tcp的代表tls也值得继续关注。不过基于现有tcp永远解决不了真正的并发问题,物理网络切换问题,天然缺陷太多。至于 是 rtt-0(1)的gquic能胜出,还是rtt-1(2)的dtls能胜出,这个就不太好说了。个人感觉反射攻击防范和rtt-0都是主流需求。不过,如果能够使用会话保持,无视物理网络切换,也许rtt-x就不再是问题了。个人猜测,未来不会是单一协议的填写,也不会太多。更多的可能是几种不同偏向的协议并存。(dtls,quic ?)
雪    币: 234
活跃值: (289)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
Altai001 2020-7-24 17:29
22
0

重新编辑

最后于 2020-7-24 18:03 被Altai001编辑 ,原因:
雪    币: 234
活跃值: (289)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
Altai001 2020-7-25 11:28
23
0

.

最后于 2020-7-29 18:28 被Altai001编辑 ,原因:
雪    币: 162
活跃值: (819)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
骇客技术 2020-9-21 09:59
24
0

这篇文章不错, 可以给后来者很多参考, 大体结构都有了, 除了握手消息hash那段没截图, 这个你自己hook后数据就有了, 另外说句那段乱七八糟数据是psk握手用的, 安卓也是这个流程,  重现下楼主流程, 还原 mmtls 不难.

最后于 2020-9-21 10:01 被骇客技术编辑 ,原因:
雪    币: 713
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
安小白MCY 2020-9-28 11:06
25
0

mmtls最终使用的密钥是有HKDF-Expand扩展出来的。mmtls把info参数分为:length,label,handshake_hash。其中length等于out_key_length,label是标记密钥用途的固定字符串,handshake_hash表示握手消息的hash值,这样扩展出来的密钥保证连接内唯一。

最后于 2020-9-28 11:44 被安小白MCY编辑 ,原因:
游客
登录 | 注册 方可回帖
返回