ここ最近、Microsoft 365の侵害調査に携わる機会が増えてきたのだが、その際に少し困ったのがUnified Audit Log (UAL) の調査だった。
UALをCSVとしてエクスポートすると、肝心のデータはJSON形式でAuditDataというひとつのカラムに全てぶち込まれているので、Microsoft ExcelやLibreOffice Calcを使った調査には向いていない。
で、職場の同僚がjqコマンドを使って調査していたのにインスパイアされて、UALの調査に役立ちそうなjqコマンドを自分なりにまとめてみた。
- 調査にあたって
- トリアージ
- ログオン関連
- AiTM フィッシング関連
- ファイルアクセス関連
- アクセスされたリソースを抽出
- 特定のIPアドレスがアクセスしたリソースを抽出
- 特定のIPアドレスがアクセスしたリソースをタイムライン形式で表示
- ダウンロードされたリソースを抽出
- 特定のIPアドレスがダウンロードしたリソースを抽出
- 特定のIPアドレスがダウンロードしたリソースをタイムライン形式で表示
- プレビューされたリソースを抽出
- 特定のIPアドレスがプレビューしたリソースを抽出
- 特定のIPアドレスがプレビューしたリソースをタイムライン形式で表示
- ページビューされたリソースを抽出
- 特定のIPアドレスがページビューしたリソースを抽出
- 特定のIPアドレスがページビューしたリソースをタイムライン形式で表示
- メール関連
- メール関連のオペレーションを抽出
- 受信ルール関連のオペレーションを確認
- 気になるオペレーションを深堀
- メール関連のレコード・タイプを抽出
- Bindレコードを抽出
- 特定のIPアドレスのBindレコードをメッセージIDとともに表示
- Syncレコードを抽出
- 特定のIPアドレスのSyncレコードを抽出
- 消去されたメールを抽出
- MoveToDeletedItemsオペレーションを抽出
- 特定のIPアドレスまたはセッションIDのMoveToDeletedItemsオペレーションを抽出
- SoftDeleteオペレーションを抽出
- 特定のIPアドレスまたはセッションIDのSoftDeleteオペレーションを抽出
- HardDeleteオペレーションを抽出
- 特定のIPアドレスまたはセッションIDのHardDeleteオペレーションを抽出
- メール作成オペレーションを抽出
- メール送信オペレーションを抽出
調査にあたって
UALをJSON形式でエクスポート
UALのエクスポートにはSearch-UnifiedAuditLogを使用するが、そのためにはまずPowerShellのモジュールをインストールしてExchange Onlineに接続する必要がある。
Install-Module AzureAD
Install-Module MSOnline
Install-Module ExchangeOnlineManagement
Install-Module Microsoft.Graph
Connect-ExchangeOnline -UserPrincipalName <UPN> -ShowProgress $true
Exchange Onlineに接続できたらSearch-UnifiedAuditLogでUALをJSON形式でエクスポートする。
Search-UnifiedAuditLog -startdate yyyy-mm-dd -enddate yyyy-mm-dd -resultsize 5000 -userids user.name@mail.com | select-object -expandproperty auditdata | out-file -encoding utf8 UAL.json
Search-UnifiedAuditLog -startdate yyyy-mm-dd -enddate yyyy-mm-dd -resultsize 5000 -IPAddresses 1.2.3.4, 2a05:541:116:39::2 | select-object -expandproperty auditdata | out-file -encoding utf8 badIPs.json
Search-UnifiedAuditLogは最大で5000レコードまで取得可能。-resultsizeを指定しないと100レコードまでしか取得されない。上記の例では-useridsでユーザー名のみ指定しているが、必要に応じて-Operationsや-RecordTypeでフィルターすること。
Microsoft Purview ポータルからUALをCSV形式でエクスポートした場合は、AuditDataカラムの全てのJSONデータを一つのJSONファイルにまとめて保存する。
対象のJSONファイルを変数に定義。
$UAL_JSON='UAL.json'
JSONデータを整型された状態で出力
cat $UAL_JSON | jq '.'
特定のIPアドレスの特定のオペレーションをタイムライン形式で表示
cat $UAL_JSON | jq -r 'select(.ClientIP == "1.2.3.4" or .ClientIPAddress == "1.2.3.4" or .ActorIpAddress == "1.2.3.4") | select(.Operation == "FileAccessed" or .Operation == "FileAccessedExtended") | "\(.CreationTime),\(.Workload),\(.ApplicationDisplayName),\(.SourceFileName),\(.ObjectId)"'
上記はクライアントIPアドレス1.2.3.4のファイルアクセス関連のオペレーションをタイムライン形式で表示する。
jqコマンドの出力結果をCSVに保存
(echo "CreationTime,ClientIP,ActorIpAddress,Workload,ApplicationDisplayName,SourceFileName,ObjectId" && cat $UAL_JSON | jq -r 'select(.ClientIP == "1.2.3.4" or .ActorIpAddress == "1.2.3.4") | select(.Operation == "FileAccessed" or .Operation == "FileAccessedExtended") | "\(.CreationTime),\(.ClientIP),\(.ActorIpAddress),\(.Workload),\(.ApplicationDisplayName),\(.SourceFileName),\(.ObjectId)"') > FileAccessed.csv
上記のコマンドだと、JSONの値にカンマやダブルクォートが含まれているとCSVが崩れてしまう。以下は改良したコマンド。
(echo "CreationTime,UserId,ClientIP,ClientIPAddress,Workload,Operation,ResultStatus,MailboxOwnerUPN,ActorInfoString,Subject,ParentFolderPath,InternetMessageId" && \
cat $UAL_JSON | jq -r '
select(.ClientIP == "1.2.3.4" or .ClientIPAddress == "1.2.3.4" or .ActorIpAddress == "1.2.3.4") |
select(.Operation == "Update") |
[
.CreationTime,
.UserId,
.ClientIP,
.ClientIPAddress,
.ActorIpAddress,
.Workload,
.Operation,
.ResultStatus,
.MailboxOwnerUPN,
.ActorInfoString,
.Item.Subject,
.Item.ParentFolder.Path,
.Item.InternetMessageId
] | @csv
') > update-1.2.3.4.csv
(echo "CreationTime,UserId,ClientIP,ClientIPAddress,Workload,Operation,Subject,InternetMessageId,ParentFolderPath" && \
cat $UAL_JSON | jq -r '
select(.Workload == "Exchange") |
select(.Operation == "SoftDelete" or .Operation == "MoveToDeletedItems" or .Operation == "HardDelete") |
select(.ClientIP == "1.2.3.4" or .ClientIPAddress == "1.2.3.4" or .ActorIpAddress == "1.2.3.4") |
. as $parent | .AffectedItems[] |
[
$parent.CreationTime,
$parent.UserId,
$parent.ClientIP,
$parent.ClientIPAddress,
$parent.ActorIpAddress,
$parent.Workload,
$parent.Operation,
.Subject,
.InternetMessageId,
.ParentFolder.Path
] | @csv
') > mail-deletion-1.2.3.4.csv
# one liner
(echo "CreationTime,UserId,ClientIP,Workload,Operation,SourceFileName,ObjectId,UserAgent" && cat $UAL_JSON | jq -r 'select(.ClientIP == "1.2.3.4") | select(.Operation == "FileAccessed" or .Operation == "FileAccessedExtended" or .Operation == "FilePreviewed") | [.CreationTime,.UserId,.ClientIP,.Workload,.Operation,.SourceFileName,.ObjectId,.UserAgent] | @csv') > file-accessed-previewed-1.2.3.4.csv
(echo "CreationTime,UserId,ClientIP,Workload,Operation,AlwaysDeleteOutlookRulesBlob,Force,MoveToFolder,Name,MarkAsRead,StopProcessingRules" && cat $UAL_JSON | jq -r 'select(.Operation == "New-InboxRule") | . as $parent | .Parameters[] | [$parent.CreationTime,$parent.UserId,$parent.ClientIP,$parent.Workload,$parent.Operation,($parent.Parameters[] | "\(.Value)")] | @csv') | uniq > New-InboxRule.csv
ClientIP vs ClientIPAddress vs ActorIpAddress
ClientIPは殆どのWorkloadにて記録される。ClientIPAddressはExchange Workloadにて記録される。ActorIpAddressは AzureActiveDirectory Workloadにて記録される。
トリアージ
grepで手っ取り早く全てのデータを検索
cat $UAL_JSON | jq -r '.' | grep -i <your keyword here> | sort | uniq -c | sort -rnk1
検索対象のキーワードがUALのどのフィールドに存在するか不明な場合に便利。
ユーザー名を抽出
cat $UAL_JSON | jq -r '.UserId' | sort | uniq -c | sort -rnk1
オペレーションを抽出
cat $UAL_JSON | jq -r '"\(.Workload),\(.Operation),\(.ClientIP),\(.ClientIPAddress),\(.ActorIpAddress)"' | sort | uniq -c | sort -rnk1
特定のIPアドレスのオペレーションを抽出したい場合は以下のようにする。
cat $UAL_JSON | jq -r 'select(.ClientIP == "1.2.3.4" or .ClientIPAddress == "1.2.3.4" or .ActorIpAddress == "1.2.3.4") | "\(.Workload),\(.Operation)"' | sort | uniq -c | sort -rnk1
オペレーションの詳細を表示
cat $UAL_JSON | jq -r 'select(.Operation == "Create")'
上記は全てのCreateオペレーションの全情報を表示する。
特定のIPアドレスのオペレーションのみ確認したい場合は以下のようにする。
cat $UAL_JSON | jq -r 'select(.ClientIP == "1.2.3.4" or .ClientIPAddress == "1.2.3.4" or .ActorIpAddress == "1.2.3.4") | select(.Operation == "Create")'
IPアドレスを抽出
cat $UAL_JSON | jq -r '.ClientIP' | sort | uniq -c | sort -rnk1
cat $UAL_JSON | jq -r '.ClientIPAddress' | sort | uniq -c | sort -rnk1
cat $UAL_JSON | jq -r '.ActorIpAddress' | sort | uniq -c | sort -rnk1
User-Agentを抽出
cat $UAL_JSON | jq -r '.ExtendedProperties[]? | select(.Name == "UserAgent") | .Value' | sort | uniq -c | sort -rnk1
cat $UAL_JSON | jq -r '.UserAgent' | sort | uniq -c | sort -rnk1
cat $UAL_JSON | jq -r '.ActorInfoString' | sort | uniq -c | sort -rnk1
cat $UAL_JSON | jq -r '.ClientInfoString' | sort | uniq -c | sort -rnk1
特定のIPアドレスのUser-Agentを抽出
cat $UAL_JSON | jq -r 'select(.ClientIP == "1.2.3.4" or .ClientIPAddress == "1.2.3.4" or .ActorIpAddress == "1.2.3.4") | .ExtendedProperties[]? | select(.Name == "UserAgent") | .Value' | sort | uniq -c | sort -rnk1
cat $UAL_JSON | jq -r 'select(.ClientIP == "1.2.3.4" or .ClientIPAddress == "1.2.3.4" or .ActorIpAddress == "1.2.3.4") | .UserAgent' | sort | uniq -c | sort -rnk1
cat $UAL_JSON | jq -r 'select(.ClientIP == "1.2.3.4" or .ClientIPAddress == "1.2.3.4" or .ActorIpAddress == "1.2.3.4") | .ActorInfoString' | sort | uniq -c | sort -rnk1
cat $UAL_JSON | jq -r 'select(.ClientIP == "1.2.3.4" or .ClientIPAddress == "1.2.3.4" or .ActorIpAddress == "1.2.3.4") | .ClientInfoString' | sort | uniq -c | sort -rnk1
ログオン関連
ログオンに成功したIPアドレスを抽出
cat $UAL_JSON | jq -r 'select(.Operation == "UserLoggedIn") | .ClientIP' | sort | uniq -c | sort -rnk1
ログオンに失敗したIPアドレスを抽出
cat $UAL_JSON | jq -r 'select(.Operation == "UserLoginFailed") | .ClientIP' | sort | uniq -c | sort -rnk1
ログオンに失敗したIPアドレスをエラー内容とともに抽出
cat $UAL_JSON | jq -r 'select(.Operation == "UserLoginFailed") | "\(.ClientIP),\(.LogonError)"' | sort | uniq -c | sort -rnk1
ログオンを試みたIPアドレスをユーザーエージェントとともに抽出
cat $UAL_JSON | jq -r 'select(.Operation == "UserLoggedIn" or .Operation == "UserLoginFailed") | "\(.CreationTime),\(.Workload),\(.Operation),\(.ClientIP),\(.ExtendedProperties[]? | select(.Name == "UserAgent") | .Value)"' | sort
AiTM フィッシング関連
AiTM (adversary-in-the-middle) フィッシングとは、多要素認証の回避を目的としたフィッシングである。
ざっくり説明すると、プロキシサーバーをかませて、ユーザーとユーザーがログオンしようとしているWebサイトのやりとりを中継し、セッション・クッキーを盗むフィッシング手法である。
以下はおおまかな攻撃の流れ
- 攻撃者のサーバーにホストされている偽のログインページにユーザーを誘導する。
- 偽のログインページにて、ユーザーがパスワードと多要素コードを入力する。
- 攻撃者サーバーは入力されたパスワードと多要素コードを窃取しつつ、これらの認証情報をユーザーがログオンしようとしている正規のWebサイトに渡す。
- Webサイトは認証情報を検証し、問題が無ければセッション・クッキーを返す。
- 攻撃者サーバーがセッション・クッキーを窃取する。
- 攻撃者サーバーは攻撃を悟られないように、ユーザーを別のページへリダイレクトする。
- 攻撃者は窃取したセッション・クッキーを用いて、ユーザーがログオンしようとしていたWebサイトにログオンする。
Microsoft 365環境でAiTM フィッシングが発生した場合はセッションIDを調べるのが効果的である。
セッションIDとは文字通り、ログオン・セッションを識別するためのIDのこと。攻撃者に乗っ取られたセッションIDと紐づいたログを調べることで、攻撃者の活動の概要を知ることが出来る。(ただし、全てのログにセッションIDが記録されるわけではないので、その点は留意)
攻撃者にセッションが乗っ取られた場合、同一のセッションIDに対して複数のIPアドレスからのログオンが発生する。上述したAiTMフィッシングの流れでいうと、2. は正規のユーザーが攻撃者サーバーを介してログオンするので、攻撃者サーバーのIPアドレスが記録される。7. は攻撃者からのログオン試行で、多くの場合、攻撃者サーバーとは異なるIPアドレスからログオンが行われる。 なので、同一のセッションIDに対して異なる2つのIPアドレスからのログオンが発生することになる。
以下はセッションIDの調査に役立つワンライナーである。
セッションIDを抽出
cat $UAL_JSON | jq -r '.DeviceProperties[]? | select(.Name == "SessionId") | .Value' | sort | uniq -c | sort -rnk1
IPアドレスとともにセッションIDを抽出
cat $UAL_JSON | jq -r 'select(.DeviceProperties != null)' | jq -r '{cip: .ClientIP, sessid: (.DeviceProperties[] | select(.Name == "SessionId").Value)}|"\(.sessid),\(.cip)"' | sort | uniq -c | sort -rnk1
特定のIPアドレスのセッションIDを抽出
cat $UAL_JSON | jq -r 'select(.ClientIP == "1.2.3.4" or .ClientIPAddress == "1.2.3.4" or .ActorIpAddress == "1.2.3.4") | .DeviceProperties[]? | select(.Name == "SessionId") | .Value' | sort | uniq -c | sort -rnk1
特定のセッションIDのオペレーションを抽出
cat $UAL_JSON | jq 'select(.DeviceProperties[]? | select(.Name == "SessionId" and .Value == "006e3309-6b8f-e4cc-e79f-e2f7db7448b2")) | .Operation' | sort | uniq -c | sort -rnk1
ファイルアクセス関連
アクセスされたリソースを抽出
cat $UAL_JSON | jq -r 'select(.Operation == "FileAccessed" or .Operation == "FileAccessedExtended") | .ObjectId' | sort -u
特定のIPアドレスがアクセスしたリソースを抽出
cat $UAL_JSON | jq -r 'select(.ClientIP == "1.2.3.4" or .ClientIPAddress == "1.2.3.4" or .ActorIpAddress == "1.2.3.4") | select(.Operation == "FileAccessed" or .Operation == "FileAccessedExtended") | .ObjectId' | sort -u
特定のIPアドレスがアクセスしたリソースをタイムライン形式で表示
cat $UAL_JSON | jq -r 'select(.ClientIP == "1.2.3.4" or .ClientIPAddress == "1.2.3.4" or .ActorIpAddress == "1.2.3.4") | select(.Operation == "FileAccessed" or .Operation == "FileAccessedExtended") | "\(.CreationTime),\(.Workload),\(.ApplicationDisplayName),\(.SourceFileName),\(.ObjectId)"'
ダウンロードされたリソースを抽出
cat $UAL_JSON | jq -r 'select(.Operation == "FileDownloaded") | .ObjectId' | sort -u
特定のIPアドレスがダウンロードしたリソースを抽出
cat $UAL_JSON | jq -r 'select(.ClientIP == "1.2.3.4" or .ClientIPAddress == "1.2.3.4" or .ActorIpAddress == "1.2.3.4") | select(.Operation == "FileDownloaded") | .ObjectId' | sort -u
特定のIPアドレスがダウンロードしたリソースをタイムライン形式で表示
cat $UAL_JSON | jq -r 'select(.ClientIP == "1.2.3.4" or .ClientIPAddress == "1.2.3.4" or .ActorIpAddress == "1.2.3.4") | select(.Operation == "FileDownloaded") | "\(.CreationTime),\(.Workload),\(.ApplicationDisplayName),\(.SourceFileName),\(.ObjectId)"'
プレビューされたリソースを抽出
cat $UAL_JSON | jq -r 'select(.Operation == "FilePreviewed") | .ObjectId' | sort -u
特定のIPアドレスがプレビューしたリソースを抽出
cat $UAL_JSON | jq -r 'select(.ClientIP == "1.2.3.4" or .ClientIPAddress == "1.2.3.4" or .ActorIpAddress == "1.2.3.4") | select(.Operation == "FilePreviewed") | .ObjectId' | sort -u
特定のIPアドレスがプレビューしたリソースをタイムライン形式で表示
cat $UAL_JSON | jq -r 'select(.ClientIP == "1.2.3.4" or .ClientIPAddress == "1.2.3.4" or .ActorIpAddress == "1.2.3.4") | select(.Operation == "FilePreviewed") | "\(.CreationTime),\(.Workload),\(.ApplicationDisplayName),\(.SourceFileName),\(.ObjectId)"'
ページビューされたリソースを抽出
cat $UAL_JSON | jq -r 'select(.Operation == "PageViewed") | .ObjectId' | sort -u
特定のIPアドレスがページビューしたリソースを抽出
cat $UAL_JSON | jq -r 'select(.ClientIP == "1.2.3.4" or .ClientIPAddress == "1.2.3.4" or .ActorIpAddress == "1.2.3.4") | select(.Operation == "PageViewed") | .ObjectId' | sort -u
特定のIPアドレスがページビューしたリソースをタイムライン形式で表示
cat $UAL_JSON | jq -r 'select(.ClientIP == "1.2.3.4" or .ClientIPAddress == "1.2.3.4" or .ActorIpAddress == "1.2.3.4") | select(.Operation == "PageViewed") | "\(.CreationTime),\(.Workload),\(.ApplicationDisplayName),\(.SourceFileName),\(.ObjectId)"'
メール関連
メール関連のオペレーションを抽出
cat $UAL_JSON | jq -r 'select(.Workload == "Exchange") | .Operation' | sort | uniq -c | sort -rnk1
受信ルール関連のオペレーションを確認
cat $UAL_JSON | jq -r 'select(.Workload == "Exchange") | select(.Operation == "New-InboxRule" or .Operation == "Remove-InboxRule" or .Operation == "Set-InboxRule" or .Operation == "UpdateInboxRules") | "\(.ClientIP),\(.ClientIPAddress),\(.Operation)"' | sort | uniq -c | sort -rnk1
ATTENTION!!!
New-InboxRuleなどの受信ルール関連のオペレーションはIPアドレスを以下のフォーマットで記録する。
"ClientIP": "<IP address>:<port>"
e.g.) "ClientIP": "1.2.3.4:14355"
なので、.ClientIP == "1.2.3.4" or .ClientIPAddress == "1.2.3.4" or .ActorIpAddress == "1.2.3.4"でフィルターした場合、オペレーションを見落とす恐れがある。
気になるオペレーションを深堀
cat $UAL_JSON | jq -r 'select(.Workload == "Exchange") | select(.Operation == "New-InboxRule")'
cat $UAL_JSON | jq -r 'select(.Workload == "Exchange") | select(.Operation == "Set-InboxRule")'
cat $UAL_JSON | jq -r 'select(.Workload == "Exchange") | select(.Operation == "UpdateInboxRules")'
メール関連のレコード・タイプを抽出
cat $UAL_JSON | jq -r 'select(.Workload == "Exchange") | select(.Operation == "MailItemsAccessed")|.RecordType' | sort | uniq -c | sort -rnk1
Bindレコードを抽出
cat $UAL_JSON | jq -r 'select(.Workload == "Exchange") | select(.Operation == "MailItemsAccessed")| select(.RecordType == 50) | "\(.Folders[]?.Path),\(.ClientIPAddress),\(.ClientInfoString),\(.ActorInfoString)"' | sort | uniq -c | sort -rnk1
Bindとは OWA、 IMAP、 POP3などの新しいバージョンのOutlookクライアントがメールにアクセスした場合に記録されるレコードで、アクセスしたメールのメッセージIDが記録される。メッセージIDを調べることで、どのメールがアクセスされたか確認できる。
特定のIPアドレスのBindレコードをメッセージIDとともに表示
cat $UAL_JSON | jq -r 'select(.ClientIPAddress == "1.2.3.4") | select(.Workload == "Exchange") | select(.Operation == "MailItemsAccessed")| select(.RecordType == 50) | "\(.CreationTime),\(.Folders[].Path),\(.Folders[].FolderItems[].InternetMessageId)\(.ClientIPAddress),\(.ClientInfoString),\(.ActorInfoString)"'
Syncレコードを抽出
cat $UAL_JSON | jq -r 'select(.Workload == "Exchange") | select(.Operation == "MailItemsAccessed")| select(.RecordType == 2) | "\(.Folders[]?.Path),\(.ClientIPAddress),\(.ClientInfoString),\(.ActorInfoString)"' | sort | uniq -c | sort -rnk1
Syncとは古いバージョンのOutlookクライアントとMicrosoft Exchangeのフォルダが同期した際に記録されるレコードである。Bindと異なりメッセージIDは記録されないので、どのメールがアクセスされたかを確認することはできない。どのフォルダが同期されたかは確認できる。
特定のIPアドレスのSyncレコードを抽出
cat $UAL_JSON | jq -r 'select(.ClientIPAddress == "1.2.3.4") | select(.Workload == "Exchange") | select(.Operation == "MailItemsAccessed")| select(.RecordType == 2) | "\(.CreationTime),\(.Folders[].Path),\(.ClientIPAddress),\(.ClientInfoString),\(.ActorInfoString)"' | sort | uniq -c | sort -rnk1
消去されたメールを抽出
- MoveToDeletedItems: メールがDeleted Itemsフォルダに移動したことを示す。
- SoftDelete: メールが完全に削除された、もしくはDeleted Itemsフォルダから削除されたことを示す。SoftDeleteされたメールはRecoverable Itemsフォルダに移動する。
- HardDelete: メールがRecoverable Itemsフォルダから削除されたことを示す。
MoveToDeletedItemsオペレーションを抽出
cat $UAL_JSON | jq -r 'select(.Workload == "Exchange") | select(.Operation == "MoveToDeletedItems") | "\(.ClientIP),\(.ClientIPAddress),\(.ActorIpAddress),\(.SessionId),\(.AffectedItems[].Subject),\(.AffectedItems[].Attachments),\(.AffectedItems[].ParentFolder.Path)"'
特定のIPアドレスまたはセッションIDのMoveToDeletedItemsオペレーションを抽出
cat $UAL_JSON | jq -r 'select(.Workload == "Exchange") | select(.Operation == "MoveToDeletedItems") | select(.ClientIP == "1.2.3.4" or .ClientIPAddress == "1.2.3.4" or .ActorIpAddress == "1.2.3.4" or .SessionId == "005cf4f9-147b-db21-e773-6deec9666a2b") | "\(.CreationTime),\(.ClientIP),\(.ClientIPAddress),\(.ActorIpAddress),\(.SessionId),\(.AffectedItems[].Subject),\(.AffectedItems[].Attachments),\(.AffectedItems[].ParentFolder.Path)"'
SoftDeleteオペレーションを抽出
cat $UAL_JSON | jq -r 'select(.Workload == "Exchange") | select(.Operation == "SoftDelete") | "\(.ClientIP),\(.ClientIPAddress),\(.ActorIpAddress),\(.SessionId),\(.AffectedItems[].Subject),\(.AffectedItems[].Attachments),\(.AffectedItems[].ParentFolder.Path)"'
特定のIPアドレスまたはセッションIDのSoftDeleteオペレーションを抽出
cat $UAL_JSON | jq -r 'select(.Workload == "Exchange") | select(.Operation == "SoftDelete") | select(.ClientIP == "1.2.3.4" or .ClientIPAddress == "1.2.3.4" or .ActorIpAddress == "1.2.3.4" or .SessionId == "005cf4f9-147b-db21-e773-6deec9666a2b") | "\(.CreationTime),\(.ClientIP),\(.ClientIPAddress),\(.ActorIpAddress),\(.SessionId),\(.AffectedItems[].Subject),\(.AffectedItems[].Attachments),\(.AffectedItems[].ParentFolder.Path)"'
HardDeleteオペレーションを抽出
cat $UAL_JSON | jq -r 'select(.Workload == "Exchange") | select(.Operation == "HardDelete") | "\(.ClientIP),\(.ClientIPAddress),\(.ActorIpAddress),\(.SessionId),\(.AffectedItems[].Subject),\(.AffectedItems[].Attachments),\(.AffectedItems[].ParentFolder.Path)"'
特定のIPアドレスまたはセッションIDのHardDeleteオペレーションを抽出
cat $UAL_JSON | jq -r 'select(.Workload == "Exchange") | select(.Operation == "HardDelete") | select(.ClientIP == "1.2.3.4" or .ClientIPAddress == "1.2.3.4" or .ActorIpAddress == "1.2.3.4" or .SessionId == "005cf4f9-147b-db21-e773-6deec9666a2b") | "\(.CreationTime),\(.ClientIP),\(.ClientIPAddress),\(.ActorIpAddress),\(.SessionId),\(.AffectedItems[].Subject),\(.AffectedItems[].Attachments),\(.AffectedItems[].ParentFolder.Path)"'
メール作成オペレーションを抽出
cat $UAL_JSON | jq -r 'select(.Workload == "Exchange") | select(.Operation == "Create") | "\(.ClientIP),\(.ClientIPAddress),\(.SessionId),\(.Operation),\(.Item.Subject),\(.Item.Attachments),\(.Item.ParentFolder.Path)"'
# filter with IP
cat $UAL_JSON | jq -r 'select(.Workload == "Exchange" and .Operation == "Create" and (.ClientIP == "1.2.3.4" or .ClientIPAddress == "1.2.3.4" or .ActorIpAddress == "1.2.3.4")) | "\(.CreationTime),\(.ClientIP),\(.ClientIPAddress),\(.SessionId),\(.Operation),\(.Item.Subject),\(.Item.Attachments),\(.Item.ParentFolder.Path)"'
メール送信オペレーションを抽出
cat $UAL_JSON | jq -r 'select(.Workload == "Exchange") | select(.Operation == "Send") | "\(.ClientIP),\(.ClientIPAddress),\(.SessionId),\(.Operation),\(.Item.Subject),\(.Item.Attachments),\(.Item.ParentFolder.Path)"'
# filter with IP
cat $UAL_JSON | jq -r 'select(.Workload == "Exchange" and .Operation == "Send" and (.ClientIP == "1.2.3.4" or .ClientIPAddress == "1.2.3.4" or .ActorIpAddress == "1.2.3.4")) | "\(.CreationTime),\(.ClientIP),\(.ClientIPAddress),\(.SessionId),\(.Operation),\(.Item.Subject),\(.Item.Attachments),\(.Item.ParentFolder.Path)"'