
https://hackerone.com/reports/863553
Die URL-Validierungslogik, die bei der Verarbeitung von /appsuite/api/oxodocumentfilter&action=addfile angewendet wird, weist drei Schwachstellen auf, die zur Ausführung eines Time of Check Time of Use (ToCToU)-SSRF-Angriffs genutzt werden können. Dieses Problem ermöglicht es Angreifern, HTTP-GET-Anfragen an interne Netzwerkdienste zu senden und kann zur Offenlegung geschützter Informationen führen.
Die URL-Validierungslogik in der Methode URITools.getFinalURL, die hier implementiert ist, weist eine ToCToU-Schwachstelle auf.
URL u = new URL(url);
if (validator.isPresent()) {
Optional<OXException> exception = validator.get().apply(u);
if (exception.isPresent()) {
throw exception.get();
}
}
URLConnection urlConnnection = u.openConnection();
Im obigen Code wird die DNS-Auflösung des Hostnamens der Eingabe-URL sowohl zum Zeitpunkt der Prüfung (validator.get().apply(u)) als auch zum Zeitpunkt der Nutzung (u.openConnection()) über die Methode InetAddress.getByName durchgeführt. Wenn ein Angreifer das DNS-Auflösungsergebnis nach dem Zeitpunkt der Prüfung und vor dem Zeitpunkt der Nutzung ändern kann, kann er den Validator umgehen. Diese Schwachstelle allein ist aufgrund der folgenden Einschränkungen äußerst schwer auszunutzen:
InetAddress.getByName die DNS-Auflösungsergebnisse für 30 Sekunden zwischen, wenn die DNS-Auflösung erfolgreich ist, und für 10 Sekunden, wenn die DNS-Auflösung fehlschlägt.validator.get().apply(u) und u.openConnection() ist extrem klein (bei normalen URLs weniger als eine Millisekunde). Schwachstelle Nr. 2 wird verwendet, um diese Einschränkung zu umgehen.Der URL-Validator AddFileAction.validator, der hier implementiert ist, validiert die Länge der Eingabe-URL nicht. Durch die Bereitstellung einer URL mit großer Größe kann der Angreifer das Zeitintervall zwischen den InetAddress.getByName-Methodenaufrufen zum Zeitpunkt der Prüfung und zum Zeitpunkt der Nutzung vergrößern. Ein größeres Zeitintervall ermöglicht es dem Angreifer, Schwachstelle Nr. 1 leicht auszunutzen.
Die Methode HostList.contains, die hier implementiert ist, gibt false zurück, wenn die DNS-Auflösung des Hostnamens der Eingabe-URL fehlschlägt.
// Need to resolve as last resort
try {
return contains(InetAddress.getByName(toCheck), false);
} catch (UnknownHostException e) {
// Cannot be resolved
return false;
}
Der AddFileAction.validator ruft die Methode blackImageUrlHostlist.contains auf, um zu prüfen, ob der Hostname der Eingabe-URL oder die IP-Adresse, auf die er aufgelöst wird, in der Blacklist enthalten ist. Wenn ein Angreifer die DNS-Auflösung des Hostnamens fehlschlagen lässt, werden die IP-Adressprüfungen übersprungen und die URL wird akzeptiert.
Betrachten wir einen Hostnamen randomid.dns.pointer.pw, dessen autoritativer Nameserver vom Angreifer kontrolliert wird. Die Angriffsstrategie besteht darin, die DNS-Auflösung von randomid.dns.pointer.pw zum Zeitpunkt der Prüfung (validator.get().apply(u);) fehlschlagen zu lassen und zum Zeitpunkt der Nutzung (u.openConnection()) erfolgreich sein zu lassen. Dies ermöglicht es dem Angreifer, IP-Adress-Blacklist-Filter zu umgehen und HTTP-GET-Anfragen an jede geblacklistete IP-Adresse auszuführen. Der Angreifer kann die folgenden Schritte ausführen, um diesen Angriff durchzuführen:
InetAddress.getByName-Cache auf dem Server aus, indem du die addfile-Aktion mit den Anfragedaten {"add_imageurl": "http://randomid.dns.pointer.pw"} ausführst. Zu diesem Zeitpunkt wird der autoritative DNS-Server so eingestellt, dass die DNS-Auflösung von randomid.dns.pointer.pw fehlschlägt, indem er den Status SERVFAIL zurückgibt. InetAddress.getByName wird dieses Fehlerergebnis für 10 Sekunden zwischenspeichern.pointer.pw, für DNS-Anfragen vom Typ A des Hostnamens randomid.dns.pointer.pw die Adresse 127.0.0.1 zurückzugeben.InetAddress.getByName im nächsten Schritt zum Zeitpunkt der Prüfung die zwischengespeicherte Antwort (SERVFAIL) zurückgibt und zum Zeitpunkt der Nutzung (url.openConnection()) 127.0.0.1 zurückgibt.Installiere golang von https://golang.org/dl/
Installiere Open-Xchange und Documents in einer virtuellen Maschine mit mindestens 4 GB RAM, indem du den Anleitungen https://oxpedia.org/wiki/index.php?title=AppSuite:Open-Xchange_Installation_Guide_for_Debian_9.0 und https://oxpedia.org/wiki/index.php?title=AppSuite:Documents_Installation_Guide#Debian_GNU.2FLinux_9.0_.28valid_from_v7.10.29 folgst.
Lade die Datei poc.zip herunter und entpacke sie.
Öffne ein Terminal / eine Befehlszeile und setze das aktuelle Verzeichnis auf den extrahierten poc.zip-Ordner.
Führe den folgenden Befehl aus:
go run . -serverRoot="http://172.16.66.130" -username="testuser" -password="secret" -targetPath="appsuite/v=7.10.3-9.20200409.083030/apps/themes/logo.png" -targetPort="80" -payloadSize=25 -startSleepDuration=6600
wobei 172.16.66.130 die IP-Adresse der VM ist.
add_imageurlhttp://u{25MB}:[email protected]/path/to/internal/resource.pngu{25MB}