Kindeditor漏洞 編輯代碼內(nèi)容被執(zhí)行
kindeditor漏洞描述:在kindeditor編輯代碼添加到數(shù)據(jù)庫時(shí)沒有任何問題,也就是一些HTML代碼不會被執(zhí)行,例如:<a href="#">web編程</a>,這樣的代碼在首次編輯的時(shí)候沒有被執(zhí)行。但是,從數(shù)據(jù)庫里取出來再放到kindeditor里進(jìn)行修改的時(shí)候問題就出現(xiàn)了,這行HTML代碼被執(zhí)行了,結(jié)果這樣:web編程 變成了超鏈接的形式。
解決辦法:先看下面這張圖
這張圖是本站后臺代碼文件,我將從數(shù)據(jù)庫里取出來的內(nèi)容中的“&”進(jìn)行了替換,替換成了實(shí)體“&”。然后你再取修改之前插入的代碼,就可以正常顯示了。
特別注意:上圖中我使用的是PHP語言來修改的,其他服務(wù)器端腳本語言思想是一樣的,進(jìn)行替換。
KindEditor上傳解析漏洞
影響版本:<= kindeditor 3.2.1(09年8月份發(fā)布的最新版)
漏洞利用:利用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. //根據(jù)爆出的絕對路徑,修改path的值為AppServ/www/67cms/
5. 這時(shí)將遍歷d:/AppServ/www/67cms/下的所有文件和文件名
上傳修改拿shell漏洞
影響版本:
KindEditor 3.5.2~4.1
漏洞利用:
打開編輯器,將一句話改名為1.jpg 上傳圖片,
打開文件管理,進(jìn)入“down”目錄,跳至尾頁,最后一個(gè)圖片既是我們上傳的一句話
點(diǎn)擊改名
點(diǎn)擊改名
打開谷歌瀏覽器的 審查元素
找到form表單
修改“jpg”為“asp”
名字修改為1 保存
1 取消上傳網(wǎng)絡(luò)圖片選項(xiàng)
### cd KindEditor/plugins/image/image.js 第13行
allowImageRemote = K.undef(self.allowImageRemote, true)
將 true 改為 false 即可,前后對比圖效果如下:
before:
after:
2 解決無法保存空格的BUG
### cd KindEditor/kindeditor.js
### 第752行 將第一個(gè)和最后一個(gè) \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 解決復(fù)制粘貼、點(diǎn)擊圖片等操作滾動條自動下拉的BUG
### cd KindEditor/kindeditor.js
### 第1521行 將 y = box.top + pos.y; 替換成
y = pos.y;
4 圖片上傳路徑問題
### 舉個(gè)栗子:修改圖片上傳路徑為根目錄下的atcImg文件夾:
### cd KindEditor/php/upload_json
### $save_path為圖片上傳的路徑 $save_url為KindEditor中生成img標(biāo)簽的url路徑 修改成下圖所示即可:
KindEditor默認(rèn)上傳圖片生成的url路徑是不帶域名的絕對路徑,如果我們希望生成之后帶上域名就需要對urlType進(jìn)行設(shè)置了.
KindEditor中的urlType有4個(gè)參數(shù),默認(rèn)空值" "、"relative"、"absolute"、"domain"。初始化kindeditor時(shí)可以指定以下參數(shù):
urlType : " " //默認(rèn)為空,絕對路徑
urlType : "relative" //相對路徑
urlType : "absolute" //絕對路徑
urlType : "domain" //帶域名的絕對路徑。
3種不同的路徑效果如下圖所示:
絕對路徑 :
相對路徑 :
帶域名的絕對路徑 :
五 解決文本中插入的程序代碼里的HTML實(shí)體標(biāo)簽被直接解析出來的BUG
###在PHP中添加此函數(shù) , 在向Kindeditor中插入文本內(nèi)容之前使用此函數(shù)將文本內(nèi)容中的&符號替換即可解決
function
htmlRep($html){
$html = str_replace(
' '
,
' '
, $html);
$html = str_replace(
'>'
,
'>'
, $html);
$html = str_replace(
'<'
,
'<'
, $html);
return
$html;
}
六 美化樣式
###設(shè)置KindEditor生成的iframe中的樣式(也就是編輯器內(nèi)容框的樣式)
例如我想 : 修改body的內(nèi)邊距為10px
進(jìn)入kindeditor.js 第3535行 找到_getInitHtml函數(shù) 第一行arr數(shù)組里的代碼就是iframe的HTML內(nèi)容
那么直接將style標(biāo)簽中的 'body {margin:0;padding:5px;}' 替換為 'body {margin:0;padding:10px;}' 即可
###整合SyntaxHighlighter至編輯器中
一般大家都是在文章頁引入語法高亮插件 , 在這里我想說的是 , 為什么不直接引入至編輯器中呢? 不要嫌麻煩, 帶來好處是不言而喻的:
一是可以直接在編輯器就中看到代碼被渲染的效果 , 一點(diǎn)對比色都沒有的代碼在寫文章的時(shí)候是真滴辣眼睛
二是減少文章頁的HTTP請求 , 減少服務(wù)器壓力 , 提升頁面加載速度 , 僅僅引入一個(gè)css文件即可
三是SyntaxHighlighter是異步的 , 訪客訪問你的文章頁假如內(nèi)容特別多, 那么在DOM沒有加載完 , 你的代碼就等著不會被著色 , 很難受!
廢話就不多講了, 直接上干貨
1 首先需要引入SyntaxHighlighter.css 在初始化Kindeditor時(shí)指定cssPath
cssPath :
'./SyntaxHighlighter/styles/shCoreDefault.css'
2 進(jìn)入kindeditor.js 第3594行 將arr.push中的內(nèi)容替換為如下(在編輯器生成的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這個(gè)文件是個(gè)空文件 , 原因是KindEditor有一個(gè)蜜汁BUG, 不解析引入的第一個(gè)JS文件 , 可能是哪里設(shè)置了什么東西吧 , 不管它
//所以我在這里引入SyntaxHighlighter的JS文件之前先引入一個(gè)空文件來解決這個(gè)BUG
3 進(jìn)入KindEditor/plugins/code.js 將默認(rèn)的pre標(biāo)簽的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();
//加入了此行 每次插入代碼后調(diào)用highlight()方法著色pre標(biāo)簽的代碼
document.getElementsByClassName('ke-edit-iframe')[0].contentWindow.SyntaxHighlighter.highlight();
}
}
//找到43行yesBtn屬性, 將其替換為以上代碼, 然后你需要清除以前的緩存, 下次在插入代碼后就能讓代碼立刻被著色
那么騷年, 你以上已經(jīng)完事了嗎?不存在的, 是不是感覺還差點(diǎn)什么?快想想~
猜到了嗎? 你還需要增加一個(gè)隱藏域來保存編輯器的內(nèi)容, 為啥?因?yàn)?span style="box-sizing: border-box; color: rgb(229, 102, 0);">Kindeditor還有個(gè)很煩的BUG: 源碼中的div標(biāo)簽里的值被強(qiáng)行縮進(jìn)
可以來看看是什么樣子的, 你改完就能發(fā)現(xiàn)這個(gè)東西了, 點(diǎn)擊顯示HTML代碼的那個(gè)按鈕, 原本著色后的代碼行號是這樣的:
很整齊對吧~
然而kindEditor顯示的源碼中竟然被莫名其妙弄出這么大片的空白出來, 你想改還改不掉:
雖然在編輯器中樣式是正確的, 但是插入到數(shù)據(jù)庫中空白就會被保存下來, 再放到文章頁顯示那效果就爆炸咯, 是這個(gè)樣子 :
沒辦法, 這個(gè)時(shí)候只能增加一個(gè)隱藏域來接受iframe中的HTML值, 提交之前將值保存進(jìn)去, 再插入到數(shù)據(jù)庫
那么保存下來的代碼就不會有一點(diǎn)縮進(jìn), 做法也很簡單, 上代碼:
//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;
};
//你需要一個(gè)如上所示的input隱藏域, 和一個(gè)class為form的form表單, 將這段代碼加入到你的提交頁面中,
//在提交之前會通過submit事件將body中的HTML代碼加入到隱藏域中, 然后通過后臺提交到數(shù)據(jù)庫
//C函數(shù)是我常用的獲取element的自定義函數(shù) rmCd函數(shù)功能是將多余的div和JS標(biāo)簽刪除, 只取出純真~的文章內(nèi)容的HTML代碼
完成以上工作后, 基本算是大工告成了, 但是還可能出現(xiàn)小瑕疵 , 經(jīng)過測試Chrome下可能出現(xiàn)行數(shù)稍有誤差的情況 , Firefox下卻不會
那么解決這種問題也很簡單, 單獨(dú)給Chrome加個(gè)樣式就好了 :
//kindeditor.js 大約3586行 找到此函數(shù)_each() 將其內(nèi)容替換為以下內(nèi)容即可
_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:
想要達(dá)到以上的效果很簡單, 有2種方法:
1 初始化時(shí)指定item選項(xiàng)的值
2 直接修改kindeditor.js里面item的默認(rèn)值
這里我毫不猶豫地選擇了第二種方式 , 暴力修改
//第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你現(xiàn)在只是將圖標(biāo)刪除了而已, 還有樣式也需要改, 那么進(jìn)入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;
}
行數(shù)可能會稍有偏差, 根據(jù)選擇器修改指定內(nèi)容即可, 修改完之后你就可以舒服了~
七 編輯頁初始高度自適應(yīng) && 工具欄根據(jù)滾動條智能定位
###高度自適應(yīng)
當(dāng)進(jìn)入編輯頁時(shí), 編輯器里是有內(nèi)容的, 內(nèi)容高度比編輯器的初始高度高很多, 此時(shí)還需要自己手動去拉伸textarea不是很麻煩?
雖然用全屏模式不會有此問題, 但是全屏模式編寫文章時(shí)看到的樣式和發(fā)布文章之后去文章頁看到的樣式差距會很大(因?yàn)?span style="box-sizing: border-box; color: rgb(229, 102, 0);">寬度不一樣)
所以我不用全屏模式, 解決這個(gè)問題也很簡單, 我寫了一個(gè)定時(shí)器監(jiān)聽文本高度, 等待初始化完成之后直接改變編輯器高度即可
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);
};
###工具欄智能定位
當(dāng)我的文本內(nèi)容很多, 高度非常高的時(shí)候, 滾動條需要拉很遠(yuǎn)才能到最底部, 此時(shí)工具欄是固定在編輯器最上方的
那我需要將底部文字小小地加個(gè)粗豈不是都要拉滾動條拉個(gè)2分鐘才能加到粗? 然后加完粗再拉個(gè)2分鐘拉回底部?
所以為了解決這個(gè)問題, 我加了一個(gè)滾動條監(jiān)聽事件
當(dāng)滾動條到達(dá)工具欄的高度時(shí), 工具欄定位就固定在屏幕上方, 也就是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監(jiān)聽事件綁定到DOM加載完成事件上(kindEditor.ready) , 如果你寫了ready函數(shù)了, 那么你只需要將我的代碼追加進(jìn)去即可
//我只展示了實(shí)現(xiàn)智能定位這個(gè)功能的代碼, C和getTop2個(gè)函數(shù) 是我經(jīng)常用到的自定義函數(shù), 功能就是類似于JQ的$和offset()
當(dāng)然加了這段JS你還是不能舒服, 因?yàn)檫€缺少樣式, 比如點(diǎn)擊按鈕的下拉欄是根據(jù)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配合使用, 這次就真滴舒服了, 闊以來看看修改完后的效果:
如對本文有疑問,請?zhí)峤坏浇涣髡搲瑥V大熱心網(wǎng)友會為你解答!! 點(diǎn)擊進(jìn)入論壇