b01lers(php.galf)

目录

前文

 正文


前文

<?php

class A{
    public $code=NULL;
    public $args=NULL;
    public function __construct($code,$args=NULL){
        $this->code=$code;
        $this->args=$args;
        print_r("2333") ;



}
public function __invoke($code,$args){
        echo $code;
    print_r("执行invoke") ;

}
}
$B=new A(55,66);
$B(33,44);

233 333执行invoke说明执行了construct和invoke

 throw new A(55, 100);也会对construct进行初始化

然后肯定是从index.php开始出发,php文件不算太多,可以逐个看一下出口也就是能够命令执行获得flag的地方。

最终可以在noitpecxe.php下面找到可疑点,因为这俩参数还是构造函数传进来的,也就是说我们可以通过调用实参来操作。

 正文

index.php


        <?php
            define('block', TRUE);
            require("parser/syntaxreader.php");
            include("flag.php");
            $code = "ohce ohce ohce ohce ohce ohce ohce";
            $args = "flag.php,aaa,aaa,highlight_file,orez_lum,orez_vid,syntaxreader";
            $result = NULL;


                if (!isset($_COOKIE['DEBUG'])){//如果cookie中不存在,DEBUG
                    $result = new syntaxreader($code, $args);
                } 
                else if (strcmp($_COOKIE['DEBUG'], hash("md5")) == 0) {
                    echo "Warning: Adming debugging enabled!";
                    $result = new syntaxreader($code, $args, NULL);
                } else {
                    $debug = array("Debugging Enabled!", 69);
                    $result = new syntaxreader($code, $args, $debug);
                }
                $result->run();

        ?>

这里code args是post传参可控,我这里直接把答案先写出来方便理解。

这里肯定会调用 syntaxreader的构造函数,看了一下三者的区别,其实就是末尾的debug传参的问题,第一个if和第二个elseif都是NULL,但是第三个确有值,这是唯一的差别。

syntaxreader.php 

public function __construct($lines, $args, $debug = NULL) {
            $this->code = explode("\n", $lines);//这里使用\n作为分隔符号,切成数组
            $this->args = $args;
            $this->result = $result;
            if (isset($debug)) {//这里不可能执行到的
                // disable debugging mode
                throw new noitpecxe(...$debug);
            }
        }

如果debug为true的话那么就可以直接初始化noipecxe,然后这里正好是我们一开始想到的漏洞点,直接让$error_func($this->message); ==== hightlight(flag.php)

这里说明一下数组传参,  $debug数组传参就会把参数逐个给形参也就是

(message,code,previous,error_func)

(flag.php,aa,aa,highlight)

noipecxe.php

<?php
class noitpecxe extends Exception
{
    public $error_func = NULL;
    public function __construct($message, $code, $previous = null, $error_func = "printf") {
        // remove when PHP 5.3 is no longer supported
        $this->error_func = $error_func;//printf
        $this->message = $message;//args的值,是个数组
        $previous = NULL;
        //dont care what ur code is LOL!
        $code = 69;
        parent::__construct($message, $code, $previous);
    }

    public function __toString() {
        $error_func = $this->error_func;//这里引用到了另一个函数
        $error_func($this->message);
        return __CLASS__ . ": {$this->code}\n";
    }
}
?>
$result->run(); ::parse

里面作用就是分割数组,并且code的值一定要一直是oche

public function parse() {
            $parsable = array("ohce");
            $arg_val = 0;
            $code = $this->code;
            $args = $this->args;
            $result = $this->result;

            for ($i = 0; $i < count($code); $i++) {//去掉刚才数组分割中的空格
                $code[$i] = trim($code[$i]);
            }

            $args = explode(",", $args);
            for ($i = 0; $i < count($args); $i++) {//对传入的args进行,分割且去掉空格
                $args[$i] = trim($args[$i]);
            }


            for ($i = 0; $i < count($code); $i++) {
                $token = explode(" ", $code[$i]);//通过空格继续分割
                for ($j = 0; $j < count($token); $j++) {
                    try {
                        if (!in_array($token[$j], $parsable)) {//这里必须要满足里面ohce
                            throw new noitpecxe("Non-Parsable Keyword!\n", 101);
                        }
                        if ($args[$arg_val] == NULL) {//args传入的不能为空
                            throw new noitpecxe("No Arguments!\n", 990);
                        }
                        if ($args[$arg_val] === "noitpecxe") {//不能是这个的值
                            throw new noitpecxe("No Exceptions!\n", 100);
                        }
                        $class = new $token[$j];//玄机在这里,这里肯定是一个跳转类的东西
                        $class($args, $arg_val);//我们可以根据参数来看调的哪个
                        $arg_val++;
                    } catch (noitpecxe $e) {
                        echo "Error Executing Code! Error: " . $e . "\n";
                    }
                    
                }

 然后就会调用oche.php

  public function __invoke($args, $arg_val) {
        $this->args = $args[$arg_val];
        $arg_val++;
        $parsable = array("orez_lum", "orez_dda");
        if (in_array($this->args, $parsable)) { // we can run operators in ohce!
            $class = new $this->args;
            $this->result = $class($args, $arg_val);
        } else {
            $this->result = $this->args;
        }
        $this->result = strrev($this->result) . "\n";
        echo $this->result;
    }

orez_lum和orez_dda内容几乎一样,调用谁都一样,然后调用orez_vid

为什么要调用它呢,看一下传参值

$class($arg, $arg_val); 
orez_vid  ($arg = "div", $arg_val = 0, $result = NULL)
new $arg[$arg_val]("div", $result, $arg);  
syntaxreader public function __construct($lines, $args, $debug = NULL)
throw new noitpecxe(...$debug);
public function __construct($message, $code, $previous = null, $error_func = "printf")

所以我们一开始传入的arg就可以一条线的到达我们的执行命令,然后就是看一下中间的条件,只有

$_COOKIE['DEBUG']存在即可和上面的index.php判断一样,ok结束
 public function __invoke($arg = "div", $arg_val = 0, $result = NULL) {
        if (!isset($_COOKIE['DEBUG'])) {  //just gonna prevent people from using this
                    throw new noitpecxe("You need to enable debugging mode to access this!\n", 0);
        }
        if ($arg[$arg_val] == NULL) {
            throw new noitpecxe("No Arguments!\n", 990);
        }
        if ($arg[$arg_val] === "noitpecxe") {
            throw new noitpecxe("No Exceptions!\n", 100);
        }
        if (isset($result)) {
            throw new noitpecxe("No dividing by zero!\n", 0);
        }
        // smart to call the constructor so there is an exception! I was a genius!
        $class = new $arg[$arg_val]("div", $result, $arg);
        $arg_val++;
        $this->result = $arg[$arg_val] / 0; // dividing by zero??
        return $this->result;
    }

这里卡了一下,debug是数组类型的,这点可以看php中赋值得知。 

就是我们输入的code是以空格分割的,这里+就是空格的意思,但我用空格也过去了qwq        ,一定要静下心来审计!!!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值