dawnsmithcyber/azure-kql-threat-hunting
GitHub: dawnsmithcyber/azure-kql-threat-hunting
一个 Azure 威胁狩猎实战案例,提供 KQL 查询语句用于检测 IP 轮换侦察、遗留协议风险以及身份层暴力破解行为。
Stars: 0 | Forks: 0
# Azure KQL 威胁狩猎
Azure KQL 分析可能的威胁 ✅
# 🛡️ 针对“VPN 跳跃”侦察的 Azure KQL 分析
## 📝 仓库描述
利用 KQL 进行 Azure 威胁狩猎的项目,旨在识别“VPN 跳跃”模式,并分析遗留协议 (Telnet) 与加密标准 (SSH) 的安全风险。
## 📝 概述
本仓库记录了在 Azure 环境中进行的一次主动威胁狩猎会话。在此次实验中,我发现了一种侦察模式,攻击者利用“VPN 跳跃”——在 `85.217.149.x` 范围内的多个 IP 地址之间快速切换——来探测网络漏洞。
## 🔍 调查摘要
* **识别:** 发现了来自单个 `/24` 子网的异常流量模式。
* **分析:** 利用 **Kusto Query Language (KQL)** 按特定日期范围和 IP 子网筛选防火墙日志。
* **结论:** **100% 的流量被拒绝。** 网络安全组 在网络边界成功缓解了此次探测。
## ⚠️ 风险深度剖析:端口 23 (Telnet) vs. 端口 22 (SSH)
日志显示了对 **端口 23** 的重复访问尝试。从欺诈猎手 的角度来看,理解目标背后的“原因”至关重要:
| 特性 | 端口 23 (Telnet) | 端口 22 (SSH) |
| :--- | :--- | :--- |
| **安全性** | **无** (明文) | **高** (加密) |
| **风险概况** | 凭据可通过 MitM 嗅探 | 加密网络协议 |
| **建议** | **立即禁用** | 用于安全远程访问 |
**核心洞察:** Telnet 以明文形式传输数据,使其成为凭据盗窃的高价值目标。此次实验强化了我们为何优先选择 SSH 等加密替代方案的原因。
## 🕵️ 后续步骤:身份定位查询
当攻击者未能突破网络层时,他们通常会转向 **身份层** (用户账户)。
为了搜寻这些转向行为,我执行以下查询,以检查这些“跳跃”的 IP 是否正试图暴力破解特定的用户名:
检查“跳跃”的 IP 是否针对特定用户账户
SigninLogs
| where IPAddress startswith "85.217.149"
| where ResultType != 0 // 筛选失败登录
| summarize
FailureCount = count(),
TargetedAccounts = make_set(UserPrincipalName),
DistinctAccountCount = dcount(UserPrincipalName)
by IPAddress, ResultDescription
| order by FailureCount desc
### 💡 经验教训
### 🔍 可见性即胜利
如果没有 **日志聚合**,“VPN 跳跃”攻击看起来就像是互不相关、随机噪声。集中式日志记录 (Azure Sentinel/Log Analytics) 提供了必要的“上帝视角”,以将点连成线并看清数据背后的真实故事。如果你看不到模式,就无法猎杀威胁。
### 🛡️ 协议卫生
此次调查强化了我们绝不能开放 **端口 23 (Telnet)** 的原因。即使防火墙成功阻止了流量,仅存在未加密的遗留协议就是一种隐患。它就像一个信标,吸引复杂攻击者进行进一步探测。过渡到 **SSH (端口 22)** 不仅是最佳实践,更是现代安全的必要条件。
### 🏰 纵深防御
虽然在此场景中 Azure 防火墙守住了边界,但“欺诈猎手”绝不会认为工作已经完成。监控 **登录日志** 是至关重要的第二道防线。通过从网络日志转向身份日志,我们要确保未能突破网络的攻击者没有通过基于身份的欺诈或撞库找到“后门”。
### 📝 执行摘要
在 Azure 环境进行主动狩猎期间,我发现了一种涉及“VPN 跳跃”的侦察模式。一名外部攻击者在 85.217.149.x 子网内循环使用多个 IP,以绕过基本的速率限制和基于 IP 的信誉过滤。调查重点是此流量是否绕过了防火墙,并评估了目标端口的风险概况。
### 🔍 技术分析
1. 识别“跳跃”模式
攻击者利用狭窄的 IP 范围来模拟合法的分布式流量。为了验证防火墙是否成功丢弃了这些数据包,我执行了以下 KQL 查询:
代码片段
// 检查来自可疑子网的允许与拒绝流量
AzureDiagnostics
| where TimeGenerated between (datetime(2026-03-01) .. datetime(2026-03-09))
| where SourceIP startswith "85.217.149"
| summarize Count = count() by Action, SourceIP, DestinationPort
| order by Count desc
结果:来自此范围的所有流量均被标记为 Deny。未记录到成功的入口。
2. 协议风险评估:端口 23 (Telnet)
日志显示了对端口 23 的探测。与使用加密网络协议保护传输数据的 SSH (端口 22) 不同,Telnet 以明文形式传输数据。
漏洞:“中间人” 攻击可以轻易嗅探凭据。
补救措施:确保在网络安全组 级别关闭端口 23,并强制所有远程管理使用 SSH。
### 💡 关键要点
纵深防御:尽管攻击者通过 IP 轮换持续尝试,但预配置的防火墙规则阻止了入侵。
可见性即胜利:知道如何按日期时间和 IP 范围进行筛选,能让猎手看到日志背后的“故事”,而不仅仅是原始数据。
## 🕵️ 下一步行动:“账户目标”查询
一旦你知道他们在敲门,就需要查看他们是否已开始尝试转动特定用户账户的把手。在出现“跳跃”模式后,你的下一个首选动作应该是检查来自这些相同 IP 的失败身份验证尝试的登录日志。
接下来尝试此查询:
它查找与您发现的可疑 IP 范围相关的“登录失败” (ResultType 50126) 或“账户锁定”事件。
代码片段
SigninLogs
| where IPAddress startswith "85.217.149"
| where ResultType != 0 // 筛选失败 (0 表示成功)
| summarize FailureCount = count(), UniqueAccountsTargeted = dcount(UserPrincipalName) by IPAddress, ResultDescription
| order by FailureCount desc
这将告诉你他们是否已从“探测防火墙”转变为“暴力破解会计部的 Jennifer”。
标签:AMSI绕过, Azure Sentinel, Azure 监控, Cloudflare, KQL, Kusto 查询语言, MITRE ATT&CK, NSG, PE 加载器, SSH 安全, Telnet 风险, VPN 跳跃, 凭据窃取, 威胁检测, 安全运营, 密码管理, 扫描框架, 插件系统, 数据统计, 明文传输, 端口扫描, 网络安全组, 身份攻击