首页
社区
课程
招聘
[翻译]HTML5沙盒绕过
2017-3-7 21:50 6166

[翻译]HTML5沙盒绕过

2017-3-7 21:50
6166

滥用协议加载本地文件,绕过HTML5沙盒,打开弹出窗口和更多

1025日那天,研究员@ 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上会发生什么。它开了!在注册表的下一个匹配项是计算器协议。这会有用吗?

真的!我确信这将会使漏洞编写者厌烦。他们现在会弹出什么应用程序呢?calcnotepad都可以在内存不破坏的状态下被打开,然后在powershellcmd.exe是不被赞同的。微软移除了你们的乐趣。

这可能是枚举所有加载的协议,看到哪个程序接收参数后我们可以试着为它们注入代码(二进制或者纯javascript,取决于应用程序的编码和如何对待参数)。在这里有很多有趣的东西可以玩,如果我们继续寻找协议我们会发现大量的应用程序被打开(包括在我电脑上我所不知道的Candy Crush)

通过按F3键几次,我学到了很多。例如,有一个microsoft-edge协议在新的标签页中加载URLs。这似乎并不重要,直到我们意识到html页面应该被受到限制。这个弹出窗口阻止程序会阻止我们打开20microsoft-edge:http://www.google.com 标签页吗?

   


[ PoC – Open popUps on MS Edge ]


HTML5沙盒是什么呢?如果你不熟悉它,它只是一种用来限制网页使用沙箱iframe属性或沙箱的http头。举个例子,如果我们想渲染在iframe中的内容,确保它不会运行JavaScript(甚至打开新标签)我们就可以用这个标签:

<iframe src=”sandboxed.html” sandbox></iframe>

  渲染页面将被完全限制。本质上它只能渲染HTML/CSS,没有javascript或者权限访问像cookie的东西。事实上,如果我们使用沙箱的粒度和至少允许新窗口/标签,都应该继承沙箱的属性,并且从iframe中打开的连接都会被沙盒组织。然后使用microsoft-edge协议会完全绕过这个限制。


[ PoC – Bypass HTML5 Sandbox on MS Edge ]


很高兴看到microsoft-edge协议允许我们绕过不同的限制。我没有走的更远,但你可以尝试一下。这是一个发现的旅程,记住一个孤单的鸣叫点燃了我发挥一点的动力(这个语句不好翻译),最后给我们的东西,真正值得更多的研究。

继续在注册表中按着F3中,会发现read协议引起了我的注意因为当阅读它的(javascript)的源代码时有潜力成为UXSS,但是Edge尝试一次又一次的崩溃。他崩溃太多次了。例如,设置iframelocation”read:”会足够让浏览器所有标签页崩溃。想看吗?

[ PoC – Crash on MS Edge ]

好吧,我很好奇会发生什么。所以我往”read“协议中添加少量字节,然后挂起windbg观察是否崩溃在无效的数据。快速和简单的,没有啥特别的:

read:xncbmx,qwieiwqeiu;asjdiw!@#$%^&*read

   是的,我真的打了那些字。唯一找不到任何来自使http[s]崩溃的read:协议的方法。其他能够使浏览器崩溃。

所以让我们将Edge附加到windbg中,一个我用它来简单的杀死进程和子进程的快速下流的方法,重新打开并且附加到最近的使用EdgeHtml.dll的子进程。当然有更容易的方法,但是,是的我就是这样。打开命令行..

taskkill /f /t /im MicrosoftEdge.exe
 
** Open Edge and load the webpage but make sure it doesn't crash yet **
 
tasklist /m EdgeHtml.dll


足够了。现在登录WinDbg并且附加到最近的使用EdgehtmlEdge进程列表。记住要在WinDbg中使用符号表。

 

一旦连接,只要在Windbg中按F5或者g[ENTER]Edge保持运行。像是我现在的屏幕看起来那样。在我的页面左边部分是我测试东西的,右边部分,WinDbg附加的特殊Edge进程。

  我们将使用window.openread:协议搭配来代替iframe协议,因为它更舒适,想想看,有protocols/urls,无论怎么嵌入最终都可能会改变顶部位置。

如果以一个在iframe中的协议开始,我们自己的网页(顶部)将被卸下,失去我们刚刚键入的代码。我特定的测试页面保存了我输入的,并且如果浏览器崩溃,它很可能会被恢复。但是即使一切都保存,当我摆弄代码时这很可能会改变我测试页的URL

左边屏幕可以很快地输入和执行Javascript代码,在右边我们准备了WIndbg来揭示我们这个崩溃的背后发生了什么。去吧,让我们运行javascript代码,砰!windbg坏了。


ModLoad: ce960000 ce996000   C:\Windows\SYSTEM32\XmlLite.dll
ModLoad: c4110000 c4161000   C:\Windows\System32\OneCoreCommonProxyStub.dll
ModLoad: d6a20000 d6ab8000 C:\Windows\SYSTEM32\sxs.dll
 
(2c90.33f0): Security check failure or stack buffer   overrun - code c0000409 (!!! second chance !!!)
EdgeContent!wil::details::ReportFailure+0x120:
84347de0 cd29 int 29h

好吧,似乎是Edge知道会发生错误,因为它在一个叫”ReportFailure”的函数里面,对吗?来吧,我知道我们可以马上假设如果Edge在这里,它失败了有点”gracefully”。所以让我们来检查堆栈跟踪,看看我们从哪里来的。在WinDbg里输入”k”

0:030> k
# Child-SP RetAddr Call Site
00 af248b30 88087f80 EdgeContent!wil::details::ReportFailure+0x120
01 af24a070 880659a5 EdgeContent!wil::details::ReportFailure_Hr+0x44
02 af24a0d0 8810695c EdgeContent!wil::details::in1diag3::FailFast_Hr+0x29
03 af24a120 88101bcb EdgeContent!CReadingModeViewerEdge::_LoadRMHTML+0x7c
04 af24a170 880da669 EdgeContent!CReadingModeViewer::Load+0x6b
05 af24a1b0 880da5ab EdgeContent!CBrowserTab::_ReadingModeViewerLoadViaPersistMoniker+0x85
06 af24a200 880da882 EdgeContent!CBrowserTab::_ReadingModeViewerLoad+0x3f
07 af24a240 880da278 EdgeContent!CBrowserTab::_ShowReadingModeViewer+0xb2
08 af24a280 88079a9e EdgeContent!CBrowserTab::_EnterReadingMode+0x224
09 af24a320 d9e4b1d9 EdgeContent!BrowserTelemetry::Instance::2::dynamic
0a af24a3c0 8810053e shlwapi!IUnknown_Exec+0x79
0b af24a440 880fee33 EdgeContent!CReadingModeController::_NavigateToUrl+0x52
0c af24a4a0 88074f98 EdgeContent!CReadingModeController::Open+0x1d3
0d af24a500 b07df508 EdgeContent!BrowserTelemetry::Instance'::2::dynamic
0e af24a5d0 b0768c47 edgehtml!FireEvent_BeforeNavigate+0x118

检查前两行,叫做ReportFailure的废话,你不认为Edge在这里是因为发生错误了?当然!让我们继续下去直到我们找到有意义的函数名。下一个是所谓的FailFast的废话,它也像是一个Edge知道错误的函数。但是我们想要找到的是时Edge不怎么愉快的代码,所以继续往下读。

下一个是名为_LoadRMHTML的无用的函数。这对我来说好多了,你不同意吗?事实上,它的名字让我觉得实在加载HTML一样。这在崩溃前破坏起来很有趣,所以为什么不在_LoadRMHTML上面几行设置一个断点呢?我们检查了堆栈跟踪,现在我们将要查看代码。首先让我们从那个点反汇编开始(函数+偏移),这很容易,在WinDbg里使用”ub”命令。

0:030> ub EdgeContent!CReadingModeViewerEdge::_LoadRMHTML+0x7c
EdgeContent!CReadingModeViewerEdge::_LoadRMHTML+0x5a:
8810693a call qword ptr [EdgeContent!_imp_SHCreateStreamOnFileEx (882562a8)]
88106940 test eax,eax
88106942 jns EdgeContent!CReadingModeViewerEdge::_LoadRMHTML+0x7d (8810695d)
88106944 mov rcx,qword ptr [rbp+18h]
88106948 lea r8,[EdgeContent!`string (88261320)]
8810694f mov r9d,eax
88106952 mov edx,1Fh
88106957 call EdgeContent!wil::details::in1diag3::FailFast_Hr(8806597c)

   我们只关注名字,忽略一切,好吗?就像当我们试图找到一个mime类型错误的变化,我们将在这里推测,如果我们失败了,我们当然会继续深入下去。

  但是有时候可以快速的看到调试器上揭露了很多东西。

我们知道Edge将会在这个判断段的最后一条指令崩溃(address 88106957, FailFast_Hr)。我们的目的是想知道我们为什么会在那个位置,到底是谁把我们送到那里。上面的代码的第一个指令似乎是调用一个复杂的名字的函数,这显然向我们揭示了大量的信息。

 

EdgeContent!_imp_SHCreateStreamOnFileEx

 

  在位于!前面的指令的第一部分是模块(exedll,等),在这种情况下,它是EdgeContent并且我们甚至不关心它的扩展 ,它只是代码。在!后是一个有趣的名字_imp_SHCreateStreamOnFileEx似乎是创建文件流的一个函数。你同意吗?事实上,_imp_部分让我觉得,也许这是一个加载不同二进制库的入口函数。让我们gooogle看看是否会发现有趣的东西。

  相当不错。我们搜索点击后第一个结果是确切的名称。

   

Ok。此函数接受的第一个参数是指向制定文件名的空终止字符串的指针。有趣!如果这段代码被执行,那么,它应该接受一个指向文件名作为第一个参数。但是我们怎样才能看到第一个参数呢?这很容易,我们正在使用winx64,调用约定/参数传递告诉我们开始的4个参数是RCXRDXR8R9”(讲整数/指针).这意味着第一个参数第一个参数(一个文件名的指针)将被装入寄存器RCX

有了这些信息,我们可以在Edge调用那个函数之前设置断点,观察RCX在那个时刻是什么。让我们重新启动吧因为此时已经有点晚了。Edge早已崩溃了。请重新做上面描述的步骤(kill Edge, open it, load the page, find the process and attach)

这次,我们将这事一个断点代替运行(F5)进程。当我们执行我们的“军装”命令,WinDbg透露了确切的偏移。

 

0:030> ub EdgeContent!CReadingModeViewerEdge::_LoadRMHTML+0x7c
EdgeContent!CReadingModeViewerEdge::_LoadRMHTML+0x5a:
8810693a ff1568f91400 call qword ptr [EdgeContent!_imp_SHCreateStreamOnFileEx (882562a8)]
88106940 85c0 test eax,eax

所以断点应该EdgeContent!CReadingModeViewerEdge::_LoadRMHTML+0x5a处被断下。我们输入”bp”和函数名+偏移量,回车,然后”g”Edge运行起来。

0:029> bp EdgeContent!CReadingModeViewerEdge::_LoadRMHTML+0x5a
0:029> g


这很令人兴奋。我们希望看到在shcreatestreamonfileex执行前RCX指向右边的文件名(或字符串)。让我们运行代码,感受破坏吧。好吧我感觉断点连接着我的童年。让我们运行JavaScript代码,bangWinDbg停在那儿了。

 

Breakpoint 0 hit
EdgeContent!CReadingModeViewerEdge::_LoadRMHTML+0x5a:
8820693a ff1568f91400 call qword ptr [EdgeContent!_imp_SHCreateStreamOnFileEx (883562a8)]


 

太好了,现在我们可以检查RCX指向的内容。为了做到这一点,我们将使用”D”命令(显示内存)@和寄存器名,就像这样:

0:030> d @rcx
02fac908 71 00 77 00 69 00 65 00-69 00 77 00 71 00 65 00 q.w.i.e.i.w.q.e.
02fac918 69 00 75 00 3b 00 61 00-73 00 6a 00 64 00 69 00 i.u.;.a.s.j.d.i.
02fac928 77 00 21 00 40 00 23 00-24 00 25 00 5e 00 26 00 w.!.@.#.$.%.^.&.
02fac938 2a 00 00 00 00 00 08 00-60 9e f8 02 db 01 00 00 *.......`.......
02fac948 10 a9 70 02 db 01 00 00-01 00 00 00 00 00 00 00 ..p.............
02fac958 05 00 00 00 00 00 00 00-00 00 00 00 19 6c 01 00 .............l..
02fac968 44 14 00 37 62 de 77 46-9d 68 27 f3 e0 92 00 00 D..7b.wF.h'.....
02fac978 00 00 00 00 00 00 08 00-00 00 00 00 00 00 00 00 ................

  这对于我的眼睛来说不是很好,但是在第一行的右边,我看到了看起来像是一个unicode字符串的东西。让我们再次以Unicode方式显示内容(du)


0:030> du @rcx
02fac908 "qwieiwqeiu;asjdiw!@#$%^&*"

 

很好1这个字符串迷住我了!看看这个Javascript代码就是我们刚刚跑过的。

看来,传递给这个函数的参数是我们在逗号后面输入的任何东西。有了这些知识,加上知道它正在期望一个文件,我们可以在我的驱动器尝试一个完整的路径。因为EdgeAppContainer里面运行着,我们将尝试访问一个文件。比如来自windows/system32目录的一些文件。

 

read:,c:\windows\system32\drivers\etc\hosts

 

我们也会删除逗号之前似乎无关的垃圾(尽管它的研究价值更多!) 让我们快速detach,重新运行Edge,运行我们的新代码。

 

url = "read:,c:\\windows\\system32\\drivers\\etc\\hosts";
 
w = window.open(url, "", "width=300,height=300");


 

正如预期的那样,本地文件在新窗口加载中的没有崩溃。

[ PoC – Open hosts on MS Edge ]

漏洞猎人啊,我在这里就停下来了,但我相信所有这些东西值得更多的研究,这取决于你是否有乐趣:

a)  通过查询字符串枚举所有加载的协议和攻击那些应用程序。

b)把玩microsoft-edge:可以绕过HTML5的沙盒,弹出窗口阻止程序,谁也不知道的另外的东西。

c)继续研究read:协议。我们找到了阻止它崩溃的一种方法但要记得有一个函数SHCreateStreamOnFileEx,我们期望影响到的东西。值得更多尝试。同时,我们可以继续争论是否使用逗号分割参数,如果调试二进制文件对于你来说很入料,那么你还可以试试XSS的阅读观。

我希望你能够找到大量的漏洞!如果你有问题,可以在@magicmac2000告诉我。

祝您一天愉快!

 

 

Reported to MSRC on 2016-10-26
From: Manuel Caballero
Sent: 2016/10/26
To: secure@microsoft.com
Subject: MS Edge HTML5 Sandbox Escapes
 
Hey fellows! Here’s an Edge Sandbox escape. http://www.cracking.com.ar/demos/sandboxedge
 
IMO, it’s a bad idea to let all those protocols run straight out of the box because the attack surface of Edge ends up being huge, but hey, it’s your browser! =)
 
Cheers!
Manuel.


 感觉应该能够学的挺多东西的,有木有给个windows10的iso下载连接地址。

 

 


[培训]内核驱动高级班,冲击BAT一流互联网大厂工 作,每周日13:00-18:00直播授课

收藏
点赞1
打赏
分享
最新回复 (2)
雪    币: 1746
活跃值: (227)
能力值: ( LV9,RANK:210 )
在线值:
发帖
回帖
粉丝
hackyzh 3 2017-3-7 21:53
2
0
原文参考连接:http://www.brokenbrowser.com/abusing-of-protocols/
雪    币: 5697
活跃值: (984)
能力值: ( LV9,RANK:400 )
在线值:
发帖
回帖
粉丝
玉涵 5 2018-4-23 09:33
3
0
感谢分享
游客
登录 | 注册 方可回帖
返回