다음을 통해 공유


빠른 시작: Python을 사용하여 펌웨어 분석에 펌웨어 이미지 업로드

이 문서에서는 Python 스크립트를 사용하여 펌웨어 이미지를 펌웨어 분석에 업로드하는 방법을 설명합니다.

펌웨어 분석은 펌웨어 이미지를 분석하고 펌웨어 이미지의 보안 취약성을 이해하는 도구입니다.

필수 조건

이 빠른 시작에서는 펌웨어 분석에 대한 기본적인 이해를 가정합니다. 자세한 내용은 디바이스 빌더의 펌웨어 분석을 참조하세요. 지원되는 파일 시스템 목록은 펌웨어 분석에 대한 질문과 대답을 참조 하세요.

환경 준비

  1. 이 패키지를 사용하려면 Python 버전 3.8 이상이 필요합니다. Python 버전을 확인하려면 python --version 명령을 실행합니다.
  2. Azure 구독 ID, 이미지를 업로드하려는 리소스 그룹의 이름, 작업 영역 이름, 업로드하려는 펌웨어 이미지의 이름을 기록해 두세요.
  3. Azure 계정에 Azure 구독에 대한 펌웨어 분석에 펌웨어 이미지를 업로드하는 데 필요한 권한이 있는지 확인합니다. 펌웨어 이미지를 업로드하려면 구독 또는 리소스 그룹 수준에서 소유자, 기여자, 보안 관리자 또는 펌웨어 분석 관리자여야 합니다. 자세한 내용은 펌웨어 분석 역할, 범위 및 기능을 참조 하세요.
  4. 펌웨어 이미지가 Python 스크립트와 동일한 디렉터리에 저장되어 있는지 확인합니다.
  5. 이 스크립트를 실행하는 데 필요한 패키지를 설치합니다.
    pip install azure-mgmt-iotfirmwaredefense
    pip install azure-identity
    
  6. az login 명령을 실행하여 Azure 계정에 로그인합니다.

다음 Python 스크립트를 실행합니다.

다음 Python 스크립트를 .py 파일에 복사하고 펌웨어 이미지와 동일한 디렉터리에 저장합니다. subscription_id 변수를 Azure 구독 ID로 바꾸고, 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())