了解你的工具
1998年,我负责带领团队为各组织进行现场漏洞评估。在评估的技术部分,我们使用ISS的Internet Scanner产品,这是一款商业扫描器。几年前,在我读研究生时,SATAN扫描器已经发布,但它是开源的,你可以查看代码了解其工作原理。而Internet Scanner则不是这样。
当我们开始仔细研究时,发现这款商业产品返回的结果并不准确。一个非常明显的例子是AutoAdminLogon设置:你可以将此值设置为“1”,你选择的管理员账户名将包含在另一个值中,而密码将以明文形式包含在第三个值中。系统重启时,这些凭据将用于自动登录系统。
是的,明文密码。
我们在一个大型组织内的办公室进行了扫描,产品返回了21个启用了AutoAdminLogon功能的实例。然而,该组织知道实际上只有一个系统设置了此功能;其他20个系统曾经设置过,但该功能已被禁用。在这20个系统上,AutoAdminLogon值被设置为“0”。我们确定商业产品仅检查AutoAdminLogon值的存在,而没有进一步检查该值是否设置为“1”,也没有检查包含明文密码的值是否实际存在。
我们还发现了大量其他类似不正确的检查,以及其他高度可疑的检查。因此,我们开始编写一个名为NTCAT的工具来替代商业产品。该工具包含各种查询,所有这些查询都基于研究并包含对Microsoft知识库的引用,因此任何运行该工具的人都可以查阅,了解正在查询的内容、响应的含义,并向客户解释。
后来,在以咨询角色支持CBP并等待机构安全许可时,Nessus扫描器是当时流行的扫描工具。有一天,我听到CIRT的一位资深成员与另一位等待安全许可的人交谈,告诉他们Nessus扫描器通过向目标端点发送一系列特制的TCP数据包(可能通过nmap),然后将响应映射到矩阵来确定Windows操作系统的版本。我听着觉得这太复杂了。我找到一台安装了Nessus的系统,开始阅读各个模块,发现Nessus通过尝试与目标端点建立SMB连接并读取注册表来确定Windows版本。如果扫描器在没有必要权限的情况下运行,许多模块将无法连接并直接失败。
时间跳到2007年和2008年,IBM ISS X-Force ERS团队正在深入进行PCI取证检查。当时,我们是认证组织名单上的七家公司之一;被银行告知需要取证的商户会访问PCI网站,找到列出的公司名称,并总是打电话给所有七家公司,看看谁能提供最好(即最低)的价格,却没有意识到当时价格是由Visa设定的(这是在PCI委员会成立之前)。
随着我们团队的成长,并且由于我们需要在提供信息和报告方面满足非常严格的时间要求,Chris Pogue和我选定了一个特定的商业工具,我们的大多数分析师都熟悉该工具,并为他们提供了记录的程序,以便高效地完成所需流程,包括文件名、哈希值、路径搜索和信用卡号扫描。
在一次特定的任务中,商户网站的某人告知我们该商户处理JCB和Discover卡。这很重要,因为我们的PCI联络人需要获取这些品牌的联系人,以便我们可以共享被盗的信用卡号(CCN)。我们开始工作,但发现没有找到这两个信用卡品牌的任何匹配结果。
第一步是确认商户确实处理这些品牌…我们得到了肯定的答复。接下来,我们联系了这些品牌,获取了测试用的CCN,并对这些号码运行了我们的流程…结果一无所获。零。没有。完全没有。
结果发现,我们使用的商业套件包含一个名为IsValidCreditCard()的内部函数,经过大量测试和在用户论坛上的多次查询,发现该函数不将这两个品牌识别为有效。因此,在一些外部协助下,我们编写了一个函数调用来覆盖内部函数调用,并让我们团队的所有人都将其添加到他们的系统中。新函数运行速度稍慢,但Chris和我坚持要求团队像信用卡和AV扫描这样的长时间运行流程应在晚上运行,而不是在工作开始时启动。这样,你就不会在可以进行实际工作时因长时间运行的流程而占用镜像。
2020年,我在一家IR咨询提供商工作,发现团队中的一些人使用CyLR;当时的中间件是plaso,后端是Kibana。那年三月,微软发布了一篇关于人为操作勒索软件的精彩博客文章,其中他们描述DoppelPaymer勒索软件使用WMI持久性。知道团队遇到了多起涉及该特定变体的勒索软件任务,我问他们是否看到任何WMI持久性。他们回答“没有”。我问,你们是如何确定的?他们回答说,他们检查了这些任务的Kibana输出,没有得到任何结果。
该工具集的收集过程获取了WMI存储库的副本,所以我很好奇为什么没有观察到任何结果。然后我发现,至少在当时,plaso没有WMI存储库的解析器;因此,数据被收集了,但没有被解析…而后端“未发现”的结果被 unquestioningly 接受。
所有这些只是想说明,了解并理解你的工具如何工作是很重要的。当我运营一个内部SOC时,L3 DF分析师能够使用我们采用的工具集从端点转储内存。他们经常这样做是为了检查特定的IP地址;然而,他们中的大多数人认为运行strings并搜索相关IP地址就足够了。我必须与他们合作,让他们理解(a)IP地址在内存中大多不以ASCII/Unicode存储,以及(b)不同的工具(Volatility、bulk_extractor)为了识别IP地址而查找不同的结构。因此,如果他们打算转储内存,运行strings既不是寻找IP地址的充分方法,也不是合适的方法。
了解你的工具如何工作,它们如何完成其功能。理解它们的能力和局限性。有时你可能会遇到以前未曾想到的情况或环境,你将必须参与、提出问题,并有意识地参与以确定工具处理该问题的能力。