原文:brokenbrowser
原作者:Manuel Caballero
译:Holic (知道创宇404安全实验室)

攻击者喜欢收集受害者的指纹特征。我们之前已经见识了两种技术,坏人可以通过检测特定文件(来逃避分析人员),甚至可以获取特定关联应用的名称。Microsoft 修补了诸如此类的特性,而今天我们会看到如何在 Edge 上检测安装的浏览器扩展程序。

另外,如此精彩的研究和 PoC 来自于 Inria Privatics, Gábor GulyásNataliia Bielova

安装扩展程序

我在扩展应用商店随意选了 AdGuard 广告屏蔽插件。两次点击之后,它已经安装并自动打开感谢页面,而且在开始研究之前给了我灵感。下面一探究竟。

这一切从 URL 开始。如果我们可以在 iframe 中加载之,并检测其存在 (onload/onreadystatechange/不胜枚举),即区分出它与默认的 Edge 404 页面, 我们基本就完成任务了。但很不幸,iframe 拒绝加载 ms-browser-extension: 协议。

<iframe src="ms-browser-extension://EdgeExtension_AdguardAdguardAdBlocker_m055xr0c82818/pages/thankyou.html"></iframe>  

OK。那么用 window.open 又如何?至少可以用脚本打开这些 URL 吧?试一下便知!

win = window.open("ms-browser-extension://EdgeExtension_AdguardAdguardAdBlocker_m055xr0c82818/pages/thankyou.html");  
// returns null when the URL is ms-browser-extension: (not useful for us)

打开了!但是对我们并不重要,因为不管安没安装插件, window.open() 返回的都是 null 而不是 window 对象。换而言之,我们试图使用扩展程序协议 ms-browser-extension 打开新窗口时:它总是返回 null 的。所以即使能打开新窗口(这是个很丑的解决方案),我们也不能检验内容是否得以加载。

来自扩展程序的图片呢?或许图像暴露在主页的时候,使用 onload/onerror 事件,我们可以检测到扩展程序是否安装。我们先看看扩展文件在我们文件系统中的位置。

查找扩展程序相关文件

启动 Process Monitor,过滤 MicrosoftEdgeCP.exe。关闭 Edge,并通过复制到地址栏的方法打开 AdGuard 感谢页面,Bang!我们马上就能在 Process Monitor 中看到文件所在的位置。记住,我们的目标是从这个扩展程序中找出一个图像,看看能否加载它,并通过 onload/onerror 检测其存在。

看来扩展程序文件在这里:

C:\Program Files\WindowsApps\Adguard.AdguardAdBlocker_2.5.18.0_neutral__m055xr0c82818\Extension\Pages  

转到上层(父)文件夹,我们可以看到,就像 Chrome 和 Firefox,其中有个 manifest.json,允许某些资源被任何网站加载。

"web_accessible_resources": [
   "elemhidehit.png", 
   "lib/content-script/assistant/css/assistant.css", 
   "lib/content-script/assistant/i/close.svg", 
   "lib/content-script/assistant/i/logo.svg", // Let's use this one!
   "lib/content-script/assistant/i/logo-white.svg"
]

其中大多是图像,我们用脚本试着加载 logo.svg。如果 onload 得以触发,说明扩展程序已安装,否则说明用户没有该扩展名。

var img = new Image();

img.onload = function(){alert("Extension Detected")}  
img.onerror = function(){alert("Extension NOT Detected")}

img.src = "ms-browser-extension://EdgeExtension_AdguardAdguardAdBlocker_m055xr0c82818/lib/content-script/assistant/i/logo.svg";  

而我并不为之所动。我们基本上没有用到什么新的东西,就像其他检测方法一样(对应 Chrome/FF),我们依赖于特定扩展程序的配合,使资源得以加载。如果一个扩展程序在 manifest 中没有 web 可访问资源 的话,我们如何检测呢?

插件检测的通用方法

在各种技巧玩了几分钟,试着加载不可访问的资源后,我决定厂商用类似于 Soroush 的 IE DTD 技巧。试着使用 Microsoft XMLDOM 对象加载资源,并根据错误号就能知道文件是否存在。在 Edge 上没有 XMLDOM 对象,但是我们可以做一些就像常规 XMLHTTPRequest 做的事情。

如果尝试打开资源而且扩展程序存在的话,它会抛出拒绝访问的错误,否则是文件找不到的错误。实际上,为了纪念 Soroush 的神奇发现,我们尽量做的和他一样优雅,并使用接受到的错误号进行判断。一段代码值千言,请看下面:

var extension = "ms-browser-extension://EdgeExtension_AdguardAdguardAdBlocker_m055xr0c82818";  
try  
{
     var xhr = new XMLHttpRequest();
     xhr.open("GET", extension, false);
     xhr.send(null);
}
catch(e)  
{
     if (e.number == -2147024891) alert("Exists");
     else alert("Does not exist");
}

现在看起来不错了,感谢 Soroush 的精彩思路!

另外,你有没有注意到我们使用的URL甚至没有指向特定资源?这个 xml技巧与目录名有关,甚至不需要指向扩展程序的特定资源,所以现在有插件的 ID 就足以进行检测了。如果要构建一个通用探针来查找已经安装的扩展程序,就像我们在 Chrome 和 Firefox 中见过的这种,首先要再 Edge 上安装所以的扩展程序,并记下所有的 ID。这颇为简单,只需要安装扩展程序,加载空白页,按下 F12,就足以展现插件的 ID。我已经安装的其中的几个,在下方清晰可见。

有了这些名称,现在可以为 Microsoft Edge 创建一个通用扩展检测器了。只有已禁用的扩展程序才不会在开发人员工具中加载,不过我们仍可以在注册表中找到它们。

HKEY_CLASSES_ROOT\Local Settings\Software\Microsoft\Windows\CurrentVersion\AppContainer\Storage\microsoft.microsoftedge_8wekyb3d8bbwe\MicrosoftEdge\Extensions  

有一点值得注意,即使用户已经禁用扩展程序,我们的检测方法依然有效。以下便是用上述方法检测20个扩展的PoC。

[ PoC – Edge Detect Installed Extensions ]

Have a nice day! 🙂