はじめに
Microsoft Defender for Storage のマルウェアスキャンの機能がパブリックプレビューになりました。
これまでも Microsoft Defender for Storage はハッシュ評価ベースのマルウェア検出をサポートしていました。今回パブリックプレビューになったのは、Microsoft Defenders Antivirus によってマルウェアをスキャンする方式です。
Malware Scanning in Defender for Storage helps protect your storage accounts from malicious content by performing a full malware scan on uploaded content in near real time, using Microsoft Defenders Antivirus capabilities.
引用:Malware Scanning in Defender for Storage
気になる機能なので実際に試してみました
設定
新しいマルウェアスキャンの機能は、ストレージアカウント単位で課金されるプランでのみサポートされています。もしトランザクション単位で課金されるプランを利用している場合には、プランを変更する必要があります。
今回はサブスクリプション単位で Microsoft Defender for Storage を有効化するものの、別途費用のかかるマルウェアスキャンは任意のストレージアカウントで個別に設定する方式とします。ですので、サブスクリプション単位でのマルウェアスキャンを無効にした状態でプランを変更します。
そのうえで、マルウェアスキャンを有効化したいストレージアカウント側でサブスクリプション単位の設定を上書きする形でマルウェアスキャンを有効化します
マルウェアスキャンを有効化すると、そのストレージアカウントの名前を含む Event Grid のシステムトピックが自動的に作成されます。
> Get-AzResource -ResourceGroupName 0324blob | Where-Object { $_.Name -like "*<NAME>*"} | ft Name, ResourceType
Name ResourceType
---- ------------
<NAME>-463726bd-b31f-490e-ab01-3028ed08ccdb Microsoft.EventGrid/systemTopics
<NAME> Microsoft.Storage/storageAccounts
このシステムトピックには、Blob が作成された際にマルウェアスキャンの仕組みに対して Webhook を送信するサブスクリプションの設定が入っています。
> $subscriptions = Get-AzEventGridSystemTopicEventSubscription -ResourceGroupName 0324blob -SystemTopicName <NAME>-463726bd-b31f-490e-ab01-3028ed08ccdb
> $subscriptions.PsEventSubscriptionsList[0].EventSubscriptionName
StorageAntimalwareSubscription
> $subscriptions.PsEventSubscriptionsList[0].Destination
EndpointUrl :
EndpointBaseUrl : https://japaneast.a3.storageav.azure.com:5142/EventCapture/<MY SUB ID>/<NAME>
MaxEventsPerBatch : 1
PreferredBatchSizeInKilobytes : 64
(中略)
> $subscriptions.PsEventSubscriptionsList[0].Filter
SubjectBeginsWith :
SubjectEndsWith :
IncludedEventTypes : {Microsoft.Storage.BlobCreated}
IsSubjectCaseSensitive :
EnableAdvancedFilteringOnArrays :
AdvancedFilters : {data.blobType}
また、マルウェアスキャンの仕組みから Blob 上のファイルにアクセスするために、対象のストレージアカウントに対して storageDataScanner からのリソースアクセスが許可されます。
> $rules = Get-AzStorageAccountNetworkRuleSet -ResourceGroupName 0324blob -StorageAccountName <NAME>
> $rules.ResourceAccessRules | fl *
TenantId : <MY TENANT ID>
ResourceId : /subscriptions/<MY SUB ID>/providers/Microsoft.Security/datascanners/storageDataScanner
さらに、マルウェアスキャンの仕組みから各種 Azure リソースにアクセスするために RBAC が追加されます。
> $roles = Get-AzRoleAssignment -ObjectId 447346bc-bfc4-44c8-b2a8-20e2d10e24ed
> $roles | fl displayname, scope, RoleDefinitionName
DisplayName : storageDataScanner
Scope : /subscriptions/<MY SUB ID>
RoleDefinitionName : Storage Blob Data Reader
DisplayName : storageDataScanner
Scope : /subscriptions/<MY SUB ID>
RoleDefinitionName : Storage Blob Data Owner
DisplayName : storageDataScanner
Scope : /subscriptions/<MY SUB ID>/resourceGroups/0324blob/providers/Microsoft.Storage/storageAccounts/<NAME>
RoleDefinitionName : Storage Blob Data Owner
DisplayName : storageDataScanner
Scope : /subscriptions/<MY SUB ID>/resourceGroups/0324blob/providers/Microsoft.EventGrid/topics/malware
RoleDefinitionName : EventGrid Data Sender
動作確認
適当なテキストファイルと EICAR な文字を含むテキストファイルをアップロードします。スキャンの結果は Blob の index tag に記録されます。
> Get-AzStorageBlobTag -Blob aaaa.txt -Container malware -Context $context
Name Value
---- -----
Malware Scanning scan result No threats found
Malware Scanning scan time UTC 2023-03-29 08:56:44Z
> Get-AzStorageBlobTag -Blob cccc.txt -Container malware -Context $context
Name Value
---- -----
Malware Scanning scan result Malicious
Malware Scanning scan time UTC 2023-03-29 09:32:34Z
そして、Microsoft Defender for Cloud のアラートが発火します。ここから先は他の Microsoft Defender for Cloud のアラート運用と同じことができます。
対象のストレージアカウントのログから、storageDataScanner(447346bc-bfc4-44c8-b2a8-20e2d10e24ed)が Blob を取得した後に最終的にタグを設定していることが分かります。
> $query = 'StorageBlobLogs | where AccountName == "<NAME>" | where RequesterObjectId == "447346bc-bfc4-44c8-b2a8-20e2d10e24ed" | project TimeGenerated, AccountName, OperationName, CallerIpAddress, ObjectKey | sort by TimeGenerated asc'
> $result = Invoke-AzOperationalInsightsQuery -WorkspaceId $wsid -Query $Query
> $result.Results | ft *
TimeGenerated AccountName OperationName CallerIpAddress ObjectKey
------------- ----------- ------------- --------------- ---------
2023-03-29T10:09:15.8222836Z <NAME> GetBlobProperties 10.40.0.10:51597 /<NAME>/malware/cccc.txt
2023-03-29T10:09:15.8346511Z <NAME> GetBlob 10.40.0.10:51597 /<NAME>/malware/cccc.txt
2023-03-29T10:09:16.66083Z <NAME> GetBlobTags 10.0.0.32 /<NAME>/malware/cccc.txt
2023-03-29T10:09:16.6648907Z <NAME> GetBlobProperties 10.0.0.32:60411 /<NAME>/malware/cccc.txt
2023-03-29T10:09:16.6725846Z <NAME> SetBlobTags 10.0.0.32 /<NAME>/malware/cccc.txt
各種設定や上記のログを見る限りでは、次のような挙動をしていそうです。
- ストレージアカウントに Blob が作成される
- Blob が作成されたイベントが Event Grid 経由でマルウェアスキャンの仕組みに通知される
- マルウェアスキャンの仕組みは、イベントに含まれる Blob の URL を利用して対象のストレージアカウントから Blob をダウンロードする
- マルウェアスキャンの仕組みは、ダウンロードした Blob をスキャンする
- マルウェア出会った場合には、マルウェアスキャンの仕組みは対象の Blob の Tag を更新する
Event Grid トピックとの連携
マルウェアスキャンを設定する際に Event Grid トピックを紐づけられます。そうすると、スキャンするたびに次のようなフォーマットのイベントが届くようになります。イベントにはスキャン結果が含まれているので、Event Grid サブスクリプションで Azure Functions を起動して、検査済みの安全なファイルだけを別のストレージアカウントに複製するようなイベントドリブンな処理を実現できます。
{
"eventType": "Microsoft.Security.MalwareScanningResult",
"metadataVersion": "1",
"topic": "/subscriptions/<MY SUB ID>/resourceGroups/0324blob/providers/Microsoft.EventGrid/topics/malware",
"dataVersion": "1.0",
"id": "4387860d-aba4-4e66-b0fb-b9e23b7dba6d",
"eventTime": "2023-03-29T10:42:44.8611215Z",
"data": {
"scanResultType": "Malicious",
"scanFinishedTimeUtc": "2023-03-29T10:42:44.8607887Z",
"correlationId": "4387860d-aba4-4e66-b0fb-b9e23b7dba6d",
"blobUri": "https://<NAME>.blob.core.windows.net/malware/cccc.txt",
"scanResultDetails": {
"sha256": "275A021BBFB6489E54D471899F7DB9D1663FC695EC2FE2A2C4538AABF651FD0F",
"malwareNamesFound": [
"DOS/EICAR_Test_File"
]
},
"eTag": "0x8DB3042536EB955"
},
"subject": "storageAccounts/<NAME>/containers/malware/blobs/cccc.txt"
}
{
"eventType": "Microsoft.Security.MalwareScanningResult",
"metadataVersion": "1",
"topic": "/subscriptions/<MY SUB ID>/resourceGroups/0324blob/providers/Microsoft.EventGrid/topics/malware",
"dataVersion": "1.0",
"id": "02f1590d-aa50-412e-a189-16a5b86ef1b7",
"eventTime": "2023-03-29T10:42:57.0647849Z",
"data": {
"scanResultType": "No threats found",
"scanFinishedTimeUtc": "2023-03-29T10:42:57.0639487Z",
"correlationId": "02f1590d-aa50-412e-a189-16a5b86ef1b7",
"blobUri": "https://<NAME>.blob.core.windows.net/malware/aaaa.txt",
"scanResultDetails": null,
"eTag": "0x8DB3042599FF38A"
},
"subject": "storageAccounts/<NAME>/containers/malware/blobs/aaaa.txt"
}
Log Analytics との連携
マルウェアスキャンを有効化する際に Log Analytics を紐づけられます。そうすると、StorageMalwareScanningResults テーブルにスキャン結果が格納されます。Kusto を使いこなせば、マルウェアが見つかった際に Azure Monitor からシステムの担当者にアラートを発火したり、Azure Monitor Workbook でスキャン結果のダッシュボードを作ったりできそうです。
> $query = 'StorageBlobLogs | where AccountName == "<NAME>" | where RequesterObjectId == "447346bc-bfc4-44c8-b2a8-20e2d10e24ed" | project TimeGenerated, AccountName, OperationName, CallerIpAddress, ObjectKey | sort by TimeGenerated asc'
> $result = Invoke-AzOperationalInsightsQuery -WorkspaceId $wsid -Query $Query
> $result.Results | fl *
TimeGenerated : 2023-03-29T10:09:01.3546233Z
OperationName : Scan
StorageAccountName : <NAME>
BlobUri : https://<NAME>.blob.core.windows.net/malware/cccc.txt
ScanResultType : No threats found
ScanResultDetails :
TimeGenerated : 2023-03-29T10:09:16.6668373Z
OperationName : Scan
StorageAccountName : <NAME>
BlobUri : https://<NAME>.blob.core.windows.net/malware/cccc.txt
ScanResultType : Malicious
ScanResultDetails : {"malwareNamesFound":["DOS/EICAR_Test_File"],"sha256":"275A021BBFB6489E54D471899F7DB9D1663FC695EC2FE2A2C4538AABF651FD0F"}
まとめ
パブリックプレビューになった Microsoft Defender for Storage のマルウェアスキャンを試しました。設定も簡単ですし、他システムとの連携も用意に実現できる仕組みですので GA が待ち遠しいです。