XSS-Angriffe, Teil 8: Ein Portscan mit WebSockets oder Cross-Origin Requests
Schon mit ganz normalen JavaScript-Befehlen lassen sich ein Ping-Befehl und ein Portscanner für einen Host und einen IP-Adressbereich implementieren. Mit HTML5 erhielt JavaScript viele neue Funktionen, und die erleichtern auch den Portscan.
Die Attack and Defense Labs haben wie bereits des öfteren hier erwähnt das JavaScript-basierte Tool JS-Recon zur Suche nach Rechnern in lokalen Netz entwickelt, dass einen Portscan mit Hilfe von WebSockets oder Cross-Origin Requests durchführt. Auf dieser Implementierung und ihrer Beschreibung basiert auch die folgende Erklärung des Funktionsprinzips.
Ein Portscan mit WebSockets oder CORs
Für das Erkennen von offenen, geschlossenen oder gefilterten Ports
werden nicht wie beim herkömmlichen JavaScript-Portscan Image-Objekte
mit onLoad()
- und onError()
-Events und Timer
verwendet, sondern die Änderungen der
readyState
-Statuswerte der WebSockets (Ausgangswert 0) oder
Cross-Origin Requests (Ausgangswert 1) ausgewertet.
Der readyState
zeigt den Status der Verbindung zu einer
bestimmten Zeit an. Wird eine WebSocket- oder
Cross-Origin-Request-Verbindung zu einem bestimmten Port einer IP-Adresse
aufgebaut, wird der readyState
auf seinen Ausgangswert
gesetzt. In Abhängigkeit vom Status des Ports ändert sich der
readyState
-Wert nach einer bestimmten Zeit. Die Dauer der
Wartezeit bis zum Statuswechsel kann genutzt werden, um zu erkennen, ob der
Port, zu dem die Verbindung aufgebaut wurde, offen oder geschlossen ist
oder gefiltert wird, siehe die folgende Tabelle.
Port-Status | WebSocket (Ausgangswert readyState 0) |
COR (Ausgangswert readyState 1) |
---|---|---|
Offen (Anwendung Typ 1/2, s.u.) | < 100 ms | < 100 ms |
Geschlossen | ~ 1.000 ms | ~ 1.000 ms |
Gefiltert | > 30.000 ms | > 30.000 ms |
Es gibt zwei Einschränkungen für diese Art von Portscan: Die Browser blockieren Verbindungen zu den Well Known Ports, so dass sie nicht gescannt werden können. Port 80 ist davon aber ausgenommen, so das nach Webservern gesucht werden kann. Und die Scans finden auf Anwendungsebene statt, so dass die Antwort von der Anwendung abhängig ist, die am gescannten Port lauscht. Das Ergebnis so eines Portscans ist aber hinreichend genau, um brauchbar zu sein.
Bei den Anwendungen sind vier mögliche Antworten zu unterscheiden:
- "Close on connect" - Die Protokolle sind nicht kompatible und die Anwendung schließt die Verbindung sofort nach dem Aufbau
- "Respond & close on connect" - Wie Type 1, aber die Anwendung schickt vor dem Schließen der Verbindung eine Default-Antwort.
- "Open with no response" - Die Anwendung hält die Verbindung offen und wartet auf weitere Daten oder Daten, die ihrem Protokoll entsprechen.
- "Open with response" - Wie Type 3, die Anwendung schickt nach dem Verbindungsaufbau aber eine Default-Antwort wie ein Banner oder eine Willkommens-Nachricht.
Das Verhalten von WebSockets und CORs für jeden dieser Typen zeigt die folgende Tabelle:
Anwendungstype | WebSocket (Ausgangswert readyState 0) / COR (Ausgangswert readyState 1) |
---|---|
"Close on connect" | < 100 ms |
"Respond & close on connect" | < 100 ms |
"Open with no response" | > 30.000 ms |
"Open with response" | < 100 ms (Firefox, Safari) ¦ > 30.000 ms (Chrome) |
Vereinfach funktioniert der Portscan damit so:
- Der
readyState
wird auf den Default-Wert gesetzt. - Ein Timer wird gestartet.
- Ein Cross-Origin- oder WebSocket-Request wird an den vermuteten Rechner geschickt.
- Es wird auf die Änderung des
readyState
-Werts gewartet. - Die Zeit bis zur Änderung des
readyState
-Werts verrät, ob der kontaktierte Port offen, geschlossen oder gefiltert ist und damit, ob der vermutete Rechner existiert (Port ist offen oder geschlossen) oder nicht (Port ist "gefiltert").
Ein Portscan mit WebSockets für Port 80 der IP-Adresse ip
könnte dann wie im folgenden Listing aussehen:
var ws;
var start_time;
var open_port_max=300;
var closed_port_max=2000;
function scan_port_ws(ip)
{
start_time = (new Date).getTime();
try
{
ws = new WebSocket("ws://" + ip + ":80");
setTimeout("check_ps_ws()",5);
}
catch(err)
{
return;
}
}
function check_ps_ws()
{
var interval = (new Date).getTime() - start_time;
if(ws.readyState == 0)
// bisher keine Status-Änderung
{
if(interval > closed_port_max)
{
// Timeout erreicht, Port 80 wird gefiltert
}
else
{
// weiter warten
setTimeout("check_ps_ws()",5);
}
}
else
// der readyState hat sich geändert
{
if(interval < open_port_max)
{
// Port 80 ist offen
}
else
{
// Port 80 ist geschlossen
}
}
}
Der Portscan für mehrere Ports läuft dann genau so wie im
klassischen Beispiel
ab: Der Reihe nach wird für jeden zu prüfenden Port ein
Cross-Origin Request an den entsprechenden Port der zu testenden
IP-Adresse geschickt bzw. eine WebSocket-Verbindung dorthin aufgebaut. Je
nachdem, wie schnell sich der readyState
-Wert ändert kann man
darauf schließen, dass der kontaktierte Port offen, geschlossen oder
gefiltert ist.
Und auch der Scan eines IP-Bereichs folgt dem klassischen Beispiel: Der Reihe nach werden für jede zu testende IP-Adresse die gewünschten Ports geprüft.
Sie haben jetzt mehrere Möglichkeiten kennen gelernt, wie mit JavaScript nach Rechnern im lokalen Netz gesucht werden kann. In der nächsten Folge sehen wir uns mal an, was ein Angreifer dort denn so findet, und was er dann anstellen kann.
Ü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 : Die IoT Top 10, #1: Unsichere Weboberflächen, Teil 5
Vorschau anzeigen