移動APP安全測試
1 移動APP安全風險分析
1.1 安全威脅分析
安全威脅從三個不同環節進行劃分,主要分為客戶端威脅、資料傳輸端威脅和服務端的威脅。
1.2 面臨的主要風險
1.3 Android測試思維導圖
1.4 反編譯工具
有兩種反編譯方式,dex2jar和apktool,兩個工具反編譯的效果是不一樣的,dex2jar反編譯出java原始碼,apktool反編譯出來的是java彙編程式碼。
dex2jar主要是用來把之前zip解壓出來的classed.dex轉成jar包的
jd-gui主要是用來開啟Jar包的
2 本地客戶端安全
2.1 反編譯保護
2.1.1 問題描述
APP原始碼對於一個公司是非常重要的資訊資源,對APP的保護也尤為重要,APP的反編譯會造成原始碼被惡意者讀取,以及APP的邏輯設計,
Ø 反編譯方法
我們一般想要反編譯一個apk,無非就是想獲得三樣東西:圖片資源、XML資源、程式碼資源
一. 圖片資源獲取
首先準備一個apk,這裡是一個.apk字尾的檔案,我們先把字尾改成,zip,開啟zip檔案在res目錄下,我們就可以獲取到我們需要的圖片了。
二. XML資源獲取
我們可以在剛剛開啟的zip檔案目錄下看到很多.xml的檔案,這個xml檔案是無法直接開啟的,當你嘗試著開啟的時候都是亂碼或者是空白,那麼我們要如何獲取到這個xml資源呢,這時候就需要藉助一個jar包,就是它,axmlprinter2.jar,這個東西你只要百度下,就能搜到。然後 你把他放跟你解壓出來的xml放在同級目錄下,用cmd命令找到這個目錄,
我這邊的示例是將xml放在了E盤,大家根據情況,cd到自己解壓出來的目錄下,然後執行
java -jar AXMLPrinter2.jar xxxxx.xml>xxxxx.txt
這個時候你就能獲取到xml裡的東西啦
三. 程式碼資源獲取
這個重中之重了,這也是我們主要想要獲取到的東西。但是存在一點,這裡能夠正確反編譯出來的只有未加密或者沒有混淆的程式碼,如果想要反編譯一些加密或者混淆後代碼,俺們就需要其他途徑解決了
首先要準備兩樣東西:dex2jar.rar和jd-gui.zip這兩個工具。
dex2jar主要是用來把之前zip解壓出來的classed.dex轉成jar包的
jd-gui主要是用來開啟Jar包的
dex2jar用法:
把dex2jar 解壓後,然後將之前zip的classes.dex放到 dex2jar目錄下,
注意,必須要跟dex2jar.bat是同級目錄。
然後又要用到cmd,cd 到dex2jar目錄下,打命令列
dex2jar.bat classes.dex
然後你的目錄裡會多一個jar包
多了一個 classes-dex2jar.jar的檔案
然後在用jd-gui把jar包開啟,最終apk的程式碼就這樣被剝離出來了
2.1.2 檢測方法
通過反編譯工具看是否能夠對APP進行反編譯
2.1.3 修復方法
採用加密和混淆技術達到反編譯保護。
混淆技術作用是增加了使用者反編譯後閱讀程式碼的難度。
2.2 APP二次打包
2.2.1 二次打包描述
“Android APP二次打包”則是盜版正規Android APP,破解後植入惡意程式碼重新打包。不管從效能、使用者體驗、外觀它都跟正規APP一模一樣但是背後它確悄悄執行著可怕的程式,它會在不知不覺中浪費手機電量、流量,惡意扣費、偷窺隱私等等行為。
面對二次打包不少公司都有自己的防範措施,知名公司的APP幾乎都是自己在程式內部做過處理防止其APP被二次打包,一旦打包後重新執行則程式自動退出。接下來,我就來詳解一下如何防止APP被二次打包。
要實現程式碼內部防止APP被二次打包首先得了解APK的機器識別原理,APK的唯一識別是依靠包名和簽名來做鑑定的,類似豌豆夾的洗白白、360手機衛士等安全軟體對APK的山寨識別,他們就是依賴包名來確定APK然後通過簽名來確定其是否山寨。所以說自己的程式內部在啟動的時候可以通過獲取APK本身的簽名然後和正確的簽名做對比來識別自己是否被二次打包。
2.2.2 防二次打包檢測方法
利用二次打包工具對APP進行二次打包,看APP能否成功打包執行,如果重新打包後無法執行程式說明有防二次打包安全措施。
2.2.3 防二次打包修復方法
採用簽名的方法進行保護:獲取二次打包後APK的簽名與正確的APK簽名做對比,判斷APK程式是否進行過二次打包。
建議:客戶端使用從屬方證書進行簽名後進行釋出而不是使用第三方開發商的證書進行簽名,以防開發商內部監管異常,證書濫用的情況出現。
2.3 元件匯出安全
2.3.1 四大元件描述
Android主要包含4大元件,分別是activity元件、service元件、content provider元件和broadcast receiver元件。
Ø Activity元件
(1)一個Activity通常就是一個單獨的螢幕(視窗)。
(2)Activity之間通過Intent進行通訊。
(3)android應用中每一個Activity都必須要在AndroidManifest.xml配置檔案中宣告,否則系統將不識別也不執行該Activity。
Ø Service元件
(1)service用於在後臺完成使用者指定的操作。
(2)開發人員需要在應用程式AndroidManifest.xml配置檔案中宣告全部的service,使用<service></service>標籤。
(3)Service通常位於後臺執行,它一般不需要與使用者互動,因此Service元件沒有圖形使用者介面。Service元件需要繼承Service基類。Service元件通常用於為其他元件提供後臺服務或監控其他元件的執行狀態。
Ø Content Provider元件
(1)android平臺提供了Content Provider使一個應用程式的指定資料集提供給其他應用程式。其他應用可以通過ContentResolver類從該內容提供者中獲取或存入資料。
(2)只有需要在多個應用程式間共享資料是才需要內容提供者。例如,通訊錄資料被多個應用程式使用,且必須儲存在一個內容提供者中。它的好處是統一資料訪問方式。
(3)ContentProvider實現資料共享。ContentProvider用於儲存和獲取資料,並使其對所有應用程式可見。這是不同應用程式間共享資料的唯一方式,因為android沒有提供所有應用共同訪問的公共儲存區。
Ø broadcast receiver
(1)你的應用可以使用它對外部事件進行過濾,只對感興趣的外部事件(如當電話呼入時,或者資料網路可用時)進行接收並做出響應。廣播接收器沒有使用者介面。然而,它們可以啟動一個activity或serice來響應它們收到的資訊,或者用NotificationManager來通知使用者。通知可以用很多種方式來吸引使用者的注意力,例如閃動背燈、震動、播放聲音等。一般來說是在狀態列上放一個持久的圖示,使用者可以開啟它並獲取訊息。
(2)廣播接收者的註冊有兩種方法,分別是程式動態註冊和AndroidManifest檔案中進行靜態註冊。
(3)動態註冊廣播接收器特點是當用來註冊的Activity關掉後,廣播也就失效了。靜態註冊無需擔憂廣播接收器是否被關閉,只要裝置是開啟狀態,廣播接收器也是開啟著的。也就是說哪怕app本身未啟動,該app訂閱的廣播在觸發時也會對它起作用。
Ø 四大元件總結
(1)4大元件的註冊
4大基本元件都需要註冊才能使用,每個Activity、service、Content Provider都需要在AndroidManifest檔案中進行配置。AndroidManifest檔案中未進行宣告的activity、服務以及內容提供者將不為系統所見,從而也就不可用。而broadcast receiver廣播接收者的註冊分靜態註冊(在AndroidManifest檔案中進行配置)和通過程式碼動態建立並以呼叫Context.registerReceiver()的方式註冊至系統。需要注意的是在AndroidManifest檔案中進行配置的廣播接收者會隨系統的啟動而一直處於活躍狀態,只要接收到感興趣的廣播就會觸發(即使程式未執行)。
(2)4大元件的啟用
內容提供者的啟用:當接收到ContentResolver發出的請求後,內容提供者被啟用。而其它三種元件activity、服務和廣播接收器被一種叫做intent的非同步訊息所啟用。
2.3.2 元件安全檢查方法
1、 AndroidManifest.xml檔案中activity元件裡面有設定android:exported為true,表示此元件可以被外部應用呼叫。
2、 AndroidManifest.xml檔案中activity元件裡面有設定android:exported為false,表示此元件不可以被外部應用呼叫。只有同一個應用的元件或者有著同樣user ID的應用可以
3、 AndroidManifest.xml檔案中activity元件裡面沒有設定android:exported屬性,但是有intent-filter,則exported預設屬性為true,true表示此元件可以被外部應用呼叫。
4、 AndroidManifest.xml檔案中activity元件裡面沒有設定android:exported屬性,也沒有設定intent-filter,則exported預設屬性為false,false表示此元件不可以被外部應用呼叫。只有同一個應用的元件或者有著同樣user ID的應用可以
備註:採用drozer工具可以進行檢測元件是否存在匯出風險
2.3.3 修復建議
(1)如果應用的Service元件不必要匯出,或者元件配置了intent filter標籤,建議顯示設定元件的“android:exported”屬性為false
(2)如果元件必須要提供給外部應用使用,建議對元件進行許可權控制
2.4 Webview漏洞
2.4.1 WebView任意程式碼執行漏洞
2.4.1.1 描述
Ø 出現該漏洞的原因有三個
WebView 中 addJavascriptInterface() 介面
WebView 內建匯出的 searchBoxJavaBridge_物件
WebView 內建匯出的 accessibility 和 accessibilityTraversalObject 物件
Ø addJavascriptInterface 介面引起遠端程式碼執行漏洞
JS呼叫Android的其中一個方式是通過addJavascriptInterface介面進行物件對映, 當JS拿到Android這個物件後,就可以呼叫這個Android物件中所有的方法,包括系統類(java.lang.Runtime 類),從而進行任意程式碼執行。
Ø searchBoxJavaBridge_介面引起遠端程式碼執行漏洞
在Android 3.0以下,Android系統會預設通過searchBoxJavaBridge_的Js介面給 WebView 新增一個JS對映物件:searchBoxJavaBridge_物件
該介面可能被利用,實現遠端任意程式碼。
Ø accessibility和 accessibilityTraversal介面引起遠端程式碼執行漏洞
問題類似以上
2.4.1.2 檢測方法
Ø addJavascriptInterface 介面引起遠端程式碼執行漏洞
檢查是通過addJavascriptInterface介面進行物件對映
Ø searchBoxJavaBridge_介面引起遠端程式碼執行漏洞
檢查是否通過searchBoxJavaBridge_的Js介面給 WebView 新增一個JS對映物件
Ø accessibility和 accessibilityTraversal介面引起遠端程式碼執行漏洞
問題類似以上
2.4.1.3 修復建議
Ø addJavascriptInterface 介面引起遠端程式碼執行漏洞
B1. Android 4.2版本之後
Google 在Android 4.2 版本中規定對被呼叫的函式以 @JavascriptInterface進行註解從而避免漏洞×××
B2. Android 4.2版本之前
在Android 4.2版本之前採用攔截prompt()進行漏洞修復。
Ø searchBoxJavaBridge_介面引起遠端程式碼執行漏洞
刪除searchBoxJavaBridge_介面
// 通過呼叫該方法刪除介面
removeJavascriptInterface();
Ø accessibility和 accessibilityTraversal介面引起遠端程式碼執行漏洞
刪除accessibility和 accessibilityTraversal介面
2.4.2 密碼明文儲存漏洞
2.4.2.1 描述
WebView預設開啟密碼儲存功能:
mWebView.setSavePassword(true)
開啟後,在使用者輸入密碼時,會彈出提示框:詢問使用者是否儲存密碼;
如果選擇”是”,密碼會被明文保到 /data/data/com.package.name/databases/webview.db 中,這樣就有被盜取密碼的危險
2.4.2.2 檢測方法
方法1、使用者輸入密碼時看是否有彈出提示框,詢問使用者是否儲存密碼,如果有詢問則表示存在漏洞,否則不存在。
方法2、檢查程式碼中setSavePassword的值是否為false。
2.4.2.3 修復建議
關閉密碼儲存提醒
WebSettings.setSavePassword(false)
2.5 資料安全-本地敏感資訊保安
2.5.1 APP所在目錄的檔案許可權
2.5.1.1 問題描述
測試客戶端APP所在目錄的檔案許可權是否設定正確,非root賬戶是否可以讀,寫,執行APP目錄下的檔案。
2.5.1.2 檢測方法
採用ls –l檢視app目錄的檔案許可權,其它組成員不允許讀寫許可權。Linux檔案許可權為第一個為檔案所有者對此檔案的許可權,第二個為所有者所在組的其它成員對此檔案的許可權,第三個為其他組成員對此檔案的許可權。
2.5.1.3 修復建議
檢查App所在的目錄,其許可權必須為不允許其他組成員讀寫
2.5.2 SQLite資料庫檔案的安全性
2.5.2.1 描述
SQLite,是一款輕型的資料庫,是遵守ACID的關係型資料庫管理系統.是開源的,高效率的,可嵌入且程式驅動的資料庫。
我們都知道,Android系統內建了SQLite資料庫,並且提供了一整套的API用於對資料庫進行增刪改查操作。資料庫儲存是我們經常會使用到的一種儲存方式,相信大多數朋友對它的使用方法都已經比較熟悉了吧。在Android中,我們既可以使用原生的SQL語句來對資料進行操作,也可以使用Android API提供的CRUD方法來對資料庫進行操作,兩種方式各有特點,選擇使用哪一種就全憑個人喜好了。
不過,使用SQLite來儲存資料卻存在著一個問題。因為大多數的Android手機都是Root過的,而Root過的手機都可以進入到/data/data//databases目錄下面,在這裡就可以檢視到資料庫中儲存的所有資料。如果是一般的資料還好,但是當涉及到一些賬號密碼,或者聊天內容的時候,我們的程式就會面臨嚴重的安全漏洞隱患。
2.5.2.2 檢測方法
手機進行root之後,檢視/data/data//databases下的資料庫檔案是否包含敏感資訊。
2.5.2.3 修復建議
重要資訊進行加密儲存
2.5.3 Logcat日誌
2.5.3.1 描述
檢測客戶端對應的Logcat日誌是否會列印一些使用者或伺服器的敏感資訊。
2.5.3.2 檢測方法
通過usb連線手機,然後使用adb logcat -v time > d:\xx的方式獲取logcat資訊
或者使用DDMS工具檢視logcat資訊。
2.5.3.3 修復建議
具有敏感資訊的除錯資訊開關一定要關閉。
對於安卓開發來講,我們解決敏感資訊問題就是對重要資料進行加密儲存,log日誌不列印敏感資訊。切記不要把賬號密碼等敏感資訊儲存在本地明文儲存,如果一定要儲存敏感資訊務必進行加密儲存重要資訊。
2.5.4 敏感資料明文儲存於Sdcard
2.5.4.1 描述
Android提供了幾種儲存持久化應用資料的選擇,其中之一就是外部儲存(/sdcard, /mnt/sdcard)。外部儲存包括裝置內部的微型或標準大小的SD卡,掛載到PC上的Android裝置儲存卡以及Android/obb目錄。
Android4.1之前的版本,存放在外部儲存的檔案是world-readable(能夠被任何使用者讀取的)和world-writable(能夠被任何使用者寫入)。從Android4.1到Android4.3,一個app想要寫入外部儲存的任意檔案時,只需在AndroidManifest檔案中宣告WRITE_EXTERNAL_STORAGE許可權。但從Android4.4開始,引入了基於目錄結構建立分組和檔案模式,這使得一個app在外部儲存中的只能在以自己包名命名的目錄下才具有檔案的讀寫許可權。非系統級的app只允許在Android/data/<package-name>/目錄下操作。因此,每個app的檔案讀寫許可權被獨立開來,不能互相訪問。
上面描述的訪問許可權限制的不足,導致寫入到外部儲存的檔案可能存在被同一裝置上不同的app修改和讀取的風險(Android4.4之前版本)。
2.5.4.2 檢測方法
檢視是否有程式碼把內容寫入到外部儲存裝置。
2.5.4.3 修復建議
在將檔案儲存到外部儲存之前,先對檔案內容進行加密。
2.6 鍵盤安全風險
2.6.1 鍵盤劫持測試
2.6.1.1 描述
安卓應用中的輸入框預設使用系統軟鍵盤,手機安裝×××後,×××可以通過替換系統軟鍵盤,記錄應用的密碼。
2.6.1.2 檢測方法
通過觀察app在輸入密碼的地方是否會彈出自定義的軟鍵盤。
2.6.1.3 修復建議
建議客戶端開發自定義軟鍵盤而不是使用系統軟體盤以防止鍵盤劫持×××。
2.6.2 軟鍵盤安全性測試
2.6.2.1 描述
測試客戶端是否使用隨機佈局的密碼軟鍵盤。
2.6.2.2 檢測方法
用眼觀察每次彈出來的自定義的軟鍵盤是否隨機變化佈局
2.6.2.3 修復建議
建議客戶端對自定義軟鍵盤進行隨機化處理,同時在每次點選輸入框時都進行隨機初始化。
2.7 螢幕錄影測試
2.7.1 描述
測試通過連續截圖,是否可以捕捉到使用者密碼輸入框的密碼。
2.7.2 檢測方法
通過連續截圖,是否可以捕捉到使用者密碼輸入框的密碼。
2.7.3 修復建議
建議客戶端針對第三方或系統截圖編寫抵抗邏輯,例如遮蔽和截圖相關的函式或是當客戶端處於程序棧頂層時將截圖圖片用純黑×××片物件進行覆蓋。
2.8 介面劫持保護
2.8.1 介面劫描述
Activity劫持是指當啟動某個視窗元件時,被惡意應用探知,若該視窗介面是惡意程式預設的×××物件,惡意應用將啟動自己仿冒的介面覆蓋原介面,使用者在毫無察覺的情況下輸入登入資訊,惡意程式在把獲取的資料返回給服務端。
需要理解,Android啟動一個Activity時,是這樣設計的,給Activity加入一個標誌位FLAG_ACTIVITY_NEW_TASK,就能使它置於棧頂並立馬呈現給使用者。但是這樣的設計卻有一個缺陷。如果這個Activity是用於盜號的偽裝Activity呢?這種現象在XcodeGhost事件中,已經被證實是可以實現的。
在Android系統當中,程式可以列舉當前執行的程序而不需要宣告其他許可權,這樣的話,就可以編寫一個程式,啟動一個後臺的服務,這個服務不斷地掃描當前執行的程序,當發現目標程序啟動時,就啟動一個偽裝的Activity。如果這個Activity是登入介面,那麼就可以從中獲取使用者的賬號密碼,具體的過程如下圖:
2.8.2 介面劫持防護方法
作為一名移動應用開發者,要防禦APP被介面劫持,最簡單的方法是在登入視窗等關鍵Activity的onPause方法中檢測最前端Activity應用是不是自身或者是系統應用。如果檢測到不是自己,則彈出告警或者退出。
2.8.3 介面劫持案例
應用存在釣魚劫持風險。應用程式沒有做防釣魚劫持措施,通過劫持應用程式的登入介面,可以獲取使用者的賬號和密碼,可能導致使用者賬號資訊的洩露。
2.8.4 整改建議
應用程式自身通過獲取棧頂activity,判斷系統當前執行的程式,一旦發現應用切換(可能被劫持),給予使用者提示以防範釣魚程式的欺詐。
獲取棧頂activity(如下圖),當涉及敏感activity(登入、交易等)切換時,判斷當前是否仍留在原程式,若不是則通過Toast給予使用者提示。
使用HTML5架構或android+HTML5混合開發,實現登陸、支付等關鍵頁面,降低被劫持的風險。
2.9 本地拒絕服務
2.9.1 漏洞描述
Android系統提供了Activity、Service和Broadcast Receiver等元件,並提供了Intent機制來協助應用間的互動與通訊,Intent負責對應用中一次操作的動作、動作涉及資料、附加資料進行描述,Android系統則根據此Intent的描述,負責找到對應的元件,將Intent傳遞給呼叫的元件,並完成元件的呼叫[1]。Android應用本地拒絕服務漏洞源於程式沒有對Intent.getXXXExtra()獲取的異常或者畸形資料處理時沒有進行異常捕獲,從而導致×××者可通過向受害者應用傳送此類空資料、異常或者畸形資料來達到使該應用crash的目的,簡單的說就是×××者通過intent傳送空資料、異常或畸形資料給受害者應用,導致其崩潰。
本地拒絕服務漏洞影響範圍:Android系統所有版本
2.9.2 漏洞檢測方法
使用Android掃描工具可以進行掃描。
2.9.3 修復建議
本地拒絕服務漏洞修復建議:
1) 將不必要的匯出的元件設定為不匯出
出於安全考慮,應將不必要的元件匯出,防止引起拒絕服務,尤其是防毒、安全防護、鎖屏防盜等安全應用; 在AndroidMenifest.xml檔案中,將相應元件的“android:exported”屬性設定為“false”,如下示例:<android:exported="false">
2) intent處理資料時進行捕獲異常
建議處理通過Intent.getXXXExtra()獲取的資料時進行以下判斷,以及用try catch方式進行捕獲所有異常,以防止應用出現拒絕服務漏洞:
1) 空指標異常;
2) 型別轉換異常;
3) 陣列越界訪問異常;
4) 類未定義異常;
5) 其他異常;
2.10 資料備份allowBackup
2.10.1 漏洞描述
Android API Level 8 及其以上 Android 系統提供了為應用程式資料的備份和恢復功能,此功能的開關決定於該應用程式中 AndroidManifest.xml 檔案中的 allowBackup 屬性值,其屬性值預設是 True。當 allowBackup 標誌為 true 時,使用者即可通過 adb backup 和 adb restore 來進行對應用資料的備份和恢復,這可能會帶來一定的安全風險。
Android 屬性 allowBackup 安全風險源於 adb backup 容許任何一個能夠開啟 USB 除錯開關的人從Android 手機中複製應用資料到外設,一旦應用資料被備份之後,所有應用資料都可被使用者讀取;adb restore 容許使用者指定一個恢復的資料來源(即備份的應用資料)來恢復應用程式資料的建立。因此,當一個應用資料被備份之後,使用者即可在其他 Android 手機或模擬器上安裝同一個應用,以及通過恢復該備份的應用資料到該裝置上,在該裝置上開啟該應用即可恢復到被備份的應用程式的狀態。
尤其是通訊錄應用,一旦應用程式支援備份和恢復功能,×××者即可通過 adb backup 和 adb restore 進行恢復新安裝的同一個應用來檢視聊天記錄等資訊;對於支付金融類應用,×××者可通過此來進行惡意支付、盜取存款等;因此為了安全起見,開發者務必將 allowBackup 標誌值設定為 false 來關閉應用程式的備份和恢復功能,以免造成資訊洩露和財產損失。
1、不在 AndroidManifest.xml 檔案設定 allowBackup 屬性值,其預設值為 true,則應用可通過 adb 命令進行備份整個應用的資料
AndroidManifest.xml檔案內容:
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.alibaba.jaq.allowbackuppoc" android:versionCode="1" android:versionName="1.0"> <uses-sdk android:minSdkVersion="10"/> <uses-permission android:name="android.permission.READ_PHONE_STATE" /> <application android:label="@string/app_name"> <activity android:name="LoginActivity" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity> <activity android:name=".HomeActivity"/> </application> </manifest> |
2、在 AndroidManifest.xml 檔案顯示設定 allowBackup 屬性值為 false,即android:allowBackup="false",則 Android 應用不可通過 adb 命令進行備份和恢復整個應用的資料
AndroidManifest.xml檔案內容:
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.alibaba.jaq.allowbackuppoc" android:versionCode="1" android:versionName="1.0"> <uses-sdk android:minSdkVersion="10"/> <uses-permission android:name="android.permission.READ_PHONE_STATE" /> <application android:allowBackup="false" android:label="@string/app_name"> <activity android:name="LoginActivity" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity> <activity android:name=".HomeActivity"/> </application> </manifest> |
2.10.2 檢測方法
檢視AndroidManifest.xml檔案中是否有allowBackup,如果沒有則allowBackup屬性值,預設allowBackup值為True,則預設為可以備份應用資料,存在安全風險;如果allowBackup屬性值為false,則不可以備份應用資料。
2.10.3 修復方法
把AndroidManifest.xml檔案中allowBackup屬性值設定為false。
2.11 Debug除錯
2.11.1 描述
在準備釋出應用之前要確保關閉debug屬性,即設定AndroidMainifest.xml中android:debuggable="false",false表示關閉debug除錯功能,true表示開啟debug除錯功能,但是有時候會忘記關掉這個屬性。Debug除錯開啟會存在應用被除錯的風險。
2.11.2 檢測方法
在釋出之前最好進行測試,使用aapt工具:
aapt list -v -a myfile.apk
這個命令將會列印和apk相關的所有詳細資訊,找到“android:debuggable",它的值分為:
0x0: debuggable false
0xffffffff: debugabble true
例如,在我的測試中,這一行的資訊是:
A: android ebuggable(0x0101000f)=(type 0x12)0x0
這說明我的Release Build已經關閉了debuggable!
2.11.3 修復建議
把debuggable關閉
android:debuggable=false
3 通訊過程安全
3.1 通訊保密性
3.1.1 採用HTTPS通訊
3.1.1.1 描述
驗證客戶端和伺服器之前的通訊是否使用https加密通道,採用https協議通訊可以防止資訊在傳輸過程被竊聽的風險。。
3.1.1.2 檢測方法
通過抓包工具(例如burpsuite、fiddler)抓取通訊資訊,看是否進行加密通訊。
3.1.1.3 修復建議
使用https進行加密通訊。
3.1.2 SSL劫持×××——證書校驗
3.1.2.1 描述
目前雖然很多Android APP使用了https通訊方式,但是隻是簡單的呼叫而已,並未對SSL證書有效性做驗證,https通訊只是對通訊通道進行了加密,可以防止監聽資料的風險,但是無法防止中間人×××方式,通過中間人攔截代理方式可以讓採用https通訊的資料暴露無遺,這樣×××者就可以利用中間人攔截代理來做劫持×××,這種漏洞讓https形同虛設,可以輕易獲取手機使用者的明文通訊資訊。
證書校驗是為了防止中間人劫持×××,分為強校驗和弱校驗。強校驗就是在手段端先預埋好服務端的證書,當手機端與服務端通訊時獲取證書,並且與手機本地預埋的服務端證書做對比,一旦不一致,則認為遭到了中間人劫持×××,自動斷開與服務端的通訊。弱校驗則是在手機端校驗證書的域名和手機真實訪問的域名是否一致、證書頒發機構等資訊。
強校驗流程圖:
弱校驗流程圖:
方案對比
方案 |
優點 |
缺點 |
強校驗:伺服器證書鎖定 |
安全性最高,實施×××必須拿到對應伺服器私鑰證書。 |
更換證書時APP影響大 |
弱校驗:根證書鎖定+域名驗證 |
更換伺服器證書不受影響 |
安全性和CA機構以及域名驗證機制有關。 |
3.1.2.2 檢測方法
通過抓包看手機端程式是否執行正常,如果通過代理方式抓包,手機APP自動強制退出,說明手機APP有做證書校驗。
3.1.2.3 整改方法
採用強校驗或者弱校驗方法。
3.2 訪問控制
3.2.1 描述
測試客戶端訪問的URL是否僅能由手機客戶端訪問。是否可以繞過登入限制直接訪問登入後才能訪問的頁面,對需要二次驗證的頁面(如私密問題驗證),能否繞過驗證。
3.2.2 檢測方法
利用截包工具獲取url,能用瀏覽器開啟該url。
3.2.3 修復建議
建議伺服器進行相應的訪問控制,控制對應頁面僅能通過手機客戶端訪問。同時進行頁面訪問控制,防止繞過登陸直接訪問頁面的非法訪問。
4 服務端安全
4.1 安全策略設定
4.1.1 密碼複雜度策略
4.1.1.1 描述
測試客戶端程式是否檢查使用者輸入的密碼,禁止使用者設定弱口令
4.1.1.2 檢測方法
修改設定使用者名稱密碼時,可以設定111111類似弱口令
4.1.1.3 修復建議
建議在伺服器編寫檢測密碼複雜度的安全策略,並將其運用到賬號註冊,密碼修改等需要進行密碼變更的場景,以防止×××者通過弱金鑰遍歷賬戶的方式進行暴力猜解。
4.1.2 認證失敗鎖定策略
4.1.2.1 描述
測試客戶端是否限制登入嘗試次數。防止×××使用窮舉法暴力破解使用者密碼
4.1.2.2 檢測方法
錯誤密碼登入請求多次(10次以上還沒有就有問題了,一般都是3次)
4.1.2.3 修復建議
建議在服務端編寫賬戶鎖定策略的邏輯,當一天內多次輸入密碼錯誤時進行賬號鎖定以防止×××者通過暴力猜解密碼。
4.1.3 單點登入限制策略
4.1.3.1 描述
測試能否在兩個裝置上同時登入同一個帳號。
4.1.3.2 檢測方法
測試能否在兩個裝置上同時登入同一個帳號。
4.1.3.3 修復建議
建議在伺服器進行賬號登陸限制相應邏輯程式碼的編寫,通過Session或資料庫標誌位的方式控制同一時間只有一個裝置可以登陸某一賬號。
4.1.4 會話超時策略
4.1.4.1 描述
測試客戶端在一定時間內無操作後,是否會使會話超時並要求重新登入。超時時間設定是否合理。
4.1.4.2 檢測
客戶端在一定時間內無操作(20分鐘足夠),是否會話超時登入
4.1.4.3 建議
建議在客戶端編寫會話安全設定的邏輯,當10分鐘或20分鐘無操作時自動退出登入狀態或是關閉客戶端。
4.1.5 介面切換保護
4.1.5.1 描述
檢查客戶端程式在切換到後臺或其他應用時,是否能恰當響應(如清除表單或退出會話),防止使用者敏感資訊洩露
4.1.5.2 檢測方法
應用切換到後臺但程式沒有結束執行,再返回應用的時候是否有身份驗證 ,手勢密碼或者登陸密碼。
4.1.5.3 修復建議
建議客戶端新增響應的邏輯,在進行程序切換操作時提示使用者確認是否為本人操作。
4.1.6 UI敏感資訊保安
4.1.6.1 描述
檢查客戶端的各種功能,看是否存在敏感資訊洩露問題。
4.1.6.2 檢測方法
比如登入時,密碼輸入錯誤,APP是否會提示密碼輸入錯誤
4.1.6.3 修復建議
建議使用者名稱或密碼輸入錯誤均提示“使用者名稱或密碼錯誤”,若客戶端同時還希望保證客戶使用的友好性,可以在登陸介面通過溫馨提示的方式提示輸入錯誤次數,密碼安全策略等資訊,以防使用者多次輸入密碼錯誤導致賬號鎖定。
4.1.7 安全退出
4.1.7.1 描述
驗證客戶端在使用者退出登入狀態時是否會和伺服器進行通訊以保證退出的及時性
4.1.7.2 檢測方法
客戶端在使用者退出登入時,檢視session是否可用
4.1.7.3 修復建議
保證客戶端和伺服器同步退出,APP退出時伺服器端的清除會話
4.1.8 密碼修改驗證
4.1.8.1 描述
驗證客戶端在進行密碼修改時的安全性
4.1.8.2 檢測方法
是否存在原密碼驗證
4.1.8.3 修復建議
建議在修改密碼時,客戶端及伺服器系統增添原密碼輸入驗證身份的邏輯,以防Cookie登陸修改密碼的×××。
4.1.9 手勢密碼
4.1.9.1 手勢密碼修改和取消
4.1.9.1.1 描述
檢測客戶端在取消手勢密碼時是否會驗證之前設定的手勢密碼,檢測是否存在其他導致手勢密碼取消的邏輯問題
4.1.9.1.2 檢測方法
檢測客戶端在取消手勢密碼時是否會驗證之前設定的手勢密碼,檢測是否存在其他導致手勢密碼取消的邏輯問題
4.1.9.1.3 修復建議
不應該存在其他導致手勢密碼取消的邏輯,客戶端在取消手勢密碼時應驗證之前設定的手勢密碼
4.1.9.2 手勢密碼本地資訊儲存
4.1.9.2.1 描述
檢測在輸入手勢密碼以後客戶端是否會在本地記錄一些相關資訊,例如明文或加密過的手勢密碼。
4.1.9.2.2 檢測方法
找到儲存檔案,看其是否加密
4.1.9.2.3 修復建議
應該進行加密
4.1.9.3 手勢密碼鎖定策略
4.1.9.3.1 描述
測試客戶端是否存在手勢密碼多次輸入錯誤被鎖定的安全策略。防止×××使用窮舉法暴力破解使用者密碼。因為手勢密碼的儲存容量非常小,一共只有9!=362880種不同手勢,若手勢密碼不存在鎖定策略,×××可以輕易跑出手勢密碼結果。手勢密碼在輸入時通常以a[2][2]這種3*3的二維陣列方式儲存,在進行客戶端同伺服器的資料互動時通常將此二維陣列中數字轉化為類似手機數字鍵盤的b[8]這種一維形式,之後進行一系列的處理進行傳送
4.1.9.3.2 檢測方法
嘗試多次輸入手勢密碼錯誤,例如連續輸入3次或者5次密碼錯誤,看是否會鎖定賬號。
4.1.9.3.3 修復方法
手勢密碼策略建議連續輸入3次或者5次進行鎖定。
4.2 任意賬號註冊
4.2.1 描述
使用任意賬號可以進行註冊,造成非實名制註冊風險,惡意註冊者可以註冊大量賬號。大量賬號可以用於薅羊毛等惡意操作。
4.2.2 檢測方法
使用手機號139****1234註冊某個APP,獲取驗證碼060503,在確認提交時,攔截請求,修改註冊的手機號碼,即可註冊任意賬號,這裡修改為136****5678(任意手機號);即可使用136****5678(任意手機號)登入,均可以通過驗證登入。
4.2.3 修復建議
註冊過程最後的確認提交時,伺服器應驗證提交的賬號是否是下發驗證碼的手機號。
4.3 簡訊重放×××
4.3.1 描述
檢測應用中是否存在資料包重放×××的安全問題。是否會對客戶端使用者造成簡訊轟炸的困擾。
4.3.2 檢測方法
利用burpsuite抓包,然後進行重放操作。
4.3.3 修復建議
token和手機號一起,重放無法造成簡訊轟炸,另外就是限制每個手機號每天只能傳送簡訊次數,例如10次。每個ip每分鐘只能傳送3次。
4.4 簡訊驗證碼
4.4.1 描述
簡訊驗證碼對於防止暴力破解是一種有效的手段,但是如果驗證碼沒有使用有效,則會導致其無法發揮防暴力破解的效果。
4.4.2 檢測方法
檢測簡訊驗證碼是否可以多次重複使用。一般驗證碼使用一次及失效。
檢測簡訊驗證碼的有效期,一般驗證碼5分鐘內有效即可。
4.4.3 修復建議
設定簡訊驗證碼使用一次即失效,並且每個簡訊驗證碼在5分鐘內有效。
4.5 業務邏輯漏洞
此處主要是一些越權漏洞。
4.6 服務端其他漏洞
此處和web端漏洞類似,例如SQL注入、XSS、任意檔案上傳漏洞等等。