
Vor einem Jahr, am 21. MĂ€rz 2019, kam auf HackerOne ein sehr guter ab . Bei der EinfĂŒhrung eines Null-Bytes (ASCII 0) in das POST-Parameter eines der API-Anfragen der Webmail, die einen HTTP-Redirect zurĂŒckgab, waren in den Redirect-Daten Teile uninitialisierter Speicher sichtbar, in denen hĂ€ufig Fragmente aus GET-Parametern und Headern anderer Anfragen an denselben Server enthalten waren.
Dies ist eine kritische Schwachstelle, da die Anfragen unter anderem Sitzungscookies enthalten. Nach ein paar Stunden wurde ein temporĂ€rer Fix implementiert, der das Null-Byte filterte (wie sich spĂ€ter herausstellte, war das nicht ausreichend, da die Möglichkeit einer CRLF-/ASCII 13, 10-Injektion blieb, was es ermöglicht, die Header und Daten der HTTP-Antwort zu manipulieren; das ist weniger kritisch, aber dennoch unangenehm). Gleichzeitig wurde das Problem an Sicherheitsanalysten und Entwickler ĂŒbergeben, um die Ursachen des Bugs zu finden und zu beseitigen.
Mail.ru Mail ist eine sehr komplexe Anwendung, an der eine Vielzahl von verschiedenen Frontend-/Backend-Komponenten beteiligt sein kann, sowohl Open-Source- (ein groĂer Dank an alle Entwickler von freier Software) als auch Eigenentwicklungen. Es gelang, alle Komponenten auĂer Nginx und OpenResty auszuschlieĂen und das Problem bis zum Aufruf im OpenResty-Skript einzugrenzen, das sich nicht wie erwartet verhielt (das EinfĂŒgen eines Null-Bytes oder eines Zeilenumbruchs ĂŒber GET-Parameter mit Rewrite im ngx_http_rewrite_module, der laut Dokumentation verwendet wird und eigentlich absolut Ă€hnlich funktionieren sollte, ist nicht möglich). Mögliche Konsequenzen wurden beseitigt, eine maximal strenge Filterung hinzugefĂŒgt und ĂŒberprĂŒft, dass die Filterung alle möglichen Vektoren ausschaltet. Aber der Mechanismus, der zu einem Leck des Speicherinhalts fĂŒhrte, blieb ein RĂ€tsel. Einen Monat spĂ€ter wurde der Bug-Report als behoben geschlossen, aber die Analyse der Ursachen wurde auf spĂ€tere Zeiten verschoben.
OpenResty ist ein sehr beliebtes Plugin, das es ermöglicht, Lua-Skripte innerhalb von Nginx zu schreiben, und es wird in mehreren Mail.ru-Projekten verwendet, weshalb das Problem nicht als behoben angesehen wurde. Nach einiger Zeit kam man jedoch darauf zurĂŒck, um die wahren Ursachen, mögliche Konsequenzen zu verstehen und Empfehlungen fĂŒr Entwickler zu geben. An der Untersuchung des Quellcodes wirkten mit und . Es stellte sich heraus, dass:
- Bei der Verwendung von rewrite in nginx mit Benutzerdaten besteht in einigen Konfigurationen die Möglichkeit zur Directory Traversal (und wahrscheinlich SSRF), aber das ist ein bekanntes Problem und sollte von statischen Konfigurationsanalysatoren erkannt werden in und von Yandex (ja, das nutzen wir auch, danke). Bei der Verwendung von OpenResty kann diese Möglichkeit leicht ĂŒbersehen werden, betrifft jedoch nicht unsere Konfiguration.
Konfigurationsbeispiel:
location ~ /rewrite { rewrite ^.*$ $arg_x; } location / { 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 einer Speicherleckage fĂŒhrt, wenn die rewrite-Zeichenfolge ein Nullbyte enthĂ€lt. Bei der RĂŒckgabe einer Umleitung reserviert nginx einen neuen Speicherpuffer, der der vollstĂ€ndigen LĂ€nge der Zeichenfolge entspricht, kopiert die Zeichenfolge jedoch ĂŒber eine Zeichenfolgenfunktion, bei der das Nullbyte ein Terminator ist, sodass die Zeichenfolge nur bis zum Nullbyte kopiert wird und der Rest des Puffers nicht initialisierte Daten enthĂ€lt. Eine detaillierte Analyse finden Sie .
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 ermöglicht die Verwendung von GET-Parametern nur in der rewrite. Daher ist es nicht möglich, die Injektion ĂŒber benutzerkontrollierte Parameter in nginx auszunutzen. POST-Parameter sind dabei jedoch nicht geschĂŒtzt. OpenResty ermöglicht die Arbeit sowohl mit GET- als auch mit POST-Parametern, daher besteht bei der Verwendung von POST-Parametern ĂŒber OpenResty die Möglichkeit zur Injektion von Sonderzeichen.
Konfigurationsbeispiel:
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
...
Standort: http://localhost:8337/{...kann secret enthalten...}
...
Weitere MaĂnahmen
Das Problem wurde den Entwicklern von nginx und OpenResty gemeldet, die Entwickler betrachten das Problem nicht als Sicherheitsfehler in nginx, da es in nginx selbst keine Möglichkeit gibt, den Fehler ĂŒber die Injektion von Sonderzeichen auszunutzen, der Fix wurde am 16. Dezember veröffentlicht. Nach 4 Monaten seit der Meldung wurden auch bei OpenResty keine Ănderungen vorgenommen, obwohl das VerstĂ€ndnis besteht, dass eine sichere Variante der Funktion ngx.req.set_uri() erforderlich ist. Am 18. MĂ€rz 2020 veröffentlichten wir Informationen, am 21. MĂ€rz veröffentlichte OpenResty , die eine URI-ĂberprĂŒfung hinzufĂŒgt.
Portswigger Ich habe einen guten Artikel gelesen und Kommentare von OpenResty und Nginx erhalten (tatsĂ€chlich ist der Kommentar, dass nur ein kleiner Speicherbereich offenbart wird, falsch und irrefĂŒhrend; dies hĂ€ngt von der LĂ€nge der Zeile nach dem Nullbyte ab und kann ohne explizite LĂ€ngeneinschrĂ€nkungen vom Angreifer kontrolliert werden).
Was war also der Fehler und was kann getan werden, um ihn zu verhindern?
Lag der Fehler bei nginx? Ja, das war er, denn ein Speicherleck ist in jedem Fall ein Fehler.
Gab es einen Fehler bei OpenResty? Ja, mindestens die Sicherheitsfrage bezĂŒglich der von OpenResty angebotenen FunktionalitĂ€t wurde nicht untersucht und dokumentiert.
Wurde ein Konfigurations- / Nutzungfehler bei OpenResty gemacht? Ja, denn in Ermangelung einer klaren Angabe wurde eine unĂŒberprĂŒfte Annahme ĂŒber die Sicherheit der verwendeten FunktionalitĂ€t getroffen.
Welcher dieser Fehler stellt eine SicherheitsanfĂ€lligkeit mit einem Bounty von $10000 dar? FĂŒr uns ist das eigentlich nicht wichtig. Bei jeder Software, insbesondere am Schnittpunkt mehrerer Komponenten, die von verschiedenen Projekten und Entwicklern bereitgestellt werden, kann niemand garantieren, dass alle Eigenheiten ihrer Funktionsweise bekannt und dokumentiert sind und dass keine Fehler vorhanden sind. Daher tritt jede SicherheitsanfĂ€lligkeit genau dort auf, wo sie die Sicherheit beeinflusst.
In jedem Fall wÀre es eine gute Praxis, die Eingabedaten, die an ein externes Modul / API gesendet werden, zu normalisieren oder so weit wie möglich zu beschrÀnken / zu filtern, wenn es keine klaren Anweisungen und kein eindeutiges VerstÀndnis gibt, dass dies nicht erforderlich ist.
Errata
Nach Erfahrung , um die Sprachreinheit zu wahren:
Bug Bounty â Wettbewerb zur Fehlerjagd
Fehlerbericht â Fehlermeldung
Redirect â Weiterleitung
Open Source â mit offenem Code
Errata â Arbeit an Fehlern
Quelle: habr.com
