0x00写在最前
这篇文章写于2018年9月,时至今日,微软的Edge已经采用chromium内核。经过测试,以下讲解的签名问题也不存在(对于注入的DLL已经没有强制签名策略),谨以此文章记录之前做过的调查。
0x01 前言
Edge作为微软为Win10推出的安全浏览器,其中包含了很多安全特性。从Windows 10 TH2开始新增了三项针对DLL加载的安全特性,其中一项是禁止特定进程加载未签名的DLL(SignatureMitigationOptIn),也就是说使用传统的注入方式(如远程线程注入)向Edge浏览器里注入未签名的DLL已经行不通了!但在最近的课题研究中,我发现可以注入未签名的DLL到MicrosoftEdge.exe以及MircosoftEdgeCP.exe进程内,这包括最新的Win10 1803、1709以及1703等多个平台。下面就这个发现做一些介绍。
0x02 进程签名检查方法
从Win8.1开始推出的SDK中有一个结构体,可以用来查看每一个进程的签名验证机制,结构体如下所示:
typedef struct _PROCESS_MITIGATION_BINARY_SIGNATURE_POLICY {
union {
DWORD Flags;
struct {
DWORD MicrosoftSignedOnly : 1;
DWORD StoreSignedOnly : 1;
DWORD MitigationOptIn : 1;
DWORD AuditMicrosoftSignedOnly : 1;
DWORD AuditStoreSignedOnly : 1;
DWORD ReservedFlags : 27;
} DUMMYSTRUCTNAME;
} DUMMYUNIONNAME;
} PROCESS_MITIGATION_BINARY_SIGNATURE_POLICY, *PPROCESS_MITIGATION_BINARY_SIGNATURE_POLICY;
该结构体截取自MSDN,其中我们需要关注的两个值分别是StoreSignedOnly和MitigationOptIn,它们的意义如下:
- StoreSignedOnly位为1代表的意思是阻止进程加载没有Windows Store签名的映像文件。
- MitigationOptIn位为1代表的意思是阻止进程加载没有微软,Windows Store以及WHQL签名的映像文件。
前面提到的一个安全特性(禁止加载未签名的DLL)就在这个结构体里面。利用上面的结构体以及公开的API GetProcessMitigationPolicy我们可以写个程序用来验证某个进程的签名验证机制。
对MicrosoftEdge.exe进程的签名验证机制查看结果如下图1所示:
图 1
我们可以看到 StoreSignedOnly和MitigationOptIn 的值都是1,这意味着没有6(Store)级签名的DLL是不能够注入到MicrosoftEdge.exe进程内的。
下面我们使用未签名的DLL(图2)注入MicrosoftEdge.exe进程来验证一下,结果如图3所示:
图2
图3
很明显结果是失败的,我们确实无法通过远程注入的方式将未签名的DLL注入到MicrosoftEdge.exe进程内!
0x03 绕过Edge签名验证机制
在一台干净的Win10机器上,导入我事先已经准备好的注册表文件,重新启动MicrosoftEdge.exe程序,然后查看MicrosoftEdge.exe进程的签名策略,结果如图4所示:
图4
由图可以惊喜的发现 StoreSignedOnly 和MitigationOptIn 的值均是0,也就是MicrosoftEdge.exe进程的签名验证机制被关闭了。那么如果我们再次注入之前未签名的DLL是否能够成功呢?
再次执行注入命令,结果如下图5所示:
图5
我们看到结果是成功的,为了万无一失我们使用Process Explorer来看一下我们的DLL是否在MicrosoftEdge.exe进程内,结果如图6所示:
图6
确实是成功注入未签名的DLL到MicrosoftEdge.exe里面了!
那么成功的点在什么地方呢?在上面所做的操作中我们只是多了一步导入注册表文件的操作,是的,成功的点就在这里,下面我们介绍注册表的内容(图7)。
图7
这3个注册表键是IME使用的,也就是在安装任何一个第三方输入法的时候,都会产生这3个注册表键,其中GUID值 {E7EA138E-69F8-11D7-A6EA-00065B84435C}是任意的。
在研究课题(如何更好地控制Edge的UI)的过程中,发现外围(Edge进程外部)控制始终是有瑕疵的,要么是效率问题,要么是控制不当存在崩溃现象。所以想到能够在内部控制是最理想的。
在经过一番调查后,联想到输入法是否可以实现Edge注入呢?毕竟输入法的某些DLL是注入到使用它的进程内的。
由此我发现了通过这3个注册表键,可以关闭MicrosoftEdge.exe及其保护进程的签名验证机制!那这会不会影响其他的进程(主要是Win10系统内置的进程)呢?
图8
从图8可以看出导入注册表后,SkypeApp.exe进程的签名策略(StoreSignedOnly位为1)并未发生改变。后经过测试发现其他进程的签名策略也没有受影响,可见以上3个注册表键影响的只是(暂未发现其他)Edge浏览器进程。至于为什么会影响Edge浏览器,并且Edge的签名策略是如何关闭的,我不得而知,至少从安全层面上来说,这应该属于Edge的"安全漏洞"吧。
0x04 总结
在与微软的数封邮件沟通之后,被对方告知是特意为第三方输入法而做的“设计”,并不打算对此进行任何修复。对于此说法个人觉得有点牵强,原因有以下几点:
- 第三方输入法是常见并被用户常常使用的软件,因为安装第三方输入法而导致Edge浏览器可以被未签名的DLL注入是存在风险的!
- 即使这是为第三方输入法而做的特别设计,微软也是不需要把StoreSignedOnly位关闭的,在前面提到SkypeApp.exe进程内可以正常使用第三方输入法,而该进程的StoreSignedOnly位始终是1(这要求所注入的DLL签名级别在6级)。那么对于Edge浏览器而言为了第三方输入法连最基本的Store签名级别也关闭了,这种设计岂不是自相矛盾,设计不合理?
0x05 附录
Microsoft Edge binary injection mitigation overview – Where security meets innovation
Protecting Microsoft Edge against binary injection - Microsoft Edge Blog
http://blogs.360.cn/post/poc_edgesandboxbypass_win10th2_new_security_features.html