PHP中命令执行的几种姿势总结

命令执行是web攻击中常用的手法之一,在PHP中,可调用以下函数来实现命令执行,如

1、exec()

exec函数用的较少,主要是因为该函数默认返回值是执行结果的最后一行,并不会有全部的执行结果。如果要打印执行结果,需遍历打印output数组,

1.1 函数原型

string exec ( string command, array &output, int &return_var)

//command参数是要执行的命令
//output数组是保存输出结果
//return_var整形用来保存命令执行后的状态码,0代表执行成功,1代表执行失败

1.2 实例用法

<?php
	$command = 'ls /';
	$ret=exec($command,$output,$a);

	#默认只返回第一行结果
	echo "第一行结果:".$ret,PHP_EOL,PHP_EOL;

	#打印出执行状态码
	echo "Status: ",$a,PHP_EOL,PHP_EOL;

	#数组的长度
	$length=count($output);    
	  for($i=0;$i<$length;$i++){
	  	echo $output[$i];
	  	echo PHP_EOL;
	}
?>

可得如下结果,

PHP中命令执行的几种姿势总结

2、shell_exec() 

shell_exec可以字符串的形式,返回所有结果,使用方便,较为常见

2.1 函数原型

shell_exec(string $cmd): string
// cmd 要执行的命令
// 返回结果string

2.2 实例用法

<?php 
	$cmd = "ls /";
	$output = passthru($cmd);
	echo $output,PHP_EOL;
?>

返回结果如下,

PHP中命令执行的几种姿势总结

3、system()

system 和exec 类似,返回执行的结果的最后一行,且将执行结果回显到标准输出中

3.1 函数原型

system(string command , int & return_var)
//command参数是要执行的命令,
//return_var参数存放返回的值,可不写该参数

3.2 实例用法 

<?php 
	$cmd = 'ls /';
	$output = system($cmd,$resCode);
	echo $resCode == 0 ? '执行成功!':'执行失败',PHP_EOL,PHP_EOL;

	echo $output;
?>

返回结果如下,

PHP中命令执行的几种姿势总结

 4、`$command` 

4.1 函数原型

php 执行运算符,也就是数字键1前面的反引号,可见PHP官方文档,PHP 支持一个执行运算符:反引号(``)。注意这不是单引号!PHP 将尝试将反引号中的内容作为 shell 命令来执行,并将其输出信息返回(即,可以赋给一个变量而不是简单地丢弃到标准输出)。使用反引号运算符“`”的效果与函数 shell_exec() 相同。

4.2 实例用法

<?php
	$cmd = "ls /";
	echo `$cmd`,PHP_EOL;
?>

5、passthru()

同 exec() 函数类似, passthru() 函数 也是用来执行外部命令(command)的。 当所执行的 Unix 命令输出二进制数据, 并且需要直接传送到浏览器的时候, 需要用此函数来替代 exec() 或 system() 函数。 常用来执行诸如 pbmplus 之类的可以直接输出图像流的命令。 通过设置 Content-type 为 image/gif, 然后调用 pbmplus 程序输出 gif 文件, 就可以从 PHP 脚本中直接输出图像到浏览器。

5.1 函数原型

passthru(string $command, int &$return_var = ?): void
// command 为执行的命令
// 状态码

5.2 实例用法

同system、exec 类似,将输入输出到了标准输出

6、popen()

6.1 函数原型

popen ( string command, string mode )
//打开一个指向进程的管道,该进程由派生给定的 command 命令执行而产生。
//返回一个和 fopen() 所返回的相同的文件指针,只不过它是单向的(只能用于读或写
//)并且必须用 pclose() 来关闭。此指针可以用于 fgets(),fgetss() 和 fwrite()。

6.2 实例用法

<?php
  $command='ls /';
  $fd = popen($command, 'r'); 
  while($s=fgets($fd)){
    print_r($s);
  }
?>

7、proc_open()

proc_open — 执行一个命令,并且打开用来输入/输出的文件指针。类似 popen() 函数, 但是 proc_open() 提供了更加强大的控制程序执行的能力。

7.1 函数原型

proc_open(
    mixed $cmd,
    array $descriptorspec,
    array &$pipes,
    string $cwd = null,
    array $env = null,
    array $other_options = null
): resource

7.2 实例用法

proc_open 用法稍显复杂,通常其他函数被过滤时,可以考虑使用此函数

<?php
	$command = 'ls /';
	$descriptorspec=array( 
        0=>array('pipe','r'), 
        1=>array('pipe','w'),
        2=>array('pipe','w') 
    );
    $handle=proc_open($command,$descriptorspec,$pipes,NULL);
    if(!is_resource($handle)){
      die('proc_open failed');
    }
    while($s=fgets($pipes[1])){
      print_r($s);
    }
    while($s=fgets($pipes[2])){
      print_r($s);
    }
    fclose($pipes[0]);
    fclose($pipes[1]);
    fclose($pipes[2]);
    proc_close($handle);
?>

上一篇:Redis 事务处理


下一篇:Java反弹shell小记(个人学习记录)