
Vor einem Jahr, am 21. MĂ€rz 2019, in auf HackerOne kam ein sehr guter ab . Bei der Implementierung eines Nullbytes (ASCII 0) in einen POST-Parameter einer der API-Anfragen der Webmail, die einen HTTP-Redirect zurĂŒckgab, waren in den Redirect-Daten Ausschnitte uninitialisierter Speicherbereiche sichtbar, in denen hĂ€ufig Fragmente aus GET-Parametern und Headern anderer Anfragen an denselben Server offenbart wurden.
Dies ist eine kritische Schwachstelle, da die Anfragen unter anderem Sitzungscookies enthalten. Einige Stunden spÀter wurde ein temporÀrer Fix erstellt, der das Nullbyte filterte (wie sich spÀter herausstellte, war das nicht ausreichend, da weiterhin eine Möglichkeit zur Injektion von CRLF / ASCII 13, 10 bestand, was die Manipulation von Headern und HTTP-Antwortdaten ermöglicht, weniger kritisch, aber dennoch unangenehm). Zeitgleich wurde das Problem an die Sicherheitsanalysten und Entwickler weitergeleitet, um die Ursachen des Bugs zu untersuchen und zu beheben.
Mail.ru ist eine sehr komplexe Anwendung, bei der eine Vielzahl verschiedener Frontend-/Backend-Komponenten beteiligt sein kann, sowohl Open-Source (ein groĂes Dankeschön an alle Entwickler von Open-Source-Software) als auch eigenentwickelte. Es gelang, alle Komponenten auĂer nginx und openresty auszuschlieĂen und das Problem bis zum Aufruf im OpenResty-Skript zu lokalisieren, das sich nicht wie erwartet verhielt (es ist nicht möglich, ein Null-Byte oder einen Zeilenumbruch ĂŒber GET-Parameter mit rewrite im ngx_http_rewrite_module einzufĂŒgen, das laut Dokumentation verwendet wird und angeblich absolut gleichartig funktionieren sollte). Mögliche Folgen wurden ausgeschlossen, eine so strenge Filterung wie möglich hinzugefĂŒgt und ĂŒberprĂŒft, dass die Filterung alle möglichen Vektoren ausschlieĂt. Der Mechanismus, der zu einem Speicherleck fĂŒhrte, blieb jedoch ein RĂ€tsel. Nach einem Monat wurde der Fehlerbericht als gelöst geschlossen, und die Untersuchung der Ursachen des Fehlers wurde auf unbestimmte Zeit verschoben.
OpenResty ist ein sehr beliebtes Plugin, das das Schreiben von Lua-Skripten innerhalb von nginx ermöglicht und in mehreren Projekten von Mail.ru verwendet wird. Daher galt das Problem nicht als gelöst. Nach einiger Zeit kehrten sie jedoch zurĂŒck, um die wahren Ursachen, mögliche Konsequenzen zu verstehen und Empfehlungen fĂŒr die Entwickler zu erstellen. An den Analysen des Quellcodes waren beteiligt und . Es stellte sich heraus, dass:
- Es gibt beim Einsatz von rewrite mit benutzerdefinierten Daten in nginx die Möglichkeit des Directory Traversal (und wahrscheinlich SSRF) in einigen Konfigurationen, was ein bekanntes Problem ist und von statischen Konfigurationsanalysatoren in und von Yandex (ja, das verwenden wir auch, danke). Bei der Verwendung von OpenResty kann man diese Möglichkeit leicht ĂŒbersehen, aber unsere Konfiguration war davon nicht betroffen.
Beispielkonfiguration:
location ~ \/rewrite { rewrite ^.*$ $arg_x; }\n\nlocation \/ { root html; index index.html index.htm; }Ergebnis
curl localhost:8337/rewrite?x=/..//..//..//..//..//..//..//etc//passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
... - In Nginx gibt es einen Fehler, der zu einem Speicheraustritt fĂŒhrt, wenn die Rewrite-Zeile ein Nullbyte enthĂ€lt. Beim Ausgeben einer Umleitung reserviert Nginx einen neuen Speicherpuffer, der der vollstĂ€ndigen LĂ€nge der Zeile entspricht, kopiert die Zeile jedoch ĂŒber eine Zeichenfolgenfunktion, in der das Nullbyte ein Zeilenbegrenzer ist, sodass die Zeile nur bis zum Nullbyte kopiert wird und der Rest des Puffers nicht initialisierte Daten enthĂ€lt. Eine detaillierte Analyse ist verfĂŒgbar. .
Konfigurationsbeispiel (^@ Nullbyte)
location ~ /memleak { rewrite ^.*$ "^@asdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdasdf"; } location / { root html; index index.html index.htm; }Ergebnis
curl localhost:8337/secret -vv
...
curl localhost:8337/memleak -vv
...
Standort: http://localhost:8337/secret
...
- Nginx schĂŒtzt GET-Parameter vor der Injektion von Steuerzeichen und erlaubt nur die Verwendung von GET-Parametern in der Rewrite-Regel. Daher ist es nicht möglich, ĂŒber kontrollierte Benutzerparameter Injektionen in Nginx zu nutzen. POST-Parameter sind dabei nicht geschĂŒtzt. OpenResty erlaubt die Arbeit mit sowohl GET- als auch POST-Parametern, weshalb bei der Verwendung von POST-Parametern ĂŒber OpenResty die Möglichkeit besteht, spezielle Zeichen zu injizieren.
Beispielkonfiguration:
location ~ /memleak { rewrite_by_lua_block { ngx.req.read_body(); local args, err = ngx.req.get_post_args(); ngx.req.set_uri( args["url"], true ); } } location / { root html; index index.html index.htm; }Ergebnis:
curl localhost:8337 -d "url=secret" -vv
...
curl localhost:8337 -d "url=asdfasdfasdfasdfasdfasdfasdfasdf" -vv
...
Location: http://localhost:8337/{...kann secret enthalten...}
...
Weitere Reaktion
Das Problem wurde an die Entwickler von nginx und OpenResty gemeldet. Die Entwickler betrachten das Problem nicht als Sicherheitsfehler in nginx, da es in nginx keine Möglichkeit gibt, den Fehler durch die Injektion von Sonderzeichen auszunutzen. Fix wurde am 16. Dezember veröffentlicht. In den vier Monaten seit dem Bericht gab es in OpenResty ebenfalls keine Ănderungen, obwohl klar war, dass eine sichere Variante der Funktion ngx.req.set_uri() notwendig war. Am 18. MĂ€rz 2020 veröffentlichten wir Informationen, und am 21. MĂ€rz brachte OpenResty , die eine URI-PrĂŒfung hinzufĂŒgt.
Portswigger eine gute Artikel und holte sich Kommentare von OpenResty und Nginx (obwohl der Kommentar, dass nur ein kleiner Teil des Speichers offengelegt wird, falsch und irrefĂŒhrend ist, da dies durch die LĂ€nge der nachfolgenden Zeichenkette nach dem Null-Byte bestimmt wird und bei fehlenden expliziten LĂ€ngenbeschrĂ€nkungen vom Angreifer kontrolliert werden kann).
Also, wo lag der Fehler und was kann getan werden, um ihn zu verhindern?
Gab es einen Fehler in nginx? Ja, gab es, denn die Offenlegung von Speicherinhalt ist in jedem Fall ein Fehler.
Gab es einen Fehler in OpenResty? Ja, die Sicherheitsfragen bezĂŒglich der angebotenen OpenResty-FunktionalitĂ€ten sind mindestens nicht untersucht und dokumentiert worden.
Wurde ein Fehler in der Konfiguration oder Nutzung von OpenResty gemacht? Ja, denn in Ermangelung einer ausdrĂŒcklichen Angabe wurde eine unĂŒberprĂŒfte Annahme ĂŒber die Sicherheit der verwendeten FunktionalitĂ€t getroffen.
Welche dieser Fehler stellt eine SicherheitsanfĂ€lligkeit mit einem Bug-Bounty von 10.000 $ dar? FĂŒr uns ist das im Grunde genommen nicht wichtig. In jeder Software, insbesondere an der Schnittstelle mehrerer Komponenten, vor allem wenn diese von verschiedenen Projekten und Entwicklern bereitgestellt werden, kann niemand garantieren, dass alle Besonderheiten ihres Betriebs bekannt und dokumentiert sind und dass es keine Fehler gibt. Daher tritt jede SicherheitsanfĂ€lligkeit genau dort auf, wo sie die Sicherheit beeinflusst.
In jedem Fall ist es eine gute Praxis, Eingabedaten zu normalisieren oder so weit wie möglich zu beschrĂ€nken/filteren, die an externe Module/APIs gesendet werden, wenn es keine ausdrĂŒcklichen Anweisungen oder eindeutiges VerstĂ€ndnis dafĂŒr gibt, dass dies nicht erforderlich ist.
Errata
Aus Erfahrung , um die sprachliche Klarheit zu bewahren:
Bug-Bounty â Wettbewerb zur Fehlersuche
Fehlerbericht â Fehlermeldung
Weiterleitung â Weiterleitung
Open Source â Open Source
Errata â Arbeiten an Fehlern
Quelle: habr.com
