Поделиться через


Краткое руководство. Отправка образов встроенного ПО в Defender для Интернета вещей с помощью Python

В этой статье объясняется, как использовать скрипт Python для отправки образов встроенного ПО в Defender для Интернета вещей.

Анализ встроенного ПО Defender для Интернета вещей — это средство, которое анализирует образы встроенного ПО и предоставляет представление об уязвимостях безопасности в образах встроенного ПО.

Необходимые компоненты

В этом кратком руководстве предполагается базовое понимание анализа встроенного ПО Defender для Интернета вещей. Дополнительные сведения см. в разделе "Анализ встроенного ПО для построителей устройств". Список поддерживаемых файловых систем см. в статье "Часто задаваемые вопросы о анализе встроенного ПО Defender для Интернета вещей".

Подготовка среды

  • Для использования этого пакета требуется Python версии 3.8+ . Выполните командуpython --version, чтобы проверка версию Python.
  • Запишите идентификатор подписки Azure, имя группы ресурсов, в которой вы хотите отправить изображения, имя рабочей области и имя образа встроенного ПО, который вы хотите отправить.
  • Убедитесь, что у вашей учетной записи Azure есть необходимые разрешения для отправки образов встроенного ПО в Defender для Интернета вещей для вашей подписки Azure. Вы должны быть владельцем, участником, Администратор безопасности или Администратор анализом встроенного ПО на уровне подписки или группы ресурсов для отправки образов встроенного ПО. Дополнительные сведения см. в разделе "Роли анализа встроенного ПО Defender для Интернета вещей", "Области" и "Возможности".
  • Убедитесь, что образ встроенного ПО хранится в том же каталоге, что и скрипт Python.
  • Установите пакеты, необходимые для выполнения этого скрипта:
    pip install azure-mgmt-iotfirmwaredefense
    pip install azure-identity
    
  • Войдите в учетную запись Azure, выполнив команду az login.

Выполните следующий скрипт Python

Скопируйте следующий скрипт Python в .py файл и сохраните его в том же каталоге, что и образ встроенного ПО. subscription_id Замените переменную идентификатором подписки Azure с именем группы ресурсов, resource_group_name в которой вы хотите отправить образ встроенного ПО и firmware_file именем образа встроенного ПО, который сохраняется в том же каталоге, что и скрипт Python.

from azure.identity import AzureCliCredential
from azure.mgmt.iotfirmwaredefense import *
from azure.mgmt.iotfirmwaredefense.models import *
from azure.core.exceptions import *
from azure.storage.blob import BlobClient
import uuid
from time import sleep
from halo import Halo
from tabulate import tabulate

subscription_id = "subscription-id"
resource_group_name = "resource-group-name"
workspace_name = "default"
firmware_file = "firmware-image-name"

def main():
    firmware_id = str(uuid.uuid4())
    fw_client = init_connections(firmware_id)
    upload_firmware(fw_client, firmware_id)
    get_results(fw_client, firmware_id)

def init_connections(firmware_id):
    spinner = Halo(text=f"Creating client for firmware {firmware_id}")
    cli_credential = AzureCliCredential()
    client = IoTFirmwareDefenseMgmtClient(cli_credential, subscription_id, 'https://management.azure.com')
    spinner.succeed()
    return client

def upload_firmware(fw_client, firmware_id):
    spinner = Halo(text="Uploading firmware to Azure...", spinner="dots")
    spinner.start()
    token = fw_client.workspaces.generate_upload_url(resource_group_name, workspace_name, {"firmware_id": firmware_id})
    fw_client.firmwares.create(resource_group_name, workspace_name, firmware_id, {"properties": {"file_name": firmware_file, "vendor": "Contoso Ltd.", "model": "Wifi Router", "version": "1.0.1", "status": "Pending"}})
    bl_client = BlobClient.from_blob_url(token.url)
    with open(file=firmware_file, mode="rb") as data:
        bl_client.upload_blob(data=data)
    spinner.succeed()

def get_results(fw_client, firmware_id):
    fw = fw_client.firmwares.get(resource_group_name, workspace_name, firmware_id)

    spinner = Halo("Waiting for analysis to finish...", spinner="dots")
    spinner.start()
    while fw.properties.status != "Ready":
        sleep(5)
        fw = fw_client.firmwares.get(resource_group_name, workspace_name, firmware_id)
    spinner.succeed()

    print("-"*107)

    summary = fw_client.summaries.get(resource_group_name, workspace_name, firmware_id, summary_name=SummaryName.FIRMWARE)
    print_summary(summary.properties)
    print()

    components = fw_client.sbom_components.list_by_firmware(resource_group_name, workspace_name, firmware_id)
    if components is not None:
        print_components(components)
    else:
        print("No components found")

def print_summary(summary):
    table = [[summary.extracted_size, summary.file_size, summary.extracted_file_count, summary.component_count, summary.binary_count, summary.analysis_time_seconds, summary.root_file_systems]]
    header = ["Extracted Size", "File Size", "Extracted Files", "Components", "Binaries", "Analysis Time", "File Systems"]
    print(tabulate(table, header))

def print_components(components):
    table = []
    header = ["Component", "Version", "License", "Paths"]
    for com in components:
        table.append([com.properties.component_name, com.properties.version, com.properties.license, com.properties.file_paths])
    print(tabulate(table, header, maxcolwidths=[None, None, None, 57]))

if __name__ == "__main__":
    exit(main())