区块链安全,哈希函数暴露的攻击向量与对策

2023-09-18 11:12:15

区块链安全,哈希函数暴露的攻击向量与对策

简介
Length Extension Attack 是一种与某些特定类型的哈希函数(如 MD5,SHA-1 和 SHA-2)的特性有关的攻击。简单来说,这种攻击利用了一个事实,即知道 H(message) 和 message 的长度,我们可以轻松计算出 H(message || padding || extension) 而不需要知道 message 本身。其中 “||” 表示连接,“padding” 是根据哈希函数的规定添加的。

这是因为这些哈希函数使用了 Merkle-Damgård 结构,它将输入切片为多个块,并且每个块的哈希值依赖于前一个块的哈希值。这意味着一旦我们计算出了某个消息的哈希值,就有了一个状态,可以从那里开始并添加更多的块。

一种服务端验证模式

为方便描述漏洞场景,我们首先假设有这样一种服务端验证模式,即用户尝试登录时,服务端会根据用户的 ID、名字以及一个仅服务端知道的 30 位密钥,通过特定的哈希算法生成一个哈希值,并将其下发给客户端。随后,当客户端尝试访问某些特定接口,例如修改用户权限的接口时,服务端会根据前端 POST 的角色 ID、角色名字、角色权限以及同样的 30 位密钥,重新生成哈希进行验证。如果上传的哈希与服务端生成的哈希一致,则视为验证通过,并将新的角色权限写入数据库。

为便于理解,下面是根据描述写的一些简单的代码做为示例:

越权思路

由于验证模式存在漏洞,攻击者可以在不知道 SecretKey 的情况下,通过重新构造交易请求,达到绕过权限验证的目的。越权攻击的核心思路在于利用长度扩展攻击的特性。攻击者首先需要获取到原始的哈希值,并通过简单的迭代算法计算出原始数据的长度。一旦得到这些信息,就可以将额外的越权参数添加到原始数据中,并利用相同的哈希算法生成恶意的哈希值。

长度扩展攻击原理

Length Extension Attack 发生的原因在于部分哈希函数的内部机制。这些函数在处理输入数据前,首先将数据分割成固定长度的块,然后在每个块的末尾进行填充以满足特定的要求。这种设计导致攻击者可以在知道原始消息哈希值和长度的情况下,通过填充和附加新数据,构造出新的有效哈希值。

以 SHA-256 为例,其工作在 512 比特的块上。对于长度不是 512 比特的倍数的数据,需要进行填充操作。其填充规则如下:

  1. 在数据的末尾添加一个 “1” 比特;
  2. 添加一定数量的 “0” 比特,使得数据的长度模 512 等于 448(详细内容见 [1]);
  3. 在最后面添加一个 64 位长的块,表示原始数据的长度。

简而言之,将一个 “1” 后面跟着 m 个 “0”,再加上一个 64 位或 128 位的整数,附加到消息的末尾,以生成长度为 512*n 的填充消息。附加的整数是原始消息的长度。然后,填充消息将被哈希函数处理为 n 个 512 位的块。

构造方法

在这个示例中,我们将以上面图片提到的代码做为一个特定的场景,其中数据字符串为 data=“user_id=1&user_name=aa”,密钥为 SecretKey=“Length_extension_attack_secret”。服务端会解析上传的数据中的 data 字段,并通过分隔符 & 解析出所需的参数 user_id 和 user_name。如果存在 role 字段,服务端也会获取该字段的值。然后,服务端会将所有字段与 SecretKey 进行哈希运算,并与上传的验证哈希进行比较。如果哈希值一致,则认为参数符合规则,并直接使用。

首先,我们通过登录 loginHandler 接口获取根据 data 和 SecretKey 使用 SHA-256 生成的哈希值 hash=“37d310d3465506486431fb2c2eb163f0f470479703f66dc9e5fdead8a3390c68”。

接下来,我们将探讨破解的难度。以我们的测试情况为例,根据长度扩展攻击的原理,只要知道 H(message) 和 message 的长度,我们就可以通过长度扩展攻击添加新的数据。原来的 message = SecretKey + data,现在我们手上已经有 H(message),只需知道 message 的长度,就可以构造一个新的哈希值。由于 SecretKey 是一个 30 位的密钥,只需经过 30 次迭代,就可以得知真正的 message 的长度。因此,我们可以很容易地构造出一个新的哈希值。由于我们需要使用 admin 的权限,所以我们要将恶意的字段 “&role=admin” 拼接到原来的数据中。

我们可以利用长度扩展攻击的特性,在不知道 SecretKey 的情况下,添加新的数据并生成一个新的哈希值。这里使用一个已经实现此功能的库 [2] 来完成测试。再使用工具生成新的哈希值 。

由于 adminActionHandler 的接口验证是根据上传的 user_id,user_name 和 role 来验证 hash 的,我们这时候上传的数据是 user_id=1,user_name=aa\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x70 以及 role=admin,如下图所示:

哈希值为 84ae4ae437eeabf3bd8a26294392770b86f64a81998194156ac003d58a21acd0。之后就可以调用 adminActionHandler 接口,服务端收到数据后,会把上传的哈希与 sha256(SecretKey + fakeData) 进行对比,通过验证之后将会执行一些敏感操作。这样,我们就成功地利用长度扩展攻击绕过了服务端验证,并实现了越权操作。

其他可能的攻击场景

**1. 文件完整性验证:**如果文件的完整性是通过连接密钥和文件内容,然后对其进行哈希来验证的,那么攻击者可能会扩展文件并生成一个有效的哈希,从而绕过完整性检查;
**2. Web 应用安全:**在 Web 应用中,如果使用了易受长度扩展攻击的哈希函数来验证用户提交的数据,攻击者可能会利用这一点来提交恶意数据;
**3. 数字签名:**在某些数字签名方案中,如果签名是通过连接私钥和消息,然后对其进行哈希来生成的,那么攻击者可能会扩展消息并生成一个有效的签名;
**4. 密码存储:**虽然不常见,但如果密码是通过连接密钥(例如盐)和密码,然后对其进行哈希来存储的,那么攻击者可能会尝试使用长度扩展攻击来破解密码。

如何防范

1. 选择不易受长度扩展攻击的哈希函数,例如 SHA-3;
**2. 使用 HMAC:**HMAC 需要一个密钥和一个消息作为输入,输出的结果既依赖于密钥,也依赖于消息,因此攻击者在不知道密钥的情况下无法进行长度扩展攻击;
**3. 加强权限验证:**在服务端增加额外的权限验证步骤,例如使用多因素认证。

以下是一些常用的 Hash 算法的特性:

算法碰撞抵抗选择前缀碰撞攻击预映像抵抗长度扩展攻击
MD52^182^392^123.4易受攻击
SHA-12^61.22^63.42^160易受攻击
SHA-256 (SHA-2)2^65.5-2^254.9易受攻击
SHA-512 (SHA-2)2^32.5-2^511.5易受攻击
SHA-32^50-未知不易受攻击
BLAKE2s2^112-2^241不易受攻击
BLAKE2b2^224-2^481不易受攻击
结语

对于长度扩展攻击,一种有效的防护措施是使用不受此类攻击影响的哈希函数,例如 SHA-3 和 BLAKE2。另外,还可以通过 HMAC(密钥散列消息认证码)结构来进行防护。这些措施可有效提高系统的安全性,确保数据完整性和应用程序的稳定性。

更多推荐

skywalking入门

参考:https://www.jianshu.com/p/ffa7ddcda4ab参考:https://developer.aliyun.com/article/1201085skywalking(APM)调用链路分析以及应用监控分析工具Skywalking主要由三大部分组成:agent、collector、webap

行为型模式-策略模式和责任链模式对比

一、区别:目的和问题解决方式:策略模式的主要目的是将一组算法或行为封装成独立的策略对象,并使客户端能够在运行时选择其中一个策略来执行。这种模式通常用于实现相同操作的不同算法或策略之间的切换和替换。责任链模式的主要目的是将请求的发送者和接收者解耦,允许多个对象依次处理请求,直到其中一个对象能够处理请求为止。责任链模式通常

opencv dnn模块 示例(16) 目标检测 object_detection 之 yolov4

博客【opencvdnn模块示例(3)目标检测object_detection(2)YOLOobjectdetection】测试了yolov3及之前系列的模型,有在博客【opencvdnn模块示例(15)opencv4.2版本dnn支持cuda加速(vs2015异常解决)】说明了如何使用dnn模块进行cuda加速推理。

Android 混淆使用及其字典混淆(Proguard)

1.使用背景ProGuard能够通过压缩、优化、混淆、预检等操作,检测并删除未使用的类,字段,方法和属性,分析和优化字节码,使用简短无意义的名称来重命名类,字段和方法。从而使代码更小、更高效、更难进行逆向工程。Android代码混淆,又称Android混淆,是一种AndroidAPP保护技术,用于保护APP不被破解和逆

css知识学习系列(2)-每天10个知识点

目录1.基础知识CSS中的伪元素和实际元素有什么区别?2.动画与过渡CSS中的transition和animation有何区别?在什么情况下使用哪种动画?3.Flexbox在Flexbox布局中,“flex-wrap”属性有什么作用?4.Grid请解释CSS中的网格线(gridlines)和轨道(tracks)是什么?

Docker 容器生命周期:创建、启动、暂停与停止

🌷🍁博主猫头虎带您GotoNewWorld.✨🍁🦄博客首页——猫头虎的博客🎐🐳《面试题大全专栏》文章图文并茂🦕生动形象🦖简单易学!欢迎大家来踩踩~🌺🌊《IDEA开发秘籍专栏》学会IDEA常用操作,工作效率翻倍~💐🌊《100天精通Golang(基础入门篇)》学会Golang语言,畅玩云原生,走遍大

Android设计支持库

本文所有的代码均存于https://github.com/MADMAX110/BitsandPizzas设计支持库(DesignSupportLibrary)是Google在2015年的I/O大会上发布的全新MaterialDesign支持库,在这个support库里面主要包含了8个新的MaterialDesign组件

C#里面的三种定时计时器:Timer

在.NET中有三种计时器:1、System.Windows.Forms命名空间下的Timer控件,它直接继承自Componet。Timer控件只有绑定了Tick事件和设置Enabled=True后才会自动计时,停止计时可以用Stop()方法控制,通过Stop()停止之后,如果想重新计时,可以用Start()方法来启动计

什么是Jmeter?Jmeter使用的原理步骤是什么?

1.1什么是JMeterApacheJMeter是Apache组织开发的基于Java的压力测试工具。用于对软件做压力测试,它最初被设计用于Web应用测试,但后来扩展到其他测试领域。它可以用于测试静态和动态资源,例如静态文件、Java小服务程序、CGI脚本、Java对象、数据库、FTP服务器,等等。JMeter可以用于对

【Linux】分布式版本控制工具git

​​📝个人主页:@Sherry的成长之路🏠学习社区:Sherry的成长之路(个人社区)📖专栏链接:Linux🎯长路漫漫浩浩,万事皆有期待上一篇博客:【Linux】Linux调试器-gdb文章目录一、前言二、版本控制1、何为版本控制2、版本控制工具①集中式版本控制工具②分布式版本控制工具三、代码托管平台四、Lin

【TAPD】实践:TAPD 项目管理配置

目录一、30人以内团队申请免费企业版(1)首次申请试用期3个月(2)进一步申请免费续期二、成员管理三、用户组管理四、项目管理(1)首个项目配置(2)自定义项目模板(3)二次创建项目五、自定义项目模板好处一、30人以内团队申请免费企业版【Tapd】30人以内团队:申请永久免费的Tapd企业版步骤https://gusan

热文推荐