Skip to content

XSS-Angriffe, Teil 6: Ein verbesserter Portscanner

Bisher haben Sie schon erfahren, wie sich mit JavaScript ein Ping-Befehl und ein Portscanner für einen Host implementieren lässt. Dieser Portscanner wird nun zu einem Portscanner für einen IP-Adressbereich erweitert.

Ein einfacher Portscanner für einen IP-Adressbereich

Soll nicht nur ein einzelner Host, sondern ein IP-Adressbereich gescannt werden, muss scanHost() lediglich für jede zu prüfende IP-Adresse aufgerufen werden. Werden die IP-Adressen als String in der Form a.b.c.d übergeben, muss daraus zuerst ein Array mit Integer-Werten erzeugt werden. Dies kann eine Funktion nach folgendem Muster übernehmen:

function erzeugeIPArray(ipString) {
   var stringArray = ipString.split('.');
      // String in Array mit Strings aufteilen
   var intArray = new Array();
      // Array für Integer-Werte bereitstellen
   var i;
   for(i =0; i < stringArray.length; i++) 
   {
      intArray[i] = parseInt(stringArray[i]);
         // String in Integer-Wert umwandeln
    }
    return intArray;
}

Die IP-Adressen können nicht durch einfaches Heraufzählen durchgegangen werden. Stattdessen übernimmt zum Beispiel folgende Funktion das Berechnen der nächsten IP-Adresse:

function erhoeheIP(dieIP) {
   var i;
   for(i = 3; i>=0; i--) 
   {
      if(dieIP[i] < 255 ¦¦ i == 0) 
      {
         dieIP[i]++;
         return dieIP;
      } 
      else {
         // Der Wert im aktuellen Segment i kann nicht erhöht werden,
         // da dass zu einem Überlauf führen würde
         // Daher muss im Segment davor weitergemacht werden
         dieIP[i] = 0;
         dieIP[i-1]++;
      }
   }
}

Beide Beispiele orientieren sich an der Demo der SPI Labs (auf archive.org).

Jetzt geht es los! Aber wo????

Wir haben jetzt alles zusammen, um nicht nur einen einzelnen Host, sondern einen ganzen IP-Adressbereich zu scannen. Das einzige, was für einen automatisierten Scan jetzt noch fehlt, ist der Startpunkt: Welche IP-Adressen sollen gescannt werden?

In einer Demo wie der der SPI Labs (auf archive.org), von GNUCITIZEN oder den Attack and Defense Labs können Start- und Ziel-Adresse einfach über ein Formular abgefragt werden, ein Angreifer hat diese Möglichkeit aber nicht. OK, theoretisch könnte er versuchen, sein Opfer per Social Engineering zur Eingabe der IP-Adressen zu bewegen, aber so ein Angriff wäre wohl nicht besonders erfolgreich. Also muss der Angreifer Start- und Zieladressen selbst festlegen.

Dabei könnte er einfach 'blind' arbeiten und sein Script verschiedene, typische Adressbereiche für lokale Netze durchprobieren lassen. Die meisten in Homeoffices und kleinen Unternehmen eingesetzten DSL-Router verwenden in der Default-Einstellung Adressen aus dem Bereich 192.168.0.* oder 192.168.1.*, und bekanntlich werden Default-Einstellungen äußerst selten geändert. Auch bei größeren Unternehmen kann ein Versuch in diesem Bereich oder in den anderen privaten Bereichen nicht schaden, und falls das Unternehmen einen eigenen IP-Adressbereich reserviert hat, wird der natürlich auch durchsucht. Wobei ein Durchsuchen aller möglichen Bereiche am entstehenden Aufwand scheitert: Der Scan dauert schlicht zu lange, um erfolgreich abgeschlossen zu werden. Möchte der Angreifer nicht 'blind' arbeiten, muss er die aktuelle IP-Adresse des Rechners ermitteln, auf dem der eingeschleuste Skriptcode läuft. Am schönsten wäre es natürlich, wenn man die einfach abfragen könnte. Das geht nicht mit JavaScript, dafür aber mit Java.

Cyberangriff! Ihre IP-Adresse, bitte!

Diese Möglichkeit wurde bereits 2003 auf der Mailingliste NT-Bugtraq erwähnt: 'Using Java from Javascript'. Eine aktuellere Beispiel-Implementierung gibt es bei GNUCITIZEN, der entsprechende Code ist auch Bestandteil der von GNUCITIZEN entwickelten AttackAPI. Daraus stammt auch der folgende Ausschnitt:

AttackAPI.dom.getInternalIP = function () {
  try {
    var sock = new java.net.Socket();

    sock.bind(new java.net.InetSocketAddress('0.0.0.0', 0));
    sock.connect(new java.net.InetSocketAddress(document.domain,
              (!document.location.port)?80:document.location.port));

    return sock.getLocalAddress().getHostAddress();	
    } catch (e) {}

    return '127.0.0.1';
};

Es wird eine Java-Socket-Verbindung zwischen Client und Webserver aufgebaut. Nach einem erfolgreichen Verbindungsaufbau wird die Socket-Struktur mit Informationen über die Verbindung gefüllt - darunter auch die lokale IP-Adresse, die dann nur noch abgefragt werden muss.

Nun ist Java in letzter Zeit ziemlich in Verruf geraten und im Browser nicht mehr automatisch verfügbar. Die lokale IP-Adresse lässt sich mit etwas Aufwand aber auch mit Hilfe von JavaScript ermitteln. Die Attack and Defense Labs haben das Problem zum Beispiel so gelöst:

Ausgehend von der Annahme, dass die meisten SOHO-Benutzer IP-Adressen aus dem Bereich 192.168.x.x verwenden, der Router meist die Adresse 192.168.x.1 hat und seine Admin-Oberfläche über Port 80 oder 443 erreichbar ist, lässt sich die lokale IP-Adresse in zwei Schritten ermitteln:

  1. Stelle fest, in welchem Subnet sich der Rechner befindet
    Dazu kann Port 80 und/oder 443 der IP-Adressen 192.168.0.1 bis 192.168.255.1 gescannt werden. Befindet sich der angegriffene Webbrowser zum Beispiel im Subnet 192.168.5.x, würde sein Router mit der IP-Adresse 192.168.5.1 auf den Scan antworten und damit das Subnet verraten.
  2. Stelle fest, welche IP-Adresse der Rechner hat
    Nachdem das Subnet bekannt ist kann das gesamte Subnet nach einem Port gescannt werden, der von Personal Firewalls gefiltert wird wie zum Beispiel Port 30000. Es wird also von 192.169.x.2 bis 192.168.x.254 nach Port 30000 gesucht. Wird die IP-Adresse des eigenen Rechners erreicht, gibt es eine Antwort (open/closed), da der vom Browser erzeugte Request an Port 30000 von der eigenen Personal Firewall nicht blockiert wird.

Jetzt können wir mit ganz normalen JavaScript im lokalen Netz nach interessanten Zielen suchen. In der nächsten Folge wird noch eine dabei störende Kleinigkeit aus dem Weg geräumt, danach geht es um Portscans im Zeitalter von HTML5 (und damit Cross-Origin Requests und WebSockets).

Carsten Eilers


Übersicht über alle Artikel zum Thema

Cross-Site Scripting im Überblick, Teil 1: Reflektiertes XSS
Cross-Site Scripting im Überblick, Teil 2: Persistentes XSS
Cross-Site Scripting im Überblick, Teil 3: Der MySpace-Wurm Samy
Angriffe über Cross-Site Scripting: Der Sourcecode des MySpace-Wurms Samy
Cross-Site Scripting im Überblick, Teil 4: DOM-basiertes XSS
Cross-Site Scripting im Überblick, Teil 5: Resident XSS
XSS-Angriffe, Teil 1: Informationen einschleusen
XSS-Angriffe, Teil 2: Cookies und Tastendrücke ausspähen
XSS-Angriffe, Teil 3: Zugangsdaten ausspähen
XSS-Angriffe, Teil 4: Ein Blick in die History, und dann auf ins LAN!
XSS-Angriffe, Teil 5: Ein Portscan (nicht nur) im LAN
XSS-Angriffe, Teil 6: Ein verbesserter Portscanner
XSS-Angriffe, Teil 7: Hindernisse beim JavaScript-Portscan beseitigen
XSS-Angriffe, Teil 8: Ein Portscan mit WebSockets oder Cross-Origin Requests
XSS-Angriffe, Teil 9: Der Router im Visier
XSS-Angriffe, Teil 10: Weitere Angriffe auf den Router
XSS-Angriffe, Teil 11: Unerwünschtes Firmware-Update für den Router
XSS-Angriffe, Teil 12: Browser-basierte Botnets
XSS-Angriffe, Teil 13: Fortgeschrittene Angriffe
XSS-Angriffe, Teil 14: Das Browser Exploitation Framework BeEF

Trackbacks

Dipl.-Inform. Carsten Eilers am : Filet-o-Firewall - ein neuer browserbasierter Angriff auf die Firewall

Vorschau anzeigen
Jetzt habe ich gestern doch glatt vergessen, den Text online zu stellen. Also mit kurzer Verzögerung: Wie angekündigt geht es ab dieser Folge erst mal wieder um aktuellere Themen. Den Anfang machen Schwachstellen in und Angriffe au

Dipl.-Inform. Carsten Eilers am : Die IoT Top 10, #1: Unsichere Weboberflächen, Teil 5

Vorschau anzeigen
Die Beschreibung der gefährlichsten Schwachstellen in den Geräten des IoT geht weiter. In der Liste der Top IoT Vulnerabilities von OWASP sind wir immer noch bei Platz 1, dem &quot;Insecure Web Interface&quot;. Aber wenigstens sind wir beim zweiten