php弱类型引发的血案
Posted 无级安全
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了php弱类型引发的血案相关的知识,希望对你有一定的参考价值。
一个php题目代码审计的CTF题目:
来自西电网信杯线下赛
if(intval($password) < 232 && intval($password + 1) > 233))
直接提交password=0x123
就好了
同样的代码 在php7里面测试不成功 这是为什么呢
在PHPstudy里面测试
php5+的版本里面都是成功的
php7+的版本里面都是失败的
修改一下代码
echo '+++++++++++++++++++++++++++++++++++++++++++++++';
echo '<br>';
echo $password;
echo '<br>';
echo intval($password);
echo '<br>';
echo $password+1;
echo '<br>';
echo intval($password + 1);
echo '<br>';
echo '+++++++++++++++++++++++++++++++++++++++++++++++';
测试一下效果:
php7里面 结果如下:
0x1234
0
1
1
php5里面 结果如下:
0x1234
0
4661
4661
猜测:
最开始以为是和这个intval有关系
后来发现intval的结果是一样的,那么问题就出在php5和php7的强制类型转换上,按照上面的结果可以发现,php5在相加之前把0x1234 变成一个十进制数字,而php7则是将0x1234 变成0之后和1相加,那么问题来了,为什么会有这种差异呢 ,去查阅一下文档就知道了
PHP 在变量定义中不需要(或不支持)明确的类型定义;变量类型是根据使用该变量的上下文所决定的。也就是说,如果把一个 string 值赋给变量 $var,$var 就成了一个 string。如果又把一个integer 赋给 $var,那它就成了一个integer。
PHP 7 以前的版本里,如果向八进制数传递了一个非法数字(即 8 或 9),则后面其余数字会被忽略。PHP 7 以后,会产生 Parse Error。
有一个弱类型的通用语句:
$test = $_GET['test'];
echo $test + 1;
//test=1asdf
php5
2
php7
2
查看文档
主要因为php5.6到php7 之后一些特性的变化
https://www.php.net/manual/zh/migration70.incompatible.php
string处理上的调整
十六进制字符串不再被认为是数字
含十六进制字符串不再被认为是数字。例如:
<?php
var_dump("0x123" == "291");
var_dump(is_numeric("0x123"));
var_dump("0xe" + "0x1");
var_dump(substr("foo", "0x1"));
?>
Output of the above example in PHP 5:
bool(true)
bool(true)
int(15)
string(2) "oo"
Output of the above example in PHP 7:
bool(false)
bool(false)
int(0)
Notice: A non well formed numeric value encountered in /tmp/test.php on line 5
string(3) "foo"
这就一目了然了。
我是个菜
以上是关于php弱类型引发的血案的主要内容,如果未能解决你的问题,请参考以下文章