pear
Pear 是 PHP 扩展与应用库(the PHP Extension and Application Repository)的缩写,是一个 PHP 扩展及应用的一个代码仓库。Pear 仓库代码是以包(package)分区,每一个 Pear package
都是一个独立的项目有着自己独立的开发团队、版本控制、文档和其他包的依赖关系信息。Pear package 以 phar、tar 或 zip 发布。
既然是个包管理器,那么就应该存在下载和安装包的功能,那么pear命令是如何实现的呢?
实际上pear命令是sh脚本,源码如下:
1 | #!/bin/sh |
通过看最后一行可以知道其实它是通过php调用了pearcmd.php,那么pearcmd.php中$argv是从哪里来的呢,通过简单查找可以看到其调用了另一个php文件中某个类方法:
1 | require_once 'Console/Getopt.php'; |
再次跟进Console/Getopt.php,找到该方法的实现:
1 | public static function readPHPArgv() |
可以看到获取$argv的方式是global $argv --> $_SERVER['argv'] --> $GLOBALS['HTTP_SERVER_VARS']['argv']
同时我们知道当我们include一个可以被php解析的文件的时候,php代码会被自动执行,这样在registerargcargv开启的情况下我们就有可能通过包含pearcmd.php与操控$_SERVER[‘argv’]来执行pear命令。
如何控制$_SERVER[‘argv’]
main/php_variables.c
1 | PHPAPI void php_build_argv(const char *s, zval *track_vars_array) |
可以知道argv通过query_string取值,并通过+作为分割符
漏洞利用
,假如存在以下环境:
- 安装了pear
- 开启了registerargcargv
- 存在可控的
include $_GET['f']
(即使是include $_GET['f'].php
)
那么我们就可以通过上面的知识实现任意文件下载从而getshell:
1 | //将一句话木马写入临时目录的一个PHP文件里面 |