WEB攻防-PHP特性-函数缺陷对比

而使用===必须类型一致,传入y=1.0  / y=1

MD5函数

在 PHP 中,md5() 函数的一个已知缺陷是所谓的“0e”碰撞。这个问题特定于 PHP 的字符串比较机制,而不是 md5() 函数本身。当使用 == 运算符比较两个字符串时,如果字符串以“0e”开头,后面跟着一系列数字,PHP 会将这些字符串解释为科学记数法表示的浮点数,并进行数值比较而不是字符串比较。

//2、MD5函数缺陷绕过 ==弱对比 ===强类型对比
if($_GET['name'] != $_GET['password']){
    if(MD5($_GET['name']) == MD5($_GET['password'])){
        echo $flag;
    }
    echo '?';
}

根据代码逻辑,先判断传入的name和password不相等,再判断name和password讲过md5加密后相等,才会输出flag,否则输出问号

测试用例会用到以下两个字符串

QNKCDZO以MD5加密:0e830400451993494058024219903391

240610708以MD5加密:0e462097431906509019562988736854

正常情况下,如name=test&password=123456,md5加密是不相等的

而当我们使用上面两个用例字符串,md5加密后php会判断相等

当你尝试对数组使用 md5() 函数时,PHP 会发出一个警告,告诉你 md5() 期望的是一个字符串,而你提供的是一个数组。然后,由于无法对数组进行哈希计算,它会返回 null。在使用=比较时,传入两个数组比较,等于null=null返回true

//2、MD5函数缺陷绕过 ==弱对比 ===强类型对比
if($_GET['name'] != $_GET['password']){
    if(MD5($_GET['name']) === MD5($_GET['password'])){
        echo $flag;
    }
    echo '?';
}

上面解释过产生0e碰撞是因为php当作了科学计数比较,而使用 === 进行字符串比较会同时比较值和类型,因此不会受到上述“0e”碰撞问题的影响。

这种情况可以使用传入数组的方式绕过,name[]=1和password[]=2显然满足两者不相等这个条件,而md5不对数组哈希,并报Warning返回null,所以null===null返回true

intval

intval( $var, $base )是 PHP 中的一个内置函数,用于获取变量的整数值,默认是十进制。这个函数尝试将给定的变量转换为整数类型。如果变量是字符串,那么它会解析字符串直到遇到一个非数字字符为止,然后返回该数字。如果字符串开头就是一个非数字字符,那么它会返回 0。

当使用 intval() 函数并设置基数(base)为 0 时,它会根据字符串的内容来尝试猜测其原始的数字基数,并进行相应的转换。这通常用于处理以特定前缀开头的数字字符串,如十六进制(以 “0x” 或 “0X” 开头)或八进制(以 “0” 开头),如果字符串不符合这些模式,它会被尝试解析为十进制数。

注意:如果字符串不是一个有效的八进制或十六进制数(即,如果它包含除了 0-7 之外的字符对于八进制,或者除了 0-9 和 a-f(不区分大小写)之外的字符对于十六进制),那么 intval() 将返回 0。

测试代码:

//3、intval缺陷绕过
$i='666';
$ii=$_GET['n'];
if(intval($ii)==$i){
    echo $flag;
    echo "<br>";
}


$i='666';
$ii=$_GET['n'];
if(intval($ii,0)==$i){
    echo $flag;
}

使用666safs两个都能正常输出 ,都能正常截断后面的字符串,但改为十六进制0x29a则只有base等与0的才能正常识别输出

strpos

strpos() 是 PHP 中的一个字符串函数,用于查找一个子字符串在另一个字符串中首次出现的位置。

strpos(string $haystack, mixed $needle, int $offset = 0): int|false

参数说明:

  • $haystack:必需。要搜索的字符串。
  • $needle:必需。要查找的字符串。如果该参数不是字符串,它会被转换为整数并视为字符的 ASCII 值。
  • $offset:可选。从 $haystack 字符串中的哪个位置开始搜索。

返回值:

  • 如果找到子字符串,则返回其第一次出现的位置的索引(基于0的索引)。
  • 如果没有找到子字符串,则返回 false

测试代码:

//4、对于strpos()函数,我们可以利用换行进行绕过(%0a)
$i='666';
$ii=$_GET['h'];
if(strpos($ii,$i,0)){
    echo $flag;
}

在这段代码中,如果h=666,并不会输出flag,因为strpos返回 666 在 $ii 中首次出现的位置的索引,而666 是字符串的开始,它将返回 0,0在php同样代表false

可以通过换行进行绕过:%0a666

%0a:表示换行

也可以在有必要的条件下使用 数组 返回null

//4、对于strpos()函数,我们可以利用换行进行绕过(%0a)
$i='666';
$ii=$_GET['h'];
if(strpos($ii,$i,0)===null){
    echo $flag;
}

in_array

in_array() 是 PHP 中的一个函数,用于检查一个值是否存在于数组中。它的基本语法如下:

bool in_array ( mixed $search , array $array [, bool $strict = FALSE ] )

参数说明:

  • $search:必需。要搜索的值。
  • $array:必需。要搜索的数组。
  • $strict:可选。如果设置为 TRUE,则还会检查 $search 的类型是否和数组中的元素类型相同。默认为 FALSE。(True类似===,Flase类似==)

返回值:

  • 如果在数组中找到值则返回 TRUE,否则返回 FALSE

测试代码:

//5、in_array第三个参数安全
$whitelist = [1,2,3];
$page=$_GET['i'];
if (in_array($page, $whitelist)) {
    echo "yes";
}

preg_match

preg_match 是 PHP 中的一个函数,用于执行一个正则表达式匹配。如果匹配成功,它会返回 1;如果匹配失败或发生错误,它会返回 0;如果没有进行匹配,它会返回 false

preg_match只能处理字符串,如果不按规定传一个字符串,传一个数组进入,就会使preg_match失效,从而绕过该函数的检测。

测试代码:

if(isset($_GET['num'])){
    $num = $_GET['num'];
    if(preg_match("/[0-9]/", $num)){
        die("no no no!");
    }
    if(intval($num)){
        echo $flag;
    }
}

从代码逻辑看,获取并判断num参数值是否为空,不为空则判断匹配num值中是否有0-9的字符,符合条件执行die输出nonono并杀死程序,否则执行下一个条件intval(num)取整操作,不为flase输出flag

正常输入数字,会杀死程序

当我们传一个数组,就能绕过正则的检测

str_replace

str_replace 是 PHP 中的一个函数,用于在字符串中查找并替换指定的值。它接受一个或多个搜索值(需要被替换的),以及对应的替换值,并在给定的主字符串中进行替换。

缺陷是无法迭代过滤,可以双写绕过

测试代码:

//7、str_replace无法迭代过滤
$sql=$_GET['s'];
$sql=str_replace('select','',$sql);
echo $sql;

这段代码会过滤掉select并替换为空

最后

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数网络安全工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年网络安全全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。

img

img

img

img

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上网络安全知识点!真正的体系化!

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

]

[外链图片转存中…(img-fAJkUJlm-1715546979188)]

[外链图片转存中…(img-RwWzCotj-1715546979188)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上网络安全知识点!真正的体系化!

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值