Web 攻防:PHP特性漏洞 - MD5值比较绕过

1. MD5 简介

  • md5() 函数计算字符串的 MD5 散列。

1.1 语法

md5(string,raw) 
  1. string:必需。规定要计算的字符串。
  2. raw:可选。规定十六进制或二进制输出格式:
    • TRUE - 原始 16 字符二进制格式
    • FALSE - 默认。32 字符十六进制数

1.2 返回值

  • 计算成功,返回MD5值。
  • 计算失败,返回false。

1.3用法

<?php
	$str = "Hello";
	echo md5($str);
?>

8b1a9953c4611296a827abf8c47804d7

2. 0e 绕过:科学计数法

2.1 介绍

  • MD5() 遇到公式,会运算公式,在对公式的值计算 md5 的值。
  • 由于 0 和任何数相乘都等于0,所以 0e 开头的任何数MD5都是相同的。

科学计数法,大小等价,0e 和 0E 结果相同。
格式为:aEb = a × 10^b,即 a 乘以 10 的 b 次幂。

2.2 实例

<?php
    var_dump(md5(0));
    var_dump(md5(0e123));
    var_dump(md5(0e456));
?>

输出:

string(32) "cfcd208495d565ef66e7dff9f98764da"
string(32) "cfcd208495d565ef66e7dff9f98764da"
string(32) "cfcd208495d565ef66e7dff9f98764da"

2.3 绕过思路(一)

  • 遇到强、弱比较( md5(a)===md5(b)md5(a)==md5(b) ),可以使用 0e 绕过。
<?php
    var_dump(md5(0e123) === md5(0e456));
    var_dump(md5(0e123) == md5(0e456));
?>

输出:

bool(true)
bool(true)

2.4 绕过思路(二)

  • 遇到弱比较( md5(a)==0 ),可以传入QNKCDZO等绕过。

0e绕过还有一种变体:如果某个字符串的MD5值是0e开头的,在比较时,PHP也会先把它计算成 0,再参与比较。

<?php
	echo md5('QNKCDZO');
	var_dump(md5('QNKCDZO') == 0);
	var_dump(md5('QNKCDZO') === 0);
?>

输出:

0e830400451993494058024219903391
bool(true)
bool(false)

一些MD5值为0e开头的字符串:

QNKCDZO   => 0e830400451993494058024219903391
240610708 => 0e462097431906509019562988736854
s878926199a => 0e545993274517709034328855841020
s155964671a => 0e342768416822451524974117254469
s214587387a => 0e848240448830537924465865611904
s214587387a => 0e848240448830537924465865611904

3. 数组绕过

  • md5() 不能处理数组,数组都返回 null。同时会报一个Warning,不影响执行,不用管。
<?php
	var_dump(md5([1]));
	var_dump(md5([2]));
?>

输出:

Warning: md5() expects parameter 1 to be string, array given in /box/script.php on line 2
NULL

Warning: md5() expects parameter 1 to be string, array given in /box/script.php on line 3
NULL

3.1 绕过思路(一)

  • 遇到强比较(a===b)时,可以使用数组绕过。GET传参时,以 a[]=1&b[]=2 这种形式传递数组。
<?php
    $a = array(1);
    $b = array(2);

    var_dump(md5($a) == md5($b));
    var_dump(md5($a) === md5($b));
?>

输出:

Warning: md5() expects parameter 1 to be string, array given in /box/script.php on line 2

Warning: md5() expects parameter 1 to be string, array given in /box/script.php on line 2
bool(true)

Warning: md5() expects parameter 1 to be string, array given in /box/script.php on line 3

Warning: md5() expects parameter 1 to be string, array given in /box/script.php on line 3
bool(true)

4. 算数运算配合自动类型转换

4.1 运算符绕过

  • md5() 遇到运算符,会先运算,再计算结果的MD5值。
<?php 
    var_dump(md5(1 + 2));
    var_dump(md5(3));
    var_dump(md5(1 * 2));
    var_dump(md5(2));
    var_dump(md5(1 & 1));
    var_dump(md5(true));

输出:

string(32) "eccbc87e4b5ce2fe28308fd9f2a7baf3"
string(32) "eccbc87e4b5ce2fe28308fd9f2a7baf3"
string(32) "c81e728d9d4c2f636f067f89cc14862c"
string(32) "c81e728d9d4c2f636f067f89cc14862c"
string(32) "c4ca4238a0b923820dcc509a6f75849b"
string(32) "c4ca4238a0b923820dcc509a6f75849b"

4.2 运算符 + 类型转换

  • 当字符串与数字类型运算时,会将字符串转换字符串转换成数字类型,再参与运算,最后计算运算结果的MD5值。
<?php 
    var_dump(md5('1' + 2));
    var_dump(md5(3));
    var_dump(md5('1' * 2));
    var_dump(md5(2));

输出:

string(32) "eccbc87e4b5ce2fe28308fd9f2a7baf3"
string(32) "eccbc87e4b5ce2fe28308fd9f2a7baf3"
string(32) "c81e728d9d4c2f636f067f89cc14862c"
string(32) "c81e728d9d4c2f636f067f89cc14862c"

5. 数值类型

  • 虽然 md5() 要求传入字符串,但传入整数或小数也不会报错;数字相同时,数值型和字符串的计算结果是相同的。
<?php 
    var_dump(md5(123));
    var_dump(md5('123'));
    var_dump(md5(10.1));
    var_dump(md5('10.1'));

输出:

string(32) "202cb962ac59075b964b07152d234b70"
string(32) "202cb962ac59075b964b07152d234b70"
string(32) "88d1955de012defb14b2db6f4797ff20"
string(32) "88d1955de012defb14b2db6f4797ff20"
  • 15
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值