进一步考察与UI相关的安全漏洞-下

340 篇文章 28 订阅
97 篇文章 5 订阅

在这里插入图片描述

提取私人信息

在介绍这个漏洞之前,让我们先了解一下占位符。众所周知,当我们与自动填充建议的用户界面互动时,如果将鼠标悬停在每个建议的条目上,都会发生一些有趣的事情。一个占位符值将被放置在我们试图填写的任何输入中。不过,这个占位符的值不应该允许网页随意访问:只有当用户明确选择了他们认为合适的条目后,浏览器才能读取自动填充数据。除此之外,占位符将被设置为所有具有匹配名称的输入。这意味着信用卡号码、地址、用户名、全名等都可以被提取出来。
在这里插入图片描述
我第一次意识到这个微妙的安全问题是因为这个漏洞(作者Mark Amery),它使用CSS/字体技巧来提取占位符数据。

现在回到这个漏洞本身。在试图找出我之前提到的问题(关于浏览器用户界面的伪造)的解决方案时,我偶然发现了一个有趣的行为。在研究问题(2)时,我在自动填充出现时切换了输入的类型,结果导致自动填充的用户界面一直存在。在这个例子中,我所做的不是改变输入类型,而是在第一个自动填充建议的用户界面出现时,让另一个自动填充用户界面出现:

1.用户与一个输入元素“A”互动

2.自动填充建议出现在输入元素“A”上

3.让自动填充建议出现在输入元素“B”上

4.从文档中删除输入元素“B”。

这样一来,最后剩下的只有输入元素“A”(包括来自自动填充建议的占位符值),而实际的建议用户界面并不存在。这对攻击者来说是好事,因为现在他们有充分的时间来提取数据,而以前,一旦自动填充建议消失,占位符值就会被删除。

下面是针对这一特定行为的小型PoC:

hit down arrow
< Br >< br >< form id="qsub" >
    < input id="qa" name=email placeholder="tester" type=text autocomplete=email >< /form >< form name="addr1.1" id="paymentForm" action="" method="post" >
    < input type="text" id="nameInput" name="name" autofocus >< /form >< script >
    nameInput.onkeydown = (e) = > {
        setTimeout((g) = > {
            qa.click();
            qa.focus();
            document.execCommand("insertText", false, "\u0000");
            qa.remove();
        }, 215);
    };
< /script >

我发现有两种方法可以提取这些数据并将其暴露在网页上,具体如下所示。

CVE-2021-21177:拖放占位符的值

一个有趣的函数是document.execCommand(‘selectAll’),其作用就是选择一个可编辑文档中的所有文本(我们可以通过contenteditable=true属性将所有元素设置为可编辑)。我注意到,当占位符停留在输入中时,如果执行这个命令,它将被选中。不够,由于我们无法自动复制和粘贴所选的值(没有剪贴板使用权限),所以,我使用了另一种方法:拖放!

所以,漏洞利用过程变为:

1.让用户点击页面

2.触发占位符持久性故障

3.诱使用户拖放页面的一部分

前面,我们已经介绍了完成任务(1)的方法,对于任务(2),我的方法是放置一个冒充iframe的图片,当用户试图使用不存在的滚动条向下滚动时,他们会在不知不觉中拖放他们的自动填充占位符值。

学习视频

基于拖放方法的原始PoC可以从这里找到。

在这个漏洞的相关报告中,最初的讨论似乎是为了防止拖放适用于占位符的值。实际上,已经有一个CSS可以做到这一点“ -webkit-user-select: none;”。但这还不够,主要问题是自动填充数据的持久性。

实际上,拖放已经是一种经常遇到的用户互动了,所以我想看看是否可以用一个更好的提取占位数据的方法来代替它。CSS和字体似乎根本不适用于占位符数据,所以,经过一番折腾,我最终发现了一个不同的方法。

CVE-2021-21177:使用window.find()提取占位符的值

这个函数一出现在我的脑海中,我就对它抱有很大的期望,结果确实如此。

众所周知,window.find()是一个非常有用的API,网页通过它对自身的内容进行搜索。假设我们有一个只有Hello World文本的文档,那么window.find(“Hello”)==true,window.find(“World”)==true,当然window.find(“doesntexist”)==false。

现在,完整的漏洞利用过程如下所示:

1.用户按下向下箭头

2.触发占位符故障

3.使用window.find提取占位符

这意味着,用户只需要在一个恶意的页面上按下方向键,我就能提取很多私人信息,其中最危险的是信用卡信息。

学习视频

原始PoC可以从这里找到。

CVE-2021-21216:隐藏自动填充建议的用户界面

我们知道,有一些UI应该始终显示给用户。其中,最受欢迎的是当我们进入全屏时出现的“You are now in fullscreen”的信息。由于进入全屏后,由于浏览器的头部会消失,因此,攻击者可以轻易通过伪造的信息来代替它来欺骗用户的。

我清楚地认识到,自动填充建议的用户界面和全屏用户界面一样重要。这是因为,在它从未显示出来的情况下,攻击者就可以让用户按下某些键盘按钮,并神不知鬼不觉地用自动填充值来填充隐藏的输入元素。关于这一点,我也是从一个漏洞利用代码中领悟到的:相应的PoC是一个游戏,以获得提取数据所需的用户手势。

使用一个类似于之前讨论的本地浏览器伪造的漏洞,我注意到:可以让自动填充建议的UI“出现”在用户屏幕之外。因此,换句话说,攻击者可以让用户看不到自动填充的用户界面,尽管该界面确实存在。

利用这个漏洞的方法非常简单:

1.诱骗用户访问恶意页面,设法让他们点击向下的箭头。

2.让隐藏的自动填充出现在屏幕外的某个地方,并选择第一个建议的结果,随后用占位符的值填充多个隐藏的输入。

3.让恶意页面诱导用户点击“Enter”键。

这样的话,就能让用户会在不知不觉中用自动填充数据填写一个隐藏的表单。

学习视频

原始PoC可以从这里找到。

自动挖掘UI安全漏洞

我开发了一个审查UI安全问题的工具,当然,这只能算是我学习Fuzzer工作原理的副产品,因为我在加入目前团队之前,从未真正使用过Fuzzer。这是一个非常简陋的工具,几乎都不能算作Fuzzer,之所以这么说,是因为Fuzzer通常能够发现内存问题。通常来说,浏览器的崩溃是出现安全问题的明确信号,但检测用户界面问题却没有这样明确的信号。所以,我为该工具设置了一个模式,以观察的用户可以手动选择某个东西看起来是不是很奇怪。

结果是,我既能发现内存问题的漏洞,也能发现与UI有关的设计缺陷。在继续之前,让我先介绍一下这个简单的自动测试器是如何工作的。

⚪使用普通Web内容可调用的UI列表及其相应的PoC,我创建了一个测试用例,以随机的顺序随机地显示这些用户界面。当测试用例运行时,我就进行某种导航操作:

    -在历史中导航

    -导航到一个新标签

    -打开一个弹出式窗口

    -在一个iframe中运行测试案例 + (可选)呈现两个按钮,看看是否出现某些奇怪的东西

    -如果出现:保存测试用例,并开始新的迭代

    -如果没有出现:直接开始新的迭代

这个实验确实找到了一些有趣的结果,具体如下所示。

smartscreen:FlyoutShower中的堆使用后释放漏洞(仅限Edge浏览器

这个内部漏洞是我最先发现的,该漏洞与Smartscreen有关。Smartscreen是Edge浏览器特有的一种功能,相当于谷歌的安全浏览功能:进行相应的检查,以确保下载的文件和访问的网站没有被标记为恶意的。

然而,它们的区别在于Edge处理被标记为潜在网络钓鱼网站的网站的具体方式。如果我们使用Edge浏览器导航到这种类型的网站,就会看到:
在这里插入图片描述

因此,这自然成为我实现自动化的UI调用命令之一。不久后,我发现Edge崩溃了,原来是浏览器进程崩了。

< html >
 
< body >
    < script >
        const blob = new Blob(
            [
                `< iframe id="qss"
    src="https://nav.smartscreen.msft.net/other/areyousure.html"
    target="_blank" rel="noreferrer noopener" >< /iframe >`,
            ], {
                type: "text/html"
            }
        );
        var test = window.open(window.URL.createObjectURL(blob));
        var blank = window.open("about:blank");
        setTimeout(function() {
            blank.close();
            test.close();
        }, 1400);
    < /script >< /body >
 
< /html >

之所以出现这种情况,是因为SmartScreen UI没有安全地处理指向WebContents对象的指针所致。在Chromium和Edge浏览器中,WebContents对象是直接与标签的寿命挂钩的。由于标签可以自行关闭,考虑到它们有一个开启器,我们可以滥用调用这个用户界面的自行关闭的标签,并可靠地令其崩溃。

使用这种技术,我们在Edge和上游浏览器中还发现了其他一些与UI相关的漏洞,这些漏洞要么还没有被完全修复,要么没有那么有趣,因此,这里就不介绍了。

CVE-2020-26953:绕过Firefox中的全屏UI

作为BVR团队的一员,我们被鼓励对其他浏览器中进行相关的安全测试。虽然Chromium的代码库与Firefox不同,但两者可能具有相同的设计缺陷。这样做的另一个好处是:可以了解Firefox是如何处理某种行为的,并从中获得启示。

在一个周末,我决定修改自己的工具,看看对Firefox的效果如何,结果发现一个UI设计缺陷不断出现,但并不稳定。这个漏洞会导致浏览器进入全屏时,通知用户进入全屏的UI完全不可见。

最初报告的PoC中有一个谜团:似乎只有在建立websocket连接并失败的情况下,它才会起作用。不仅如此,你还必须不断地把它改变到另一个无效的位置(假设是为了绕过任何缓存)。

原始PoC可以从这里找到。

一位Mozilla员工(Gijs)指出,PoC中神秘的websocket部分可以用卸载处理程序中的console.log()调用代替。这个变化对我来说是个谜,console.log与全屏UI显示与否有什么关系?如果您想了解其中的缘由,请参阅Bugzilla的相关报告。

按照上述报告给出的建议,我用卸载处理程序替换了websocket连接,还添加了一个blob导航,而不是导航到同一个页面,最终得到了一个更可靠的PoC。

关于修订版的PoC,可以从这里找到。

学习视频

对我来说,这具有很重要的意义,因为这个漏洞是以半自动的方式发现的,从而让我看到了自动挖掘逻辑/设计漏洞的潜力。

与标签相关的安全漏洞

标签是用户界面的一部分,可以说是浏览器中比较复杂的用户界面之一。因此,当我注意到标签页中的一个安全漏洞被修复时,我觉得这个代码中一定还有更多的漏洞尚未发现。例如,通过标签,我们可以将它们添加到组中,进行拖放,将一个窗口中的标签转换成另一个窗口中的标签,反之亦然,等等。正如之前提到的,标签是可以自行关闭(如果它们有一个开启器的话)的,这意味着网页内容可以控制标签的寿命。

我所做的事情,只是创建了一个脚本来打开标签,而这些标签会自行关闭;然后,在这个连续的打开和关闭标签的过程中,对标签的不同功能进行了相应的处理。

以下安全漏洞已被上报并随后得到了修复。

CVE-2021-21197:TabStrip的堆缓冲区溢出

这里被利用的主要标签功能是将标签拖放到自己的窗口中的能力。当一个标签在拖动另一个标签到自己的窗口时关闭,就会发生崩溃。

相关的PoC可以从这里找到。

CVE-2021-21192:标签组中的堆缓冲区溢出漏洞

这里再次利用了拖放技术,只不过,这次拖动的不是一个普通的标签,而是在标签关闭时将标签组拖出并拖入主窗口。

相关的PoC可以从这里找到。

CVE-2021-21154:页签列(Tab Strip)中的堆缓冲区溢出

您猜对没错:在一些标签关闭时拖动一组标签会导致这种崩溃。在这个例子中,用到了通过按住shift键+选择范围来选择标签的主要标签功能。

相关的PoC可以从这里找到。

CVE-2021-21180:标签搜索功能中UAF漏洞

该漏洞与一个相对较新的功能有关,该功能使用户能够搜索自己的活动标签。我发现,这个新的标签搜索用户界面实际上就是一个位于chrome://tab-search.top-chrome/的WebUI。
在这里插入图片描述
在这个标签搜索用户界面中,我们可以关闭标签,但是,当我们在自己的窗口中打开“chrome://tab-search.top-chrome/”,然后试图使用标签搜索用户界面的关闭机制来关闭自己时,就会触发UAF漏洞。

小结

我们希望本文能够帮助读者了解UI安全的相关知识,正如您所看到的,这并不是一个单纯的逻辑/设计问题,因为有时还会掺杂内存损坏问题。另外,UI安全的审计工作,是很难实现自动化和模糊处理的,即使是围绕着标签的内存问题也需要进行拖放操作,但是几乎没有Fuzzer会模拟这些操作。由此看起来,UI安全是自动化漏洞挖掘领域中的一块处女地,一旦获得突破,将曝出更多的安全漏洞。

领取网络安全相关的学习资料

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值