10月25日那天,研究员@ msedgedev推特了一个链接,吸引了我的主意,因为当我点击它(在Chrome)时,Windows应用商店的应用程序打开了。也许它不会让你吃惊,但它让我吃了一惊!
据我所知,Chrome有这样的良好习惯,在打开外部程序之前会询问用户,但是在这种情况下,它没有警告而直接打开了。
这很不同并且引起了我的注意,因为我从未接受过在chrome中打开Windows Store的情况。有一些扩展和协议被自动打开了,但我从来没有准许过Windows Store。
这个缩短的Twitter连接被重定向到https://aka.ms/extensions-storecollection,之后再次被重定向到令人感兴趣的链接ms-windows-store://collection/?CollectionId=edgeExtensions。
这是一个我所不知道的协议,所以我马上尝试在多数协议驻留的地方:注册表。搜索”ms-windows-store”后立马返回我们在包ID里的字符串,这个包ID似乎是Windows Store的应用程序。
注意到我们也在一个叫”Windows.Protocol”的键位置。我看了看里面是否有其他应用程序,并且发现它们有大量自己的协议注册。这很好直接从浏览器打开了一个新的攻击面。但是先让我们按F3看看我们是否能够发现其他所匹配的。
看来the ms-windows-store:这个协议也接受搜索参数,所以我们可以直接从谷歌浏览器中打开我们自定义的搜索。事实上,Windows Store应用程序似乎在Edge引擎中被渲染成html是很有趣的因为我们也许会尝试XSS或者这个应用程序是本地的,发送大数据块看看会发生什么?
但是我们现在不会这样做,让我们回到注册表,按F3看看我们能找到什么。
这一点很有趣,因为它给了我们线索,关于假如它们以字符串URL:作为前缀,如何快速的找到更多的协议。让我们重置我们搜索到的”URL“,并且看看我们获得的。按Home键会带我们回到注册表的顶部,而且搜索”URL”会立即返回第一个匹配项”URL:about:blank“,确认一下我们是不是疯子。
再次按下F3,然后我们会发现bingnews协议,但是这次Chrome要求我们确认是否打开它。没问题,让我们试试在Edge上会发生什么。它开了!在注册表的下一个匹配项是计算器协议。这会有用吗?
真的!我确信这将会使漏洞编写者厌烦。他们现在会弹出什么应用程序呢?calc和notepad都可以在内存不破坏的状态下被打开,然后在powershell中cmd.exe是不被赞同的。微软移除了你们的乐趣。
这可能是枚举所有加载的协议,看到哪个程序接收参数后我们可以试着为它们注入代码(二进制或者纯javascript,取决于应用程序的编码和如何对待参数)。在这里有很多有趣的东西可以玩,如果我们继续寻找协议我们会发现大量的应用程序被打开(包括在我电脑上我所不知道的Candy Crush)。
通过按F3键几次,我学到了很多。例如,有一个microsoft-edge协议在新的标签页中加载URLs。这似乎并不重要,直到我们意识到html页面应该被受到限制。这个弹出窗口阻止程序会阻止我们打开20个microsoft-edge:http://www.google.com 标签页吗?
HTML5沙盒是什么呢?如果你不熟悉它,它只是一种用来限制网页使用沙箱iframe属性或沙箱的http头。举个例子,如果我们想渲染在iframe中的内容,确保它不会运行JavaScript(甚至打开新标签)我们就可以用这个标签:
渲染页面将被完全限制。本质上它只能渲染HTML/CSS,没有javascript或者权限访问像cookie的东西。事实上,如果我们使用沙箱的粒度和至少允许新窗口/标签,都应该继承沙箱的属性,并且从iframe中打开的连接都会被沙盒组织。然后使用microsoft-edge协议会完全绕过这个限制。
很高兴看到microsoft-edge协议允许我们绕过不同的限制。我没有走的更远,但你可以尝试一下。这是一个发现的旅程,记住一个孤单的鸣叫点燃了我发挥一点的动力(这个语句不好翻译),最后给我们的东西,真正值得更多的研究。
继续在注册表中按着F3中,会发现read协议引起了我的注意因为当阅读它的(javascript)的源代码时有潜力成为UXSS,但是Edge尝试一次又一次的崩溃。他崩溃太多次了。例如,设置iframe的location为”read:”会足够让浏览器所有标签页崩溃。想看吗?
好吧,我很好奇会发生什么。所以我往”read“协议中添加少量字节,然后挂起windbg观察是否崩溃在无效的数据。快速和简单的,没有啥特别的:
read:xncbmx,qwieiwqeiu;asjdiw!@#$%^&*read。
是的,我真的打了那些字。唯一找不到任何来自使http[s]崩溃的read:协议的方法。其他能够使浏览器崩溃。
所以让我们将Edge附加到windbg中,一个我用它来简单的杀死进程和子进程的快速下流的方法,重新打开并且附加到最近的使用EdgeHtml.dll的子进程。当然有更容易的方法,但是,是的我就是这样。打开命令行..
足够了。现在登录WinDbg并且附加到最近的使用Edgehtml的Edge进程列表。记住要在WinDbg中使用符号表。
一旦连接,只要在Windbg中按F5或者g[ENTER]让Edge保持运行。像是我现在的屏幕看起来那样。在我的页面左边部分是我测试东西的,右边部分,WinDbg附加的特殊Edge进程。
我们将使用window.open和read:协议搭配来代替iframe协议,因为它更舒适,想想看,有protocols/urls,无论怎么嵌入最终都可能会改变顶部位置。
如果以一个在iframe中的协议开始,我们自己的网页(顶部)将被卸下,失去我们刚刚键入的代码。我特定的测试页面保存了我输入的,并且如果浏览器崩溃,它很可能会被恢复。但是即使一切都保存,当我摆弄代码时这很可能会改变我测试页的URL。
左边屏幕可以很快地输入和执行Javascript代码,在右边我们准备了WIndbg来揭示我们这个崩溃的背后发生了什么。去吧,让我们运行javascript代码,砰!windbg坏了。
好吧,似乎是Edge知道会发生错误,因为它在一个叫”ReportFailure”的函数里面,对吗?来吧,我知道我们可以马上假设如果Edge在这里,它失败了有点”gracefully”。所以让我们来检查堆栈跟踪,看看我们从哪里来的。在WinDbg里输入”k”。
检查前两行,叫做ReportFailure的废话,你不认为Edge在这里是因为发生错误了?当然!让我们继续下去直到我们找到有意义的函数名。下一个是所谓的FailFast的废话,它也像是一个Edge知道错误的函数。但是我们想要找到的是时Edge不怎么愉快的代码,所以继续往下读。
下一个是名为_LoadRMHTML的无用的函数。这对我来说好多了,你不同意吗?事实上,它的名字让我觉得实在加载HTML一样。这在崩溃前破坏起来很有趣,所以为什么不在_LoadRMHTML上面几行设置一个断点呢?我们检查了堆栈跟踪,现在我们将要查看代码。首先让我们从那个点反汇编开始(函数+偏移),这很容易,在WinDbg里使用”ub”命令。
我们只关注名字,忽略一切,好吗?就像当我们试图找到一个mime类型错误的变化,我们将在这里推测,如果我们失败了,我们当然会继续深入下去。
但是有时候可以快速的看到调试器上揭露了很多东西。
我们知道Edge将会在这个判断段的最后一条指令崩溃(address 88106957, FailFast_Hr)。我们的目的是想知道我们为什么会在那个位置,到底是谁把我们送到那里。上面的代码的第一个指令似乎是调用一个复杂的名字的函数,这显然向我们揭示了大量的信息。
EdgeContent!_imp_SHCreateStreamOnFileEx
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!