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


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

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

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

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

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

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

  1. Для использования этого пакета требуется Python версии 3.8+ . Выполните команду python --version , чтобы проверить версию Python.
  2. Запишите идентификатор подписки Azure, имя группы ресурсов, в которой вы хотите отправить изображения, имя рабочей области и имя образа встроенного ПО, который вы хотите отправить.
  3. Убедитесь, что у вашей учетной записи Azure есть необходимые разрешения для отправки образов встроенного ПО в анализ встроенного ПО для подписки Azure. Вы должны быть владельцем, участником, администратором безопасности или администратором анализа встроенного ПО на уровне подписки или группы ресурсов для отправки образов встроенного ПО. Дополнительные сведения см. в статье "Анализ встроенного ПО", "Области" и "Возможности".
  4. Убедитесь, что образ встроенного ПО хранится в том же каталоге, что и скрипт Python.
  5. Установите пакеты, необходимые для выполнения этого скрипта:
    pip install azure-mgmt-iotfirmwaredefense
    pip install azure-identity
    
  6. Войдите в учетную запись 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())