zachncurry/Rogue-DNS-Server-Detection-and-Remediation

GitHub: zachncurry/Rogue-DNS-Server-Detection-and-Remediation

该项目通过 Python 脚本实现网络设备 DNS 配置的自动化审计、违规检测、告警通知与远程修复,解决企业内网遭遇流氓 DNS 篡改后的快速响应问题。

Stars: 0 | Forks: 0

# 流氓 DNS 服务器检测与修复
Python IT 自动化 **简介**
在一次网络安全事件中,假设你是一家公司的网络管理员:公司内部的域名系统 (DNS) 服务出现故障,设备正通过一个流氓 DNS 地址进行解析。你的任务是快速查明根本原因,验证并修正受影响设备的配置,并实施持久的防护措施以防止问题复发。你将管理一个基于 GitLab 的项目及其工作分支,开发 Python 脚本来枚举设备、验证连通性和 DNS 设置、自动通知利益相关者、创建修复工单,并确保所有受影响的设备都得到正确配置,从而恢复 DNS 服务。
_注意:目前我正在将实验的代码从 VS 提交到 GitLab 仓库。不过,我将 GitHub 作为我唯一的真实数据源、备份以及个人作品集仓库。_
**关键成果**
- 整合 Python 脚本、模块、包和库,以实现网络任务和流程的自动化。 **网络拓扑图**
_GSN3 实例_
image ## 第一部分 **场景**
作为公司的网络管理员,你收到了关于 DNS 服务中断的网络安全事件警报。内部 DNS 服务目前已宕机,并且你发现几台网络设备已被重新配置为使用未经授权且具有潜在恶意的 DNS 地址。必须立即采取行动以恢复正常的 DNS 功能并保障网络安全。 **问题陈述:**
我负责查明 DNS 解析问题的根本原因并恢复正常运营。这包括调查未经授权的 DNS 更改的来源、验证并修正所有受影响设备的 DNS 配配置,以及实施即时的修复步骤来保护网络免受进一步的破坏。 ## 第二部分 **场景**
在解决了即时的 DNS 服务中断并恢复了所有网络设备上正确的 DNS 配置后,你意识到有必要防止未来发生类似事件。作为网络管理员,你有责任实施主动防御措施,以便在未经授权的 DNS 更改或服务中断影响业务运营之前,检测并响应这些异常。 **问题陈述:**
为了确保持续的网络安全性与可靠性,你必须设计并实施一个能够定期监控整个网络中的 DNS 配置和设备状态的解决方案。该解决方案应当在检测到任何异常或未经授权的更改时自动向利益相关者发送警报,从而帮助防止未来发生与 DNS 相关的攻击或中断。 # 流程概述 **策略:** - 使用公认的《项目管理知识体系指南》和系统工程最佳实践来制定计划 - 保持小型的开发/测试周期,以降低错误的复杂性 **架构选择:** - 以 GitHub 作为文档的唯一真实数据源。 - 本次实验提供了一个包含网络设备的 CSV 文件。我们将以此为契机,假定该 CSV 是由上游系统生成供我们使用的,而无需编写代码去发现网络上的设备/节点。 - 为每个操作(如 Ping、获取 DNS 配置等)创建单元测试,然后添加一个循环来尝试 CSV 中的所有设备,努力使开发/测试周期尽可能小。 **战术方法/系统思维/工作分解结构** - 概述所需的每一项操作 - 读取/导入 CSV - Ping 每台设备 - 查询 DNS 配置设置 - 将当前 DNS 配置与预期 DNS 配置进行比较(DNS1 Server @ 10.10.10.10 或 DNS2 Server @ 10.10.10.20) - 创建警报/触发器以启动修复 - 通过 API 调用创建工作工单 - 发送电子邮件警告通知 - 重启 DNS 服务器 - 更新受影响设备中的 DNS 配置 - 连接到每台受影响设备并确保配置更改准确无误 - 发送解决通知邮件 - 明确每个步骤所需的数据,例如设备名称、IP 地址、子网、用户名、密码等 - 确定在终端中显示的内容及方式(逐行显示或表格摘要) - 为每个所需操作开发单元测试 - 扩展单元测试以涵盖 CSV 中列出的所有设备 - 将多个模块化功能整合到一个统一、单一的脚本中,以完成端到端的启动、分析和修复流程,该流程可被设置为按选定的计划自动运行。 **正式的工作分解结构 (PMP 本能发作!)**
_虽然有专门的项目管理软件,但一个简单的 PowerPoint 组织结构图有助于规划你的开发流程。利用它来构建一个视觉层级:概述每个操作,拆解完成该操作的步骤,并确定所需的数据点。在编写任何伪代码之前执行此操作,可以帮助你可视化操作顺序、规划第三方集成、利用现有的 API 以及发现缺失的数据。虽然这通常与瀑布模型相关联,但这种视觉映射同样适用于敏捷功能的范围界定,同时能降低复杂性、协调跨职能团队并简化利益相关者的签字确认。_ image image **使用的库:** - CSV - Tabulate - Requests - Platform - re - Subprocess - Telnetlib - Datetime - EmailMessage - smtplib - pandas **代码开发进度/变更日志** 1. [unitReadCSV.py](https://github.com/zachncurry/Rogue-DNS-Server-Detection-and-Remediation/blob/01613626c8dd8845d15437ce52f92bf895de892d/unitReadCSV.py):确认了能够将 CSV 文件添加到文件夹内的文件结构中,并读取和处理其中包含的数据 2. [unitPing.py](https://github.com/zachncurry/Rogue-DNS-Server-Detection-and-Remediation/blob/01613626c8dd8845d15437ce52f92bf895de892d/unitPing.py):确认了能够使用硬编码的主机信息对设备执行 Ping 操作 3. [csvPing.py](https://github.com/zachncurry/Rogue-DNS-Server-Detection-and-Remediation/blob/01613626c8dd8845d15437ce52f92bf895de892d/csvPing.py):确认了能够从 CSV 文件读取设备信息、对每台设备执行 Ping 操作,并将每次 Ping 的结果返回到表格中 4. [unitDNS.py](https://github.com/zachncurry/Rogue-DNS-Server-Detection-and-Remediation/blob/01613626c8dd8845d15437ce52f92bf895de892d/unitDNS.py):确认了能够使用硬编码的主机信息获取设备的 DNS 配置设置 5. [csvDNS.py](https://github.com/zachncurry/Rogue-DNS-Server-Detection-and-Remediation/blob/01613626c8dd8845d15437ce52f92bf895de892d/csvDNS.py):确认了能够从 CSV 读取设备信息、执行 Ping 操作并获取 DNS 配置详情,并将每个结果添加到表格中 6. [unitEmailAPI.py](https://github.com/zachncurry/Rogue-DNS-Server-Detection-and-Remediation/blob/01613626c8dd8845d15437ce52f92bf895de892d/unitEmailAPI.py):确认了能够连接 SMTP 服务器并发送硬编码的电子邮件信息 7. [csvDNScompare.py](https://github.com/zachncurry/Rogue-DNS-Server-Detection-and-Remediation/blob/01613626c8dd8845d15437ce52f92bf895de892d/csvDNScompare.py):获取 csvDNS 表,并将当前 DNS 配置与我们可接受的 DNS 配置进行评估 8. [unitCompare.py](https://github.com/zachncurry/Rogue-DNS-Server-Detection-and-Remediation/blob/3bbbbc3f8e35f2829ded44b47bd396f0f9e21619/unitCompare.py):增加了一项验证检查,确认是否有任何设备发出了警报以启动修复流程,否则确认成功。这将成为位于循环顶部的决策树节点,将调用 UnitEmailAPI、unitHelpDeskTicket 和重试函数,最终触发最后的成功邮件。 9. [csvDNSCompareEmail.py](https://github.com/zachncurry/Rogue-DNS-Server-Detection-and-Remediation/blob/32c48eb0134a75beb9fa69cf4ae08cc5e32758e4/csvDNSCompareEmail.py):这会提取初始表的一个子集,将其转换为 panda 表或数据框(因为直接将其转换为 HTML 表格比编写另一个循环更容易),并触发警报邮件。未在图中展示的是我们的资源文件夹,该文件夹以前包含设备列表,现在还包含了 HTML 格式的警报邮件模板。 10. [unitTicketAPI.py](https://github.com/zachncurry/Rogue-DNS-Server-Detection-and-Remediation/blob/457737ddb46200bb4b1b5f0e9fd719388aad40ca/unitTicketAPI.py):测试通过 API 获取和推送到服务台工单的调用。 11. [csvDNS_Email_Ticket.py](https://github.com/zachncurry/Rogue-DNS-Server-Detection-and-Remediation/blob/dc9121f8a0e14555fa476241081e05453adac4d1/csvDNS_Email_Ticket.py):增加了为每台受影响的机器创建工单的功能。 12. [csvDNS_Email_Ticket_RestartDNS.py](https://github.com/zachncurry/Rogue-DNS-Server-Detection-and-Remediation/blob/a64058b92b62fdf07f1c7d68706077f098612a6a/csvDNS_email_ticket_RestartDNS.py):将服务台工单信息添加到修复表和警报邮件中,为最终用户提供额外的上下文背景,并管理循环逻辑以确定事件何时得到完全解决。然后添加了 DNS 服务器的停止和启动(重启)操作。 13. [unitConnectCorrect.py](https://github.com/zachncurry/Rogue-DNS-Server-Detection-and-Remediation/blob/449d535a6ea20c21b00f08fec9fa9bc033a59f3d/unitConnectCorrect.py):硬编码设备信息、用户名、密码和流氓 DNS IP 等信息,以测试连通性、进行移除和更新。发现 22 端口虽然打开但超时,这表明需要增加尝试其他端口号的能力。 14. [csvConnectCorrect.py](https://github.com/zachncurry/Rogue-DNS-Server-Detection-and-Remediation/blob/09488f6ab22c8a452652fbeff2ccf608db3db7e0/csvConnectCorrect.py):合并了单元 DNS 配置脚本,进行了几处修改,最终大获成功! 15. [RemediationFinal.py](https://github.com/zachncurry/Rogue-DNS-Server-Detection-and-Remediation/blob/1d42c50dc0dbd6020eebfe74213bb8129d6a1e4f/RemediationFinal.py):重构了逻辑以应对持续发生的流氓 DNS 服务器攻击,添加了最终的通知邮件、更新后的服务台工单以及最终的修复表/结果。

## 初始结果
在 GSN3 上初始化网络、对设备执行 Ping 操作并获取其 DNS 配置记录后,发现了一些问题。
我们的网络被配置为使用位于 10.10.10.10 和 10.10.10.20 的两个 DNS 服务器,但是发现了一个无效的 DNS 服务器地址:203.0.113.10。
_127.0.0.53 是网络中常见的环回地址_
_203.0.113.10 是一个研究分配的 IPv4 地址,这里用来代表恶意 IP 地址_
以下是 csvDNS.py 文件的终端结果: image image **所需的修复步骤**
1. 分析每台设备是否存在任何不合规的 DNS 设置 2. 向分发列表发送包含表格摘要的警报邮件 3. 为每台不合规的设备创建服务台工单 4. 重启所有 DNS 服务器 5. 连接并修正网络上的每台不合规设备,确保仅列出/配置了策略批准的 DNS 服务器 6. 向分发列表发送包含表格摘要的解决通知邮件 # 下一步
从比较功能开始,将这段有趣的伪代码转化为功能性解决方案。
对于 csvDNS.py{Summary Table} 中的每一行{
将 csvDNS.py{parse.DNSConfig} 中的摘要表与 DNS 策略进行比较
IF:
如果违反 DNS 策略,则 append.dnsViolationSummary
调用 _Email Everybody Function_ (SMTP API)
调用 _CYA Ticket System_ (Help Desk API)
Update Resume 🤣🤣
ELSE:
Print(DNS policy is giving compliance) _IYKYK_
**实施决策**
**决策点:** 我应该将比较和修复工作中的哪些部分加入到当前的 DNS 查询逻辑中,还是应该将 DNS 文件输出的表格作为新表格的输入?
**决策逻辑:** 起初我想将其合并以简化代码,但是在仔细思考之后(通过编写本节内容),现在我想要将它们分开,因为我们将需要重新调用此 DNS 查询功能,以确保我们的修复工作已成功完成。如果我们将这种下游逻辑合并到初始的 DNS 查询中,我们将不得不添加一个计数器并清除计数器,而不是通过返回 ALERT 或 SUCCESS 来触发下游工作流,并且我们将根据在修复逻辑中接收到的返回值是 ALERT 或 SUCCESS 来管理循环条件。在生产环境中,如果修复工作失败了 X 次,我们可能还需要考虑实施升级机制,例如发送额外的电子邮件、提升工单优先级等。 _此视觉图有助于概述决策逻辑,以及我们将如何在下游重复使用 DNS 查询_
_我们需要一个计数器来跟踪修复工作失败的次数,逻辑可以是:如果计数为 0 且状态为 COMPLIANT,则不做任何操作;否则如果计数 != 0 且状态为 COMPLIANT,则发送成功邮件_
image ## 修复步骤 1
[csvDNScompare.py](https://github.com/zachncurry/Rogue-DNS-Server-Detection-and-Remediation/blob/01613626c8dd8845d15437ce52f92bf895de892d/csvDNScompare.py)
在这里,我们获取设备的完整列表,将我们配置的 DNS 服务器与 DNS 服务器策略/可接受的 DNS 服务器进行评估,并在右侧的新列中标记出“ALERT!”。
image
## 修复步骤 2
[csvDNSCompareEmail.py](https://github.com/zachncurry/Rogue-DNS-Server-Detection-and-Remediation/blob/32c48eb0134a75beb9fa69cf4ae08cc5e32758e4/csvDNSCompareEmail.py)
现在我们有了一个分析所有设备的表格,并发现几台设备上配置了恶意的 DNS,我们创建了一个新的修复表来单独管理这些设备。
image
然后我们向利益相关者发送警报邮件通知,告知他们存在的问题。
_该表格被转换为 panda dataframe 然后转换为 HTML,而不是创建另一个循环函数。_

image
## 修复步骤 3
[csvDNS_Email_Ticket.py](https://github.com/zachncurry/Rogue-DNS-Server-Detection-and-Remediation/blob/dc9121f8a0e14555fa476241081e05453adac4d1/csvDNS_Email_Ticket.py)
使用循环创建较小的修复表,并在循环的每次迭代中,通过服务台 API 创建服务台工单,然后将成功消息和工单详情返回给终端。
image ## 修复步骤 4
[csvDNS_Email_Ticket_RestartDNS.py](https://github.com/zachncurry/Rogue-DNS-Server-Detection-and-Remediation/blob/a64058b92b62fdf07f1c7d68706077f098612a6a/csvDNS_email_ticket_RestartDNS.py)
在这里,我们连接到每台 DNS 服务器并重启它们的服务。
image

同时更新了邮件表格,通过解析创建服务台工单返回的 JSON,将工单 ID 和状态也包含在内。
这将提供状态管理,作为我们评估何时应发送解决通知邮件的数据点。
而且总的来说,在 IT 机构工作过的经验告诉我,你需要确保收件箱以外也有相关文档记录,这为利益相关者提供了审计所需的安心保障。
image
image
## 修复步骤 5
连接并修正网络上的每台不合规设备,确保仅列出/配置了策略批准的 DNS 服务器
为了连接到每台设备,我们需要传递用户名和密码信息,我们在表格中没有包含这些信息,并且仅在最初 Ping 和获取 DNS 配置时使用过一次。
虽然有几种方法可以做到这一点,但我打算编写一个 CSV 读取器来附加我们的修复表,以便在此函数中短暂存储这些信息。
**伪代码**
- 读取修复表
- 读取 CSV,仅解析修复表中列出的设备
- 附加用户名和密码
- 通过 SSH 使用 IP、用户名、密码连接到每台设备
- 移除流氓 DNS IP(仅仅添加 IP 是不够的,因为设备可以存储多个 IP)
- 添加主 DNS IP
- 添加备用 DNS IP
- 获取 DNS 配置
- 验证 DNS 配置现在是否已合规
- 更新工单状态
[unitConnectCorrect.py](https://github.com/zachncurry/Rogue-DNS-Server-Detection-and-Remediation/blob/449d535a6ea20c21b00f08fec9fa9bc033a59f3d/unitConnectCorrect.py):硬编码设备信息、用户名、密码和流氓 DNS IP 等信息,以测试连通性、进行移除和更新。发现 22 端口虽然打开但超时,这表明需要增加尝试其他端口号的能力。
我继续重构了代码以最小化 Main() 函数,添加了 MARK 符号以便于搜索,并以更符合逻辑的顺序重新排列了各项功能。
同时还添加了一个状态管理整数,以便在尝试 3 次后触发升级机制。
[csvConnectCorrect.py](https://github.com/zachncurry/Rogue-DNS-Server-Detection-and-Remediation/blob/09488f6ab22c8a452652fbeff2ccf608db3db7e0/csvConnectCorrect.py)
image
image
image
image
image
值得庆幸的是,我已经提前开始着手处理逻辑和最大尝试次数管理,因为现在实验环境开始抛出错误,我很高兴地报告,我的脚本处理得非常完美!
我仍然需要更新工单的状态。我将这一点加入了项目范围,这样我就可以将相关信息包含在本次实验第一部分的最终邮件中。 ## 修复步骤 6
[RemediationFinal.py](https://github.com/zachncurry/Rogue-DNS-Server-Detection-and-Remediation/blob/1d42c50dc0dbd6020eebfe74213bb8129d6a1e4f/RemediationFinal.py)
_噢——叫我理发师吧,因为我抓住了那些边界情况!_ ✂️🤣🤣 **所作的更改**
- 重构了逻辑以应对持续发生的流氓 DNS 服务器攻击(由实验环境模拟) - 添加了最终的解决通知邮件 - 添加了更新服务台工单的功能 - 并得出了最终的修复结果 **解决通知邮件**
image
image
**终端输出**
_我删除了用于故障排除的表格,并在终端中添加了动态语句以优化用户体验,使得任何人都能理解该程序的操作/状态。_
_在 8/1/26 重新运行了实验以获取更好的终端图像,结果实验运行了不同的模式:显示所有 4 台设备均已被攻陷,而不是之前的 3 台然后 1 台的模式,这也是为什么拥有一个良好的实验环境对于测试你的想法如此重要!_ image
image
image
image
image
**不开玩笑了……我不仅喜欢通过实践来学习,也同样重视通过反馈与合作来进步。**
**如果你对如何优化这个项目或我可以在哪里改进有任何想法,让我们携手合作吧!**
**在 LinkedIn 上与我联系:**
https://www.linkedin.com/in/zachary-curry-pmp

**关于第二部分的更多内容即将推出...** ## 里程碑反思
虽然这个项目还有很多工作要做,但我想借此片刻记录下经验教训,并分享如果重来一次我会采取哪些不同的做法。 **经验教训** - **价值的深度:** 如何通过编写代码/自动化手段连接到网络上的设备。以前我是界面操作大师,意思是我可以到处点击,直到在电脑上找到 IP 和 DNS 配置。后来,我通过获取 Linux(Linux Essentials 认证)和网络设备(CCNA 认证)的实操经验提升了我的知识储备。这把那项基础知识提升到了一个新的高度。例如,当我需要解决 DHCP 服务器的 IP 分配问题时,我知道这意味着什么,以及触发、等待和检索所需的过程,这帮助我理解了在查找库/编码建议时应该搜索什么。 - **威胁的现实与培训的重要性:** 恶意行为者改变整个网络的速度能有多快。提示一下:只需几秒钟。我以前就知道网络安全设备很重要,但现在我真正明白,一旦有人获得了网络的访问权限,你就失去了控制。以前当我在每个月强制观看网络钓鱼邮件培训视频时,我觉得这很烦人,现在我想的是:我们怎样才能让更多的人理解他们的重要性。我认为,对于技术和非技术员工来说,更有价值的做法是实时观看代码的运行过程,或者是升级我们的培训方式,例如发送一封钓鱼邮件,如果员工点击了它——就锁定他们的电脑,并要求他们在解除锁定之前亲自向培训团队报到,以此来展示这种威胁究竟有多么真实。 - **规划:** 我一直很喜欢做规划,正如我的导师曾对我说过的那样:按图规划,但顺应地形行事。在这次实验中,这一点极其真切,因为当交付了更多代码时,实验环境会修改其行为,幸好我已经进行了规划并提前记录了需要考虑的边界情况(虽然不是全部),这为我节省了大量时间。 - **耐心与节奏 - 平衡:** 这可能是我感触最深的一点。该实验是一个虚拟机 (VM),每次只允许运行六个小时,你无法延长时长,无法暂停,一旦停止所有工作都将丢失。此外,你无法一次性复制和粘贴超过 20 行的代码块,这迫使我有时每天两次将我的 VS 连接到虚拟机上的 GitLab。到了快结束时,重置环境大约需要 30 分钟。此外,一旦我在实验室中运行代码进行测试,我要么选择重新开始,要么手动重新配置设备,但这并不符合实验本身的行为。无论是对手头的任务还是对个人而言,这都是一次很棒的学习经历。起初,我很懊恼……我很不满意😉😉;然而,我学会了坦然接受延长自己的时间表,并在虽然还有很多事情要完成的情况下结束一天的工作,努力在第二天保持精力充沛。在我的生活中不断重新学习这一课真是无比宝贵,这真的是一种福气。 - 由此我还学到了,你可以一次下载多个包,例如:"pip install pandas tabulate requests paramiko" 可以通过单条命令按顺序下载 pandas、tabulate、requests 和 paramiko。 **如果重来一次我会怎么做** - **规划:** 事情一旦做过,事后看总是无比清晰……我漏掉了一些边界情况,现在我发现我的规划存在盲区。我没有写下那些重要的变量状态组合,这导致我最后的 48 小时集中精力在寻找 Bug 上。如果我当时记录了所有的组合,比如:通过初步审查 - 工单:开启,审查失败 - 工单:关闭,我就能更好地找出所有的边界情况,以确保代码万无一失。我的规划主要集中在工作流上,我也预料到了许多状态,但错过了较小的边界情况,从而导致了延误。 - **集中式决策函数:** 目前逻辑分布在几个函数中,这对于任何试图推进此代码库的人来说都不太理想,如果我当初做了更好的规划,也许我就能够将逻辑统一整合到单个函数中。 ## 下一步
**第二部分** 1. 添加定期自动化功能
标签:DNS安全, Docker 部署, IP 地址批量处理, Python自动化, 字符串匹配, 网络安全, 网络运维, 自动化运维, 逆向工具, 隐私保护