MD5 绕过第一式:弱比较绕过

news2024/12/23 3:52:47

文章目录

  • 参考
  • 环境
  • MD5
      • 韧性
      • 脆弱性
      • md5()
  • 隐式类型转换
      • 字符串连接
      • 数学运算
      • 布尔判断
      • 相等运算符
  • 科学计数法
      • 科学计数法
      • 前缀 0E 与 0e
  • PHP8 与 PHP 其他版本下字符串转化为数值的具体规则
      • PHP8
          • 数值字符串
          • 优化
      • 其他版本
      • 更为详细的讲解
  • 字符串与字符串的弱比较
  • 字符串与数值的弱比较
  • 0e215962017

参考

项目描述
搜索引擎BingGoogle
AI 大模型文心一言通义千问讯飞星火认知大模型ChatGPT
PHP 手册PHP Manual
wsfgrdghPHP8中字符串与数字的比较更智能
PHP RFC 文档Saner string to number comparisons

环境

项目描述
PHP5.5.05.6.87.0.07.2.57.4.98.0.08.2.9

MD5

MD5(Message Digest Algorithm 5) 是一种常用的哈希函数算法,用于将 任意长度 的数据转换为 固定长度 的哈希值。MD5MD4 算法的改进版本,由 Ronald Rivest1992 年设计并广泛使用。

MD5 算法的 输出结果 是一个 128 位,即长度为 16 字节的哈希值,通常表示为一个 32 位十六进制数

韧性

  1. 不可逆性
    MD5 是一种 单向哈希函数,具有不可逆性的特性。这意味着 无法 通过 已知的 MD5 哈希值 来准确地 确定原始输入数据

  2. 雪崩效应
    MD5 的雪崩效应是指 对输入数据微小改变 会导致 输出哈希值发生巨大变化 的特性。具体来说,即使输入数据只有一个比特位的改变,其计算得到的 MD5 哈希值也会产生 全局性的变化,而不仅仅在修改的位置上体现出差异。

  3. 唯一性
    理想情况下,对于不同的输入数据,MD5 算法生成的 哈希值应该是唯一的。也就是说,不同的输入数据应该产生不同的哈希值。

  4. 快速性
    MD5 是一种快速计算哈希值的算法,适用于 对大量数据进行哈希计算 的场景。

脆弱性

MD5 算法的 哈希输出空间 相对较小,仅有 128 位(仅能容纳 128 位二进制数据),而 输入空间是无限的,这种 输入与输出的不匹配性 导致了哈希碰撞的 可能性。攻击者可以使用 巧妙构造的输入数据,通过精心选择的 碰撞攻击算法,找到 具有相同哈希值的不同输入

  1. 碰撞攻击
    由于 MD5 的 设计特点算法结构,使得攻击者能够使用巧妙构造的输入数据来找到碰撞。碰撞攻击的发现使得 MD5 不再适用于对数据完整性和身份验证进行可靠保护。

  2. 预计算攻击
    由于 MD5 的 计算速度较快,攻击者可以 预先计算常见输入数据的 MD5 哈希值并将其存储在哈希表中。这样,在实际攻击过程中,攻击者可以通过将需要进行破解的哈希值与预先计算的哈希值进行 比对 来实现对哈希值的快速破解。

md5()

在 PHP 中,md5() 函数用于计算给定字符串的 MD5 哈希值,该函数采用一个字符串作为输入并返回其 对应的哈希值

md5(string $string, bool $binary = false): string

其中:

项目描述
$string要计算 MD5 哈希值的字符串。
$binary参数值为一个 布尔类型 的数据,用于指定返回的哈希值是 二进制格式 还是 十六进制格式。默认为 false,表示返回 十六进制格式 的哈希值,如果设置为 true,则返回 二进制格式 的哈希值。

举个栗子

<?php

// 尝试将字符串 Hello World 转换为 MD5 哈希值
var_dump(md5('Hello World'));

// 尝试将字符串 12 转换为 MD5 哈希值
var_dump(md5('12'));

// 当函数 md5() 的输入值为数值时将自动将非数值数据转换为数值数据
var_dump(md5(12));

执行效果

string(32) "b10a8db164e0754105b7a99be72e3fe5"
string(32) "c20ad4d76fe97759aa27a0c99bff6710"
string(32) "c20ad4d76fe97759aa27a0c99bff6710"

注:

md5 函数的 $binary 参数的值设置为 true,此时若将转换结果输出至终端中将出现 乱码 的现象。这是因为 PHP 会 自动尝试二进制数据 转换为 可以显示的文本信息。PHP 会将二进制数据中的 每一个字节 转化为对应的 ASCII 字符,而转化结果中包含了 部分不可打印字符(回车符、空字符等),这些不可见字符将以 乱码 的形式展现。其中,回车符 虽然为 不可见字符,但在文本中起着将文本内容换行的作用。对此,请参考如下示例:

<?php

// 尝试将哈希值以二进制方式输出至终端中
var_dump(md5('Hello World', true));

// 尝试将哈希值的二进制表达转换为十六进制后输出至终端中
var_dump(bin2hex(md5('Hello World', true)));

执行效果

由于二进制数据转化为文本的结果中包含不可见字符 换行符,所以 var_dump(md5('Hello World', true)); 的输出结果中以 两行 的形式呈现。

string(16) "�
��d�uA����.?�"
string(32) "b10a8db164e0754105b7a99be72e3fe5"

隐式类型转换

在 PHP 中,隐式类型转换(Implicit Type Conversion) 是指在某些操作中,PHP 会 自动 将数据 由一种数据类型转换为另一个数据类型,而 无需显式 地编写 类型转换 代码。

PHP 的隐式类型转换会按照一定规则(具体情况具体分析)对操作数进行转换,以使得相关操作 能够正常进行 下去。

字符串连接

在通过使用句点运算符 . 进行字符串连接操作时,PHP 将会尝试将其他数据类型 转换为字符串数据类型。对此,请参考如下示例:

<?php

// 尝试将两个字符串进行拼接
var_dump('Hello ' . 'World');

// 尝试将数值与字符串进行拼接
var_dump('1 + 1 = ' . 2);

// 尝试将两个数值进行拼接
var_dump(1 . 1);

执行效果

string(11) "Hello World"
string(9) "1 + 1 = 2"
string(2) "11"

数学运算

在通过 数学运算符 进行数学运算时,PHP 将会尝试将其他数据类型的数据 转换为数值类型。对此,请参考如下示例:

<?php

// 尝试对布尔值 true 与数值 1 进行减法运算
var_dump(true - 1);

// 尝试对布尔值 true 与 false 进行加法运算
var_dump(true + false);

// 尝试进行字符串之间的乘法运算
var_dump('2' * '150');

// 字符串 100djdj 将被转换为 100
var_dump('100djdj' / 10);

// 字符串 djdj100 将被转换为零
var_dump('djdj100' / 10);

执行效果

int(0)
int(1)
int(300)
int(10)
int(0)

布尔判断

在需要使用布尔值的位置,PHP 将尝试将非布尔值的数据 转换为布尔类型的数据。对此,请参考如下示例:

<?php

// 尝试将空字符串转换为布尔值
if(''){
    print('Hello World' . "\n");
}

// 尝试将字符串 Hello World 转换为布尔值
if('Hello World'){
    print('Hello China' . "\n");
}

// 尝试将数值 999 转换为布尔值
if(999){
    print('久久久' . "\n");
}

执行效果

Hello China
久久久

相等运算符

在 PHP 中存在两种相等运算符,即弱类型相等运算符 == 和强类型相等运算符 ===,两者都可以用于判断两个操作数是否相等,但存在一些区别。

两者的 区别 在于,弱类型相等运算符 在对操作数进行比较之前,将 自动 进行类型转换以 使两者所属的数据类型相同。而 强类型相等运算符 在进行比较时,要求两个值的 类型 都必须 完全相同不进行类型转换。对此,请参考如下示例:

<?php

// 在通过弱类型比较运算符对数值与字符串进
// 行比较时,PHP 优先将字符串转换为数值。

// 由于两者转换为同一类型后,值相同,
// 故将返回 true。
var_dump('123' == 123);

// 由于两者的数据类型及值均不相同,故
// 将返沪 false。
var_dump('123' === 123);

执行效果

bool(true)
bool(false)

科学计数法

科学计数法

在 PHP 中,eE 均表示 科学计数法(Scientific Notation)。科学计数法由 基数指数 两部分组成,常用于 表示非常大或非常小的数值。

在科学计数法中,基数 通常 是一个浮点数,介于 110 之间,而指数是一个整数,表示要将基数乘以 10 的多少次方。基数与指数之间以字符 eE 进行分隔。

举个栗子

<?php

// 3.78 * 10 ^ 3
var_dump(3.78e3);

// 3 * 10 ^ -1
var_dump(3E-1);

执行效果

float(3780)
float(0.3)

前缀 0E 与 0e

零的任何指数次幂都为零,因此以 0E0e 为前缀的科学计数法表示的数值的结果都将为数值零。对此,请参考如下示例:

<?php

var_dump(0e3280);
var_dump((float)'0e30284083');
var_dump((float)'0esjlfjsld');

执行效果

float(0)
float(0)
float(0)

PHP8 与 PHP 其他版本下字符串转化为数值的具体规则

PHP8

数值字符串

数值字符串 是指一个包含数字字符的字符串,数值字符串可以用于直接表示一个数值。

举个栗子

"123"
"-42"
"+384"

"3.14"
"-0.5"
"0.0000"
"00000000.0000"

"2.5e3"
"1.2e-2"
"+42.0E0"

"0004746"
"0305940"
"       484748      "
" 4847      "
"               3847"

注:

  1. 包含 代表其他进制(非十进制)数值的符号 的字符串不能被称为数值字符串(数学中通常不使用这些符号来标识其他进制的数值),如 0x1F0b10101 等字符串。在 PHP 中,八进制数值 通过 前导零 来表示,但在 数值字符串中,前导零将 被视为普通数字,不具备标识八进制数值的功能
  2. 如果存在将其他进制(非十进制)的字符串转化为数值的需求,可以考虑使用 intval() 等函数进行显式类型转化。
  3. 包含空格等空白字符的字符串 为什么也可以是数值字符串?你可以理解为 一眼望去是数值的就是数值字符串😔。
优化

PHP8 仍旧保留了隐式类型转换 这一特性,但在字符串与数值的弱比较方面做出了优化。在 字符串与数值的弱比较 过程中,PHP 将 依据字符串的不同 选择 将字符串转换为数值将数值转换为字符串 后再进行比较。具体规则如下:

  1. 若字符串 符合数值字符串的定义,则 PHP 尝试 将字符串转化为数值 后再进行比较。
  2. 若字符串 不符合数值字符串的定义,则 PHP 尝试 将数值转化为字符串 后再进行比较。

其他版本

在 PHP 的 隐式类型转换过程 中,字符串转化为数值的具体规则如下:

  1. 若字符串的 首个字符不为数字且不为空格等空白字符,则将该字符串转化为零。
  2. 若字符串的 首个字符不为数字但为空格等空白字符,则尝试读取其余字符,将遇到数字前的所有空白字符均转化为零,将遇到数字后的所有空白字符视为非数字字符;在遇到非数字字符时停止对字符串的读取并将已读取字符转化为数值
  3. 若字符串的 首个字符为数字,则尝试读取其余字符,在遇到非数字字符(除符合科学计数法格式的字符 e 或 E外)时停止对字符串的读取并将已读取字符转化为数值

举个栗子

目标字符串转化结果
Hello1230
1Hell2o31
0x8aHello1230
9.384Hello9.384
0008743738Hello9488743738
1.223e100122.3

注:

PHP 在执行字符串到数值的隐式类型转换过程,均 以十进制表示法 为依据。同上述例子一般,0x8aHello123 中的 0x8a 并不会被识别为十六进制数,由于十进制中不存在 x,故 PHP 在识别到字符 x 时就将立即停止读取并将读取到的字符串 0 转化为数值,故最终的转化结果为零。

更为详细的讲解

如果对 PHP8 与 PHP 其他版本下字符串转化为数值的规则希望能有更为详细的讲解,可以参考我的另一篇博客 PHP 变动:PHP 8 版本下字符串与数值的弱比较

字符串与字符串的弱比较

在 PHP 中,若弱比较运算符的两个操作数 均为字符串。PHP 将 依据不同 PHP 版本下字符串转化为数值的规则 将两个操作数转化为数值。

在 MD5 的绕过过程中,常常使用 MD5 加密结果符合如下格式 的字符串:

前缀为 `0e` 或 `0E` (后续格式说明仅针对 PHP 8 及以上版本)且后续字符均为数字的字符串。

byGcY0e215962017 就是符合这一规则的字符串。

攻击目标中若存在 包含 MD5 解密的弱比较环节,我们便可以使用这么一些字符串尝试 使得判断结果朝符合我们的预期

举个栗子

<?php


# 变量 $user_input 中存放着用户的输入
$user_input = '0e215962017';

# != 为弱类型不等运算符,强类型不等运算符为 !==
if (md5('byGcY') != md5($user_input)) {
    print("Come to my city" . "\n");
} elseif ("Hack Me" == md5($user_input)) {
    print("Be my king" . "\n");
} else {
    print("Look at my invincible defense" . "\n");
}


# byGcY 与 0e215962017 的 MD5
# 加密结果均以 0e 为前缀,且 md5() 函数的返回
# 结果的数据类型为字符串,故将发生字符串到数值的
# 隐式类型转化。
var_dump(md5('byGcY'));
var_dump(md5($user_input));

执行效果

Look at my invincible defense
string(32) "0e591948146966052067035298880982"
string(32) "0e291242476940776845150308577824"

注:

在 PHP 中,若弱类型比较运算符的操作数 均为字符串当且仅当字符串操作数在当前 PHP 版本中均能够转化为数值时,PHP 才会将其转化为数值进行比较。否则,按照字符串的比较规则进行比较。

字符串与数值的弱比较

在 PHP 中,若弱比较运算符的两个操作数分别为 数值字符串。PHP 将 依据不同 PHP 版本的转化规则 将两个操作数中的一个转化为另一种数据类型。

字符串与字符串的弱比较一般,当攻击目标中存在 包含 MD5 解密的弱比较环节,可以通过构造字符串利用弱比较规则 使得判断结果朝符合我们的预期

举个栗子

<?php


$user_input = '0e215962017';
$hello = 'Hello WOrld';

if (0.000 != md5($user_input)) {
    print("Come to my city" . "\n");
} elseif (68 == md5($hello)) {
    print("Be my king" . "\n");
} else {
    print("Look at my invincible defense" . "\n");
}

# 由于 $hello 中的 MD5 加密结果以数字 68 开头,在
# PHP8 以下版本中,该字符串将被转化为数值 68。
var_dump(md5($hello));

执行效果

上述示例在 PHP8 以下版本 中的运行结果为:

Be my king
string(32) "68c131c6982a0bbbbae667624d8eca7d"

上述示例在 PHP8 版本 中的运行结果为:

Look at my invincible defense
string(32) "68c131c6982a0bbbbae667624d8eca7d"

0e215962017

0e215962017 这个字符串比较特殊,因为 该字符串及该字符串的 MD5 加密结果均以 0e 为前缀。在参加有关 MD5 绕过的安全竞赛时,你可能将遇到与如下类似的题目:

<?php


$user_input = '0e215962017';

if ($user_input == md5($user_input)) {
    print("Come to my city,Be my king" . "\n");
} else {
    print("Look at my invincible defense" . "\n");
}

var_dump(md5($user_input));

执行结果

Come to my city,Be my king
string(32) "0e291242476940776845150308577824"

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1044653.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

git查看自己所在的分支

很多时候可能大家不太想切换其他工具&#xff0c;又不知道自己是否在自己需要操作的分支 可以直接终端执行 git branch此时 他就会在终端将所有的本地分支输出出来 并特殊标注自己所在的分支 这样我们就可以进一步去做自己想要做的操作了 当然 随着各种编辑器的发展 这个命令…

视频剪辑软件哪个好? 2023年最新功能解析

如今聊到视频的话题&#xff0c;大家可能都注意到近年来火爆的抖音短视频。从图片到动画&#xff0c;从动画到视频。时代在发展&#xff0c;技术在更新。到了近几年小视频也火了&#xff0c;其实不乏缺有视频剪辑软件的功劳。现在不少朋友在业余时间都喜欢剪辑视频来丰富自己的…

支撑电动汽车规模化,特来电智能化升级群充产品

9月26日&#xff0c;中国领先的充电网生态运营商特来电重磅发布智能群充4.0产品&#xff0c;标志着特来电群充产品体系进一步升级&#xff0c;充电行业迎来更高质量、更高性能的设备与系统&#xff0c;充电网基础设施将更好地支撑大规模电动汽车的发展。 群充技术路线引领充电…

音频处理基础的一些笔记碎片

感谢 B 站上关于 EQ 扫盲视频分享 &#x1f50a;声音变好听-让均衡器改变你的音色|均衡器怎么调&#xff1f;&#xff08;adobe audition 2020基础教程&#xff09; 简要内容 a. 人耳能够听到的频率 20HZ-20000HZ&#xff1b; b. 人耳普遍认为低于 80HZ 是噪声&#xff1b; c. …

华为智能企业上网行为管理安全解决方案(1)

华为智能企业上网行为管理安全解决方案&#xff08;1&#xff09; 课程地址方案背景需求分析企业上网行为概述企业上网行为安全风险分析企业上网行为管理需求分析 方案设计组网架构设备选型设备简介行为管理要点分析方案功能概述 课程地址 本方案相关课程资源已在华为O3社区发…

MQTT协议知识梳理,看完你就懂了!

一.MQTT简介 MQTT是基于TCP/IP协议栈构建的异步通信消息协议&#xff0c;是一种轻量级的发布/订阅信息传输协议。MQTT在时间和空间上&#xff0c;将消息发送者与接受者分离&#xff0c;可以在不可靠的网络环境中进行扩展。 适用于设备硬件存储空间有限或网络带宽有限的场景。物…

SpringBoot 员工管理---通用模板 ---苍穹外卖day2

感谢点击 希望你有所收获! 目录 1.新增员工 需求分析:根据页面原型进行业务分析 接口设计 数据库设计 代码开发 功能测试 如何在接口文档中统一添加JWT令牌 ​ 获取当前登录员工的ID 2.员工分页查询 需求分析 代码开发 如何将日期格式化 ​3.启用禁用员工 1.新…

软件设计模式——工厂模式

摘要 本博文主要介绍软件设计模式中工厂模式&#xff0c;其中工厂设计模式的扩展为简单工厂(Simple Factory)、工厂方法(Factory Method)、抽象工厂(Abstract Factory)三种。 一、简单工厂(Simple Factory) 主要分析设计模式 - 简单工厂(Simple Factory)&#xff0c;它把实例…

day07_方法

今日内容 零、 复习昨日 一、作业讲解 二、方法[重点] 零、 复习昨日 一、作业讲解 package com.qf.homework;import java.util.Scanner;/*** desc*/ public class Homework {public static void main(String[] args) {/*** --------------------* 边写边测试* 以结果倒推* …

HTML详细基础(二)文件路径

目录 一.相对路径 二.绝对路径 三.超链接标签 四.锚点链接 首先&#xff0c;扩展一些HTML执行的原理&#xff1a; htmL(hypertext markup Language) 是一种规范&#xff08;或者说是一种标准&#xff09;&#xff0c;它通过标记符&#xff08;tag&#xff09;来标记要显示…

D课堂 | 什么是DNS?DNS是怎么运作的?

想象一下&#xff0c;你在一个陌生的城市&#xff0c;想去一家餐厅品尝美食。你知道这家餐厅的名字&#xff0c;但却不知道它的具体位置。 这时&#xff0c;你可能会打开手机地图&#xff0c;输入餐厅的名字&#xff0c;然后地图会告诉你如何到达那里。 在互联网世界里&#xf…

向量数据库库Milvus Cloud2.3 的QA问题

1. Milvus 从 2.2.x 升级至 2.3.x 的最大变化是什么? 如果用一句话来总结,那就是使用的场景更加丰富了。具体可以从两个方面来体现,即部署环境和用户的使用感。 例如,从部署环境来看,Milvus 原来只支持 X86 架构的 CPU,版本升级后,不仅可以支持 GPU,还能够支持 ARM 架构…

二叉树MFC实现

设有一颗二叉树如下&#xff1b; 这似乎是一颗经常用作示例的二叉树&#xff1b; 对树进行遍历的结果是&#xff0c; 先序为&#xff1a;3、2、2、3、8、6、5、4&#xff0c; 中序为&#xff1a;2、2、3、3、4、5、6、8&#xff0c; 后序为2、3、2、4、5、6、8、3&#xff1b…

Kubernetes 学习总结(38)—— Kubernetes 与云原生的联系

一、什么是云原生&#xff1f; 伴随着云计算的浪潮&#xff0c;云原生概念也应运而生&#xff0c;而且火得一塌糊涂&#xff0c;大家经常说云原生&#xff0c;却很少有人告诉你到底什么是云原生&#xff0c;云原生可以理解为“云”“原生”&#xff0c;Cloud 可以理解为应用程…

深入浅出DAX:数据分析

深入浅出DAX&#xff1a;数据分析 01、区间分析 1. 数据区间分析 在Power BI中&#xff0c;选择“主页”→“输入数据”&#xff0c;创建“区间辅助表”&#xff0c;如图1所示。 ■ 图1 区间辅助表 创建度量值M.区间次数&#xff0c;表达式如下&#xff1a; M.区间次数 VA…

POJ 2991 Crane 线段树

一、题目大意 我们有一台起重机的机械臂&#xff0c;它由多个节相连组成&#xff0c;如下所示。 起初的时候&#xff0c;所有的节之间的角度都是180度&#xff0c;是竖直的&#xff0c;我们可以扭转其中任意两个节的角度&#xff0c;每一次移动后题目需要输出题目最后一个点相…

干货 | 工商业用户负荷分析与预测系统项目

以下内容整理自2023年夏季学期大数据能力提升项目《大数据实践课》同学们所做的期末答辩汇报。 我们将从六个方面进行展示。 第一部分是项目背景与需求分析。在“双碳”目标的大背景下&#xff0c;能源电力行业面临着深刻的变革&#xff0c;负荷预测作用也更加突出。虚拟电厂由…

蓝牙无线IP网络多功能多媒体音柱带遥控

SV-29810T-蓝牙无线IP网络多功能多媒体音柱带遥控 蓝牙无线IP网络多功能多媒体音柱SV-29810T产品用途&#xff1a; ◆室外室内豪华型防水音柱式一体化网络音频解码扬声器&#xff0c;用于广播分区音频解码、声音还原作用◆应用场地如火车站、地铁、教堂、工厂、仓库、公园停车…

lv5 嵌入式开发-7 有名管道和无名管道

目录 1 进程间通信介绍 2 无名管道 2.1 无名管道特点 ​编辑 2.2 读无名管道 2.3 写无名管道 3 有名管道 3.1 有名管道特点 3.2 写有名管道 3.3 读有名管道 掌握&#xff1a;进程间通信方式介绍、无名管道特点、无名管道创建、无名管道读写特性&#xff1b;有名管道…

【面试题】——JavaIO篇(23题)

文章目录 1.什么是Java IO&#xff1f;2.如何从数据传输方式理解IO流&#xff1f;3.Java IO设计上使用了什么设计模式&#xff1f;4.什么是Java NIO&#xff1f;5.什么时BIO?6.什么是AIO?7.你怎么理解同步IO和异步IO?8.你怎么理解阻塞IO和非阻塞IO?9.IO中的输入流和输出流有…