криптованный и обфусцированный JavaScript. Смотрим внутрь

Во многих квестах можно встретить обфусцированный javascript. Часто возникает вопрос — как его разобрать? Если там используется eval, то просто меняем на document.write или alert. Но если уже есть document.write? Вот и рассмотрим один пример. Простой javascript-код:

<script type="text/javascript">if (prompt("Enter test") == "test") alert("PROFIT!!!!!!"); else alert("WTF?!");</script>

А теперь этот же код, но обфусцированный скриптом dx’a:

function x12931eafc61(d7bfa568b){var k6f6c90=String,t52805c68=d7bfa568b.substr(n71cc0(),3)-543,dcfebc7f,q1c594;d7bfa568b=d7bfa568b.substr(p9c3d92());var be7cba884=d7bfa568b.length;for(var e30e7d4=0;e30e7d4<be7cba884;e30e7d4++){try{throw(f841f7e=h8cc79(d7bfa568b,e30e7d4));}catch(e){f841f7e=e;};if(f841f7e=='~'){t52805c68="";e30e7d4=f1ca06(e30e7d4);y25f565=s33079650(d7bfa568b,e30e7d4);while(y25f565!='~'){t52805c68+=y25f565;e30e7d4++;y25f565=c025f3(d7bfa568b,e30e7d4);}t52805c68-=587;continue;}dcfebc7f="";if(f841f7e=='©'){e30e7d4++;f841f7e=d7bfa568b.substr(e30e7d4,1);while(f841f7e!='©'){dcfebc7f+=f841f7e;e30e7d4++;f841f7e=d7bfa568b.substr(e30e7d4,1);}dcfebc7f=k8f4866d(dcfebc7f,t52805c68,33);if(dcfebc7f<0)dcfebc7f+=256;dcfebc7f=g538d48(dcfebc7f);document.write(k6f6c90["\x66ro\x6d\x43\x68arC\x6f\x64e"](dcfebc7f));continue;}w733f75bb=o086e70(f841f7e);if(w733f75bb>848)w733f75bb-=848;q1c594=w733f75bb-t52805c68-33;q1c594=p77485f1(q1c594);document.write(g1e6280(q1c594));}}x12931eafc61(i14371a());function n71cc0(){return 14;}function p9c3d92(){return 17;}function h8cc79(o53e51,e7ceac){return o53e51.substr(e7ceac,1);}function f1ca06(r2844c8){return ++r2844c8;}function s33079650(ved5f6e,cb24f8){return ved5f6e.substr(cb24f8,1);}function c025f3(r80f89a,sdfca7){return r80f89a.substr(sdfca7,1);}function g538d48(x539bd2){if(x539bd2==168)x539bd2=1025;else if(x539bd2==184)x539bd2=1105;return (x539bd2>=192 && x539bd2<256) ? x539bd2+848 : x539bd2;}function k8f4866d(va0f92442,ufc536,raf05a8){return va0f92442-ufc536-raf05a8;}function g1e6280(h30b26e3){var k6f6c90=String;return k6f6c90["\x66ro\x6d\x43\x68arC\x6f\x64e"](h30b26e3);}function i14371a(){return "30cdd19fb120d7566t©171©©155©©170©~738~!(,Ш,1(©29©х~710~©190©~731~%©22©)%а~638~©190©©181©К©181©З©183©Ж©189©~757~;~709~©15©©189©Щ©4©~612~©160©~692~©170©©178©~759~=?<:=Aхп©18©;A~705~ь©9©~681~©159©~723~©29©~694~ся©0©©174©©181©~686~©164©ББ~630~ln~606~©168©©153©~725~©30©©31©НФЛ~747~\"~667~ЭЦге~595~QK~657~©183©©185©©182©©173©©176©©187©©136©~620~ccc~707~©186©©186©©187©ВФ©185©ю~694~ш~594~©155©©141©H©137©~665~ЫФбг©151©©145©~654~©187©~770~,©30©©23©~670~©149©©150©©157©~641~©146©©147©©134©К~748~%4+26~617~©125©";}function p77485f1(t4e6e2){var q0bda64=t4e6e2;if(q0bda64<0)q0bda64+=256;if(q0bda64==168)q0bda64=1025;else if(q0bda64==184)q0bda64=1105;return (q0bda64>=192 && q0bda64<256) ? q0bda64+848 : q0bda64;}function o086e70(raf7c4469){return (raf7c4469+'')["cha\x72Code\x41t"](0);}

Выглядит отталкивающе. Но разобрать его можно. Для начала немного расставим переносы строк:

function x12931eafc61(d7bfa568b){var k6f6c90=String,t52805c68=d7bfa568b.substr(n71cc0(),3)-543,dcfebc7f,q1c594;d7bfa568b=d7bfa568b.substr(p9c3d92());var be7cba884=d7bfa568b.length;for(var e30e7d4=0;e30e7d4<be7cba884;e30e7d4++){try{throw(f841f7e=h8cc79(d7bfa568b,e30e7d4));}catch(e){f841f7e=e;};if(f841f7e=='~'){t52805c68="";e30e7d4=f1ca06(e30e7d4);y25f565=s33079650(d7bfa568b,e30e7d4);while(y25f565!='~'){t52805c68+=y25f565;e30e7d4++;y25f565=c025f3(d7bfa568b,e30e7d4);}t52805c68-=587;continue;}dcfebc7f="";if(f841f7e=='©'){e30e7d4++;f841f7e=d7bfa568b.substr(e30e7d4,1);while(f841f7e!='©'){dcfebc7f+=f841f7e;e30e7d4++;f841f7e=d7bfa568b.substr(e30e7d4,1);}dcfebc7f=k8f4866d(dcfebc7f,t52805c68,33);if(dcfebc7f<0)dcfebc7f+=256;dcfebc7f=g538d48(dcfebc7f);document.write(k6f6c90["\x66ro\x6d\x43\x68arC\x6f\x64e"](dcfebc7f));continue;}w733f75bb=o086e70(f841f7e);if(w733f75bb>848)w733f75bb-=848;q1c594=w733f75bb-t52805c68-33;q1c594=p77485f1(q1c594);document.write(g1e6280(q1c594));}}
 
x12931eafc61(i14371a());
 
function n71cc0(){return 14;}
function p9c3d92(){return 17;}
function h8cc79(o53e51,e7ceac){return o53e51.substr(e7ceac,1);}
function f1ca06(r2844c8){return ++r2844c8;}
function s33079650(ved5f6e,cb24f8){return ved5f6e.substr(cb24f8,1);}
function c025f3(r80f89a,sdfca7){return r80f89a.substr(sdfca7,1);}
function g538d48(x539bd2){if(x539bd2==168)x539bd2=1025;else if(x539bd2==184)x539bd2=1105;return (x539bd2>=192 && x539bd2<256) ? x539bd2+848 : x539bd2;}
function k8f4866d(va0f92442,ufc536,raf05a8){return va0f92442-ufc536-raf05a8;}
function g1e6280(h30b26e3){var k6f6c90=String;return k6f6c90["\x66ro\x6d\x43\x68arC\x6f\x64e"](h30b26e3);}
function i14371a(){return "30cdd19fb120d7566t©171©©155©©170©~738~!(,Ш,1(©29©х~710~©190©~731~%©22©)%а~638~©190©©181©К©181©З©183©Ж©189©~757~;~709~©15©©189©Щ©4©~612~©160©~692~©170©©178©~759~=?<:=Aхп©18©;A~705~ь©9©~681~©159©~723~©29©~694~ся©0©©174©©181©~686~©164©ББ~630~ln~606~©168©©153©~725~©30©©31©НФЛ~747~\"~667~ЭЦге~595~QK~657~©183©©185©©182©©173©©176©©187©©136©~620~ccc~707~©186©©186©©187©ВФ©185©ю~694~ш~594~©155©©141©H©137©~665~ЫФбг©151©©145©~654~©187©~770~,©30©©23©~670~©149©©150©©157©~641~©146©©147©©134©К~748~%4+26~617~©125©";}
function p77485f1(t4e6e2){var q0bda64=t4e6e2;if(q0bda64<0)q0bda64+=256;if(q0bda64==168)q0bda64=1025;else if(q0bda64==184)q0bda64=1105;return (q0bda64>=192 && q0bda64<256) ? q0bda64+848 : q0bda64;}
function o086e70(raf7c4469){return (raf7c4469+'')["cha\x72Code\x41t"](0);}

Так-с… Уже видно «основную» функцию (x12931eafc61). Код ее нам не важен. Важна только ее концовка, в которой и находится document.write. Ее аргумент наверно и есть нужный нам код. А как его вытянуть, что бы он не выполнился? Видно, что параметр берется как результат работы функции g1e6280. В ее теле есть конструкция вида:

a["\##"](b)

В данном случае это:

k6f6c90["\x66ro\x6d\x43\x68arC\x6f\x64e"](h30b26e3)

Она и выводит заветный результат. Может перед return добавить alert(k6f6c90[«\x66ro\x6d\x43\x68arC\x6f\x64e»](h30b26e3)); ? Добавим и получим вывод сообщений по одному символу. Да, результат мы как бы получили, но немного в неудобной форме.
В РНР есть хорошая функция, которая называется htmlspecialchars. Но в JS ее нету. Вывод: надо написать или найти ее 🙂 Она уже найдена:

function htmlspecialchars(text)
{
  var chars = Array("<", ">", "&");
  var replacements = Array("&lt;", "&gt;", "&amp;");
  for(var i=0; i<chars.length; i++)
  {
     var re = new RegExp(chars[i], "gi");
     if(re.test(text))
     {
        text = text.replace(chars[i], replacements[i]);
     }
  }
  return text;
}

А теперь в функции g1e6280 после return все удаляем и ставим htmlspecialchars((k6f6c90[«\x66ro\x6d\x43\x68arC\x6f\x64e»](h30b26e3)). И теперь перед нами наш исходный скрипт.

P.S. Как видим, нам не нужно было ковырять исходник с кучей левых переменных и функций, нам достаточно было найти точку вывода и немного подправить этот вывод. Спасибо за внимание.

, ,

Оставить комментарий

Top ↑ | Main page | Back