php是世界上最好的语言,所以php自身的安全问题也是web安全的一个方面。由于其自身弱类型语言的特性以及内置函数对于传入参数的松散处理,所以会带来很多的问题,这里将进行简要介绍。
弱类型语言对变量的数据类型没有限制,可以在人很适合将变量赋值给人以的其他类型变量,同时变量可以转换成任意其他类型的数据。
比较操作符
=== 在进行比较的时候,会先判断两种字符串的类型是否相等,再比较。
== 在进行比较的时候,会先将字符串类型转化成相同,再比较。
在$a==$b的比较中
$a=' ';$b=null //true
$a=null;$b=true //true
$a=0;$b='0' //true
$a=0;$b='abcdef ' //true 而0===’abcdef ' false
Hash比较缺陷
"0e132456789"=="0e7124511451155" //true"0e123456abc"=="0e1dddada" //false"0e1abc"=="0" //true
在ctf中遇到的题目
<?php
if(isset($_GET['Username']) && isset($_GET['password']))
if (!ctype_alpha($Username)) {echo”用户名不是字符串“;}
if (!is_numeric($password) ) {echo”密码不是数字“;}
{if (md5($Username) == md5($password))
{echo "flag{hh_xxx_}"}
else{echo "请重试“;}
}
else{echo "请重试“;}
?>
该题目是让传入用户名和密码,用户名为字符串,密码为数值型,并且两个变量的md5值相等。因此便可以通过hash弱类型比较绕过校验。
strcmp漏洞绕过 php --version <5.3
strcmp是比较两个字符串,如果str1< str2 则返回< 0,如果str1大于str2返回>0, 如果两者相等返回0。
<?php
$password="***************"
if(isset($_POST['passwd'])){
if (strcmp($_POST['passwd'], $password) == 0) {
echo "Right!!!login success";n
exit(); } else {
echo "Wrong password..";
}
?>
题目让我们传入$passwd的值并且要与$password相等,但是我们不知道$password的值,strcmp期望传入字符串,但是如果传入数组将会怎么样呢,我们尝试传入数组passwd[]='flag',函数接受了不符合的类型,将会发生错误,但会判断其相等。
json绕过
<?php
if (isset($_POST['item']))
{
$message = json_decode($_POST['item']);
$key ="*********";
if ($item->key == $key) { echo "flag";
}
else
{
echo "fail";
}
}
else
{
echo "~~~~";
}
?>
json_decode函数解密成一个数组,判断数组中的值是否等于$key的值,但$key的值我们不知道,但可以通过==弱类型比较绕过。payload item={"key":0} (json不懂得小伙伴请自行百度)
条件语句的松散判断
请见下面例子
<?php
if (isset($_GET['which']))
{
$which = $_GET['which'];
switch ($which)
{
case 0:
case 1:
case 2:
require_once $which.'.php';
break;
default:
echo GWF_HTML::error('PHP-0817', 'Hacker NoNoNo!', false);
break;
}
?>
当$which='2flag'是,进行强制转换后$which变为2将会执行2.php。
in_array/array_search
$array=[0,1,2,'3'];
var_dump(in_array('abc', $array)); //true
var_dump(array_search("1admin",$a)); // true
in_array和array_search会对类型进行强制转换,并且是==进行比较,所以可以绕过。
写的仓促,如有不对的地方请大家多多指正。