专栏首页Ms08067安全实验室PbootCMS-XSS(stored)漏洞分析

PbootCMS-XSS(stored)漏洞分析

本文作者:WHITE(Ms08067实验室核心成员)

一、漏洞摘要

bootCMS是全新内核且永久开源免费的cms,在其V2.0.2版本中存在存储型XSS 漏洞名称:PbootCMS存储型XSS 产品首页:https://www.pbootcms.com 软件链接:

https://github.com/hnaoyun/PbootCMS 版本:V2.0.2-20190915

二、漏洞概述

漏洞路径为

/PbootCMS/apps/home/controller/ParserController.php

public function parserSiteLabel($content)
    {
        $pattern = '/\{pboot:site([\w]+)(\s+[^}]+)?\}/';
        if (preg_match_all($pattern, $content, $matches)) {
            $data = $this->model->getSite();
            $count = count($matches[0]);
            for ($i = 0; $i < $count; $i ++) {
                $params = $this->parserParam($matches[2][$i]);
                switch ($matches[1][$i]) {
                    case 'index':
                        $content = str_replace($matches[0][$i], Url::home('home/Index/'), $content);
                        break;
                    case 'path':
                        $content = str_replace($matches[0][$i], SITE_DIR, $content);
                        break;
                    case 'logo':
                        if (isset($data->logo) && $data->logo) {
                            if (! preg_match('/^http/', $data->logo)) {
                                $content = str_replace($matches[0][$i], $this->adjustLabelData($params, SITE_DIR . $data->logo), $content);
                            } else {
                                $content = str_replace($matches[0][$i], $this->adjustLabelData($params, $data->logo), $content);
                            }
                        } else {
                            $content = str_replace($matches[0][$i], STATIC_DIR . '/images/logo.png', $content);
                        }
                        break;
                    case 'tplpath':
                        $content = str_replace($matches[0][$i], APP_THEME_DIR, $content);
                        break;
                    case 'language':
                        $content = str_replace($matches[0][$i], get_lg(), $content);
                        break;
                    case 'statistical':
                        if (isset($data->statistical)) {
                            $content = str_replace($matches[0][$i], decode_string($data->statistical), $content);
                        } else {
                            $content = str_replace($matches[0][$i], '', $content);
                        }
                    case 'copyright':
                        if (isset($data->copyright)) {
                            $content = str_replace($matches[0][$i], decode_string($data->copyright), $content);
                        } else {
                            $content = str_replace($matches[0][$i], '', $content);
                        }
                    default:
                        if (isset($data->{$matches[1][$i]})) {
                            $content = str_replace($matches[0][$i], $this->adjustLabelData($params, $data->{$matches[1][$i]}), $content);
                        } else {
                            $content = str_replace($matches[0][$i], '', $content);
                        }
                }
            }
        }
        return $content;
    }

内容传入此函数后进行了decode_string()方法

位于PbootCMS/core/function/handle.php

function decode_string($string)
{
    if (! $string)
        return $string;
    if (is_array($string)) { // 数组处理
        foreach ($string as $key => $value) {
            $string[$key] = decode_string($value);
        }
    } elseif (is_object($string)) { // 对象处理
        foreach ($string as $key => $value) {
            $string->$key = decode_string($value);
        }
    } else { // 字符串处理
        $string = stripcslashes($string);
        $string = htmlspecialchars_decode($string, ENT_QUOTES);
    }
    return $string;
}

此方法是html实体编码转义普通字符,而不是将普通字符转义成html实体编码,应当使用escape_string()处理数据,该方法同样位于PbootCMS/core/function/handle.php。

function escape_string($string)
{
    if (! $string)
        return $string;
    if (is_array($string)) { // 数组处理
        foreach ($string as $key => $value) {
            $string[$key] = escape_string($value);
        }
    } elseif (is_object($string)) { // 对象处理
        foreach ($string as $key => $value) {
            $string->$key = escape_string($value);
        }
    } else { // 字符串处理
        $string = htmlspecialchars(trim($string), ENT_QUOTES, 'UTF-8');
        $string = addslashes($string);
    }
    return $string;
}

三、利用代码

登陆后台在后台的-基础内容-站点信息-统计代码和尾部信息等处插入xss payload payload:<img src=x onerror=alert(1)>

进入主页触发xss

四、参考信息

五、补丁

case 'statistical':
                        if (isset($data->statistical)) {
                            $content = str_replace($matches[0][$i], decode_string($data->statistical), $content);
                        } else {
                            $content = str_replace($matches[0][$i], '', $content);
                        }
                    case 'copyright':
                        if (isset($data->copyright)) {
                            $content = str_replace($matches[0][$i], decode_string($data->copyright), $content);
                        } else {
                            $content = str_replace($matches[0][$i], '', $content);
                        }

将其中的decode_string修改为escape_string即可修复!

本文分享自微信公众号 - Ms08067安全实验室(Ms08067_com),作者:徐哥

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-09-23

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 微信小程序《消灭病毒》辅助

    首先从抓包着手,我比较习惯用fiddler抓包。尝试模拟器上配置代理抓包,结果模拟器用不了。

    徐焱
  • PHP反序列化笔记

    当序列化字符串中表示对象属性个数的值大于真实的属性个数时会跳过__wakeup的执行

    徐焱
  • SSRF漏洞利用与getshell实战(精选)

    SSRF(Server-Side Request Forgery,服务器端请求伪造)是一种由攻击者构造请求,利用服务器端发起的安全漏洞。一般情况下,SSRF攻击...

    徐焱
  • .net字符串数组查找方式效率比较

    下面是代码: static void Main(string[] args) { string[] arr = new...

    用户1177503
  • (翻译)LearnVSXNow! #10 创建我们第一个工具集-重用代码

    我们在第6和第7篇创建的Calculate小工具窗还有很多可以改进的地方,所以在这篇文章里,我们不会开发新的功能,而是重构我们的代码,封装出可以重用的...

    明年我18
  • 华为oj之字符串反转

    在线提交网址: http://www.nowcoder.com/practice/e45e078701ab4e4cb49393ae30f1bb04?tpId=3...

    Enjoy233
  • 【蓝桥杯】BASIC-3 字母图形

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 ...

    喜欢ctrl的cxk
  • 这些假脸实在太逼真了!英伟达造出新一代GAN,生成壁纸级高清大图毫无破绽

    这个结构不需要人类监督,可以自动分离图像中的各种属性。这样,在或粗糙或精细的不同尺度上,人类便能自如地控制GAN的生成。

    量子位
  • 前端框架这么多,该何去何从?|洞见

    作为一个软件开发者,最大的挑战就是在不断涌现的新技术中进行取舍,持续学习是从事这一行业的必备技能。在这个领域里,技术更新最快地又非前端莫属了。各种框架的出现、版...

    ThoughtWorks
  • mysql (手机号,邮箱)匹配正则

    DencyCheng

扫码关注云+社区

领取腾讯云代金券

玩转腾讯云 有奖征文活动