Kindeditor漏洞 编辑代码内容被执行
kindeditor漏洞描述:在kindeditor编辑代码添加到数据库时没有任何问题,也就是一些HTML代码不会被执行,例如:<a href="#">web编程</a>,这样的代码在首次编辑的时候没有被执行。但是,从数据库里取出来再放到kindeditor里进行修改的时候问题就出现了,这行HTML代码被执行了,结果这样:web编程 变成了超链接的形式。
解决办法:先看下面这张图
这张图是本站后台代码文件,我将从数据库里取出来的内容中的“&”进行了替换,替换成了实体“&”。然后你再取修改之前插入的代码,就可以正常显示了。
特别注意:上图中我使用的是PHP语言来修改的,其他服务器端脚本语言思想是一样的,进行替换。
KindEditor上传解析漏洞
影响版本:<= kindeditor 3.2.1(09年8月份发布的最新版)
漏洞利用:利用windows 2003 IIS解析漏洞拿WEBSHELL
KindEditor列目录漏洞
测试版本:KindEditor 3.4.2 KindEditor 3.5.5
1.1.http://netknight.in/67cms/kindeditor/php/file_manager_json.php?path=/
2. //path=/,爆出绝对路径D:AppServwww67cmskindeditorphpfile_manager_json.php
3. 2.http://netknight.in/67cms/kindeditor/php/file_manager_json.php?path=AppServ/www/67cms/
4. //根据爆出的绝对路径,修改path的值为AppServ/www/67cms/
5. 这时将遍历d:/AppServ/www/67cms/下的所有文件和文件名
上传修改拿shell漏洞
影响版本:
KindEditor 3.5.2~4.1
漏洞利用:
打开编辑器,将一句话改名为1.jpg 上传图片,
打开文件管理,进入“down”目录,跳至尾页,最后一个图片既是我们上传的一句话
点击改名
点击改名
打开谷歌浏览器的 审查元素
找到form表单
修改“jpg”为“asp”
名字修改为1 保存
1 取消上传网络图片选项
### cd KindEditor/plugins/image/image.js 第13行
allowImageRemote = K.undef(self.allowImageRemote, true)
将 true 改为 false 即可,前后对比图效果如下:
before:
after:
2 解决无法保存空格的BUG
### cd KindEditor/kindeditor.js
### 第752行 将第一个和最后一个 \s 替换成 [ \f\n\r\t\v] 完整代码如下:
var re = /([ \f\n\r\t\v]*)<(\/)?([\w\-:]+)((?:\s+|(?:\s+[\w\-:]+)|(?:\s+[\w\-:]+=[^\s"'<>]+)|(?:\s+[\w\-:"]+="[^"]*")|(?:\s+[\w\-:"]+='[^']*'))*)(\/)?>([ \f\n\r\t\v]*)/g;
3 解决复制粘贴、点击图片等操作滚动条自动下拉的BUG
### cd KindEditor/kindeditor.js
### 第1521行 将 y = box.top + pos.y; 替换成
y = pos.y;
4 图片上传路径问题
### 举个栗子:修改图片上传路径为根目录下的atcImg文件夹:
### cd KindEditor/php/upload_json
### $save_path为图片上传的路径 $save_url为KindEditor中生成img标签的url路径 修改成下图所示即可:
KindEditor默认上传图片生成的url路径是不带域名的绝对路径,如果我们希望生成之后带上域名就需要对urlType进行设置了.
KindEditor中的urlType有4个参数,默认空值" "、"relative"、"absolute"、"domain"。初始化kindeditor时可以指定以下参数:
urlType : " " //默认为空,绝对路径
urlType : "relative" //相对路径
urlType : "absolute" //绝对路径
urlType : "domain" //带域名的绝对路径。
3种不同的路径效果如下图所示:
绝对路径 :
相对路径 :
带域名的绝对路径 :
五 解决文本中插入的程序代码里的HTML实体标签被直接解析出来的BUG
###在PHP中添加此函数 , 在向Kindeditor中插入文本内容之前使用此函数将文本内容中的&符号替换即可解决
function
htmlRep($html){
$html = str_replace(
' '
,
' '
, $html);
$html = str_replace(
'>'
,
'>'
, $html);
$html = str_replace(
'<'
,
'<'
, $html);
return
$html;
}
六 美化样式
###设置KindEditor生成的iframe中的样式(也就是编辑器内容框的样式)
例如我想 : 修改body的内边距为10px
进入kindeditor.js 第3535行 找到_getInitHtml函数 第一行arr数组里的代码就是iframe的HTML内容
那么直接将style标签中的 'body {margin:0;padding:5px;}' 替换为 'body {margin:0;padding:10px;}' 即可
###整合SyntaxHighlighter至编辑器中
一般大家都是在文章页引入语法高亮插件 , 在这里我想说的是 , 为什么不直接引入至编辑器中呢? 不要嫌麻烦, 带来好处是不言而喻的:
一是可以直接在编辑器就中看到代码被渲染的效果 , 一点对比色都没有的代码在写文章的时候是真滴辣眼睛
二是减少文章页的HTTP请求 , 减少服务器压力 , 提升页面加载速度 , 仅仅引入一个css文件即可
三是SyntaxHighlighter是异步的 , 访客访问你的文章页假如内容特别多, 那么在DOM没有加载完 , 你的代码就等着不会被着色 , 很难受!
废话就不多讲了, 直接上干货
1 首先需要引入SyntaxHighlighter.css 在初始化Kindeditor时指定cssPath
cssPath :
'./SyntaxHighlighter/styles/shCoreDefault.css'
2 进入kindeditor.js 第3594行 将arr.push中的内容替换为如下(在编辑器生成的iframe中引入SyntaxHighlighter的JS文件):
arr.push('</head><body ' + (bodyClass ? 'class="' + bodyClass + '"' : '') + '><span white-space:pre;background-color:#ffffff;"="" style="box-sizing: border-box;"><script src="./SyntaxHighlighter/scripts/0.js"></script><script src="./SyntaxHighlighter/scripts/shCore.js"></script><script src="./SyntaxHighlighter/scripts/shBrushJScript.js"></script></body></html>');
//注意 : 0.js这个文件是个空文件 , 原因是KindEditor有一个蜜汁BUG, 不解析引入的第一个JS文件 , 可能是哪里设置了什么东西吧 , 不管它
//所以我在这里引入SyntaxHighlighter的JS文件之前先引入一个空文件来解决这个BUG
3 进入KindEditor/plugins/code.js 将默认的pre标签的class改成SyntaxHighlighter需要的class
yesBtn : {
name : self.lang('yes'),
click : function(e) {
var type = K('.ke-code-type', dialog.div).val(),
code = textarea.val(),
//更改了这里 将class替换成"brush: js"这种形式 ("brush: "是固定的 , "js"是上面options中的val值)
cls = type === '' ? '' : type,
html = '<pre class="brush: ' + cls + '">\n' + K.escape(code) + '</pre>';
if (K.trim(code) === '') {
alert(lang.pleaseInput);
textarea[0].focus();
return;
}
self.insertHtml(html).hideDialog().focus();
//加入了此行 每次插入代码后调用highlight()方法着色pre标签的代码
document.getElementsByClassName('ke-edit-iframe')[0].contentWindow.SyntaxHighlighter.highlight();
}
}
//找到43行yesBtn属性, 将其替换为以上代码, 然后你需要清除以前的缓存, 下次在插入代码后就能让代码立刻被着色
那么骚年, 你以上已经完事了吗?不存在的, 是不是感觉还差点什么?快想想~
猜到了吗? 你还需要增加一个隐藏域来保存编辑器的内容, 为啥?因为Kindeditor还有个很烦的BUG: 源码中的div标签里的值被强行缩进
可以来看看是什么样子的, 你改完就能发现这个东西了, 点击显示HTML代码的那个按钮, 原本着色后的代码行号是这样的:
很整齐对吧~
然而kindEditor显示的源码中竟然被莫名其妙弄出这么大片的空白出来, 你想改还改不掉:
虽然在编辑器中样式是正确的, 但是插入到数据库中空白就会被保存下来, 再放到文章页显示那效果就爆炸咯, 是这个样子 :
没办法, 这个时候只能增加一个隐藏域来接受iframe中的HTML值, 提交之前将值保存进去, 再插入到数据库
那么保存下来的代码就不会有一点缩进, 做法也很简单, 上代码:
//HTML Tag
<input type="hidden" class="hidden" name="content" required>
//Helper
function C(c, a, f){
if(a){
return f ? f.getElementsByClassName(c) : document.getElementsByClassName(c);
}else{
return f ? f.getElementsByClassName(c)[0] : document.getElementsByClassName(c)[0];
}
}
function rmCd(p, c){
var i = 0;
while(c[i]){
p.removeChild(c[i]);
}
}
//Submit Event
C('form').onsubmit = function(e){
var b = C('ke-edit-iframe').contentWindow.document.body,
s = b.getElementsByTagName('script'),
k = C('ke-script', false, b),
h = C('hidden');
rmCd(b, s);
if(k){ rmCd(b, k); }
h.value = b.innerHTML;
};
//你需要一个如上所示的input隐藏域, 和一个class为form的form表单, 将这段代码加入到你的提交页面中,
//在提交之前会通过submit事件将body中的HTML代码加入到隐藏域中, 然后通过后台提交到数据库
//C函数是我常用的获取element的自定义函数 rmCd函数功能是将多余的div和JS标签删除, 只取出纯真~的文章内容的HTML代码
完成以上工作后, 基本算是大工告成了, 但是还可能出现小瑕疵 , 经过测试Chrome下可能出现行数稍有误差的情况 , Firefox下却不会
那么解决这种问题也很简单, 单独给Chrome加个样式就好了 :
//kindeditor.js 大约3586行 找到此函数_each() 将其内容替换为以下内容即可
_each(cssPath, function(i, path) {
if (path) {
arr.push('<link href="' + path + '" rel="stylesheet">');
arr = arr.concat([
'<style>',
'@media screen and (-webkit-min-device-pixel-ratio:0) {',
' .syntaxhighlighter table td {',
' font-family:"Microsoft YaHei" !important;',
' }',
' .syntaxhighlighter a, .syntaxhighlighter div, .syntaxhighlighter code, .syntaxhighlighter table, .syntaxhighlighter table td, .syntaxhighlighter table tr, .syntaxhighlighter table tbody, .syntaxhighlighter table thead, .syntaxhighlighter table caption, .syntaxhighlighter textarea {',
' top: 6px !important;',
' height: 19px !important;',
' }',
'}',
'</style>'
]);
}
});
###美化工具栏(删除不必要的功能按钮 并增加宽高间距)
先来看2张对比效果:
before:
after:
想要达到以上的效果很简单, 有2种方法:
1 初始化时指定item选项的值
2 直接修改kindeditor.js里面item的默认值
这里我毫不犹豫地选择了第二种方式 , 暴力修改
//第257行 修改为以下代码即可
items : [
'source', '|', 'code', '|',
'fontsize', 'forecolor', 'bold', '|',
'image', 'multiimage', 'link', '|',
'fontname', 'italic', 'underline', 'strikethrough', '|',
'flash', 'media', 'insertfile', 'table', 'hr', 'baidumap', 'pagebreak', 'anchor', '|',
'selectall', 'undo', 'redo'
],
修改完JS之后你以为就能舒服了么, nonono你现在只是将图标删除了而已, 还有样式也需要改, 那么进入Kindeditor/themes/default.css
//434行 .ke-toolbar-icon 修改样式:
{
margin: 3px auto;
}
//444行 .ke-toolbar .ke-outline 增加样式:
{
box-sizing: border-box;
width: 38px;
height: 25px;
}
//459行 .ke-toolbar .ke-separator 修改样式:
{
margin: 6px 3px 5px;
}
行数可能会稍有偏差, 根据选择器修改指定内容即可, 修改完之后你就可以舒服了~
七 编辑页初始高度自适应 && 工具栏根据滚动条智能定位
###高度自适应
当进入编辑页时, 编辑器里是有内容的, 内容高度比编辑器的初始高度高很多, 此时还需要自己手动去拉伸textarea不是很麻烦?
虽然用全屏模式不会有此问题, 但是全屏模式编写文章时看到的样式和发布文章之后去文章页看到的样式差距会很大(因为宽度不一样)
所以我不用全屏模式, 解决这个问题也很简单, 我写了一个定时器监听文本高度, 等待初始化完成之后直接改变编辑器高度即可
window.onload = function(){
function ifChg(){
var k = document.getElementsByClassName('ke-edit')[0];
if(k && k.style.height){
clearInterval(ift);
var f = k.firstElementChild;
var b = f.contentWindow.document.querySelector('.ke-content').offsetHeight + 50;
var x = k.lastElementChild;
k.style.height = b + 'px';
f.style.height = b + 'px';
x.style.height = b - 2 + 'px';
}
}
var ift = setInterval(ifChg, 300);
};
###工具栏智能定位
当我的文本内容很多, 高度非常高的时候, 滚动条需要拉很远才能到最底部, 此时工具栏是固定在编辑器最上方的
那我需要将底部文字小小地加个粗岂不是都要拉滚动条拉个2分钟才能加到粗? 然后加完粗再拉个2分钟拉回底部?
所以为了解决这个问题, 我加了一个滚动条监听事件
当滚动条到达工具栏的高度时, 工具栏定位就固定在屏幕上方, 也就是position: fixed;
function C(e, a){ return a ? document.getElementsByClassName(e) : document.getElementsByClassName(e)[0]; }
function getTop(e){
var t = 0;
while(e.nodeName !== 'BODY'){
t += e.offsetTop;
e = e.offsetParent;
}
return t;
}
KindEditor.ready(function(K) {
var s = true, t = getTop(C('ke-container')), c = C('ke-toolbar'), d = true;
function onScroll(){
if(s){
requestAnimationFrame(relFun);
s = false;
}
}
function relFun(){
if(pageYOffset >= t){
if(d){
c.classList.add('toFix');
d = false;
}
}else{
if(!d){
c.classList.remove('toFix');
d = true;
}
}
s = true;
}
window.addEventListener('scroll',onScroll,false);
});
//将scroll监听事件绑定到DOM加载完成事件上(kindEditor.ready) , 如果你写了ready函数了, 那么你只需要将我的代码追加进去即可
//我只展示了实现智能定位这个功能的代码, C和getTop2个函数 是我经常用到的自定义函数, 功能就是类似于JQ的$和offset()
当然加了这段JS你还是不能舒服, 因为还缺少样式, 比如点击按钮的下拉栏是根据body定位的, 你也需要将其改为fixed定位
所以你还需要在Kindeditor/themes/default.css中做以下修改:
//537行 .ke-menu 增加样式
{
position: fixed !important;
left: 640px !important;
top: 167px !important;
}
//596行 .ke-colorpicker 增加样式:
{
position: fixed !important;
left: 640px !important;
top: 167px !important;
}
//新增class:
.toFix{
position: fixed;
top: 136px;
box-shadow: 0 0 10px #5b5b5b;
border: 0;
}
CSS和JS配合使用, 这次就真滴舒服了, 阔以来看看修改完后的效果:
如对本文有疑问,请提交到交流论坛,广大热心网友会为你解答!! 点击进入论坛