在使用Aquatone(一款子域名挖掘工具)执行一些常规的监控时,我注意到在两个不同的子域名上有一个相似的登录页面,而这两个子域名来自于两个不相关的漏洞。

1.png

这两个子域都包含此默认登录屏幕的自定义版本

此登录屏幕后面的软件是Zoho ManageEngine ADSelfService Plus,它提供了一个门户,允许用户重置其自己的Active Directory(AD)帐户的密码。 ZOHO ManageEngine ADSelfService Plus是美国卓豪(ZOHO)公司的一套基于Web的终端用户密码管理软件。 ZOHO ManageEngine ADSelfService Plus 5.0.6之前版本中的密码重置功能存在授权问题漏洞。 该漏洞源于网络系统或产品中缺少身份验证措施或身份验证强度不足。

由于我认为我在这个产品上发现的任何漏洞都可能潜在地影响到多个公司,而且,更严重的是,因为这似乎很可能与组织的Active Directory链接在一起,所以在这里花一些时间似乎是个好主意。

经过努力,我发现了一些基本的反映跨站点脚本(XSS)漏洞,其他研究人员显然已经发现了这些漏洞。所以我得再深入一点。幸运的是,整个产品可以下载安装试用30天。

设置

由于我确信可能会找到更多的XSS漏洞,因此我决定下载并安装该软件,其目的是浏览Java源代码以查找更多漏洞。

安装软件后,我现在的优势就是能够在本地执行所有测试,并通读源代码以准确了解应用程序中发生的事情,甚至可以在安装文件夹中使用grep查找潜在的有趣文件。

为了对Java应用程序进行反向工程,我喜欢使用Bytecode Viewer(java反编译工具),它可以将Java类文件反编译并格式化为可读的Java代码。它还允许编辑字节码并即时重新编译文件,并且还可以很好地反编译Android APK文件。

2.png

现在,我开始手动浏览一些Java源文件而没有很多有趣的发现。但是,我确实了解了软件组件以及它们如何协同工作。在寻找应用程序中的复杂漏洞时,这往往是非常宝贵的,因此绝对值得花几个小时。结果,我对应用程序功能有了很好的了解,包括主要由遗留代码组成的应用程序的部分与看起来较新的部分的对比,为修复以前的安全漏洞而修改的部分等等。

有一次,我决定构建一个应用程序端点的单词列表,该列表可以有两个目的:直接针对端点执行一些“经典”安全测试,并在针对某个类似应用程序的某个端点用作有用的资源。

漏洞

1. Java中不安全的反序列化

在枚举应用程序端点的过程中,我在一个web.xml文件中发现了以下几行:

3.png

当我用谷歌搜索时,我在img参数中使用路径遍历找到了针对另一个ManageEngine产品上的cewolf端点的已发布RCE 。

可以肯定的是,在手动将一个文件放在我的本地安装的一个文件夹后,我可以通过浏览http://localhost:8888/cewolf/?img=/../../ path/to/evil.file来确认这个版本的ADSelfService Plus中也存在反序列化漏洞。

这意味着我在目标站点上有一个随时可用的Java反序列化漏洞,但只有当我找到一种方法先将任意文件上传到服务器上时,我才能利用它。

2.任意文件上传

查找任意文件上传漏洞似乎并不容易,为了最大限度地利用我的攻击面,我继续在我的设备上配置软件,这需要设置要使用的本地域控制器和Active Directory域。

通过数小时的下载ISO,在硬盘上腾出空间,VMware Workstation恶作剧,Microsoft Windows Server管理以及观看带有标题为“如何设置Windows Server 2019域控制器”之类的Youtube视频的快速前进,我终于有了一个允许我使用的设置登录到管理面板。

4.png

最后,我建立了ADSelfService Plus的工作副本,以备不时之需。

通过对应用程序的完全管理员访问权限,我现在可以进一步映射应用程序功能和API端点。出于明显的原因,我花了大部分时间研究应用程序中的所有不同上载功能,直到遇到支持上载智能卡证书配置的一项功能,导致对/LogonCustomization.do?form=smartCard&operation=Add的POST请求

当我注意到上传的证书文件没有修改名称就存储在服务器的文件系统上时,我认为这可能是利用反序列化漏洞的方法!因此,我通过源代码跟踪这个API调用,以找到更多攻击它的可能方法。

如何运作如下:

5.png

1.登录的管理员可以将智能卡配置上传到/LogonCustomization.do?form=smartCard&operation=Add;。

2.这会使用服务器端生成的秘密握手触发对/RestAPI/WC/SmartCard?HANDSHAKE_KEY=secret上服务器经过身份验证的RestAPI的后端请求;

3.在执行请求的操作之前,请针对/servlet/HSKeyAuthenticator?PRODUCT_NAME=ManageEngine+ADSelfService+Plus&HANDSHAKE_KEY=secret的第二个API端点对HANDSHAKE_KEY进行验证,根据传递的secret返回SUCCESS或FAILED;

4.如果成功,上传的证书将写入C:\ManageEngine\ADSelfService Plus\bin;

有趣的是,/ RestAPI端点是可公开访问的,因此任何带有有效HANDSHAKE_KEY的请求都将绕过用户身份验证,并由服务器处理。

此外,/servlet/HSKeyAuthenticator也是可公开访问的,允许未经授权的用户手动验证身份验证秘密是否有效。考虑到这一点,我回到了现在熟悉的源代码。

3. Bruteforceable认证密钥

在grep和安装的PostgreSQL数据库的帮助下,我确定了两个有趣的Java类,其中包含有用的API端点及其身份验证需求清单:

6.png

本地安装软件的另一个好处是可以完全访问基础数据库

com.manageengine.ads.fw.servlet中HSKeyAuthenticator.class的代码片段:

7.png

还有一个来自com.manageengine.ads.fw.api包中的RestAPIKey.class:

8.png

从这些代码中可以看到,服务器的API身份验证密钥设置为当前时间(以毫秒为单位),并且有效期为2分钟。这意味着在任何给定时刻,都有120000个可能的身份验证密钥(120秒* 1000毫秒/秒)。

换句话说,如果我可以在2分钟的时间内连续每秒生成最少1000个请求,那么在身份验证密钥过期并重新生成的那一刻,我就可以保证命中率。对于网络级别的攻击来说,这似乎是一个很大的数目,但成功的攻击并不一定超出可能的范围。尤其要记住,即使在低于100%的成功率下,并且有足够的时间,成功击中的可能性也会越来越大。

在实践中,我很快有了一个有效的概念证明,可以在几分钟之内强行破解了本地实例的秘密。

9.png

我使用暴力破解在本地实例上强行揭秘这个秘密

但是,在对一个活动目标(即通过实际的互联网连接)使用该脚本时,我就没那么幸运了。我用不同的配置和设置运行并重新运行了几个小时,整夜都没有结果,我开始担心我的方法将不得不被放弃。

此外,我暂时转移了注意力,因为我不确定我的目标服务器在哪个时区运行。最后,我使用我自己的CET (CET)中的多个偏移量重新运行了我的脚本,直到我发现Java的currentTimeMillis显然是以协调世界时(UTC)返回时间,而我本不必为此烦恼。

最后,经过更多的尝试和漏洞,我找到了以下Turbo Intruder脚本,该脚本根据实际的每秒请求数(rps),尝试使用当前时间戳前后的每一个rps / 2毫秒进行身份验证。这提供了合理的覆盖范围,并将潜在盲点降至最低:

10.png

并将HTTP请求移至base.txt文件中,以使用无标头Turbo Intruder进行攻击准备,Turbo Intruder 是一个 BurpSuite 插件,用于发送大量HTTP请求并分析结果。它的设计目的是补充 Intruder 的不足。它的特点如下:

1. 快速:Turbo Intruder 使用了一个重写的 HTTP 栈 ,用于提升速度。在许多目标上,它甚至可能超过流行的异步 Go 脚本。

2.可扩展 :Turbo Intruder 运行时使用很少的内存,从而可以连续运行几天。同时可以脱离 burpsuite 在命令行下使用。

3.灵活: Turbo Intruder 的攻击是使用 Python 配置的。这样可以处理复杂的要求,例如签名的请求和多步攻击序列。此外,自定义 HTTP 栈意味着它可以处理其他库无法处理的畸形格式请求。

4. 方便:它的结果可以通过 Backslash Powered Scanner 的高级差异算法自动过滤。这意味着您可以单击两次即可发起攻击并获得有用的结果。

11.png

现在,所需要的只是一点点耐心和很多运气。

12.png

正如预期的那样,尽管我怀疑,身份验证密钥可以成功地强制执行,即使远远低于理想的每秒1000个请求。

漏洞利用

现在,可以开始漏洞利用了。我用反序列化框架ysoserial生成了一堆Java有效载荷,发现以下工作有效:

13.png

接下来,我从上面通过脚本强行使用了身份验证密钥,并使用它通过经过身份验证的RestAPI将ysererial有效载荷上传到服务器:

14.png

为了完成任务,我向/cewolf/?img=/../../../bin/pieter发出了一个简单的GET请求,结果如下:

15.png

可以看出,成功的Java反序列化攻击导致DNS查询请求。

总结

面对一连串导致AD连接服务器上RCE的漏洞,我认为攻击者可能使用Domain Controller的链接滥用来劫持域帐户或在AD域上创建新帐户,从而导致更广泛的访问公司的内部网络,例如通过其公共VPN门户访问内部服务。

目前我已将发现的漏洞报告给两家公司,其中一个被评为“严重”。

微信截图_20200812215026.png

0x01 漏洞分析

这篇文章描述了splwow64.exe中的一个可利用的任意指针取消引用漏洞。此漏洞可以从Internet Explorer渲染器进程触发,并允许沙盒逃逸。

该漏洞允许通过将特定的LPC消息制作到splwow64.exe进程,从而从低完整性进程中任意写入splwow64.exe的地址空间。

该漏洞已经在Windows 7 x64和Windows 10 x64计算机上进行了测试。

在本文中,我将描述该漏洞的位置以及如何利用该漏洞从Internet Explorer沙盒中实现完整的沙盒逃逸。

该漏洞似乎未在Windows 7上进行修补,因此,我不会发布用于利用此漏洞的源代码。

漏洞描述

该漏洞在于处理对splwow64.exe进程的特定LPC调用,从而可以使用任意参数在splwow64地址空间中调用memcpy函数。这为攻击者提供了极为强大的原语,因为它允许在不依赖内核漏洞的情况下,在更高完整性进程的内存中进行写操作,并逃逸浏览器沙箱。

splwow64.exe进程

Splwow64.exe是一个Microsoft可执行文件,每当32位应用程序访问你已安装的打印机之一时,该文件便会执行。此进程特别有趣,因为它是Internet Explorer策略列入白名单的进程之一。换句话说,任何来自低完整性IE渲染器进程的调用都将生成此进程,这将导致splwow64.exe作为中等完整性进程被加载。

在深入分析漏洞本身之前,让我们尝试深入了解Splwow64流程的实际工作方式。

LPC端口创建

开始执行后,splwow64.exe将通过调用ZwCreatePort API创建LPC端口,并将开始等待传入连接。

让我们看一下ZwCreatePort函数。

 NTSTATUS NTAPI ZwCreatePort(PHANDLE,POBJECT_ATTRIBUTES,ULONG,ULONG,ULONG);

如你所见,第二个参数是指向“对象属性”结构的指针,该结构将指向UNICODE_STRING函数,该函数包含由进程创建的LPC端口的名称。

为了连接到该LPC端口,我们需要了解的第一件事是如何生成LPC端口名称!如果你将检查ZwCreatePort的Object Attributes指针参数多次(每次重新引导计算机后),你会注意到LPC端口名的一部分将在每次重新引导后更改。

LPC端口名称如下所示:

在Windows 10上

 \\RPC Control\\UmpdProxy_1_VARIABLEPART_0_2000

在Windows 7上

 \\RPC Control\\UmpdProxy_1_VARIABLEPART_0_0

每次重新启动计算机后,VARIABLEPART都会更改。

这意味着要能够从IE Sandboxed进程实际连接到该LPC端口,我们将需要了解如何生成LPC端口名称。

对我们来说幸运的是,生成LPC端口名的可变部分的算法非常简单,看起来像这样:

· 调用OpenProcessToken API,将当前进程的句柄作为参数传递。

· 调用GetTokenInformation API,将TokenStatistics作为TOKEN_INFORMATION_CLASS传递

· 访问新获得的TOKEN_STATISTICS结构的AuthenticationId.LowPart字段,并将其转换为十六进制字符串。

现在,你可以连接到LPC端口了!

LPC消息处理

现在,我们将需要了解splwow64进程如何解析LPC消息。由于对splwow64进程的内部工作原理的完整解释不在本文的讨论范围之内,因此我们将只关注漏洞分析,以获取有关漏洞本身及其利用的足够知识。

简而言之,splwow64将以以下方式解析传入的LPC消息:

· 它仅接受长度为0x20字节的传入消息。

· 它将把位于LPC消息的偏移量0x30、0x38和0x40处的三个指针作为参数传递给GdiPrinterThunk函数。

这意味着只要发送的消息为0x20字节长,我们就可以使用任意参数调用GdiPrinterThunk函数!

现在,我们将需要了解GdiPrinterThunk实际如何工作,以查看是否可以通过控制函数参数来触发一些有趣的东西。

GdiPrinterThunk函数

GdiPrinterThunk是一个非常复杂的函数,其工作流程将由位于第一个参数中指定地址的偏移量0x4处的字节确定。如前所述,我们实际上可以通过编写特定的LPC消息来控制GdiPrinterThunk函数传递的三个参数。换句话说,这意味着我们能够控制GdiPrinterThunk工作流程!

此函数是实际的任意解除引用漏洞所在的位置:如果作为第一个参数传递的地址的偏移量0x4处的字节为0x76(在Windows 7上为0x75),则将使用由攻击者完全控制的参数来调用memcpy函数。 !

看一下伪C代码:

 void GdiPrinterThunk(LPVOID firstAddress, LPVOID secondAddress, LPVOID thirdAddress)
 {
   ...
 
     if(*((BYTE*)(firstAddress + 0x4)) == 0x75){
       ULONG64 memcpyDestinationAddress = *((ULONG64*)(firstAddress + 0x20));
 
       if(memcpyDestinationAddress != NULL){
         ULONG64 sourceAddress = *((ULONG64*)(firstAddress + 0x18));
         DWORD copySize = *((DWORD*)(firstAddress + 0x28));
 
         memcpy(memcpyDestinationAddress,sourceAddress,copySize);
       }
     }
 
 ...
 }

这是一个任意指针取消引用,使我们可以从低完整性进程中有意地写入splwow64.exe地址空间!

但是我们如何触发它呢?

如前所述,将使用以下参数调用GdiPrinterThunk函数:

· RCX设置为LPC消息的偏移量0x30中指定的地址

· RDX设置为在LPC消息的偏移量0x40中指定的地址

· R8设置为在LPC消息的偏移量0x38中指定的地址

要构造我们的“任意地址写”原语,我们可以创建一个共享节,并在LPC消息的偏移量0x30处指定此共享节的地址。

创建共享部分后,我们可以在所需的偏移量处设置要写入的地址和要从中读取的地址,然后发送LPC消息!

解析LPC消息时,GdiPrinterThunk将访问在消息的偏移量0x30处指定的共享内存地址,如果从共享内存地址功能开始的第四个字节为0x76(在Windows 7上为0x75),则将调用具有在共享内存地址中指定由攻击者控制的参数的memcpy函数!

0x02 漏洞利用

我们可以构建功能非常强大的“ Write What Where Primitive”!不幸的是,我们仍然需要解决一些问题才能真正逃逸Internet Explorer沙箱:

· W ^ X内存:可执行页的内存不可写。换句话说,我们不能只是将有效负载写入可执行内存页面。

· ASLR:我们有能力在所需的地方写我们想要的东西。问题是我们没有信息泄漏,该信息泄漏将使我们能够知道目标进程中函数指针的地址,从而通过覆盖它来执行代码。

· 任意执行:我们可以任意写入splwow64进程的内存,但是我们仍然不知道如何在需要时触发有效负载。

W ^ X内存

由于我们无法写入可执行内存页面,也无法通过调用VirtualProtect使内存页面可写,因此我们需要考虑其他事项。首先想到的是用LoadLibraryA或WinExec之类的函数的地址覆盖现有的函数指针,只要我们能够使用任意参数触发对此函数指针的调用,我们就可以完成!

看一下OpenPrinterW函数:

如你在上面的截图中看到的,该函数将移至RAX寄存器中位于winspool.drv函数.data部分中的地址,并通过调用LdrpValidateUserCallTarget(控制流保护)来验证该地址。

在Windows 7上,它将仅跳转到.data节中保存的地址,如下图所示。

由于winspool.drv DLL的.data部分是可写的,因此我们可以使用“任意地址写”原语来覆盖存储的地址!

如上图所示,该地址已被我们选择的地址覆盖!

逆向分析

为了实现上述目的,我们将需要知道splwow64进程中winspool.drv .data节的地址!幸运的是,Windows系统上的地址空间布局随机化是基于引导的。换句话说,每个系统DLL的基地址在每个进程中都是相同的,直到下一个系统重新启动为止,无论其完整性级别如何。

这意味着将winspool.drv DLL加载到沙盒进程的地址空间中,查找其数据部分,然后从该处找到指向OpenPrinter2W函数的指针,并使用获得的地址在远程进程中通过调用将其覆盖就足够了。

尽管有上述说明,但这还不足以实现完整覆盖:在Windows 7系统上,Internet Explorer渲染器进程是32位的,而splwow64进程是64位的进程。换句话说,我们将无法获得成功利用此漏洞所需的64位地址。

为了解决这个问题,我们有两种选择:

· 生成一个64位进程以泄漏所需的地址。

· 使用Heaven’s gate 技巧在我们的Internet Explorer Wow64进程中加载64位DLL,并泄漏地址。

生成64位进程

这是解决问题的最简单,最稳定的方法。由于Internet Explorer允许从Low Integrity渲染器进程写入LocalLow文件夹,因此要泄漏所需的地址,我们只需要以下各项:

· 创建一个LeakAddresses.exe 64位可执行文件,该文件将加载winspool.drv DLL,获取所需的地址,并将结果保存在LocalLow文件夹中的文件中。

· 将LeakAddresses可执行文件拖放到LocalLow文件夹中,然后通过调用CreateProcess函数运行它。由于不会发生特权提升,因此该执行对用户不可见:该文件将作为低完整性进程执行。

· 通过读取我们的LeakAddresses可执行文件创建的文件来获取所需的地址。

· 使用获得的地址来制作LPC消息,以实现Write What Where原语。

使用 Heaven’s gate 技巧

有关此技术实际上如何工作的完整描述超出了本文的范围。简而言之,Heaven’s gate是利用Windows在64位系统上实现32位代码仿真以加载64位DLL。

通过使用此技术,你将能够在Internet Explorer进程的地址空间中加载64位DLL,从而可以泄漏所需的地址,而无需在磁盘上写入任何文件。

任意代码执行

实际上,为什么选择在OpenPrinterW函数中覆盖指向OpenPrinter2W函数的指针是有原因的。 在花了一些时间逆向 GdiPrinterThunk函数之后,我注意到,如果我们将byte参数设置为0x6A(在Windows 7上为0x69),则会发出对OpenPrinterW函数的调用,第一个参数可由我们控制:因为指向OpenPrinter2W的指针已被我们覆盖,将发出对我们选择的函数的调用!

不幸的是,我们只能控制第一个参数,因此,你应该选择仅包含一个参数的函数。我选择了以下两个函数:

· LoadLibraryA:此函数将在从其调用的进程的地址空间中加载一个库。由于此函数仅使用一个参数,因此我们可以将DLL放到Local Low文件夹中,并在splwow64.exe进程中触发对LoadLibraryA的调用。这样,我们的DLL将由中等完整性级别的进程加载,从而使Internet Explorer沙箱逃逸。

· system:由于WinExec函数具有两个参数,而我们只能控制一个参数,由于msvcrt.dll DLL已加载到splwow64地址空间中,因此我们可以调用此函数,系统函数将仅使用一个参数,并作为命令行将其作为完整性进程来执行。例如,攻击者可以以Medium Integrity用户身份运行Powershell命令。

0x03 分析总结

尽管它很简单,但此漏洞仍使攻击者能够以极其简单和确定性的方式完全逃逸Internet Explorer沙箱的攻击!我发现旧版Windows组件中的这些类型的漏洞非常神奇,并且我认为将来会发现更多此类漏洞。

根据我的测试,此漏洞利用代码仍然可以在功能完善的Windows 7系统上运行,因此,我选择不发布漏洞利用代码。

0x01 漏洞分析

这篇文章描述了splwow64.exe中的一个可利用的任意指针取消引用漏洞。此漏洞可以从Internet Explorer渲染器进程触发,并允许沙盒逃逸。

该漏洞允许通过将特定的LPC消息制作到splwow64.exe进程,从而从低完整性进程中任意写入splwow64.exe的地址空间。

该漏洞已经在Windows 7 x64和Windows 10 x64计算机上进行了测试。

在本文中,我将描述该漏洞的位置以及如何利用该漏洞从Internet Explorer沙盒中实现完整的沙盒逃逸。

该漏洞似乎未在Windows 7上进行修补,因此,我不会发布用于利用此漏洞的源代码。

漏洞描述

该漏洞在于处理对splwow64.exe进程的特定LPC调用,从而可以使用任意参数在splwow64地址空间中调用memcpy函数。这为攻击者提供了极为强大的原语,因为它允许在不依赖内核漏洞的情况下,在更高完整性进程的内存中进行写操作,并逃逸浏览器沙箱。

splwow64.exe进程

Splwow64.exe是一个Microsoft可执行文件,每当32位应用程序访问你已安装的打印机之一时,该文件便会执行。此进程特别有趣,因为它是Internet Explorer策略列入白名单的进程之一。换句话说,任何来自低完整性IE渲染器进程的调用都将生成此进程,这将导致splwow64.exe作为中等完整性进程被加载。

在深入分析漏洞本身之前,让我们尝试深入了解Splwow64流程的实际工作方式。

LPC端口创建

开始执行后,splwow64.exe将通过调用ZwCreatePort API创建LPC端口,并将开始等待传入连接。

让我们看一下ZwCreatePort函数。

 NTSTATUS NTAPI ZwCreatePort(PHANDLE,POBJECT_ATTRIBUTES,ULONG,ULONG,ULONG);

如你所见,第二个参数是指向“对象属性”结构的指针,该结构将指向UNICODE_STRING函数,该函数包含由进程创建的LPC端口的名称。

为了连接到该LPC端口,我们需要了解的第一件事是如何生成LPC端口名称!如果你将检查ZwCreatePort的Object Attributes指针参数多次(每次重新引导计算机后),你会注意到LPC端口名的一部分将在每次重新引导后更改。

LPC端口名称如下所示:

在Windows 10上

 \\RPC Control\\UmpdProxy_1_VARIABLEPART_0_2000

在Windows 7上

 \\RPC Control\\UmpdProxy_1_VARIABLEPART_0_0

每次重新启动计算机后,VARIABLEPART都会更改。

这意味着要能够从IE Sandboxed进程实际连接到该LPC端口,我们将需要了解如何生成LPC端口名称。

对我们来说幸运的是,生成LPC端口名的可变部分的算法非常简单,看起来像这样:

· 调用OpenProcessToken API,将当前进程的句柄作为参数传递。

· 调用GetTokenInformation API,将TokenStatistics作为TOKEN_INFORMATION_CLASS传递

· 访问新获得的TOKEN_STATISTICS结构的AuthenticationId.LowPart字段,并将其转换为十六进制字符串。

现在,你可以连接到LPC端口了!

LPC消息处理

现在,我们将需要了解splwow64进程如何解析LPC消息。由于对splwow64进程的内部工作原理的完整解释不在本文的讨论范围之内,因此我们将只关注漏洞分析,以获取有关漏洞本身及其利用的足够知识。

简而言之,splwow64将以以下方式解析传入的LPC消息:

· 它仅接受长度为0x20字节的传入消息。

· 它将把位于LPC消息的偏移量0x30、0x38和0x40处的三个指针作为参数传递给GdiPrinterThunk函数。

这意味着只要发送的消息为0x20字节长,我们就可以使用任意参数调用GdiPrinterThunk函数!

现在,我们将需要了解GdiPrinterThunk实际如何工作,以查看是否可以通过控制函数参数来触发一些有趣的东西。

GdiPrinterThunk函数

GdiPrinterThunk是一个非常复杂的函数,其工作流程将由位于第一个参数中指定地址的偏移量0x4处的字节确定。如前所述,我们实际上可以通过编写特定的LPC消息来控制GdiPrinterThunk函数传递的三个参数。换句话说,这意味着我们能够控制GdiPrinterThunk工作流程!

此函数是实际的任意解除引用漏洞所在的位置:如果作为第一个参数传递的地址的偏移量0x4处的字节为0x76(在Windows 7上为0x75),则将使用由攻击者完全控制的参数来调用memcpy函数。 !

看一下伪C代码:

 void GdiPrinterThunk(LPVOID firstAddress, LPVOID secondAddress, LPVOID thirdAddress)
 {
   ...
 
     if(*((BYTE*)(firstAddress + 0x4)) == 0x75){
       ULONG64 memcpyDestinationAddress = *((ULONG64*)(firstAddress + 0x20));
 
       if(memcpyDestinationAddress != NULL){
         ULONG64 sourceAddress = *((ULONG64*)(firstAddress + 0x18));
         DWORD copySize = *((DWORD*)(firstAddress + 0x28));
 
         memcpy(memcpyDestinationAddress,sourceAddress,copySize);
       }
     }
 
 ...
 }

这是一个任意指针取消引用,使我们可以从低完整性进程中有意地写入splwow64.exe地址空间!

但是我们如何触发它呢?

如前所述,将使用以下参数调用GdiPrinterThunk函数:

· RCX设置为LPC消息的偏移量0x30中指定的地址

· RDX设置为在LPC消息的偏移量0x40中指定的地址

· R8设置为在LPC消息的偏移量0x38中指定的地址

要构造我们的“任意地址写”原语,我们可以创建一个共享节,并在LPC消息的偏移量0x30处指定此共享节的地址。

创建共享部分后,我们可以在所需的偏移量处设置要写入的地址和要从中读取的地址,然后发送LPC消息!

解析LPC消息时,GdiPrinterThunk将访问在消息的偏移量0x30处指定的共享内存地址,如果从共享内存地址功能开始的第四个字节为0x76(在Windows 7上为0x75),则将调用具有在共享内存地址中指定由攻击者控制的参数的memcpy函数!

0x02 漏洞利用

我们可以构建功能非常强大的“ Write What Where Primitive”!不幸的是,我们仍然需要解决一些问题才能真正逃逸Internet Explorer沙箱:

· W ^ X内存:可执行页的内存不可写。换句话说,我们不能只是将有效负载写入可执行内存页面。

· ASLR:我们有能力在所需的地方写我们想要的东西。问题是我们没有信息泄漏,该信息泄漏将使我们能够知道目标进程中函数指针的地址,从而通过覆盖它来执行代码。

· 任意执行:我们可以任意写入splwow64进程的内存,但是我们仍然不知道如何在需要时触发有效负载。

W ^ X内存

由于我们无法写入可执行内存页面,也无法通过调用VirtualProtect使内存页面可写,因此我们需要考虑其他事项。首先想到的是用LoadLibraryA或WinExec之类的函数的地址覆盖现有的函数指针,只要我们能够使用任意参数触发对此函数指针的调用,我们就可以完成!

看一下OpenPrinterW函数:

如你在上面的截图中看到的,该函数将移至RAX寄存器中位于winspool.drv函数.data部分中的地址,并通过调用LdrpValidateUserCallTarget(控制流保护)来验证该地址。

在Windows 7上,它将仅跳转到.data节中保存的地址,如下图所示。

由于winspool.drv DLL的.data部分是可写的,因此我们可以使用“任意地址写”原语来覆盖存储的地址!

如上图所示,该地址已被我们选择的地址覆盖!

逆向分析

为了实现上述目的,我们将需要知道splwow64进程中winspool.drv .data节的地址!幸运的是,Windows系统上的地址空间布局随机化是基于引导的。换句话说,每个系统DLL的基地址在每个进程中都是相同的,直到下一个系统重新启动为止,无论其完整性级别如何。

这意味着将winspool.drv DLL加载到沙盒进程的地址空间中,查找其数据部分,然后从该处找到指向OpenPrinter2W函数的指针,并使用获得的地址在远程进程中通过调用将其覆盖就足够了。

尽管有上述说明,但这还不足以实现完整覆盖:在Windows 7系统上,Internet Explorer渲染器进程是32位的,而splwow64进程是64位的进程。换句话说,我们将无法获得成功利用此漏洞所需的64位地址。

为了解决这个问题,我们有两种选择:

· 生成一个64位进程以泄漏所需的地址。

· 使用Heaven’s gate 技巧在我们的Internet Explorer Wow64进程中加载64位DLL,并泄漏地址。

生成64位进程

这是解决问题的最简单,最稳定的方法。由于Internet Explorer允许从Low Integrity渲染器进程写入LocalLow文件夹,因此要泄漏所需的地址,我们只需要以下各项:

· 创建一个LeakAddresses.exe 64位可执行文件,该文件将加载winspool.drv DLL,获取所需的地址,并将结果保存在LocalLow文件夹中的文件中。

· 将LeakAddresses可执行文件拖放到LocalLow文件夹中,然后通过调用CreateProcess函数运行它。由于不会发生特权提升,因此该执行对用户不可见:该文件将作为低完整性进程执行。

· 通过读取我们的LeakAddresses可执行文件创建的文件来获取所需的地址。

· 使用获得的地址来制作LPC消息,以实现Write What Where原语。

使用 Heaven’s gate 技巧

有关此技术实际上如何工作的完整描述超出了本文的范围。简而言之,Heaven’s gate是利用Windows在64位系统上实现32位代码仿真以加载64位DLL。

通过使用此技术,你将能够在Internet Explorer进程的地址空间中加载64位DLL,从而可以泄漏所需的地址,而无需在磁盘上写入任何文件。

任意代码执行

实际上,为什么选择在OpenPrinterW函数中覆盖指向OpenPrinter2W函数的指针是有原因的。 在花了一些时间逆向 GdiPrinterThunk函数之后,我注意到,如果我们将byte参数设置为0x6A(在Windows 7上为0x69),则会发出对OpenPrinterW函数的调用,第一个参数可由我们控制:因为指向OpenPrinter2W的指针已被我们覆盖,将发出对我们选择的函数的调用!

不幸的是,我们只能控制第一个参数,因此,你应该选择仅包含一个参数的函数。我选择了以下两个函数:

· LoadLibraryA:此函数将在从其调用的进程的地址空间中加载一个库。由于此函数仅使用一个参数,因此我们可以将DLL放到Local Low文件夹中,并在splwow64.exe进程中触发对LoadLibraryA的调用。这样,我们的DLL将由中等完整性级别的进程加载,从而使Internet Explorer沙箱逃逸。

· system:由于WinExec函数具有两个参数,而我们只能控制一个参数,由于msvcrt.dll DLL已加载到splwow64地址空间中,因此我们可以调用此函数,系统函数将仅使用一个参数,并作为命令行将其作为完整性进程来执行。例如,攻击者可以以Medium Integrity用户身份运行Powershell命令。

0x03 分析总结

尽管它很简单,但此漏洞仍使攻击者能够以极其简单和确定性的方式完全逃逸Internet Explorer沙箱的攻击!我发现旧版Windows组件中的这些类型的漏洞非常神奇,并且我认为将来会发现更多此类漏洞。

根据我的测试,此漏洞利用代码仍然可以在功能完善的Windows 7系统上运行,因此,我选择不发布漏洞利用代码。

Cisco warns of actively exploited bug in carrier-grade routers

上周末,思科官方发布安全公告称攻击者正在尝试利用Cisco IOS XR软件中的一个高危内存耗尽DoS 漏洞。Cisco IOS XR软件是运行在运营商级路由器上的。IOS XR网络操作系统部署在多个路由器平台上,包括NCS 540 、560、 NCS 5500、8000和ASR 9000系列路由器。

漏洞分析

该漏洞CVE编号为CVE-2020-3566,存在于IOS XR软件中的距离向量多播路由协议(Distance Vector Multicast Routing Protocol,DVMRP)特征中,是由于IGMP(互联网组管理协议,Internet Group Management Protocol)包的排队管理不足导致的。攻击者可以通过发送伪造的IGMP包到受影响的设备来利用该漏洞。远程攻击者成功利用该漏洞后,可以在未认证的情况下消耗目标设备的内存,引发其他进程不稳定,其中包括内部和外部路由协议。

漏洞影响

思科安全公告中称,该漏洞影响所有运行Cisco IOS XR软件,并且活动端口配置了多播路由的思科设备。为确定设备上是否启用了多播路由,管理员可以运行show igmp interface命令。如果IOS XR路由器没有启用多播路由,输出为空,即不受到该漏洞的影响。

对受该漏洞影响的设备,管理员可以通过查看系统日志消息来检查设备是否被攻击,系统日志消息示例如下:

IOCs

漏洞在野利用vs缓解措施

8月28日,思科研究人员发现该漏洞可能被在野利用。但思科目前还未发布修复该漏洞的安全补丁,但思科在安全公告中给出了一些缓解的方法。

· 管理员可以通过限制速率来减少IGMP流量速率,增加成功利用漏洞所需要的时间。

· 用户可以向现有端口访问控制列表(ACL)中添加访问控制记录,或创建新的ACL来拒绝启用了多播路由的DVRMP流量。

思科建议进入IGMP路由器配置模式在无需处理IGMP流量的端口上禁用IGMP路由。此外,还可以通过router igmp命令、使用interface选定端口、使用router disable禁用IGMP。

思科发布的安全公告地址:https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-iosxr-dvmrp-memexh-dSmpdvfz

Cisco warns of actively exploited bug in carrier-grade routers

上周末,思科官方发布安全公告称攻击者正在尝试利用Cisco IOS XR软件中的一个高危内存耗尽DoS 漏洞。Cisco IOS XR软件是运行在运营商级路由器上的。IOS XR网络操作系统部署在多个路由器平台上,包括NCS 540 、560、 NCS 5500、8000和ASR 9000系列路由器。

漏洞分析

该漏洞CVE编号为CVE-2020-3566,存在于IOS XR软件中的距离向量多播路由协议(Distance Vector Multicast Routing Protocol,DVMRP)特征中,是由于IGMP(互联网组管理协议,Internet Group Management Protocol)包的排队管理不足导致的。攻击者可以通过发送伪造的IGMP包到受影响的设备来利用该漏洞。远程攻击者成功利用该漏洞后,可以在未认证的情况下消耗目标设备的内存,引发其他进程不稳定,其中包括内部和外部路由协议。

漏洞影响

思科安全公告中称,该漏洞影响所有运行Cisco IOS XR软件,并且活动端口配置了多播路由的思科设备。为确定设备上是否启用了多播路由,管理员可以运行show igmp interface命令。如果IOS XR路由器没有启用多播路由,输出为空,即不受到该漏洞的影响。

对受该漏洞影响的设备,管理员可以通过查看系统日志消息来检查设备是否被攻击,系统日志消息示例如下:

IOCs

漏洞在野利用vs缓解措施

8月28日,思科研究人员发现该漏洞可能被在野利用。但思科目前还未发布修复该漏洞的安全补丁,但思科在安全公告中给出了一些缓解的方法。

· 管理员可以通过限制速率来减少IGMP流量速率,增加成功利用漏洞所需要的时间。

· 用户可以向现有端口访问控制列表(ACL)中添加访问控制记录,或创建新的ACL来拒绝启用了多播路由的DVRMP流量。

思科建议进入IGMP路由器配置模式在无需处理IGMP流量的端口上禁用IGMP路由。此外,还可以通过router igmp命令、使用interface选定端口、使用router disable禁用IGMP。

思科发布的安全公告地址:https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-iosxr-dvmrp-memexh-dSmpdvfz

UltraRank.jpg

一个网络犯罪组织,专门感染网店窃取支付卡数据,对近700家网站和十几家第三方服务提供商造成了损害。

通过一家会员卡商店出售被盗的支付信息,每周获利数万美元。

该团伙名为UltraRank,至少从2015年起就活跃起来,他们使用了多个网络浏览器,恶意JavaScript代码,也称为JS嗅探器。

恶意代码注入

Group-IB的安全研究人员说,多年来,UltraRank改变了策略和基础架构。导致他们的活动与不同的团体都能联系起来,这给调查人员增加了调查难度。

在本周的一份技术报告中,研究人员提供了证据,证明UltraRank是Magecart第2、5和12组事件的幕后推手。

“ UltraRank远远超出了普通JS嗅探器运营商的概念,开发了一种具有独特技术和组织结构的自主商业模式”-Group-IB

在2015年,2016年和2018年发起的三项长期活动中,该团伙能在691个流量较大的个人网站(如体育赛事门票经销商)上植入JS嗅探器。

1.png

然而,考虑到该组织对13家web服务提供商(设计、营销、开发、广告、浏览器)的黑客攻击,他们的恶意软件可能被全球数千家网站使用。

通过将恶意代码注入这些公司提供的产品的脚本中,这些脚本随后被放置在在线商店的网络资源上,网络犯罪分子能够在所有使用了受感染脚本的在线商店中拦截客户的银行卡数据

这些受害者中包括法国  在线广告商Adverline  和广告/营销公司Brandit Agency,Brandit Agency还开发了运行Magento电子商务平台的网站。

线索

这种威胁攻击的三个事件都依赖于JS嗅探器,Group-IB将其称为FakeLogistics,WebRank和SnifLite。它们采用一些共同的功能和基础结构,这些功能和基础结构允许将恶意活动跟踪到该组织的首次攻击:

· 隐藏服务器位置和域注册模式的类似方法

· 在不同域名的多个位置存储相同的恶意代码

· 混合供应链和单目标攻击

调查起点是主机“ toplevelstatic [.] com”,该主机托管了一个JS嗅探器,该嗅探器用于破坏Brandit Agency。同一域中存储的文件存在于其他位置,并用于攻击其他在线商店。

2.png

UltraRank从此活动中赚了很多钱。从论坛出售盗窃卡数据的统计数据中,Group-IB获悉,黑客在2019年末的一周内赚了50,000美元。

他们通过ValidCC实现了货币化,ValidCC是一家出售被盗支付数据的知名商店。不过,他们与这家非法商店的合作不仅仅是出售信用卡,因为UltraRank还利用其基础设施攻击冒充ValidCC的钓鱼网站。

4.png

技术证据清楚地表明了UltraRank与ValidCC之间的联系。该连接是该商店使用的三个域的SSL证书,该证书也出现在UltraRank的基础架构上。

专业市场与盗取网店银行卡团伙之间的合作表明,网络犯罪分子精心组织、微调了经营活动,以获取最高利润。

Group-IB的威胁情报分析师Victor Okorokov说,JS嗅探器[Magecart]是用于破坏银行卡数据的工具的演变,从而使攻击的资源消耗更少。

UltraRank.jpg

一个网络犯罪组织,专门感染网店窃取支付卡数据,对近700家网站和十几家第三方服务提供商造成了损害。

通过一家会员卡商店出售被盗的支付信息,每周获利数万美元。

该团伙名为UltraRank,至少从2015年起就活跃起来,他们使用了多个网络浏览器,恶意JavaScript代码,也称为JS嗅探器。

恶意代码注入

Group-IB的安全研究人员说,多年来,UltraRank改变了策略和基础架构。导致他们的活动与不同的团体都能联系起来,这给调查人员增加了调查难度。

在本周的一份技术报告中,研究人员提供了证据,证明UltraRank是Magecart第2、5和12组事件的幕后推手。

“ UltraRank远远超出了普通JS嗅探器运营商的概念,开发了一种具有独特技术和组织结构的自主商业模式”-Group-IB

在2015年,2016年和2018年发起的三项长期活动中,该团伙能在691个流量较大的个人网站(如体育赛事门票经销商)上植入JS嗅探器。

1.png

然而,考虑到该组织对13家web服务提供商(设计、营销、开发、广告、浏览器)的黑客攻击,他们的恶意软件可能被全球数千家网站使用。

通过将恶意代码注入这些公司提供的产品的脚本中,这些脚本随后被放置在在线商店的网络资源上,网络犯罪分子能够在所有使用了受感染脚本的在线商店中拦截客户的银行卡数据

这些受害者中包括法国  在线广告商Adverline  和广告/营销公司Brandit Agency,Brandit Agency还开发了运行Magento电子商务平台的网站。

线索

这种威胁攻击的三个事件都依赖于JS嗅探器,Group-IB将其称为FakeLogistics,WebRank和SnifLite。它们采用一些共同的功能和基础结构,这些功能和基础结构允许将恶意活动跟踪到该组织的首次攻击:

· 隐藏服务器位置和域注册模式的类似方法

· 在不同域名的多个位置存储相同的恶意代码

· 混合供应链和单目标攻击

调查起点是主机“ toplevelstatic [.] com”,该主机托管了一个JS嗅探器,该嗅探器用于破坏Brandit Agency。同一域中存储的文件存在于其他位置,并用于攻击其他在线商店。

2.png

UltraRank从此活动中赚了很多钱。从论坛出售盗窃卡数据的统计数据中,Group-IB获悉,黑客在2019年末的一周内赚了50,000美元。

他们通过ValidCC实现了货币化,ValidCC是一家出售被盗支付数据的知名商店。不过,他们与这家非法商店的合作不仅仅是出售信用卡,因为UltraRank还利用其基础设施攻击冒充ValidCC的钓鱼网站。

4.png

技术证据清楚地表明了UltraRank与ValidCC之间的联系。该连接是该商店使用的三个域的SSL证书,该证书也出现在UltraRank的基础架构上。

专业市场与盗取网店银行卡团伙之间的合作表明,网络犯罪分子精心组织、微调了经营活动,以获取最高利润。

Group-IB的威胁情报分析师Victor Okorokov说,JS嗅探器[Magecart]是用于破坏银行卡数据的工具的演变,从而使攻击的资源消耗更少。

背景

客户的监控系统发现有异常行为,我临时顶替应急的同事处理一下。

连接到服务器,首先通过ps auxef 和 netstat -tulnp两个命令查看异常进程信息,果然发现了两个异常进程 xmp 和 [atd]

通过 ls -al /proc/[pid]/exe 查看这两个进程的程序位置,其中[pid]为xmp 和 [atd]两个进程的进程id

背景

客户的监控系统发现有异常行为,我临时顶替应急的同事处理一下。

连接到服务器,首先通过ps auxef 和 netstat -tulnp两个命令查看异常进程信息,果然发现了两个异常进程 xmp 和 [atd]

通过 ls -al /proc/[pid]/exe 查看这两个进程的程序位置,其中[pid]为xmp 和 [atd]两个进程的进程id