后漏洞利用模块 Danderspritz 内部揭秘
国家安全局(NSA)开发的后漏洞利用工具 Danderspritz 有一些有趣的用于秘密行动的侦察脚本。 基本上,这个工具会尽可能多地收集有关驱动程序、内存、网络流量(DSky)或 PSP (一个个人安全产品——反病毒软件)的信息。
大多数脚本都在在”Windows”的”Ops”目录中,这里面的脚本中值得进一步关注,你可以在这里找到完整的列表。
运行这里的 Fuzzbunch 和 Danderspritz 可以建立实验室。
关于这个框架的所有内容我在其他文章中都已经说过了,因此我将只关注后漏洞利用模块。 在文章的最后,我将展示如何编写自己的插件,所以请耐心阅读本文。
并不是所有的工具一开始都可以在 Danderspritz 中访问,你必须添加一个别名来使它工作,例如使用 SimonTatham 模块。
之后就可以用别名了。你还可以通过输入”python windows\SimonTatham.py“来执行它
SimonTatham模块负责查找注册表中保存的发送到 WinSCP的会话和凭据。 此模块也可以在Overseer中访问。
系统重启历史记录
在某些情况下,可能不需要每年重新启动一次系统。 此外,与其他环境数据一起关联分析可以用作沙箱检测。 脚本使用两个源来确定重新启动事件日志、转储、注册表项和日志文件的历史。 它还检查 Dr. Watson日志,这是旧版本 Windows 的错误诊断工具,以收集更多关于操作系统的信息。
事件日志
文件 reboothistory.py 包含12个功能,负责检索和解析有关系统重新启动历史的信息。 首先查看事件日志,查看以下 id:
· 6005 ——事件日志启动
· 6006 ——事件日志服务停止
· 6008 ——上次意外的关机
· 6009——用户重新启动或关闭系统
· 1001 ——应用程序崩溃或挂起
· 1074 ——系统被其他任务关闭或重新启动
· 109 ——由内核电源管理器执行的关机
· 42 ——系统进入睡眠模式
· 41——在睡眠模式期间关机(?)
· 13 ——适当的关闭(?)
· 12——系统启动
系统重启历史记录
有些 id 的说明文档很少,但是我发现每个 id 都提到了用户、其他任务或内核重启、关闭操作系统。 此外,睡眠模式在检查过程中并没有省略。
此外,还创建了引导日志,这意味着它根据特定的事件 id 计算系统的引导、关闭和启动时间。
计算启动时间的代码
注册表、转储和日志
正如前面提到的脚本检查特定注册表项和文件的存在,以检查系统重新启动历史记录。
“HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\CrashControl“是一个重要的注册表键,它包含有关意外应用程序行为(如崩溃或挂起)的有用信息,提取的值是”Dumps”和”Minidumps”。
检查崩溃控制
当从注册表中提取路径时,它调用 checkdump 函数以便从 dump 中检索元数据。
函数”checkdumps”查找位于%% SystemRoot%% 目录中扩展名为.DMP 的文件,最后显示所找到的文件的元数据。 转储的文件保存 Windows 崩溃的内存转储,但在这种情况下,内容并不重要,只收集诸如”Modified”、”Accessed”、”Created”之类的元数据即可。
从转储文件中检索元数据
Windows 错误报告(WER)功能也被滥用来检索错误和崩溃信息,来自当前用户和本地机器的错误和崩溃信息可以software\\microsoft\\windows\\windows error reporting 和 Microsoft\\Windows\\WER\\ReportQueue中找到。
“Checkdirtyshutdown”在”software\microsoft\windows\currenversion\reliability”中查找注册表项,用于跟踪每次关闭。 这里最重要的注册表键是 DirtyShutdown 和 DirtyShutdownTime,关于这些键的更多细节请点击这里。
Windows 服务器将每次关机记录到”Windows\system32\logfiles\shutdown”中,此位置也在”checkshutdownlogfiles”函数中进行检查。
Dr. Watson是 Windows 98、 Millennium 和 XP 中的一个工具,可以帮助你通过创建系统快照并分析它来解决应用程序中的问题。
在这里有趣的事情是,脚本只检查 “%%allusersprofile%%\documents\DrWatson”目录,这对于 Windows 2000是正确的。 在 XP 和 ME 中,完整的路径为“All Users\Application Data\Microsoft\Dr Watson”和“C:\Windows\Drwatson”。 这可能表明即使在新系统出现的时候脚本也没有定期更新。
Dr. Watson 检查
你可以在这里找到完整的脚本 https://github.com/francisck/DanderSpritz_docs/blob/master/Ops/PyScripts/windows/reboothistory.py
用户查询
这个模块跟踪 Windows 媒体播放器,Internet Explorer浏览器,远程桌面协议和其他活动的迹象。 可以为特定用户或系统中的每个用户进行检查。 它通过迭代 HKEY\USERS 并在42到49个字符之间选择安全标识符编号(SID)来实现这一点。 另外,有一个函数可以通过使用 siddlookup 命令将 SID 转换为用户名。
检查所有用户
Windows 媒体播放器的最后播放文件可以通过查询密钥软件 Microsoft MediaPlayer Player RecentFileList 来访问。 这是一种简单的方法,可以劫持用户最近正在观看的内容,然后对其进行详细检查。
在这个侦察脚本中,只有 Internet Explorer 是有针对性的,最后输入的网址也会被收集起来。 值得注意的是 Ripper,集合中的其他脚本负责检索其他浏览器的凭证、存储和历史记录。 在这种情况下使用的关键字是 Software\Microsoft\Internet Explorer\TypedURLs。
即使是最后一个 Windows 弹出窗口也会让你对脚本产生兴趣。 它查询 Software\Microsoft\Windows\CurrentVersion\Explorer\ComDlg32\OpenSaveMRU 以获取在 Windows 对话框弹出窗口中访问的文件列表,比如在下载或保存过程中。
另一个有趣的功能是 USB 监控,在某些情况下,它可以证明两个不同的人将同一个 USB 设备或手机插入他的电脑。 最后连接的设备可以在 SYSTEM\\CurrentControlSet\\Control\\DeviceClasses\\{53f56307-b6bf-11d0–94f2–00a0c91efb8b 中找到,并且只检查了键,但是{53f5630d-b6bf-11d0–94f2–00a0c91efb8b}类保留了连接设备的历史。 此外,这种方式可能允许检测到虚拟环境。
USB 设备检测
它与接下来我们要讲的有一个共同的、非常精确的函数——”start_run”。 注册表会跟踪你最后执行的命令,或者在 Windows 运行时在自动完成框显示提示。 负责的注册表键是 Software\Microsoft\Windows\CurrentVersion\Explorer\RunMRU。
UserAssist 是下一个 Windows 功能,收集有关操作系统及其使用的详细信息。 准确地说,SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\UserAssist 保留了诸如时间戳、执行数量或计算机上执行软件的路径等元数据。 它的结构需要具体介绍一下,在注册表中,键(路径)是 ROT13编码的,值是信息数据的二进制表示。 这个值对于不同的系统是不一样的,对于 XP,ME 是16字节,对于新的是72字节。 脚本没有检查 Win 95和98,其中值为8字节,也没有检查焦点时间值。
你可以从二进制文件中挖掘出执行数(字节4-8字节)、焦点时间(字节12-16)和时间戳(从60到68字节)。
为了找到这个模块,我们需要更深入地挖掘另一个名为 dsz 的项目,它会调用”history”和”User Assist“模块:https://github.com/francisck/DanderSpritz_docs/blob/master/Ops/PyScripts/windows/userquery.py#L45 (稍后会介绍该模块和结构)。
这个项目需要反编译,但是反编译之后,python 代码变得很容易阅读。 下面的代码清楚地显示了如何在 Windows 7中检索所描述的数据。
从 UserAssist 中获取数据
当然,脚本还保存了已执行文件和其他有用数据的 ROT13解码路径,我强烈建议你点击这里阅读关于用户辅助取证和一般用法的可能性
你可以通过设置名为”Settings”的键并创建名为”NoLog”和值为1的 DWORD 来关闭系统中的这个功能。
最后一件事是 RDP 连接的历史,整个缓存是在Software\Microsoft\Terminal Server Client\Default路径中。
完整的脚本——https://github.com/francisck/DanderSpritz_docs/blob/master/Ops/PyScripts/windows/userquery.py
持久化——信息搜集
你应该知道,每次当 DanderSpritz 连接到目标时,就会进行信息搜集。 这个功能由一堆 python 脚本实现,试图收集尽可能多的关于已经安装了 implant 的环境的详细信息。 它采用模块化设计,这意味着每个脚本都位于”lib/ops/survey”目录中的单独文件中。 在其他模块中,存在持久性检查。 这个模块背后的设计思想很简单,搜集在系统启动过程中运行的软件。 它有点类似于 TeritorialDispute (TeDi) ,后者寻找已知恶意软件和其他 APT 攻击团伙的入侵特征。 现在,让我们更多地关注代码本身的结构,首先执行的文件是”survey/launcher”中的 launcher.py”。 它得到的最重要的参数是”——module“,这是显而易见的。
在一些基本的参数和路径检查之后,使用给定的参数调用方法”plugin_launcher”。 值得强调的是,参数”bg”代表”background”,并允许在后台执行脚本。
launcher.py
“plugin_launcher“也会解析标志,如果一切正常,它会在 runpy 的帮助下执行特定的模块。
plugin_launcher 插件启动程序
实际的 persistence.py 脚本位于 lib/ops/survey 中,只接受一个参数”—maxage“,该参数表示”在为此模块重新运行命令之前使用的最大信息时间”,默认为3600。
另外,它还包含有注册表项的键、要检查的值和已知的好值。 但是,没有对计划任务进行检查。 此外,它还生成了%Program Files%, %AllUsersProfile%和%WINROOT% 的路径,但脚本中不使用这些路径。
下列项目是从脚本中摘录的:
· system\\currentcontrolset\\Services\\tcpip\\Parameters\\Winsock — 检查值— HelperDllName, known goods — ‘wshtcpip.dll’, ‘%%SystemRoot%%\\System32\\wshtcpip.dll’
· Software\\Microsoft\\Windows NT\\CurrentVersion\\Windows — 检查值— AppInit_Dlls
· Software\\Microsoft\\Windows NT\\CurrentVersion\\winlogon — 检查值 — Shell, Userinit, known goods — ‘explorer.exe’, ‘‘C:\\Windows\\system32\\userinit.exe’
· Software\\Microsoft\\Windows\\CurrentVersion\\Run[OnceEx] —已知的可利用的启动项程序— VMware Tools’: ‘“C:\\Program Files\\VMware\\VMware Tools\\VMwareTray.exe”’, ‘VMware User Process’: ‘“C:\\Program Files\\VMware\\VMware Tools\\VMwareUser.exe”
· Software\\Microsoft\\Windows NT\\CurrentVersion\\AppCompatFlags\\Custom
· %%SystemRoot%%\AppPatch\Custom
有趣的是,这个模块会在%%SystemRoot%%\AppPatch\Custom 目录中执行’dir’。 我发现了一个使用这种方法进行持久化的例子,但那是在一年前。在2016年的黑帽大会上第一次出现过,但脚本的公开时间相当古老是在2013年。
persistence.py
因此,让我们深入分析 lib\ops\files\dirs.py 中的”get_dirlisting”方法,据我所知,每个模块都是以相同的方式执行的。 因此,这种情况看起来与”registryquery”命令相同,它检索提到的注册表项。
这个例子很简单,它创建了 getDszCommand 的新实例,这个实例引用了 DanderSpritZ 命令,然后检查结果是否被缓存。
get_dirlisting 函数
像 “dir”、”registryquery”或”processes”等系统命令的结构组织方式与用于信息搜集的插件相同,但每个模块都位于 lib\ops\cmd 目录中。 “getDszCommand”方法解析传递的命令,然后从 ops\cmd 导入指定的插件。 最后返回可调用对象,如下图所示:
getDSZCommand 函数
在”generic_cache_get”(上面2个屏幕截图)方法中会根据返回的对象在 ops 项目中进行缓存数据库检查。 对于每个项目,都会创建本地数据库,通用缓存获取的目标是基于正确的标签和目标 ID https://github.com/francisck/DanderSpritz_docs/blob/86bb7caca5a957147f120b18bb5c31f299914904/Ops/PyScripts/lib/ops/project/__init__.py#L274.
我将略去这一部分,这一主题会作为单独的文章进行阐述。 在所有检查之后,最后通过调用 command.execute ()方法执行实际的命令。 命令对象是从’getDszCommand’和’execute’方法中给出的。
generic_cache_get 函数
最后,在’_actual_execute’方法的帮助下执行实际的命令,你可以看到从 dsz\cmd 调用了 RunEx,它引用另一个项目’dsz’并直接与 DanderSpritz 交互,你可以在这里找到 dsz\cmd.py 的反编译代码。
执行命令
最后让我们看看持久化概览的执行流程。
执行流程
编写自己的 Danderspritz 后漏洞利用模块
现在,我们已经掌握了所有必要的信息来构建自己的插件。 脚本集合包含了几乎所有的内容,但是我没有发现对虚拟机和最后连接的网络的检查。 要获得关于其中第一个的信息,我们检查[username]\Documents\Virtual Machines 目录。 有关连接网络的详细信息位于HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkList\Profiles\ID。
检查最后一次连接的网络和虚拟机的输出
检索网络信息
这可能有助于追踪受害者的旅行行程,比如基于他入住的酒店的 WIFI SSID 。 网络名称、上次连接时间和类别是最有趣的字段。 存储网络配置文件的位置是Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkList\Profiles\ID, SOFTWARE\Microsoft\Widows\CurrentVersion\HomeGroup\NetworkLocations\Home 和 windows\system32\networkprofiles。 我们可以使用第二个配置文件获取配置文件 ID,然后通过它检索关于每个配置文件的更多详细信息。 在最后的脚本中显示了友好的输出内容,感谢 pprint 函数的强大功能。
检查最后一次连接网络的代码
虚拟机
了解主机是否是用于常规邮件检查的沙盒以外的事情总是好的。 它可能属于研究人员或包含最高机密的虚拟机。
第一个脚本列举 c:\Users 文件夹中的所有用户,然后检查每个用户的 Documents 中是否有”Virtual Machines”目录。 此示例包括与 Danderspritz 交互以检索可能找到的目录的内容。 并且会询问用户下一步的决定,这可以通过”dsz.ui.Prompt”方法实现。
虚拟机检查
完整的脚本—— https://github.com/woj-ciech/other/blob/master/example.py
总结
正如它所显示的,侦察脚本不是火箭科学,但有很多有趣的技巧从受感染的机器上收集情报。 由于是使用模块化设计的,Danderspritz 可以很容易扩展,而且很容易编写额外的插件并将其放入 Danderspritz 中。 我对大量的侦察脚本并不感到惊讶,在这些脚本中,每一条信息都是无价的,并且可能节省你的时间。