news 2026/3/12 3:26:16

php md5值与数值字符串强弱比较问题

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
php md5值与数值字符串强弱比较问题

经典的PHP类型混淆导致安全漏洞,主要出现在松散比较(==)和弱类型转换中。


1.问题核心

松散比较(==)的问题

// 弱类型比较示例 var_dump(0 == "0"); // true var_dump(0 == "0e123456"); // true (科学计数法) var_dump("0e123" == "0e456"); // true (都被解释为0)

MD5哈希的特性

MD5哈希是32位十六进制字符串:

  • 包含字符:0-9, a-f

  • 格式如:e10adc3949ba59abbe56e057f20f883e

  • 当哈希以0e开头,后跟纯数字时,会被解释为科学计数法的0


2.漏洞原理

科学计数法解释

// PHP将"0e"开头的字符串解释为科学计数法 $hash1 = "0e462097431906509019562988736854"; $hash2 = "0e830400451993494058024219903391"; var_dump($hash1 == 0); // true var_dump($hash1 == $hash2); // true! 漏洞所在 // 因为:0e462... 和 0e830... 都被解释为 0 * 10^...

实际攻击场景

// 1. 密码哈希比较漏洞 $user_input = "QNKCDZO"; // md5: 0e830400451993494058024219903391 $stored_hash = md5($user_input); // 0e830... if ($stored_hash == "0") { // 攻击者猜测 echo "绕过成功!"; } // 2. 两个不同字符串的MD5以0e开头 $a = "240610708"; // md5: 0e462097431906509019562988736854 $b = "QNKCDZO"; // md5: 0e830400451993494058024219903391 if (md5($a) == md5($b)) { // true! echo "哈希碰撞!"; }

3.已知的0e哈希值

// 原始值 => MD5哈希 $vulnerable_pairs = [ "240610708" => "0e462097431906509019562988736854", "QNKCDZO" => "0e830400451993494058024219903391", "aabg7XSs" => "0e087386482136013740957780965295", "aabC9RqS" => "0e041022518165728065344349536299", "s878926199a" => "0e545993274517709034328855841020", "s155964671a" => "0e342768416822451524974117254469", ];

4.漏洞利用场景

场景1:密码重置绕过

// 危险代码示例 $password = $_POST['password']; $hash = md5($password); if ($hash == $stored_hash) { // 使用 == // 攻击者输入"240610708"可能匹配"QNKCDZO"的哈希 }

场景2:身份验证绕过

// 登录验证 function checkPassword($input, $stored_hash) { return md5($input) == $stored_hash; // 漏洞! } // 攻击:如果存储的哈希是0e开头的 // 输入任意0e开头的MD5原始值

场景3:API签名验证

// 签名验证 $sign = $_GET['sign']; // 应该是MD5 $expected = md5($data . $key); if ($sign == $expected) { // 漏洞 // 如果$expected是0e开头,sign=0也可通过 }

5.SHA1的类似问题

// SHA1也存在类似问题 $a = "aaroZmOk"; // sha1: 0e66507019969427134894567494305185566735 $b = "aaK1STfY"; // sha1: 0e76658526655756207688271159624026011393 var_dump(sha1($a) == sha1($b)); // true!

6.CTF常见考点

考点1:哈希扩展攻击

// MD5长度扩展攻击 $secret = "secret"; $data = "data"; $hash = md5($secret . $data); // 攻击者可构造 $secret . $data . padding . appended_data // 而无需知道$secret

考点2:JSON中的哈希比较

$data = json_decode($_POST['data'], true); if ($data['hash'] == md5($data['input'])) { // 如果data.hash=0,且md5(input)以0e开头 }

考点3:数组绕过

// MD5处理数组返回null var_dump(md5([])); // NULL var_dump(md5([]) == NULL); // true

代码审计检查点

  1. 查找松散比较:全局搜索==!=

  2. 查找MD5/SHA1使用md5(sha1(

  3. 检查哈希比较位置

    // 危险模式 if ($_GET['hash'] == md5($data)) {...} if (md5($a) == md5($b)) {...}
  4. 检查JSON/序列化数据:反序列化后可能类型混淆

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/11 19:26:17

基于Altium Designer的电源模块PCB设计完整指南

电源模块PCB设计不是“连通就行”:一位硬件老兵在Altium Designer里踩过的坑与填上的坑 你有没有遇到过这样的情况——原理图画得一丝不苟,网络标号清清楚楚,DRC全绿,Gerber也顺利导出;可板子一上电,纹波就…

作者头像 李华
网站建设 2026/3/9 17:43:37

Linux 多线程,线程分离

1.多线程1.创建多线程示例代码&#xff1a;使用for循环去创建一个一个的线程&#xff0c;让它们去循环的打印出自己的pid和线程tid&#xff0c;创建完线程之后不要忘记去释放掉线程资源&#xff0c;避免内存泄漏。#include <iostream> #include <pthread.h> #inclu…

作者头像 李华
网站建设 2026/3/9 10:33:01

大数据时代半结构化数据的存储性能优化

大数据时代半结构化数据存储性能优化&#xff1a;从原理到实践 摘要 在大数据时代&#xff0c;半结构化数据&#xff08;如JSON、用户行为日志、社交消息&#xff09;已成为数据生态的核心组成部分。然而&#xff0c;传统存储方式&#xff08;如文本文件、行存数据库&#xf…

作者头像 李华
网站建设 2026/3/11 13:42:34

语言模型推理能力的认知负荷评估研究

语言模型推理能力的认知负荷评估研究关键词&#xff1a;语言模型、推理能力、认知负荷评估、评估指标、评估方法摘要&#xff1a;本文围绕语言模型推理能力的认知负荷评估展开深入研究。首先介绍了研究的背景、目的、预期读者、文档结构和相关术语。接着阐述了语言模型推理能力…

作者头像 李华