MD5 值比较绕过
1. MD5 简介
- md5() 函数计算字符串的 MD5 散列。
1.1 语法
md5(string,raw)
- string:必需。规定要计算的字符串。
- 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"