CVE-2020-1362的漏洞如何处理

本篇文章给大家分享的是有关CVE-2020-1362之如何处理漏洞,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。

漏洞背景

WalletService 服务是 windows 上用来持有钱包客户端所使用的对象的一个服务,只存在 windows 10 中。

CVE-2020-1362是 WalletService 在处理 CustomProperty 对象的过程中出现了越界读写,此漏洞可以导致攻击者获得管理员权限,漏洞评级为高危。

微软在 2020 年 7 月更新对漏洞发布补丁。

环境搭建

1.复现环境:windows 10 专业版 1909 (内部版本号 18363.815)

2.设置 WalletService 服务启动类型为自动

CVE-2020-1362的漏洞如何处理

3.调试环境:windbg -psn WalletService 即可。

漏洞原理与分析

漏洞点是设置 CustomProperty 对象的 Group 的 get 方法和 set 方法没有检查边界。

1.get 方法的 a2 参数没有检查边界导致可以泄露堆上的一些地址。CVE-2020-1362的漏洞如何处理

2.set 方法的 a2 参数没有检查边界,可以覆盖到对象的虚表指针,从而控制程序流。CVE-2020-1362的漏洞如何处理

漏洞利用过程

创建 CustomProperty 对象

WalletService 服务由 WalletService.dll 提供,WalletService.dll 实际上是一个动态链接库形式的 Com 组件,由 svchost.exe 加载。我们可以在自己写的程序(下面称为客户端)中使用 CoCreateInstance() 或者 CoGetClassObject() 等函数来创建对象,通过调用获得的对象的类方法来使用服务提供的功能。

如何创建出漏洞函数对应的对象呢?最简单的办法是下载 msdn 的符号表,然后看函数名。

我们想要创建出 CustomProperty 对象,ida 搜索一下,发现有两个创建该对象的函数:Wallet::WalletItem::CreateCustomProperty() 和 Wallet::WalletXItem::CreateCustomProperty()。

CVE-2020-1362的漏洞如何处理

所以我们创建一个 CustomProperty 需要一个 WalletXItem 对象或者 WalletItem 对象,那么使用哪个呢?继续用 ida 搜索 CreateWalletItem 或者 CreateWalletXItem,会发现只有 CreateWalletItem。

CVE-2020-1362的漏洞如何处理

那到这里我们需要一个 WalletX 对象,继续用 ida 搜索会发现找不到 CreateWalletX,但是如果搜索 WalletX,会发现有个 WalletXFactory::CreateInstance(),如果有过 Com 组件开发经验的同学就会知道,这个是个工厂类创建接口类的函数,上面提到的 CoCreateInstance() 函数会使 WalletService 调用这个函数来创建出接口类返回给客户端。

CVE-2020-1362的漏洞如何处理

那么如何调用 WalletXFactory::CreateInstance() 并创建出 WalletX 对象呢?我们需要在客户端使用 CoCreateInstance() 。

HRESULT CoCreateInstance(
    REFCLSID rclsid, // CLSID,用于找到工厂类
    LPUNKNOWN pUnkOuter, // 设置为 NULL 即可
    DWORD dwClsContext, // 设置为 CLSCTX_LOCAL_SERVER,一个宏
    REFIID riid, // IID, 提供给工程类,用于创建接口类实例
    LPVOID *ppv // 接口类实例指针的地址
);

1.首先,我们需要 WalletXFactory 的 CLSID,可以使用 OLEViewDotNet 这个工具查看。

CVE-2020-1362的漏洞如何处理

2.其次,我们需要一个 WalletX 的 IID,这个可以用 ida 直接看 WalletXFactory::CreateInstance() 这个函数。

CVE-2020-1362的漏洞如何处理

有了 WalletXFactory 的 CLSID 和 WalletX 的 IID,然后在客户端调用 CoCreateInstance(),WalletService 就会调用 CLSID 对应的工厂类 WalletXFactory 的 CreateInstance(), 创建出 IID 对应的 WalletX 对象,并返回对象给客户端。

然后按照上面的分析,使用 WalletX::CreateWalletItem() 创建出 WalletItem 对象,然后使用 WalletItem::CreateCustomProperty() 创建出 CustomProperty 对象。

对于上面的步骤有疑问的同学可以去学一学 Com 组件开发,尤其是进程外组件开发。

伪造虚表,覆盖附表指针

由于同一个动态库,在不同的进程,它的加载基址也是一样的,我们可以知道所有dll里面的函数的地址,所以可以获得伪造的虚表里面的函数地址。

那么把虚表放哪里呢?直接想到的是放堆上。

但如果我们继续分析,会发现,CustomProperty 类里面有一个 string 对象,并且可以使用 CustomProperty::SetLabel() 对 string 类进行修改,所以,我们可以通过修改 string 类里面的 beg 指针 和 end 指针,然后调用 CustomProperty::SetLabel() 做到任意地址写。

CVE-2020-1362的漏洞如何处理

有了任意地址写,我们选择把虚表放在 WalletService.dll 的 .data 节区,以避免放在堆上可能破坏堆上的数据导致程序崩溃。

控制程序流到 LoadLibrary 函数

使用伪造 vtable 并覆盖虚表指针的办法,我们可以通过调用虚函数控制 WalletService 的程序流到任意地址了。

那么怎么提权呢?在 windows 服务提权中,通常的办法是把程序流控制到可以执行 LoadLibrary() 等函数来加载一个由我们自己编写的动态链接库,因为在加载 dll 的时候会执行 dll 里面的 DllMain(),这个方法是最强大的也是最实用的。

这里使用漏洞提交者的方法,把虚表的某个地址覆盖成 dxgi.dll 里面的 ATL::CComObject/::`vector deleting destructor(),因为这个函数调用的 LoadLibraryExW() 会使用一个全局变量作为想要加载的 dll 的路径。

CVE-2020-1362的漏洞如何处理

我们可以通过上面的 SetLabel() 进行任意地址写,修改上图的全局变量 Src,使其指向我们自己实现的动态链接库的路径,然后调用对应的虚表函数,使程序流执行到 LoadLibrarExW() 即可。

实现一个动态链接库

在 DllMain() 里面写上我们希望以高权限执行代码,然后调用虚表里面对应的函数是 WalletService 的程序流运行到 LoadLibraryEx() 即可。

注意,因为 windows 服务运行在后台,所以需要在 DllMain() 里面使用命名管道或者 socket 等技术来进行回显或者交互,其次由于执行的是 LoadLibraryExW(),所以这里的 dll 路径要使用宽字符。

其它

在控制虚表函数程序流到 LoadLibraryExW() 时,需要绕过下面两个 check。

第一个是需要设置 this+0x80 这个地址的值,使得下面的 and 操作为 true。

CVE-2020-1362的漏洞如何处理

第二个是要调整 qword_C5E88 和 qword_C5E80 是下面的变量 v4 指向具有写权限的内存。

CVE-2020-1362的漏洞如何处理

漏洞利用结果

可以获得管理员权限

CVE-2020-1362的漏洞如何处理

补丁前后对比

可以看到,打了补丁之后,get 方法和 set 方法都对 a2 参数添加了边界检测。

CVE-2020-1362的漏洞如何处理

CVE-2020-1362的漏洞如何处理

以上就是CVE-2020-1362之如何处理漏洞,小编相信有部分知识点可能是我们日常工作会见到或用到的。希望你能通过这篇文章学到更多知识。更多详情敬请关注亿速云行业资讯频道。

原创文章,作者:254126420,如若转载,请注明出处:https://blog.ytso.com/229071.html

(0)
上一篇 2022年1月12日
下一篇 2022年1月12日

相关推荐

发表回复

登录后才能评论