MD5哈希长度延展攻击

任务详情

任务描述:

在一个使用MD5哈希算法的系统中,管理员使用了一个密钥k和命令cmd的组合来生成每个命令的签名:hash(k||cmd)。你已经获得了一个允许查看文件的命令cmd=viewfile和对应的签名h,但你希望通过哈希长度延展攻击,生成一个新的签名,该签名能够让你执行删除文件的命令(删除文件的命令为rm)。

具体步骤:

  1. 研究MD5哈希长度延展攻击的机制,并找出适用于此场景的攻击方法。(3分)
  2. 使用合适的工具或脚本,基于cmd=viewfile和签名h,构造一个新的命令cmd=viewfile||padding||deletefile和新的签名。(6分)
  3. 提交你使用的攻击方法、工具或脚本的详细说明,以及成功构造的命令和新的签名。(6分)

解题

1 哈希延展攻击

image

2 构造预先计算

现在我已知内容是hash(k||cmd),k对应的内容是20211108,cmd对应的内容是viewfilehash(k||cmd)对应内容应该为d5320b5ddd3fb43f4fadc4236af772b9
下面就要根据hash(k||cmd)构造出hash(k||viewfile||padding||deletefile)
由于MD5在进行计算前会进行填充,且填充规则为先填充一个1,然后填充0,直到新的消息长度满足 (原长度 + 1 + 填充长度) 除以512的余数为448。在本题中原消息长度为128,则填充长度为320。

3 构造

这里使用hashlab库编了一个程序进行MD5延展攻击,并且得到伪造的签名

import hashlib

def md5_extend(original_message, original_hash, extension):
    # 步骤1:计算原始消息的字节长度
    original_length = len(original_message.encode())

    # 步骤2:初始化填充
    padding = b'\x80' + b'\x00' * ((56 - (original_length + 1) % 64) % 64)

    # 步骤3:添加原始消息的比特长度
    padding += (original_length * 8).to_bytes(8, byteorder='little')

    # 步骤4:计算新哈希值
    new_hash = hashlib.md5()
    new_hash.update(extension.encode())
    new_hash.update(padding)
    forged_message = original_message.encode() + padding + extension.encode()

    # 步骤5:返回伪造消息和哈希值
    return forged_message, new_hash.hexdigest()

original_message = "20211108viewfile"
original_hash = hashlib.md5(original_message.encode()).hexdigest()
extension = "rm *"
forged_message, new_hash = md5_extend(original_message, original_hash, extension)

print("原始消息:", original_message)
print("原哈希值:", original_hash)
print("伪造消息:", forged_message.hex())  # 将字节串转换为十六进制表示
print("新哈希值:", new_hash)

md5_extend函数接受原始消息(主要需要原始消息的长度)、原始哈希值和要添加的扩展内容作为输入,然后返回伪造的消息和新的哈希值。

运行结果为

PS C:\Users\Dr.Yu\OneDrive\桌面\ljp新> & C:/Users/Dr.Yu/AppData/Local/Microsoft/WindowsApps/python3.11.exe c:/Users/Dr.Yu/OneDrive/桌面/ljp新/云班课/MD5/MD5延展攻击.py
原始消息: 20211108viewfile
原哈希值: d5320b5ddd3fb43f4fadc4236af772b9
伪造消息: 32303231313130387669657766696c65800000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000726d202a
新哈希值: a1e19f6a4338a3da08265a59d0df7c34

image
伪造的消息是采取16进制输出的,以下是具体解释:

32 30 32 31 31 31 30 38 -> 20211108 (原始消息:key)
76 69 65 77 66 69 6c 65 -> viewfile (原始消息:命令)
80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -> 填充(0x80表示消息末尾,然后补零直到达到填充条件)
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -> 原始消息长度(8字节,十六进制的80)
72 6d 20 2a -> rm * (扩展内容,ASCII 字符串)

伪造的哈希结果为a1e19f6a4338a3da08265a59d0df7c34
伪造的消息为

76 69 65 77 66 69 6c 65 -> viewfile (原始消息:命令)
80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -> 填充(0x80表示消息末尾,然后补零直到达到填充条件)
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -> 原始消息长度(8字节,十六进制的80)
72 6d 20 2a -> rm * (扩展内容,ASCII 字符串)

注:一定得已知原消息长度和原消息的哈希值才可计算,思考如下:(严格证明暂时没想出来)
Length Extension Attack 是一种与某些特定类型的哈希函数(如 MD5,SHA-1 和 SHA-2)的特性有关的攻击。简单来说,这种攻击利用了一个事实,即知道 H(message) 和 message 的长度,我们可以轻松计算出 H(message || padding || extension) 而不需要知道 message 本身。其中 “||” 表示连接,“padding” 是根据哈希函数的规定添加的。

posted @ 2024-04-13 22:38  20211108俞振阳  阅读(38)  评论(0编辑  收藏  举报