安全矩阵

 找回密码
 立即注册
搜索
查看: 2730|回复: 0

某CMS 排行页面存储型XSS漏洞 分析

[复制链接]

249

主题

299

帖子

1391

积分

金牌会员

Rank: 6Rank: 6

积分
1391
发表于 2022-3-29 23:57:00 | 显示全部楼层 |阅读模式
本帖最后由 sandalwood 于 2022-3-29 23:58 编辑


2018年10月12日,某CMS官方修复了一处XSS漏洞:




简要分析
source/module/misc/misc_ranklist.php:166
<?php

function getranklist_members($offset = 0, $limit = 20) {
    require_once libfile('function/forum');
    $members = array();
    $topusers = C::t('home_show')->fetch_all_by_unitprice($offset, $limit, true);

    foreach($topusers as $member) {
        $member['avatar'] = avatar($member['uid'], 'small');
        $member['note'] = dhtmlspecialchars($member['note']);
        $members[] = $member;
    }
    return $members;
}
Dz在此处获取到$member['note']后调用了dhtmlspecialchars进行过滤,在source/function/function_core.php:203 会对'&', '"', '<', '>'进行实体编码。
<?php

function dhtmlspecialchars($string, $flags = null) {
    if(is_array($string)) {
        。。。
    } else {
        if($flags === null) {
            $string = str_replace(array('&', '"', '<', '>'), array('&amp;', '&quot;', '&lt;', '&gt;'), $string);

        } else {
            。。。
    }
    return $string;
}

从getranklist_members返回source/include/misc/misc_ranklist_index.php:113
<?php
。。。
if($ranklist_setting['member']['available']) {
    $memberlist = getranklist_members(0, 27);
}
。。。
include template('diy:ranklist/ranklist');

进行模板的渲染在 data/template/1_diy_ranklist_ranklist.tpl.php:32
<?php if($memberlist) { ?>
<a href="home.php?mod=space&amp;uid=<?php echo $memberlist['0']['uid'];?>&amp;do=profile" target="_blank" id="bid_<?php echo $memberlist['0']['uid'];?>" class="hm" <?php if($memberlist['0']['note']) { ?> tip="<?php echo $memberlist['0']['username'];?>: <?php echo $memberlist['0']['note'];?>"<?php } ?>><?php echo avatar($memberlist[0][uid],middle);?></a>
<?php } ?>

可以看到在tip属性中输出了$memberlist['0']['note']。在之前有一个onmouseover事件,跟入showTip(trhis) 在 static/js/common.js:1062
function showTip(ctrlobj) {
    $F('_showTip', arguments);
}

跟入_showTip,在 static/js/common_extra.js:912
function _showTip(ctrlobj) {
    if(!ctrlobj.id) {
        ctrlobj.id = 'tip_' + Math.random();
    }
    menuid = ctrlobj.id + '_menu';
    if(!$(menuid)) {
        var div = document.createElement('div');
        div.id = ctrlobj.id + '_menu';
        div.className = 'tip tip_4';
        div.style.display = 'none';
        div.innerHTML = '<div class="tip_horn"></div><div class="tip_c">' + ctrlobj.getAttribute('tip') + '</div>';
        $('append_parent').appendChild(div);
    }
    $(ctrlobj.id).onmouseout = function () { hideMenu('', 'prompt'); };
    showMenu({'mtype':'prompt','ctrlid':ctrlobj.id,'pos':'12!','duration':2,'zindex':JSMENU['zIndex']['prompt']});
}

通过ctrlobj.getAttribute('tip')获取tip属性的值,由于getAttribute获取的内容会自动反转义,即前面在dhtmlspecialchars编码过的内容又被解码了一次。此后拼接到div标签的innerHTML中,最后输出到页面上造成了xss
关于getAttribute,可以用下面代码测试:
<html>
<div name="&lt;a&gt;" id="div">test</div>
<script>
div1 = document.getElementById("div");
align = div1.getAttribute("name");

alert(align);
</script>
http://127.0.0.1/misc.php?mod=ranklist 当鼠标移动到头像上触发onmouseover事件,执行xss


回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|安全矩阵

GMT+8, 2025-4-24 12:49 , Processed in 0.013367 second(s), 18 queries .

Powered by Discuz! X4.0

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表