Hash扩展长度攻击过程详解

构想一个具体场景来说明Hash扩展长度攻击的过程和原理。

(1)身份鉴别场景

若用户远程登录过程如下,用户必须正确输入账号密码、账号名称、以及使用hash工具生成的签名。

$ >>login pswdA userA 059A56C34E1646BB42135410001B0080
Login Successful!

远程服务端收到用户发送的信息并进行身份鉴别,过程如下:

md5(salt||password||name) = md5('secretKeypswdAuserA')= 059A56C34E1646BB42135410001B0080
比对hash签名值相同即为该用户验证通过。

(这里可能需要对hash填充以及MD结构基础知识,相关资料很容易获取就不多重复)

深入到MD5算法内部来看,MD5会对输入数据进行分组,每个分组长度为64字节,当长度不够时则会进行填充。

这里共有1个分组(写成hex字符串形式):

7365637265744b657970737764417573657241800000000000000000000000000000000000000000000000000000000000000000000000009800000000000000

其中'7365637265744b657970737764417573657241'对应的就是'secretKeypswdAuserA',注意其中'secretKey'是服务器和用户之间的共享密钥,由服务器程序自动附加到用户的输入信息开头。

'80000000000000000000000000000000000000000000000000000000000000000000000000'是填充内容,无实际意义。

'9800000000000000'共8个字节,对应的是填充前内容的bit长度,例如这里长度是152bits,对应的小端16进制8字节就是'9800000000000000'。

(2)攻击方信息和攻击方法

这里我们假设:'secretKey'作为服务器和用户之间的共享密钥,攻击方不能获取得到,但攻击方已经获得如下信息:

(1)userA用户的密码为pswdA,hash算法为MD5,salt长度为9字节,hash签名值为 059A56C34E1646BB42135410001B0080。
(2)userB,且身份鉴别过程与userA完全一致。
(3)服务端身份鉴别算法md5(salt||password||name)。

攻击方的目标是在不知道userB的口令和hash签名的情况下,冒用userB用户身份成功登录。直接说结果,如下输入可以达到目的。

$ >>login pswdAuserA%80%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%98%00%00%00%00%00%00%00 userB 8E15573D67ED8F99EAE6AABD584E7184
Login Successful!

(3)身份鉴别过程分析

具体分析针对以上客户端的输入,服务端计算过程如下:

md5('secretKeypswdAuserA%80%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%98%00%00%00%00%00%00%00userB') = 8E15573D67ED8F99EAE6AABD584E7184

此时MD5算法的输入内容长度需要2个分组才能承载,具体如下:

第1个分组(是不是很眼熟,和userA登录时服务端hash计算的分组内容一模一样)
7365637265744b657970737764417573657241800000000000000000000000000000000000000000000000000000000000000000000000009800000000000000

第2个分组

75736572428000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002802000000000000

输出hash签名值为 8E15573D67ED8F99EAE6AABD584E7184,和攻击方输入的签名相同,身份鉴别通过。

(4)攻击方的计算

除了掌握相关信息,攻击方要具备MD5算法源码并适当修改。

# 修改MD5算法的初始输入常量为userA的hash签名059A56C34E1646BB42135410001B0080

        # hash长度扩展攻击修改
        # 修改IV为 0x059A56C3 4E1646BB 42135410 001B0080
        self.A = 0xC3569A05
        self.B = 0xBB46164E
        self.C = 0x10541342
        self.D = 0x80001B00
        self.init_A = 0xC3569A05
        self.init_B = 0xBB46164E
        self.init_C = 0x10541342
        self.init_D = 0x80001B00
        '''
        self.A = 0x059A56C3
        self.B = 0x4E1646BB
        self.C = 0x42135410
        self.D = 0x001B0080
        '''
        # 修改结束

        # self.A = 0x67452301
        # self.B = 0xEFCDAB89
        # self.C = 0x98BADCFE
        # self.D = 0x10325476
        # self.init_A = 0x67452301
        # self.init_B = 0xEFCDAB89
        # self.init_C = 0x98BADCFE
        # self.init_D = 0x10325476
        # '''
        # self.A = 0x01234567
        # self.B = 0x89ABCDEF
        # self.C = 0xFEDCBA98
        # self.D = 0x76543210
        #  '''

# 修改MD5分组长度计算值(需要额外加上512bits长度)

        length = len(self.message) * 8
        # hash长度扩展攻击修改
        length += 512
        # 修改结束

之后,直接对'userB'进行MD5签名运算即可得到与服务端一致的签名值。

message = 'userB'
MD5 = MD5(message)
MD5.fill_text()
result = MD5.run()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

游鲦亭长

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值