那些世人皆知的php-Trick(上)
MD5
1.PHP弱比较
$_GET['a'] != $_GET['b']
&&
MD5($_GET['a']) == MD5($_GET['b'])
php中 ==
只是判断值是否相等,而不会判断数据类型是否相同,如果类型不同先转换为相同类型再进行比较而PHP在处理哈希字符串时后,会把0E
开头的哈希值解释为0。所以如果两个值通过md5后值都已0E
开头,就会相等。
md5(str)
QNKCDZO
240610708
s878926199a
s155964671a
s214587387a
s214587387a
sha1(str)
sha1后以0E开头
sha1(‘aaroZmOk’)
sha1(‘aaK1STfY’)
sha1(‘aaO8zKZF’)
sha1(‘aa3OFF9m’)
2.PHP特性
$_POST['a']!==$_POST['b']
&&
md5($_POST['a'])===md5($_POST['b'])
php中md5和sha1函数都无法处理数组,会返回NULL
3.md5碰撞
(string)$_POST['a']!==(string)$_POST['b']
&&
md5($_POST['a'])===md5($_POST['b'])
}
字符串类型,强相等,且MD5相等
a=M%C9h%FF%0E%E3%5C%20%95r%D4w%7Br%15%87%D3o%A7%B2%1B%DCV%B7J%3D%C0x%3E%7B%95%18%AF%BF%A2%00%A8%28K%F3n%8EKU%B3_Bu%93%D8Igm%A0%D1U%5D%83%60%FB_%07%FE%A2
b=M%C9h%FF%0E%E3%5C%20%95r%D4w%7Br%15%87%D3o%A7%B2%1B%DCV%B7J%3D%C0x%3E%7B%95%18%AF%BF%A2%02%A8%28K%F3n%8EKU%B3_Bu%93%D8Igm%A0%D1%D5%5D%83%60%FB_%07%FE%A2
相等即可。
ereg函数漏洞
新版本去除了,官网没查到,适用低版本php
<?php
if(ereg("^[a-zA-Z0-9]+$",$_GET['pass'])===FALSE){
echo "yes";
}
?>
// ?pass = %00123
ereg() 只能处理字符串,遇到数组会返回null ,可以用 数组
绕过
也可以使用NULL截断
extract()变量覆盖
extract(),它的主要作用是将数组展开,键名作为变量名,元素值为变量值,前后端处理参数很方便。
触发条件:函数在指定参数为EXTR_OVERWRITE或者没有指定函数
<?php
$auth = '0';
$b =array("auth"=>'1');
// 这里可以覆盖$auth的变量值
extract($b);
echo ($auth);
?>
//输出 1
is_numeric
判断变量是否为数字
参考如下即可
<?php
echo is_numeric(233333); # 1
echo is_numeric('233333'); # 1
echo is_numeric(0x233333); # 1
echo is_numeric('0x233333'); # 1
echo is_numeric('233333abc'); # 0
?>
parse_str()
功能:parse_str() 函数用于把查询字符串解析到变量中,如果没有array 参数,则由该函数设置的变量将覆盖已存在的同名变量。 极度不建议 在没有 array参数的情况下使用此函数,并且在 PHP 7.2 中将废弃不设置参数的行为
。此函数没有返回值
<?php
$name="Jenny";
parse_str("name=Peter&age=43");
echo $name;
?>
#新版本必须要两个参数参数,不然报错
7.2以前版本测试成功,实现变量覆盖
弱类型比较
主要是使用 ==
时,如果一个数值和一个字符串比较,那么会将字符串转换为数值。
参考网上集合
<?php
echo 0 == 'a' ;// a 转换为数字为 0 此处php版本要大于7.0 重点注意
// 0x 开头会被当成16进制54975581388的16进制为 0xccccccccc
// 十六进制与整数,被转换为同一进制比较
'0xccccccccc' == '54975581388' ; //php要小于7.0
// 字符串在与数字比较前会自动转换为数字,如果不能转换为数字会变成0
1 == '1';
1 == '01';
10 == '1e1';
'100' == '1e2' ;
// 十六进制数与带空格十六进制数,被转换为十六进制整数
'0xABCdef' == ' 0xABCdef'; //版本要小于7.0
echo '0010e2' == '1e3';
// 0e 开头会被当成数字,又是等于 0*10^xxx=0
// 如果 md5 是以 0e 开头,在做比较的时候,可以用这种方法绕过
'0e509367213418206700842008763514' == '0e481036490867661113260034900752';
'0e481036490867661113260034900752' == '0' ;
var_dump(md5('240610708') == md5('QNKCDZO'));
var_dump(md5('aabg7XSs') == md5('aabC9RqS'));
var_dump(sha1('aaroZmOk') == sha1('aaK1STfY'));
var_dump(sha1('aaO8zKZF') == sha1('aa3OFF9m'));
?>
unset
用来销毁指定的变量
场景:销毁变量,实现变量覆盖,或者变量删除
intval()
会将从字符串的开始进行转换知道遇到一个非数字的字符
var_dump(intval('2')) //2
var_dump(intval('3abcd')) //3
var_dump(intval('abcd')) //0
in_array()
搜索数组中是否存在指定的值。
$array=[0,1,2,'3'];
var_dump(in_array('abc', $array)); //true
var_dump(in_array('1bc', $array)); //true
# 仍然是PHP在数据自动转换的过程中的问题
参考
本文来自博客园,作者:kzd的前沿思考,转载请注明原文链接:https://www.cnblogs.com/Fram3/p/15675530.html