Schwachstelle in Xinetd: Zugriff über TCPMUX

Der Superserver Xinetd ist der um zahlreiche Sicherheitsfeatures erweiterte Nachfolger des Daemons Inetd. Seine Hauptaufgabe besteht darin, auf bestimmten Netzwerkports nach Verbindungen zu lauschen. Sollte eine solche Verbindung aufgebaut werden so startet Xinetd das passende Serverprogramm. Einige sehr einfache Netzwerkprotokolle sind auch direkt in Xinetd implementiert. Dazu gehören beispielsweise die Daytime-, Discard- oder Echo-Dienste. Da Xinetd alle Netzwerkdienste verwaltet, lassen sich über den Superserver auch einfach Zugangsbeschränkungen realisieren, beispielsweise über ACLs TCP-Wrapper.

Unter den zahlreichen von Xinetd unterstützten Protokollen findet sich auch der Dienst TCPMUX beziehungsweise TCPMUXPLUS. Dieser in RFC 1078 spezifizierte Dienst wird über Port 1 bereitgestellt. Genauso speziell wie die Portnummer von TCPMUX ist auch dessen Aufgabenfeld: TCPMUX ist nur ein Vermittler. Ein Client sendet an einen TCPMUX-Daemon eine Anfrage in Form eines Protokollnamens, mit dem er eine Verbindung aufbauen möchte. Der TCPMUX-Server antwortet hierauf entweder mit “+” oder “-” je nachdem, ob der angefragte Dienst auf dem System vorhanden ist. Im Falle einer positiven Antwort wird das angeforderte Protokoll sofort gestartet. Im negativen Fall wird die Verbindung einfach geschlossen.

Unterstützt nun Xinetd auf einem System TCPMUX, verbietet aber bestimmte andere Dienste, so kann ein Angreifer per TCPMUX trotzdem auf diese zugreifen. Die Idee hinter der Attacke ist sehr einfach: Xinetd lässt TCPMUX zu, und der Angreifer kann über diesen Multiplexer Zugriff auf andere, eigentlich verbotene Protokolle erlangen.

Eine Attacke kann man folgendermaßen auf dem eigenen System reproduzieren:

  • TCPmux-server aktivieren
  • Xinetd neu starten
  • “telnet locahost 1”

Das letzte Kommando baut eine Verbindung zu TCPMUX auf. Anschließend kann dann der Name eines Dienstes eingegeben werden:

# telnet localhost 1
Trying 127.0.0.1...
Connected to localhost.localdomain (127.0.0.1).
Escape character is '^]'.
cvspserver
cvs [pserver aborted]: bad auth protocol start:

In diesem Beispiel wird der Dienst “cvspserver” verlangt, welcher dann auch startet.

Diese Sicherheitslücke wurde von Thomas Swan entdeckt, der auch ein Patch für diese Schwachstelle bereitgestellt hat. Dieser sieht so aus:

--- xinetd-2.3.14/xinetd/builtins.c.old 2012-02-15 16:29:48.263844700 -0600
+++ xinetd-2.3.14/xinetd/builtins.c 2012-02-15 16:37:52.209594438 -0600
@@ -560,17 +560,16 @@ /* Found the pointer. Validate its type. */ scp = SVC_CONF( sp );
-/*
- if ( ! SVC_IS_MUXCLIENT( sp ) )
+
+ if ( ! SVC_IS_MUXCLIENT( sp ) && ! SVC_IS_MUXPLUSCLIENT( sp ) ) { if ( debug.on ) { msg(LOG_DEBUG, "tcpmux_handler", "Non-tcpmux service name: %s.", svc_name); }
- exit(0);
+ continue; }
-*/ /* Send the accept string if we're a PLUS (+) client. */
@@ -597,6 +596,19 @@ msg(LOG_DEBUG, "tcpmux_handler", "Service name %s not found.", svc_name); }
+
+ /* If a service was not found, we should say so. */
+ if ( Swrite( descriptor, TCPMUX_NOT_FOUND, sizeof( TCPMUX_NOT_FOUND ) ) !=
+ sizeof ( TCPMUX_NOT_FOUND ) )
+ {
+ msg(LOG_ERR, "tcpmux_handler", "Not found write failed for %s.",
+ svc_name);
+ exit(0);
+ }
+
+ /* Flush and exit, nothing to do */
+ Sflush( descriptor );
+ Sclose( descriptor ); exit(0); }

Betroffen sind die Versionen vor 2.3.15.

Nach oben