评论位置的xss请参考这个文章
0x01搭建
这里测试的版本是1.1.17.10.30(17.10.30),最新版本1.2.0已修复
安装好程序
0x02复现
然后访问默认存在的文章进行评论,评论内容就是一个最常见的xss payload
http://domain/index.php/archives/1/
评论完成后,登入后台查看评论
http://domain/admin/manage-comments.php
点击编辑
接下来在点击提交即可触发
成功触发漏洞
0x03审计
问题出在manage-comments.php文件的329到365行
$('form', edit).submit(function () {
var t = $(this), tr = t.parents('tr'),
oldTr = $('#' + tr.data('id')),
comment = oldTr.data('comment');
$('form', tr).each(function () {
var items = $(this).serializeArray();
for (var i = 0; i < items.length; i ++) {
var item = items[i];
comment[item.name] = item.value;
}
});
var html = '<strong class="comment-author">'
+ (comment.url ? '<a target="_blank" href="' + comment.url + '">'
+ comment.author + '</a>' : comment.author) + '</strong>'
+ ('comment' != comment.type ? '<small><?php _e('引用'); ?></small>' : '')
+ (comment.mail ? '<br /><span><a href="mailto:' + comment.mail + '">'
+ comment.mail + '</a></span>' : '')
+ (comment.ip ? '<br /><span>' + comment.ip + '</span>' : '');
$('.comment-meta', oldTr).html(html)
.effect('highlight');
$('.comment-content', oldTr).html('<p>' + comment.text + '</p>');
oldTr.data('comment', comment);
$.post(t.attr('action'), comment, function (o) {
$('.comment-content', oldTr).html(o.comment.content)
.effect('highlight');
}, 'json');
oldTr.show();
tr.remove();
return false;
});
先打几个断点在图中几个位置
然后点击提交,此时comment的值为我们评论的作者 网站 ip等
然后在继续往下执行执行到413行触发xss
可以看到是直接把comment.text写入到了页面上导致了xss
接下来手动调一下,首先是取出评论的值 ip 作者等
$('form', edit).submit(function () {
var t = $(this), tr = t.parents('tr'),
oldTr = $('#' + tr.data('id')),
comment = oldTr.data('comment');
由于代码用是form的this这里改成取表单里面按钮
var t = $('.primary')
tr = t.parents('tr')
oldTr = $('#' + tr.data('id'))
comment = oldTr.data('comment');
comment;
取出评论的值 作者 ip 等信息
然后将值无过滤写到了页面上,导致了xss
$('.comment-content', oldTr).html('<p>' + comment.text + '</p>');
0x04 修复
可以在官方Github看到13天前提交记录看到修复
由于修复的是1.2.0我测试的版本是1.1.17.10.30没有带DOMPurify需要手动下载purify.js
https://github.com/typecho/typecho/blob/master/admin/js/purify.js
进入到/admin/js文件夹下然后下载purify.js,然后在manage-comments.php头部引入js
<script src="<?php $options->adminStaticUrl('js', 'purify.js'); ?>"></script>
然后替换manage-comments.php的330到366行替换为即可
$('form', edit).submit(function () {
var t = $(this), tr = t.parents('tr'),
oldTr = $('#' + tr.data('id')),
comment = oldTr.data('comment');
$('form', tr).each(function () {
var items = $(this).serializeArray();
for (var i = 0; i < items.length; i ++) {
var item = items[i];
comment[item.name] = item.value;
}
});
var unsafeHTML = '<strong class="comment-author">'
+ (comment.url ? '<a target="_blank" href="' + comment.url + '">'
+ comment.author + '</a>' : comment.author) + '</strong>'
+ ('comment' != comment.type ? '<small><?php _e('引用'); ?></small>' : '')
+ (comment.mail ? '<br /><span><a href="mailto:' + comment.mail + '">'
+ comment.mail + '</a></span>' : '')
+ (comment.ip ? '<br /><span>' + comment.ip + '</span>' : '');
var html = DOMPurify.sanitize(unsafeHTML, {USE_PROFILES: {html: true}});
var content = DOMPurify.sanitize(comment.text, {USE_PROFILES: {html: true}});
$('.comment-meta', oldTr).html(html)
.effect('highlight');
$('.comment-content', oldTr).html('<p>' + comment + '</p>');
oldTr.data('comment', comment);
$.post(t.attr('action'), comment, function (o) {
$('.comment-content', oldTr).html(o.comment.content)
.effect('highlight');
}, 'json');
oldTr.show();
tr.remove();
return false;
});
修复效果展示
One comment
作为一个typecho:谢谢。