Home > Windows にまつわる e.t.c.

PowerShell でセキュリティ更新プログラムの情報を取得する


Microsoft では CVE 番号と対応付けたセキュリティ更新プログラム情報を Web で公開しています。

セキュリティ更新プログラム ガイド
https://msrc.microsoft.com/update-guide/

 

その解説

新しいセキュリティ更新プログラム ガイドでの脆弱性情報の詳細
https://msrc-blog.microsoft.com/2020/11/09/20201110_sugv2/

 

この情報は API でも取得できるようになっており、その API をハンドリングするための PowerShell モジュールが提供されています。

MSRC-Microsoft-Security-Updates-API: Repo with getting started projects for the Microsoft Security Updates API
https://github.com/microsoft/MSRC-Microsoft-Security-Updates-API

 

このモジュールを使用すると、セキュリティ更新プログラム(Windows Update 情報を PowerShell でハンドリングできます。

例えば、特定 CVE 番号に対応したセキュリティ更新プログラムの KB 番号をリストアップしたり、最新のセキュリティ更新の KB 番号をリストアップしたり、最新のセキュリティ更新が適用済みなのか確認したりとか、色々使い勝手がいいデータを取得できます。

MS さんがこのデーターを Excel でハンドリングする動画があったので、動画の内容を PowerShell でハンドリングする方法をまとめました。

セキュリティ更新プログラムの情報を API で取得する方法を紹介するビデオを YouTube で公開しています
https://msrc-blog.microsoft.com/2018/02/16/howtogetsecurityupdateinfobyapi/

 

API キーの取得

Rest API を叩くので、API キーが必要です。

API キーは、以下ページで取得できます。

Microsoft Security Update API
https://portal.msrc.microsoft.com/ja-jp/developer

 

このページはマイクロソフトアカウント(MSA)でログインする必要があるのですが、使用できるアカウントが、以下のいずれかのドメインである必要があります。

@outlook.com
@live.com
@microsoft.com(MS 中の人用)

 

これらの ID を持っていない場合は、以下ページにアクセスして @outlook.com の MSA を取得してください。

Microsoft アカウント
https://account.microsoft.com/

 

たまたまですが、新しく作成したアカウントではログインに失敗し、1日放置したらログインできたので、ログインに失敗する場合は、しばらく待った方が良いと思います。

 

モジュールのインストール

セキュリティ更新モジュールは、Windows PowerShell でも、PowerShell Core(7.1.0で確認) のいずれでも使用できますが、Windows PowerShell の場合は、5.1 のみサポートされているので、5.1 以前(5.0 も NG)の場合は、5.1 にアップグレードする必要があります。

このため、5.1 にアップグレードモジュールの配布が終わっている Windows 10 1511 以前の Windows 10(古い LTSB)では PowerShell Core を使用する必要があります。

Windows PowerShell のシステム要件
https://docs.microsoft.com/ja-jp/powershell/scripting/windows-powershell/install/windows-powershell-system-requirements?WT.mc_id=WD-MVP-36880

 

モジュールインストールは以下のようにします(要管理権限)

Install-Module MSRCSecurityUpdates -Force

 

情報の取得

コマンドレットを使用する場合は、最初に API キーを Set-MSRCApiKey の -ApiKey で指定します。

情報の取得は、Get-MsrcCvrfDocument コマンドレットを使用します。

このコマンドレットは、2020-Nov のように、更新情報の年月を -ID で指定します。

こんな感じですね

Import-Module MSRCSecurityUpdates
Set-MSRCApiKey -ApiKey "Your API Key"
$cvrfDoc = Get-MsrcCvrfDocument -ID 2020-Nov

 

プロダクト名の取得

取得したデータはプロダクト ID で表現されているので、これをプロダクト名に変換するための情報を得ます。

プロダクトIDプロダクト名は、$cvrfDoc.ProductTree.FullProductName に格納されています

$FullProductName = $cvrfDoc.ProductTree.FullProductName

 

セキュリティ更新の取得

CVE 情報の取得

セキュリティ更新は CVE番号 > KB番号 > 対象プロダクト の階層構造になっています。

まずは CVE 番号の取得です。

CVE 番号は、$cvrfDoc.Vulnerability.CVE に格納されています。

Vulnerability は配列になっており、CVE 番号ごとのオブジェクトになっています。

$cvrfDoc.Vulnerability[100].CVE

 

セキュリティ更新のリリース日は $cvrfDoc.Vulnerability.RevisionHistory.Date に格納されています。

このプロパティは履歴になっているので、配列になっており、複数の値が入っていた場合は値が一番小さい日付がリリース日です。

$cvrfDoc.Vulnerability[100].RevisionHistory.Date

 

KB 情報の取得

KB 情報は、$cvrfDoc.Vulnerability.Remediations に格納されており、KB 番号は $cvrfDoc.Vulnerability.Remediations.Description.Value に格納されています。ここには数値以外の値が入っていることがあり、そのばあいは KB ではありません。

$cvrfDoc.Vulnerability[100].Remediations[5].Description.Value

 

更新の種類は $cvrfDoc.Vulnerability.Remediations.SubType に格納されています。

$cvrfDoc.Vulnerability[100].Remediations[5].SubType

 

MS が YouTube で公開している動画を見ると、$cvrfDoc.Vulnerability.Remediations.Type が 2 のデータだけを使っていたので、これに従ってデータを抽出するには以下のようにします。

[array]$Remediations = $cvrfDoc.Vulnerability[100].Remediations | ? Type -eq 2

 

対象プロダクトの取得

対象プロダクトは、$cvrfDoc.Vulnerability.Remediations.ProductID に格納されています。

単一のセキュリティ更新が複数のプロダクトに適用されることもあるので、ここは配列になっています。

$cvrfDoc.Vulnerability[100].Remediations[5].ProductID

 

この ProductID から先に取得したプロダクト名を割り当てればセキュリティ更新の一覧情報が取得できます。

指定年月に発行されたセキュリティ更新を取得するには、こんな感じにすると良いでしょう。

###############################################
# 指定年月に発行されたセキュリティ更新取得
# https://msrc.microsoft.com/update-guide/
###############################################
function GetSecurityUpdateKBs([datetime]$TergetDay){
    # API Key
    # Microsoft Security Update API(@outlook.com、@live.com MSA が必要)
    # https://portal.msrc.microsoft.com/ja-jp/developer
    $APIKey = "Your API Key"

    # セキュリティ更新を格納するオブジェクト
    class UpdateClass {
        [string] $CVE           # CVE 番号
        [string] $ReleaseDate   # リリース日
        [string] $KB            # KB 番号
        [string] $SubType       # 更新の種類
        [string] $ProductID     # プロダクト ID
        [string] $ProductName   # プロダクト名
        [string] $URI           # KB の URI
    }

    # 月の略称
    $MonthTable = @{
        1 = "Jan"
        2 = "Feb"
        3 = "Mar"
        4 = "Apr"
        5 = "May"
        6 = "Jun"
        7 = "Jul"
        8 = "Aug"
        9 = "Sep"
        10 = "Oct"
        11 = "Nov"
        12 = "Dec"
    }

    $TergetMonth = [string]$TergetDay.Year + "-" + $MonthTable[$TergetDay.Month]

    try{
        Import-Module MSRCSecurityUpdates -ErrorAction Stop
    }
    catch{
        echo "必要モジュールがインストールされていません"
        echo "以下手順でモジュールをインストールしてください(要管理権限)"
        echo "Install-Module MSRCSecurityUpdates -Force"
        return $null
    }

    Set-MSRCApiKey -ApiKey $APIKey
    $cvrfDoc = Get-MsrcCvrfDocument -ID $TergetMonth

    # プロダクト名
    $FullProductName = $cvrfDoc.ProductTree.FullProductName


    # プロダクト別のセキュリティ更新
    $Updates = @()

    # セキュリティ更新
    [array]$Vulnerabilitys = $cvrfDoc.Vulnerability

    # CVE ごとの処理
    foreach( $Vulnerability in $Vulnerabilitys){

        $CVE = $Vulnerability.CVE

        # リリース日
        [datetime]$ReleaseDate = ($Vulnerability.RevisionHistory | Sort-Object -Property Date)[0].Date

        # セキュリティ更新の抽出
        [array]$Remediations = $Vulnerability.Remediations | ? Type -eq 2

        # セキュリティ更新ごとの処理
        foreach( $Remediation in $Remediations ){

            # KB 番号が数値のデータの未処理
            if($Remediation.Description.Value -match "[0-9]+"){

                # KB 番号
                $KB = $Remediation.Description.Value

                # 更新の種類
                $SubType = $Remediation.SubType

                # プロダクトの展開
                [array]$ProductIDs = $Remediation.ProductID

                # プロダクト後の処理
                foreach( $ProductID in $ProductIDs ){
                    # 各値のセット
                    $Update = New-Object UpdateClass

                    $Update.CVE = $CVE
                    $Update.ReleaseDate = $ReleaseDate.ToString()
                    $Update.KB = $KB
                    $Update.SubType = $SubType
                    $Update.ProductID = $ProductID
                    $Update.ProductName = ($FullProductName | ? ProductID -eq $ProductID).Value
                    $Update.URI = "https://support.microsoft.com/ja-jp/help/" + $KB

                    $Updates += $Update
                }
            }
        }
    }

    return $Updates
}

 

1つのセキュリティ更新が複数の CVE 番号にの対策になっているので、製品ごとの KB 番号を確認するのであれば、KB 番号 + プロダクト ID でサマれば製品ごとのセキュリティ更新に絞ることが出来ます。

$Today = Get-Date
$Updates = GetSecurityUpdateKBs $Today
$Updates | Sort-Object -Property KB, ProductID -Unique | Export-Csv ~\Documents\WindowsUpdateInfomation4Product.csv -Encoding OEM

 

Windows OS だけを確認するのであれば、プロダクト名が Windows から始まるデータだけ抽出すると良いでしょう。

$Updates | ? ProductName -match "^Windows" | Export-Csv ~\Documents\WindowsUpdateInfomation4Windows.csv -Encoding OEM

 

後日この機能を使用して最新のセキュリティ更新が適用されているか確認するサンプルスクリプトを公開します。

 

参考情報

セキュリティ更新プログラム ガイド
https://msrc.microsoft.com/update-guide/

新しいセキュリティ更新プログラム ガイドでの脆弱性情報の詳細
https://msrc-blog.microsoft.com/2020/11/09/20201110_sugv2/

MSRC-Microsoft-Security-Updates-API: Repo with getting started projects for the Microsoft Security Updates API
https://github.com/microsoft/MSRC-Microsoft-Security-Updates-API

セキュリティ更新プログラムの情報を API で取得する方法を紹介するビデオを YouTube で公開しています
https://msrc-blog.microsoft.com/2018/02/16/howtogetsecurityupdateinfobyapi/

関連情報

関数を PowerShell プロンプトで実行する
https://www.vwnet.jp/Windows/PowerShell/2016100401/UseFunctionInPsPrompt.htm

PowerShell の関数をモジュールとしてインストールする
http://www.vwnet.jp/Windows/PowerShell/2019101401/InstallModule.htm

 

back.gif (1980 バイト)

home.gif (1907 バイト)

Copyright © MURA All rights reserved.