CTF的php内置函数bypass技巧
in_array
in_array函数用来判断一个值是否在一组数组中
总共三个参数,如果最后一个type为true,则为严格类型校验 类似于===
如果没有type=true则为弱类型匹配,此时存在类型强制转换导致绕过校验的风险
比如:
$whitelist = ["hit"]; if (in_array($page, $whitelist)) { echo "yes"; return true;
以上就是验证这个page是否满足这个hit,那么传入page=hit#即可进行绕过
经过测试,目前只发现#可以绕过这个字符串in_array校验的
下面是数字型的绕过
$whitelist = [1,2,3]; if (in_array($page, $whitelist)) { echo "yes"; return true;
可以传入page=1wff 1; 1,(前面是数字后面是字符串或者符号 进行绕过)审计代码时,留意可能存在注入点
include
include("index.php?../../../../../etc/passwd");
这样可以绕过文件包含限制,达到任意文件包含的目的
is_numeric
<!--
~~~post money and password~~~
if (isset($_POST['password'])) {
$password = $_POST['password'];
if (is_numeric($password)) {
echo "password can't be number</br>";
}elseif ($password == 404) {
echo "Password Right!</br>";
}
}
-->
如果遇上情况,传入:password=404%00即可
此函数还可以导致sql注入,传入1' or '1的hash即可
is_numeric('%201') 返回true
s_numeric('%0a1') 返回true
php中的strcmp漏洞
说明:
参数 str1第一个字符串。str2第二个字符串。如果 str1 小于 str2 返回 < 0; 如果 str1 大于 str2 返回 > 0;如果两者相等,返回 0。
可知,传入的期望类型是字符串类型的数据,但是如果我们传入非字符串类型的数据的时候,这个函数将会有怎么样的行为呢?实际上,当这个函数接受到了不符合的类型,这个函数将发生错误,但是在5.3之前的php中,显示了报错的警告信息后,将return 0 ,传入money[]=1 即可绕过。
也就是虽然报了错,但却判定其相等
php://input 如何post提交和data://text/plain;base64,d2VsY29tZSB0byB0aGUgempjdGY= 进行绕过file_get_contents()
escapeshellarg/escapeshellcmd([BUUCTF 2018]Online Tool 讲解了这个漏洞)
详细分析一下: 传入的参数是:172.17.0.2' -v -d a=1 经过escapeshellarg处理后变成了'172.17.0.2'\'' -v -d a=1',即先对单引号转义,再用单引号将左右两部分括起来从而起到连接的作用。 经过escapeshellcmd处理后变成'172.17.0.2'\\'' -v -d a=1\',这是因为escapeshellcmd对\以及最后那个不配对儿的引号进行了转义:http://php.net/manual/zh/function.escapeshellcmd.php 最后执行的命令是curl '172.17.0.2'\\'' -v -d a=1\',由于中间的\\被解释为\而不再是转义字符,所以后面的'没有被转义,与再后面的'配对儿成了一个空白连接符。所以可以简化为curl 172.17.0.2\ -v -d a=1',即向172.17.0.2\发起请求,POST 数据为a=1'。 回到mail中,我们的 payload 最终在执行时变成了'-fa'\\''\( -OQueueDirectory=/tmp -X/var/www/html/test.php \)@a.com\',分割后就是-fa\(、-OQueueDirectory=/tmp、-X/var/www/html/test.php、)@a.com',最终的参数就是这样被注入的。