Command Injection

技术文章 1年前 (2020) 完美者
852 0

标签:source   输出内容   调用   漏洞原理   void   保存   用户   函数的参数   code   

漏洞原理

命令注入(Command Injection),对一些函数的参数没有做过滤或过滤不严导致的,可以执行系统或者应用指令(CMD命令或者 bash 命令)的一种注入攻击手段。

PHP常见的执行系统命令的函数

system()
passthru()
exec()
shell_exec()
popen()
proc_open()
pcntl_exec()

system()

string system ( string $command [, int &$return_var ] )

$command为执行的命令,&return_var可选,用来存放命令执行后的状态码。
system()函数执行有回显,将执行结果输出到页面上。

<?php
    system("whoami");
?>

passthru()

void passthru ( string $command [, int &$return_var ] )

和system函数类似,$command为执行的命令,&return_var可选,用来存放命令执行后的状态码。
执行有回显,将执行结果输出到页面上。

<?php
    passthru("whoami");
?>

exec()

string exec ( string $command [, array &$output [, int &$return_var ]] )

$command是要执行的命令,$output是获得执行命令输出的每一行字符串,$return_var用来保存命令执行的状态码(检测成功或失败)。
exec()函数执行无回显,默认返回最后一行结果。

<?php
    echo exec("whoami");
?>
<?php  
    $test = "ipconfig";   
    exec($test,$array);      
    print_r($array);  
?> 

shell_exec()

string shell_exec( string &command)

&command是要执行的命令,shell_exec()函数默认无回显,通过 echo 可将执行结果输出到页面。

<?php
    echo shell_exec("whoami");
?>

反引号`

shell_exec() 函数实际上仅是反撇号 (`) 操作符的变体,当禁用shell_exec时,` 也不可执行。
在php中称之为执行运算符,PHP将尝试将反引号中的内容作为shell命令来执行,并将其输出信息返回。

<?php
    echo `whoami`;
?>

popen()

resource popen ( string $command , string $mode )

函数需要两个参数,一个是执行的命令command,另外一个是指针文件的连接模式mode,有r和w代表读和写。
函数不会直接返回执行结果,而是返回一个文件指针,但是命令已经执行。
popen()打开一个指向进程的管道,该进程由派生给定的command命令执行而产生。
返回一个和fopen()所返回的相同的文件指针,只不过它是单向的(只能用于读或写)并且必须用pclose()来关闭。
此指针可以用于fgets(),fgetss()和 fwrite()。

<?php popen( ‘whoami >> c:/1.txt‘, ‘r‘ ); ?>
<?php  
    $test = "ls /tmp/test";  
    $fp = popen($test,"r");  //popen打一个进程通道  
      
    while (!feof($fp)) {      //从通道里面取得东西  
     $out = fgets($fp, 4096);  
     echo  $out;         //打印出来  
    }  
    pclose($fp);  
?> 

proc_open()

resource proc_open ( 
string $cmd , 
array $descriptorspec , 
array &$pipes [, string $cwd [, array $env [, array $other_options ]]] 
)

与Popen函数类似,但是可以提供双向管道。

<?php  
$test = "ipconfig";  
$array =   array(  
array("pipe","r"),   //标准输入  
array("pipe","w"),   //标准输出内容  
array("pipe","w")    //标准输出错误  
);  
      
$fp = proc_open($test,$array,$pipes);   //打开一个进程通道  
echo stream_get_contents($pipes[1]);    //为什么是$pipes[1],因为1是输出内容  
proc_close($fp);  
?> 

pcntl_exec()

void pcntl_exec ( string $path [, array $args [, array $envs ]] )

path是可执行二进制文件路径或一个在文件第一行指定了 一个可执行文件路径标头的脚本;
args是一个要传递给程序的参数的字符串数组;
pcntl是linux下的一个扩展,需要额外安装,可以支持 php 的多线程操作;
pcntl_exec函数的作用是在当前进程空间执行指定程序,版本要求:PHP>4.2.0。

<?php
pcntl_exec ( "/bin/bash" , array("whoami"));
?>

对这些危险函数,可以在php.ini中禁用,进行安全加固

技术图片

漏洞判断方法

1.判断是否执行系统命令
2.判断函数或函数的参数是否可
3.判断是否拼接注入命令

命令拼接运算符

windows和unix都可以使用

command 1 && command 2 #先执行命令1,成功后再执行命令2
command 1 & command 2 #先执行命令1,不论成功都执行命令2
command 1 | command 2 #先执行命令1,将1的结果作为2的输入,只打印2的结果
command 1 || command 2 #先执行命令1,1执行失败再执行命令2,直到有命令执行成功

仅unix可以使用

;#如果每个命令都被一个分号(;)所分隔,那么命令会连续地执行下去
Newline (0x0a or \n)

在基于Unix的系统上,您还可以使用反引号或美元字符在原始命令中内嵌执行注入命令:

` injected command ` #反引号
$( injected command ) #美元符号

有时,您控制的输入会出现在原始命令的引号中。在这种情况下,需要先使用引号终止上下文(使用“或”),然后再使用适当的外壳元字符来插入新命令.

漏洞防御

不要从应用程序层代码中调用OS命令,使用更安全的平台API来实现所需功能的替代方法。
如果认为无法通过用户提供的输入调出OS命令,则必须执行强大的输入验证,有效验证的一些示例包括:
1.根据允许值的白名单进行验证。
2.验证输入是否为数字。
3.验证输入仅包含字母数字字符,不包含其他语法或空格。

参考链接
https://www.cnblogs.com/hiccup/p/5423976.html
https://zhuanlan.zhihu.com/p/161165318
https://blog.csdn.net/Auuuuuuuu/article/details/88778852
https://blog.csdn.net/Auuuuuuuu/article/details/88778852

2020-8-12 第四周

Command Injection

标签:source   输出内容   调用   漏洞原理   void   保存   用户   函数的参数   code   

原文地址:https://www.cnblogs.com/4Uuu/p/13489957.html

版权声明:完美者 发表于 2020-08-12 15:59:16。
转载请注明:Command Injection | 完美导航

暂无评论

暂无评论...