分类处理DLL植入漏洞 | MSRC博客
DLL植入(又称二进制植入/劫持/预加载)问题时常出现,但微软如何响应此类报告并不总是明确。本文旨在阐明在处理DLL植入问题时考量的参数。
众所周知,当应用程序加载DLL而未指定完整路径时,Windows会按照称为DLL搜索顺序的预定义目录顺序尝试定位DLL。默认SafeDllSearchMode下的搜索顺序如下:
- 应用程序加载的目录。
- 系统目录。使用GetSystemDirectory函数获取此目录路径。
- 16位系统目录。没有函数获取此目录路径,但会被搜索。
- Windows目录。使用GetWindowsDirectory函数获取此目录路径。
- 当前目录。
- PATH环境变量中列出的目录。注意这不包括App Paths注册表键指定的每应用程序路径。计算DLL搜索路径时不使用App Paths键。
默认DLL搜索顺序可以通过我们之前博客文章“安全加载库”中提到的各种选项进行更改。
如果攻击者能够在搜索顺序中的任何目录中植入恶意DLL,并且植入的DLL在攻击者无法访问的先前搜索目录中未找到,则应用程序中的DLL加载就成为DLL植入漏洞。例如,加载foo.dll的应用程序,如果该DLL不存在于应用程序目录、系统目录或Windows目录中,则如果攻击者有权访问当前工作目录,就可能植入foo.dll。DLL植入漏洞非常方便,攻击者工作量较少,因为DllMain()在加载DLL时立即被调用,从而提供非常简单的代码执行。如果应用程序允许加载未签名二进制文件,攻击者无需担心绕过任何缓解措施。
根据恶意DLL在DLL搜索顺序中可以植入的位置,漏洞大致分为三类:
- 应用程序目录(App Dir)DLL植入。
- 当前工作目录(CWD)DLL植入。
- PATH目录DLL植入。
以上类别指导我们的响应。让我们看看这些类别,了解如何处理每一类。
应用程序目录(App Dir)DLL植入
应用程序目录是应用程序存放其依赖的非系统DLL并信任它们完整的地方。位于程序安装目录中的文件被假定为善意、可信的,通常使用目录ACL安全控制来保护它们。任何能够替换安装目录中二进制文件的人,大概都有写入/覆盖文件所需的权限。应用程序目录被视为代码目录,应存储应用程序的代码相关工件。如果攻击者能够在不在目录ACL上的情况下实现应用程序目录内的DLL覆盖,那比替换/植入单个DLL的问题要大得多。
让我们看看涉及应用程序目录DLL植入的一些场景:
场景1:在受信任的应用程序目录中植入恶意二进制文件。 正确安装的应用程序通常通过ACL保护应用程序目录,在此场景中需要提升访问权限(通常是管理员)才能修改应用程序目录的内容。例如,Microsoft Word的安装位置是“C:\Program Files (x86)\Microsoft Office\root\Office16\”。需要管理员访问权限才能修改此目录中的任何内容。具有管理员权限的受害者可能被欺骗/社会工程植入DLL到受信任位置,但如果如此,他们可能被欺骗/社会工程做更糟的事情。
场景2:在不受信任的应用程序目录中植入恶意二进制文件。 通过XCOPY安装而未使用安装程序、在共享上可用、从互联网下载、位于非ACLed目录中的独立可执行文件等场景属于不受信任类别。例如,从互联网下载并从默认“Downloads”文件夹运行的安装程序(包括可再发行组件、ClickOnce生成的setup.exe和IExpress生成的自解压存档)。从不可信位置启动应用程序是危险的,受害者可能容易被欺骗/愚弄将DLL植入这些不受信任位置。
属于此类别的DLL植入问题,即应用程序目录DLL植入,被视为纵深防御问题,仅在未来版本更新中考虑。我们将任何属于此类别的MSRC案例解决为vNext考虑,主要是由于攻击中涉及的社会工程量和漏洞的设计性质。受害者必须被欺骗将恶意DLL(恶意软件)放置在可以触发的位置,并执行不推荐的操作(如在恶意软件同一目录运行安装程序)。非安装应用程序没有“已知良好目录/二进制文件”的参考点,除非它自己创建目录。理想情况下,安装程序应创建具有随机名称的临时目录(以防止进一步的DLL植入),将其二进制文件提取到其中,并使用它们安装应用程序。虽然攻击者可以利用路过式下载将恶意软件放置在受害者系统上,例如进入“Downloads”文件夹,但攻击的本质是社会工程。
在Windows 10 Creators Update中,我们添加了一个新的进程缓解措施,可用于缓解应用程序目录DLL植入漏洞。这个新的进程缓解措施PreferSystem32,当选择时,会切换应用程序目录和system32在DLL搜索顺序中的顺序。因此,任何恶意系统二进制文件都不能通过将其植入应用程序目录来劫持。这可以在可以控制进程创建的场景中启用。
当前工作目录(CWD)DLL植入
应用程序通常将调用它们的目录设置为CWD,这甚至适用于基于默认文件关联调用应用程序的情况。例如,从共享“D:\temp\file.abc”点击文件将使“D:\temp”成为与文件类型.abc关联的应用程序的CWD。
在远程共享(尤其是webdav共享)中托管文件的场景使CWD DLL植入问题更加脆弱。这样,攻击者可以托管恶意DLL以及文件,并社会工程受害者打开/点击文件以将恶意DLL加载到目标应用程序中。
场景3:在当前工作目录中植入恶意二进制文件。 应用程序加载在前三个受信任位置中都不存在的DLL时,会在不受信任的CWD中寻找相同的DLL。受害者从位置\server1\share2\打开.doc文件将启动Microsoft Word,如果Microsoft Word在受信任位置找不到其依赖的DLL oart.dll,它将尝试从CWD \server1\share2\加载它。由于共享是不受信任的位置,攻击者可以轻松植入oart.dll以馈入应用程序。
触发 => \server1\share2\openme.doc
应用程序 => C:\Program Files (x86)\Microsoft Office\root\Office16\Winword.exe
应用程序目录 => _C:\Program Files (x86)\Microsoft Office\root\Office16\
CWD => _\server1\share2\
恶意DLL => \server1\share2\OART.DLL
属于此类别的CWD DLL植入问题被视为重要严重性问题,我们将为此发布安全补丁。我们过去修复的大多数DLL植入问题属于此类别,公告2269637列出了其中一部分。这引出一个问题:为什么任何Microsoft应用程序会加载不存在于其应用程序目录、系统目录或Windows目录中的DLL。碰巧有各种可选组件、不同OS版本和多种架构带有不同的二进制文件集,有时应用程序在加载DLL之前未能有效考虑或验证。
PATH目录DLL植入
在DLL搜索顺序中查找DLL的最后手段是PATH目录,这是一组由各种应用程序添加的目录,以促进用户体验定位应用程序及其工件。
PATH环境变量中的目录始终是管理员ACLed的,普通用户无法修改这些目录的内容。如果我们有一个通过PATH暴露的世界可写目录,那么这比单个DLL植入实例的问题更大,我们将其作为重要严重性问题处理。但仅DLL植入问题被视为低安全问题,因为我们不期望通过此植入漏洞跨越任何安全边界。因此,属于PATH目录DLL植入类别的DLL植入问题被视为不修复。
结论
我们希望这能澄清我们如何处理报告的DLL植入问题以及我们认为哪些情况严重到需要发布安全补丁的问题。以下是通过安全发布(下游)修复/不修复的快速指南。
Microsoft将通过安全修复解决的问题
- CWD场景 - 如关联应用程序从不受信任的CWD加载DLL。
Microsoft将在下次产品发布时考虑解决的问题
- 应用程序目录场景 - 这完全由产品组根据是显式加载还是隐式加载来决定。显式加载可以调整,但隐式加载(依赖DLL)严格按设计,因为路径无法控制。
Microsoft不会解决的问题(不是漏洞)
- PATH目录场景 - 由于PATH中不能有非管理员目录,因此无法利用。
—–
Antonio Galvan, MSRC
Swamy Shivaganga Nagaraju, MSRC漏洞和缓解团队