🛡

【Elastic】続 Defender for Endpoint のログを取り込んでみた

2024/05/20に公開

はじめに

先日書いた「Defender for Endpoint のログを取り込んでみた」で
書ききれなかった Filebeat を使った方式 を今回はまとめてみました。
https://zenn.dev/logspect/articles/e68365225746a7fb6334

本投稿で説明する内容

Elastic Agent で取り込んだ場合と同様に、Filebeat azure eventhub input を使って
Defender for Endpoint のデバイスログを Elasticsearch に取り込みます。

前提

・Event Hubs 及び Azure Blob Storage は事前構築済みです。(上記ブログ記事参照)
・Defneder for Endpoint のログは Event Hubs に転送済みです。(上記ブログ記事参照)
・Elasticsearch と Kibana は Standard Edtition で事前構築済みです。
・Filebeat と Logstash は事前にインストール済みです。

【参考】
Filebeat のインストール方法(公式ページ)
Logstash のインストール方法(公式ページ)

利用環境

各ソフトウェアのバージョンは以下の通りです。

Product version
Windows OS Windows 11 Pro 22H2
macOS Sonoma 14.4.1(23E224)
Defender マルウェア対策クライアント 101.24032.0006
Defender エンジン 1.1.24030.4
Defender ウィルス対策 1.409.620.0
Defender スパイウェア対策 1.409.620.0
Amazon Linux 2023.2.20231113.0
Elasticsearch 8.11.2
Kibana 8.11.2
Logstash 8.11.2
Filebeat 8.11.2

【構成図】
・Filebeat の Azure eventhub input で Event Hubs からログを取得します。
・Logstash で JSON 解析、フィールド名修正、時刻情報取得等の ETL 処理を実施します。


全体構成図

実施手順

以下、実施手順になります。

  1. Filebeat の設定
  2. Logstash の設定
  3. Filebeat と Logstsh の起動
  4. ログの確認

1. Filebeat の設定

Filebeat で以下の設定を実施します。

  • Event Hubs からのログ取得
  • Logstash へのログ転送
  • メタデータフィールドの削除

Filebeat 設定ファイルの編集コマンドは下記になります。

Filebeat 設定ファイルの編集
$ sudo vi /etc/filebeat/filebeat.yml

1-1. Filebeat inputs の設定

Event hubs からログを取得するための設定をおこないます。
filebeat.yml の filebeat.inputs 句に以下の設定値を設定します。

filebeat.inputs 句の内容
filebeat.inputs:
  - type: azure-eventhub
    eventhub: "defenderhub"
    consumer_group: "$Default"
    connection_string: "Endpoint=sb://********************************"
    storage_account: "teststaccount99"
    storage_account_key: "********************************************"
    storage_account_container: "testcontainer01"

【設定内容】

項目名 設定値 説明
type azure-eventhub Event Hubs からログを取得することを宣言します
eventhub "defenderhub" 「イベントハブ名」を入力します
consumer_group "$Default" 「コンシューマーグループ名」を入力します
connection_string "Endpoint=sb://*******" 「接続文字列 - 主キー」を入力します
storage_account "teststaccount99" 「ストレージアカウント名」を入力します
storage_account_key "<ストレージアカウントキー>" ストレージアカウントの「アクセスキー」を入力します
storage_account_container "testcontainer01" 「ストレージコンテナ名」を入力します

【参考】
Azure eventhub input(公式ページ)

1-2. Outputs の設定

Event Hubs から取得したログを Logstash へ転送するための設定をおこないます。
filebeat.ymloutput.logstash 句に以下の設定値を設定します。

output.logstash 句の内容
output.logstash:
  # The Logstash hosts 
  hosts: ["10.0.4.104:5044"]

【設定内容】

項目名 設定値 説明
hosts ["10.0.4.104:5044"] Logstash ノードに TCP5044 ポートでログを転送します

【参考】
Configure the Logstash output(公式ページ)

【補足】
合わせて、Elasticsearch への転送設定を無効化しておきます。
filebeat.ymloutput.elasticsearch 句をコメントアウトします。

output.elasticsearch のコメントアウト
# output.elasticsearch:
#   hosts: ["localhost:9200"]

1-3. Processors の設定

メタデータフィールドの削除のための設定をおこないます。
filebeat.ymlprocessors 句に以下の設定値を設定します。

processors 句の内容
processors:
#  - add_host_metadata:
#      when.not.contains.tags: forwarded
#  - add_cloud_metadata: ~
#  - add_docker_metadata: ~
#  - add_kubernetes_metadata: ~

  - drop_fields:
      fields: ["agent", "azure", "ecs", "host", "input"]

【設定内容】

項目名 設定値 説明
add_host_metadata コメントアウト host に関するメタデータフィールドを無効化します
add_cloud_metadata コメントアウト cloud に関するメタデータフィールドを無効化します
add_docker_metadata コメントアウト docker に関するメタデータフィールドを無効化します(今回は無効化しなくてもメタデータは出力されません)
add_kubernetes_metadata コメントアウト kubernetes に関するメタデータフィールドを無効化します (今回は無効化しなくてもメタデータは出力されません)
drop_fields.fields ["agent", "azure", "ecs", "host", "input"] 上記設定のコメントでは削除できないメタデータフィールドを明示的に削除します

filebeat.yml を保存して閉じます。(:wq! で vi エディタを閉じます)

【参考】
how to remove filebeat metadata(Stack overflow)
Drop fields from events(公式ページ)

2. Logstash の設定

Logstash で以下の設定を実施します。

  • Filebeat からのログ取得
  • message フィールドの JSON 解析
  • [properties][AdditionalFields] フィールドの JSON 解析
  • フィールド名の properties の削除
  • Timestamp フィールドの時刻情報の取得
  • 不要なフィールドの削除
  • Elasticsearch へのログ転送

Logstash パイプラインファイルの編集コマンドは下記になります。

Logstash パイプラインファイルの編集
$ sudo vi /etc/logstash/conf.d/logstash.conf

2-1. input の設定

Filebeat からログを受信するための設定をおこないます。
logstash.confinput 句に以下の設定値を設定します。

input 句の内容
input {
  # input from Filebeat
  beats {
    port => 5044
  }
}

【設定内容】

プラグイン名 項目名 設定値 説明
beats port 5044 Filebeat から TCP5044 ポートでログを受信します

【参考】
Beats input plugin(公式ページ)

2-2. filter の設定

取得したログを Elasticsearch に格納するために必要な加工処理をおこないます。
logstash.conffilter 句に以下の設定値を設定します。

filter 句の内容
filter {
  # parse message field in json format
  json {
    source => "message"
  }
  # parse properties.AdditionalFields in json format
  json {
    source => "[properties][AdditionalFields]"
  }
  # rename fields starting with properties
  ruby {
    code => "
      event.get('properties').each {|k, v|
        event.set(k, v)
      }
      event.remove('properties')
    "
  }
  # use Timestamp field for @timestamp
  date {
    match => ["Timestamp", "ISO8601"]
    timezone => "UTC"
  }
  # delete redundant field
  mutate {
    remove_field => ["message", "[event][original]", "AdditionalFields"]
  }
}

【設定内容】

プラグイン名 項目名 設定値 説明
json source "message" message フィールドのテキストを JSON でパースします
json source "[properties][AdditionalFields]" [properties][AdditionalFields] フィールドのテキストを JSON でパースします
ruby code "event.get('properties').each {|k, v| event.set(k, v)} event.remove('properties')" フィールド名に properties という文字列が含まれている場合は削除します
date match ["Timestamp", "ISO8601"] Timestamp フィールドに含まれる ISO8601 形式の時刻情報を @timestamp フィールドに利用します
date timezone "UTC" Timestamp フィールドに含まれる時刻情報のタイムゾーンは UTC になります
mutate remove_field ["message", "[event][original]", "AdditionalFields"] Elasticsearch に転送不要なフィールドを削除します

【参考】
JSON filter plugin(公式ページ)
Ruby filter plugin(公式ページ)
Date filter plugin(公式ページ)
Mutate filter plugin(公式ページ)

2-3. output の設定

Elasticsearch へログを転送するための設定をおこないます。
logstash.confoutput 句に以下の設定値を設定します。

output 句の内容
output {
# output to Elasticsearch
  elasticsearch {
    hosts => ["https://10.0.4.104:9200"]
    user => "elastic"
    password => "**************"
    ssl => true
    ssl_certificate_verification => false
  }
}

【設定内容】

プラグイン名 項目名 設定値 説明
elasticsearch hosts ["https://10.0.4.104:9200"] Elasticsearch ノードに TCP9200 ポートに HTTPS でログを転送します
elasticsearch user "elastic" Elasticsearch の認証用ユーザーとして elastic を利用します
elasticsearch password "<elastic ユーザーのパスワード>" 上記ユーザーのパスワードを指定します
elasticsearch ssl true HTTPS 通信のため、SSL 有効化します
elasticsearch ssl_certificate_verification false 自己証明書を利用しているため、証明書の検証を無効とします

logstash.conf を保存して閉じます。(:wq! で vi エディタを閉じます)

【参考】
Elasticsearch output plugin(公式ページ)
Secure your connection to Elasticsearch(公式ページ)

3. Filebeat と Logstsh の起動

設定完了後、Logstash、Filebeat の順にプロセスを起動します。

Logstash の起動
$ sudo systemctl start logstash
$ sudo systemctl status logstash
Filebeat の起動
$ sudo systemctl start filebeat
$ sudo systemctl status filebeat

4. ログの確認

最後に Kibana にログインし、意図した通りのログになっていることを確認します。
Kibana にログインし、[Disocver] を開き、ログのフィールドを確認します。


ログのサンプル


ログのサンプル(続き)

上記のような状態になっていれば完成です。

まとめ

いかがでしたでしょうか?

以前のブログ記事で書いた Elastic Agent を使う方法が新しい方式になりますが
依然として Filebeat を使ったアーキテクチャで運用されている企業も多くあることでしょう。

Filebeat を使わずに Logstash で直接 Event Hubs からログを取得する方法 [1] もあります。
Logstash で直接取得する方法は記事にしませんが、filter 句の内容はそのまま使えるはずです。

Elastic Agent を使った方式含め、Defender for Endpoint のデバイスログを有効活用する上で
皆様のお役に立てれば何よりです ^^

DeviceProcessEvents サンプルログ
{
  "_index": ".ds-logs-generic-default-2024.05.17-000001",
  "_id": "XywZh48BwwfvYq_s0RV5",
  "_version": 1,
  "_score": 0,
  "_source": {
    "InitiatingProcessSignatureStatus": "Unknown",
    "ProcessTokenElevation": "None",
    "InitiatingProcessParentId": 0,
    "SHA1": "12345a2cc321a77755cc2a888a747f8d1aa9cc99",
    "ActionType": "ProcessCreated",
    "InitiatingProcessId": 36366,
    "AccountUpn": null,
    "AppGuardContainerId": null,
    "ProcessPosixFilePermissions": [
      "None"
    ],
    "InitiatingProcessIntegrityLevel": null,
    "MachineGroup": null,
    "InitiatingProcessVersionInfoOriginalFileName": null,
    "InitiatingProcessVersionInfoCompanyName": null,
    "ProcessCreationTime": "2024-05-17T15:05:11.32949Z",
    "ProcessVersionInfoProductVersion": null,
    "InitiatingProcessPosixSessionId": 1,
    "InitiatingProcessAccountSid": "S-1-4-17",
    "ProcessVersionInfoInternalFileName": null,
    "FolderPath": "/usr/libexec/xpcproxy",
    "ProcessVersionInfoProductName": null,
    "ProcessPosixSessionId": 1,
    "InitiatingProcessFolderPath": null,
    "tags": [
      "beats_input_codec_plain_applied"
    ],
    "InitiatingProcessLogonId": 0,
    "InitiatingProcessParentCreationTime": null,
    "InitiatingProcessMD5": null,
    "ProcessPosixProcessGroupId": 1,
    "AccountName": "root",
    "FileSize": 216400,
    "InitiatingProcessSignerType": "Unknown",
    "InitiatingProcessTokenElevation": "None",
    "InitiatingProcessAccountUpn": null,
    "InitiatingProcessVersionInfoFileDescription": null,
    "InitiatingProcessSHA1": null,
    "AccountDomain": "macbook-pro-2",
    "InitiatingProcessParentFileName": "",
    "DeviceId": "3212348ba2dbca444c3f4c4a1999cc1ca3cca5c9a",
    "FileName": "xpcproxy",
    "InitiatingProcessPosixEffectiveGroup": {
      "PosixGroupId": 0,
      "Name": "wheel"
    },
    "ProcessCurrentWorkingDirectory": "/",
    "InitiatingProcessVersionInfoProductVersion": null,
    "Timestamp": "2024-05-17T15:05:11.32949Z",
    "InitiatingProcessCreationTime": "2024-05-17T15:05:11.2772Z",
    "InitiatingProcessPosixProcessGroupId": 1,
    "Tenant": "DefaultTenant",
    "ProcessVersionInfoCompanyName": null,
    "InitiatingProcessFileName": "",
    "@version": "1",
    "ProcessCommandLine": "xpcproxy com.apple.mdworker.shared.0C000000-0100-0000-0000-000000000000",
    "InitiatingProcessCommandLine": "",
    "event": {},
    "LogonId": 0,
    "ProcessVersionInfoFileDescription": null,
    "AccountObjectId": null,
    "ProcessPosixEffectiveGroup": {
      "PosixGroupId": 0,
      "Name": "wheel"
    },
    "InitiatingProcessAccountObjectId": null,
    "InitiatingProcessAccountDomain": "macbook-pro-2",
    "InitiatingProcessPosixEffectiveUser": {
      "DomainName": "MacBook-Pro-2",
      "PrimaryPosixGroup": {
        "PosixGroupId": 0,
        "Name": "wheel"
      },
      "PosixUserId": 0,
      "LogonId": 0,
      "Name": "root",
      "Sid": "S-1-4-17"
    },
    "InitiatingProcessAccountName": "root",
    "InitiatingProcessVersionInfoProductName": null,
    "ReportId": 93974,
    "operationName": "Publish",
    "AccountSid": "S-1-4-17",
    "InitiatingProcessFileSize": null,
    "InitiatingProcessSHA256": null,
    "SHA256": "aa15111c255028318071f3f99999ed0cbf99999aa7457555f257befbd3f15f8a",
    "ProcessIntegrityLevel": null,
    "@timestamp": "2024-05-17T15:05:11.329Z",
    "InitiatingProcessVersionInfoInternalFileName": null,
    "_TimeReceivedBySvc": "2024-05-17T15:05:49.3185222Z",
    "data_stream": {
      "namespace": "default",
      "type": "logs",
      "dataset": "generic"
    },
    "tenantId": "99aa44c2-cc2b-1111-a333-5b32a0c099a9",
    "ProcessVersionInfoOriginalFileName": null,
    "ProcessPosixEffectiveUser": {
      "DomainName": "MacBook-Pro-2",
      "PrimaryPosixGroup": {
        "PosixGroupId": 0,
        "Name": "wheel"
      },
      "PosixUserId": 0,
      "LogonId": 0,
      "Name": "root",
      "Sid": "S-1-4-17"
    },
    "InitiatingProcessPosixRealUser": {
      "DomainName": "MacBook-Pro-2",
      "PrimaryPosixGroup": {
        "PosixGroupId": 0,
        "Name": "wheel"
      },
      "PosixUserId": 0,
      "LogonId": 0,
      "Name": "root",
      "Sid": "S-1-4-17"
    },
    "time": "2024-05-17T15:08:42.1852239Z",
    "ProcessId": 36366,
    "category": "AdvancedHunting-DeviceProcessEvents",
    "MD5": "c3a23c142242c80c8774455f5a88a9a9",
    "DeviceName": "macbook-pro-2"
  },
  "fields": {
    "InitiatingProcessSignatureStatus": [
      "Unknown"
    ],
    "ProcessTokenElevation": [
      "None"
    ],
    "InitiatingProcessParentId": [
      0
    ],
    "ActionType": [
      "ProcessCreated"
    ],
    "ProcessPosixEffectiveUser.Name": [
      "root"
    ],
    "SHA1": [
      "12345a2cc321a77755cc2a888a747f8d1aa9cc99"
    ],
    "InitiatingProcessId": [
      36366
    ],
    "InitiatingProcessPosixRealUser.LogonId": [
      0
    ],
    "InitiatingProcessPosixEffectiveUser.PrimaryPosixGroup.Name": [
      "wheel"
    ],
    "InitiatingProcessPosixRealUser.PrimaryPosixGroup.PosixGroupId": [
      0
    ],
    "InitiatingProcessPosixEffectiveUser.DomainName": [
      "MacBook-Pro-2"
    ],
    "ProcessPosixFilePermissions": [
      "None"
    ],
    "ProcessPosixEffectiveUser.PrimaryPosixGroup.Name": [
      "wheel"
    ],
    "InitiatingProcessPosixRealUser.PrimaryPosixGroup.Name": [
      "wheel"
    ],
    "ProcessPosixEffectiveUser.PrimaryPosixGroup.PosixGroupId": [
      0
    ],
    "InitiatingProcessPosixRealUser.Sid": [
      "S-1-4-17"
    ],
    "ProcessCreationTime": [
      "2024-05-17T15:05:11.32949Z"
    ],
    "InitiatingProcessPosixEffectiveUser.Name": [
      "root"
    ],
    "InitiatingProcessPosixEffectiveGroup.Name": [
      "wheel"
    ],
    "InitiatingProcessPosixSessionId": [
      1
    ],
    "InitiatingProcessAccountSid": [
      "S-1-4-17"
    ],
    "InitiatingProcessPosixRealUser.DomainName": [
      "MacBook-Pro-2"
    ],
    "FolderPath": [
      "/usr/libexec/xpcproxy"
    ],
    "ProcessPosixEffectiveUser.LogonId": [
      0
    ],
    "ProcessPosixSessionId": [
      1
    ],
    "data_stream.type": [
      "logs"
    ],
    "tags": [
      "beats_input_codec_plain_applied"
    ],
    "InitiatingProcessLogonId": [
      0
    ],
    "ProcessPosixEffectiveGroup.PosixGroupId": [
      0
    ],
    "ProcessPosixEffectiveUser.DomainName": [
      "MacBook-Pro-2"
    ],
    "ProcessPosixProcessGroupId": [
      1
    ],
    "ProcessPosixEffectiveGroup.Name": [
      "wheel"
    ],
    "AccountName": [
      "root"
    ],
    "FileSize": [
      216400
    ],
    "InitiatingProcessPosixEffectiveUser.LogonId": [
      0
    ],
    "InitiatingProcessPosixRealUser.Name": [
      "root"
    ],
    "InitiatingProcessPosixEffectiveUser.PrimaryPosixGroup.PosixGroupId": [
      0
    ],
    "InitiatingProcessSignerType": [
      "Unknown"
    ],
    "InitiatingProcessTokenElevation": [
      "None"
    ],
    "AccountDomain": [
      "macbook-pro-2"
    ],
    "DeviceId": [
      "3212348ba2dbca444c3f4c4a1999cc1ca3cca5c9a"
    ],
    "InitiatingProcessParentFileName": [
      ""
    ],
    "FileName": [
      "xpcproxy"
    ],
    "ProcessCurrentWorkingDirectory": [
      "/"
    ],
    "InitiatingProcessPosixRealUser.PosixUserId": [
      0
    ],
    "Timestamp": [
      "2024-05-17T15:05:11.32949Z"
    ],
    "InitiatingProcessCreationTime": [
      "2024-05-17T15:05:11.2772Z"
    ],
    "InitiatingProcessPosixProcessGroupId": [
      1
    ],
    "ProcessPosixEffectiveUser.PosixUserId": [
      0
    ],
    "Tenant": [
      "DefaultTenant"
    ],
    "InitiatingProcessFileName": [
      ""
    ],
    "ProcessPosixEffectiveUser.Sid": [
      "S-1-4-17"
    ],
    "@version": [
      "1"
    ],
    "InitiatingProcessCommandLine": [
      ""
    ],
    "ProcessCommandLine": [
      "xpcproxy com.apple.mdworker.shared.0C000000-0100-0000-0000-000000000000"
    ],
    "LogonId": [
      0
    ],
    "InitiatingProcessPosixEffectiveUser.PosixUserId": [
      0
    ],
    "InitiatingProcessAccountDomain": [
      "macbook-pro-2"
    ],
    "data_stream.namespace": [
      "default"
    ],
    "InitiatingProcessAccountName": [
      "root"
    ],
    "InitiatingProcessPosixEffectiveGroup.PosixGroupId": [
      0
    ],
    "ReportId": [
      93974
    ],
    "operationName": [
      "Publish"
    ],
    "InitiatingProcessPosixEffectiveUser.Sid": [
      "S-1-4-17"
    ],
    "AccountSid": [
      "S-1-4-17"
    ],
    "SHA256": [
      "aa15111c255028318071f3f99999ed0cbf99999aa7457555f257befbd3f15f8a"
    ],
    "@timestamp": [
      "2024-05-17T15:05:11.329Z"
    ],
    "_TimeReceivedBySvc": [
      "2024-05-17T15:05:49.3185222Z"
    ],
    "data_stream.dataset": [
      "generic"
    ],
    "tenantId": [
      "99aa44c2-cc2b-1111-a333-5b32a0c099a9"
    ],
    "ProcessId": [
      36366
    ],
    "time": [
      "2024-05-17T15:08:42.1852239Z"
    ],
    "category": [
      "AdvancedHunting-DeviceProcessEvents"
    ],
    "DeviceName": [
      "macbook-pro-2"
    ],
    "MD5": [
      "c3a23c142242c80c8774455f5a88a9a9"
    ]
  }
}
脚注
  1. Azure Event Hubs Plugin(公式ページ) ↩︎

Logspect Tech Blog

Discussion