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弱类型引发的血案的主要内容,如果未能解决你的问题,请参考以下文章

由一段代码引发的血案,md5绕过,foreach,php伪协议

php踩过的那些坑 strpos引发的血案

社会工程学 一则网吧留言板XSS引发的社工恐怖血案

模板链接与前置声明引发的血案

模板链接与前置声明引发的血案

模板链接与前置声明引发的血案