Outlook可能算是目前比较流行的邮箱APP之一了,近期,CyberArk公司研究团队就发现了Outlook安卓版本APP的一个跨站漏洞(XSS)- CVE-2019-1105,利用该漏洞可以在E-mail电子邮件中实现任意 JavaScript 代码执行。本文我们就一起来看看该漏洞的具体成因。
大概的漏洞利用是这样的,如果我们向受害者邮箱发送包含Payload的邮件,当受害者打开邮件之后,就会跳出形如以下的XSS窗口:
我们可以把Outlook for Andriod的APK程序进行一个逆向分析,在assets资源目录下,我们发现了一个名为“emailRenderer-android.js”的JavaScript文件,顾名思义,它是一个把邮件消息加载显示给用户查看的。在该JavaScript文件中,存在一个名为“layout”的函数,在其中它调用了名为“_linkifyPhoneNumbers”的方法。如下:
在这里,我们来谈谈Linkify类,android.text.util.Linkify是一个辅助类,通过RegEx样式匹配,自动地在TextView类(和继承的类)中创建超链接。符合特定的RegEx样式的文本会被转变成可点击的超链接,这些超链接隐式地调用startActivity(new Intent(Intent.ACTION_VIEW, uri)),符合的文本会作为目标URI。你可以指定任意的字符串样式为链接。为了方便,Linkify类提供了4种预置的通用内容类型(电子邮箱地址、电话号码、web地址和住所地址)。
_linkifyPhoneNumbers方法的第一步是创建一个正则表达式对象,其中包含可能的手机号码模式,如下:
上图可示,与_linkifyPhoneNumbers正则表达式匹配的是一个7位数序列。之后,linkifyPhoneNumbers函数定义了第二个内层函数 “replacer”,该函数首先会去解析手机号码,如下:
如果解析成功,内层函数 “replacer”会把号码数字转化生成一个对应链接,然后计数器加1并返回数据:
回到_linkifyPhoneNumbers的外层函数中来,这时_linkifyPhoneNumbers会测试它定义的正则表达式和消息中每个HTML元素之间是否匹配,如果匹配成功,外层函数会调用内层函数replacer并返回数据,这样,就能用一些未转义的文本内容来替代消息内容了,漏洞也就如此产生了:
这样一来,把数字转化为链接之后,从内容上来说就不存在转义了,攻击者可以发送包含匹配正则表达式的一串数字, replacer函数中的计数器加1,然后替代掉原先的消息内容,也就是说,把用正则表达式电话号码的消息换成一些不可转义的XSS Payload就可以了。
HTML 5 API 具备了多种新的功能特性,所以,我们可以利用它来对上述漏洞进行一个利用测试。这里,我们来看看Navigator的界面功能,它代表了一种当前状态和用户端身份信息,可以使用脚本进行查询并注册成为某种操作。我们以Navigator.vibrate()震动方法为例说明,当恶意邮件被受害者打开之后,该方法就会使手机设备产生震动脉冲。可用以下Payload来结合利用:
但只是产生震动还是不够的,我们可以在其中插入一段远程脚本,成为:
我们可用XMLHttpRequest对象来创建一个复杂脚本,它负责受害者用户浏览器和我们控制的重定向web服务器之间的通信。如下,使用XMLHttpRequest来重定向受害者:
上述代码会验证HTTP响应码状态并把链接转化为outlook特有的olm格式链接窗口跳出,如下:
但其中接收到的状态码为0,根据MDN XMLHttpRequest.status来看,说明存在错误。经过一番分析研究,我们发现其中存在一个跨站资源共享CORS防护措施,所以,需要对它进行绕过,在此我们使用cors-anywhere代理方式对上述代码作了以下修改:
这样一来,我们的CORS bypass就能成功了,通过用burp collaborator作为拦截代理,就能有效地从XSS受害者的User-agent信息中查看到我们构造的恶意消息参数情况了:
很多移动APP中都嵌入了Web应用功能,这种架构一旦其中的Web应用出现类似XSS的问题,难免会涉及本身的移动应用程序。
2019.1.24 漏洞上报MSRC
2019.1.24 MSRC声称会进行检查
2019.1.29 MSRC成功复现漏洞并表示会在之后进行修复
2019.2.20 MSRC回复称检查还在内部进行
2019.6.20 MSRC发布补丁并分配漏洞编号CVE-2019-1105
*参考来源:cyberark,clouds编译,转载请注明来自FreeBuf.COM