轉載至:https://www.secpulse.com/archives/76102.html
接安全測試(一)的內容
此流程圖是我在學校為學生講課時按課程安排做的,測試點可做為參考,主要為APP自身漏洞的客戶端測試為主。后續文章會繼續完善~
APP面臨的主要風險
客戶端:
傳統逆向分析類(反編譯、調試、加密/簽名破解…)
用戶已經中招類(輸入記錄、導出組件、進程注入…)
服務端:
系統組件類(MS12-020、ShellShock、心血、ST2…)
業務應用類(注入跨站越權執行上傳下載弱口令…)
本地客戶端測試
本章我主要介紹的本地客戶端的測試,所需要的環境、工具、APK文件結構、架構、測試點等。
客戶端測試 - 組件導出安全
什么是組件?
-
安卓APP以組件為單位進行權限聲明和生命周期管理;
組件有什么用?
-
安卓系統的組件共有四種,其主要用途分別為:
-
Activity:呈現可供用戶交互的界面,是最常見的組件;
-
Service:長時間執行后台作業,常見於監控類應用;
-
Content Provider:在多個APP間共享數據,比如通訊錄;
-
Broadcast Receiver:注冊特定事件,並在其發生時被激活
-
什么是權限聲明?
-
安卓系統定義了許多權限聲明項,分別對應一些操作系統功能
權限聲明有什么用?
-
如果一個APP或組件在沒有聲明權限的情況下就調用相關API,會被拒絕訪問;
-
但如果聲明了相關權限,安裝的時候就會有提示;
-
這樣一來,用戶就可以評估使用該APP可能帶來的風險
什么是組件導出?
-
簡而言之,就是別的APP也可以訪問這個組件。
-
再總而言之,就是組件權限的控制。
組件導出有什么用?
-
有些APP的功能需要提供一些接口給其它APP訪問,就需要把相關的接口功能放在一個導出的組件上。
組件導出有什么危害?
因為權限聲明是以組件為單位的,A組件調用B組件的功能來訪問操作系統API時,適用於B組件的權限聲明。
如果B作為導出組件,沒有進行嚴格的訪問控制,那么A就可以通過調用B來訪問原本沒有聲明權限的功能,構成本地權限提升。
四大組件詳細介紹
Activity組件漏洞
Activity是Android組件中最基本也是最為常見用的四大組件之一,是一個負責與用戶交互的組件。Activity組件中存在以下常見的漏洞。 (1)activity綁定browserable與自定義協議activity設置“android.intent.category.BROWSABLE”屬性並同時設置了自定義的協議android:scheme意味着可以通過瀏覽器使用自定義協議打開此activity。可能通過瀏覽器對app進行越權調用。(2)ActivityManager漏洞ActivityManager類中的killBackgroundProcesses函數,用於殺死進程,屬於風險API。還有通過ActivityManager被動嗅探intent。Intent嗅探腳本首先調用一個Context.getSystemService()函數,並傳給它一個ACTIVITY_SERVICE標志的標識符,該函數返回一個ActivityManager類的實例,它使得該腳本能夠與activity manager進行交互,並通過這個對象調用ActivityManager.getRecentTasks()方法。最后把intent相關的信息格式化成字符串返回出來。
Service組件
作為Android中四大組件之一,擁有重要的地位。Service具有和Activity一樣的級別,只是沒有界面,是運行於后台的服務。其他應用組件能夠啟動Service,並且當用戶切換到另外的應用場景,Service將持續在后台運行。另外,一個組件能夠綁定到一個service與之交互(IPC機制),例如,一個service可能會處理網絡操作,播放音樂,操作文件I/O或者與內容提供者(content provider)交互,所有這些活動都是在后台進行。從表面上看service並不具備危害性,但實際上service可以在后台執行一些敏感的操作。Service存在的安全漏洞包括:權限提升,拒絕服務攻擊。沒有聲明任何權限的應用即可在沒有任何提示的情況下啟動該服務,完成該服務所作操作,對系統安全性產生極大影響。
BroadcastReceiver導出漏洞
當應用廣播接收器默認設置exported='true',導致應用可能接收到第三方惡意應用偽造的廣播,利用這一漏洞,攻擊者可以在用戶手機通知欄上推送任意消息,通過配合其它漏洞盜取本地隱私文件和執行任意代碼。Android 可以在配置文件中聲明一receiver或者動態注冊一個receiver來接收廣播信息,攻擊者假冒APP構造廣播發送給被攻擊的receiver,是被攻擊的APP執行某些敏感行為或者返回敏感信息等,如果receiver接收到有害的數據或者命令時可能泄露數據或者做一些不當的操作,會造成用戶的信息泄漏甚至是財產損失。
Content Provider組件漏洞
Content Provider為存儲和獲取數據提供統一的接口。可以在不同的應用程序之間共享數據。(1)讀寫權限漏洞Content Provider中通常都含有大量有價值的信息,比如用的電話號碼或者社交帳號登錄口令,而確認一個content provider是否有能被攻擊的漏洞的最好的辦法,就是嘗試攻擊它一下。可以用drozer來尋找一些不需要權限的contentprovider:dz> runapp.provider.info –permission null這條命令能列出所有不需要任何讀寫權限的Content Provider,然后找到相對應的包,去訪問給定包存放在它的Content Provider中的數據。如果一些Content Provider的URI不需要讀權限,那就可以通過drozer工具提取其中的數據。在某些情況下,設置和執行讀寫權限不當,也會將ContentProvider中的數據暴露給攻擊者。除了提取數據,對於寫權限管理不當的Content Provider還可以向其中寫入數據,使得攻擊者可以將惡意數據插入到數據庫中。(2)Content Provider中的SQL注入漏洞和Web漏洞類似,安卓APP也要使用數據庫,那就也有可能存在SQL注入漏洞。主要有兩類,第一類是SQL語句中的查詢條件子語句是可注入的,第二類是投影操作子句是可注入的。使用drozer可以很容易的找出查詢條件子句可注入的content provider。dz> runapp.provider.query [URI] –selection “1=1”也可以使用其他恆為真的值,例如“1-1=0”,“0=0”等等。如果APP存在SQL注入漏洞,那么輸入這行指令后就會返回數據庫中的整張表。(3)Provider文件目錄遍歷漏洞當Provider被導出且覆寫了openFile方法時,沒有對Content Query Uri進行有效判斷或過濾。攻擊者可以利用openFile()接口進行文件目錄遍歷以達到訪問任意可讀文件的目的。
組件測試工具-drozer
Drozer是MWRLabs開發的一款Android安全測試框架。是目前最好的Android安全測試工具之一
環境准備:
1 手機獲得root權限
2 adb.exe、配置android環境變量
3 手機usb連接開啟debug模式(在設置>關於手機>連續點擊多次版本號,即可開啟開發者模式)
4 Window下安裝drozer
5安裝完drozer后在其目錄下把agent.apk安裝到手機
連接准備:
1 drozer console devices
啟動drozer:
adb forward tcp:31415 tcp:31415 //將pc端31415的所有數據轉發到手機上的31415端口
drozer console connect //使用drozer console 連接agent
獲取手機上所有安裝的app包名:run app.package.list 加上”-f [app關鍵字]”查找某個app,如 run app.package.list -f sieve
獲取sieve的基本信息run app.package.info –a com.mwr.example.sieve
可以看到sieve的版本信息,數據存儲目錄,用戶ID,組ID,共享庫,權限等信息
run app.package.attacksurface com.mwr.example.sieve
進一步獲取每個組件的攻擊面信息,如activity
run app.activity.info這條命令將導出你設備上的所有的activity
run app.activity.info -a com.mwr.example.sieve
其中. MainLoginActivity是app啟動時的主界面,必須可以導出,但其他兩個activity正常情況下是不能導出的
用drozer來啟動可導出且不需要權限的activity
run app.activity.start --component com.mwr.example.sieve com.mwr.example.sieve.PWList
獲取content provider的信息
run app.provider.info -a com.mwr.example.sieve
結合上面查看攻擊面的信息,這2個content provider都可導出,com.mwr.example.sieve.DBContentProvider/Keys 是需要讀寫權限的
往下關於drozer工具的使用百度都有詳細的介紹,這里不再做繼續介紹。
客戶端測試 - 組件導出安全配置
組件完全滿足以下條件之一,則可以導出
顯式聲明了android:exported="true"
未顯式聲明android:exported="false";
組件不是Content Provider;
組件包含<intent-filter>;
未顯式聲明android:exported="false";
組件是Content Provider;
聲明API最小版本<17;
AndroidManifest.xml
AndroidManifest.xml是Android應用的入口文件,它描述了package中暴露的組件(activities, services, 等等),他們各自的實現類,各種能被處理的數據和啟動位置。 除了能聲明程序中的Activities, ContentProviders, Services, 和In
android:allowClearUserData(‘true’ or ‘false’)
用戶是否能選擇自行清除數據,默認為true,程序管理器包含一個選擇允許用戶清除數據。當為true時,用戶可自己清理用戶數據,反之亦然
AndroidManifest.xm一些特定屬性的介紹,可自行百度。下面只是幾個舉例:
android:allowTaskReparenting(‘true’ or ‘false’)
是否允許activity更換從屬的任務,比如從短信息任務切換到瀏覽器任務
android:debuggable
這個從字面上就可以看出是什么作用的,當設置為true時,表明該APP在手機上可以被調試。默認為false,在false的情況下調試該APP,就會報以下錯誤:
Device XXX requires that applications explicitely declare themselves as debuggable in their manifest. Application XXX does not have the attribute ‘debuggable’ set to TRUE in its manifest and cannot be debugged.
android:exported 是Android中的四大組件 Activity,Service,Provider,Receiver 四大組件中都會有的一個屬性。
總體來說它的主要作用是:是否支持其它應用調用當前組件。
默認值:如果包含有intent-filter 默認值為true; 沒有intent-filter默認值為false。
客戶端測試 - 本地敏感信息安全
查看應用程序所在目錄(需root權限)
一般為:/data/data/{APP包(package)名}/
如遇.db文件,多為SQLite數據庫。
正常的文件權限最后三位應為空(類似“rw-rw----”),目錄可以多一個執行位(類似“rwxrwx—x”)
Android系統的五種數據存儲形式:
分別是文件存儲、SP存儲、數據庫存儲、contentprovider 內容提供者、網絡存儲
文件存儲:
以I/O流的形式把數據存入手機內存或SD卡,可以存儲大數據,如音樂、圖片或視頻等。對於手機內存來說系統會根據每個應用的包名創建一個/data/data/包名/的文件夾,訪問自己包名下的目錄是不需要權限的,並且 Android 已經提供了非常簡便的 API 可以直接去訪問該文件夾。訪問時可以用getFilesDir()和getCacheDir(),兩個的區別是系統會自動清理后者中的內容。
SD卡中的文件通常位於mnt/sdcard目錄下,不同生產商生產的手機這個路徑可能不同。操作sd卡的時通常要判斷下sd卡是否可用以及剩余空間是否足夠,因為部分手機的SD卡可卸載,SD卡處於非掛載狀態時,無法進行讀寫操作。另外一點,對SD卡的讀取和寫入操作均需要相應的權限,否則無法完成。獲取SD卡路徑的方法是Environment.getExternalStorageDirectory(),其余操作與文件存儲基本類似。
shared preferences:SP存儲
可以看到goatdroid應用的用戶名和密碼都以明文的形式存儲在 shared preferences中SP存儲本質上是一個XML文件,以鍵值對的形式存入手機內存中。常用於存儲簡單的參數設置,如登陸賬號密碼的存儲,窗口功能狀態的存儲等,該存儲文件位於:data/data/包名/shared_prefs文件夾中。使用的時候,首先需要通過context.getSharedPrefrences(String name,int mode)獲取SharedPrefrences的實例對象,存儲數據時,用SharedPrefrences的實例對象得到SharedPrefrences文件的編輯器,在編輯器中用putXxx()添加數據,之后務必用commit提交數據,否則無法獲取數據。取數據時,直接用getXxx()方法。
sp存儲自動生成xml文件,其的路徑如下:
數據庫存儲:
數據庫所有信息都存儲在單一文件內,占用內存小,並且支持基本SQL語法,是項目中經常被采用的一種數據存儲方式,通常用於存儲用戶信息等,例如在手機上做一個學生信息管理系統。SQLite 是一款內置到移動設備上的輕量型的數據庫,SQLiteOpenHelper 是Android 提供的一個抽象工具類,負責管理數據庫的創建、升級工作。數據庫的路徑為:/data/data/應用包名/databases/數據庫。
從手機文件中導出數據庫文件並不可以直接打開,因此可以用可視化工具和sqlite3操作工具進行查看。這里介紹sqlite3工具的使用。具體需要的步驟如下:
1. 執行adb shell命令進入Linuxne內核;
2. 使用cd進入數據庫所在的路徑 cd: /data/data/應用包名/databases;
3. 進入數據庫模式: sqlite3 數據庫名.db;
4. 執行SQL語句
Content Provider:
Content Provider,中文名是內存提供者,Android四大組件之一,內容提供者是應用程序之間共享數據的接口,以數據庫形式存入手機內存,可以共享自己的數據給其他應用使用。之所以需要設計一個單獨的控件來操作數據,是為了實現應用程序之間的數據傳遞。通過查看DDMS中的目錄結構可以看出,數據庫文件對於其他應用來說是不可讀、不可寫,而日常生活中又需要獲取其他應用的數據,尤其是系統自帶軟件的數據。比如打開QQ或者微信時會提示是否同步聯系人,又比如備份短信的時候,這些都需要訪問和操作其他應用的數據庫。因此谷歌工程師在底層軟件中集成了大量的方法利用內存提供者的原理,類似於在數據庫中提供一個對外訪問的路徑,供其他應用訪問。
具體操作是:創建內容提供者解析器,定義要訪問的Uri的路徑。Uri路徑有着固定的格式:”content://主機名/匹配字符”。 利用內容提供者解析器進行增刪改查,和要操作的數據庫之間建立聯系。以上內容通常用來理解內容提供者的工作原理,實際工作中很少用到自定義的內容提示者。實際中用的比較多的是用內容提供者操作系統聯系人、系統短信等系統應用的數據庫。
先看一下短信和手機聯系人有關的數據庫所在的路徑。短信在Android 模擬器下存放在的路徑是:/data/data/com.android.providers.telephony/databases/目錄,聯系人在Android 模擬器下存放在的路徑是:/data/data/com.android.providers.contacts/databases/目錄。對於短信數據庫我們關心的表數據有:address、type、body、date,分別表示發送者號碼、短信類型(收還是發)、短信內容、日期。對於聯系人數據庫的三張表一定要按照一定的順序依次查找才能得到相關的數據,在這不做解釋。盡管開發的時候不需要了解短信和手機聯系人的數據庫路徑,但是要明白短信和手機聯系人的數據是存在數據庫中的,同時數據庫對外是不開放的。
與短信有關的數據庫的目錄結構:
網絡存儲:
網絡存儲是最容易理解的一種存儲方式了。其實說簡單點就是文件的上傳和下載。經常聽到的雲備份就是這種形式。優勢也很明顯,即把數據存儲到服務器,不存儲在本地,使用的時候直接從網絡獲取,避免了手機端信息丟失以及其他的安全隱患。因此,對於這種形式就不作多的解釋
客戶端測試 - 本地敏感信息安全
用logcat命令查看APP的日志
清空日志 :logcat -c
實時查看日志 :logcat
一次性輸出 :logcat -d
發布APP前,去掉Log輸出代碼
用DDMS命令查看APP的日志
客戶端測試 – 簽名文件的分析檢測
對apk進行簽名需要用到簽名證書和簽名工具。Android系統要求對APP進行簽名的數字證書可以由開發者自己生成。簽名工具有jarsigner和signapk。jarsigner是Java本身自帶的一個工具,他也可以對jar進行簽名的;而signapk是專門為了Android應用程序apk進行簽名的工具。二者的區別是:jarsigner工具簽名時使用的是keystore簽名文件,signapk工具簽名時使用的是pk8,x509.pem文件。
簽名文件分析
應用簽名完后在應用的META-INF目錄下會有三個文件:
CERT.RSA、CERT.SF和MANIFEST.MF。
MANIFEST.MF:這是摘要文件。程序遍歷Apk包中的所有文件(entry),對非文件夾非簽名文件的文件,逐個用SHA1生成摘要信息,再用Base64進行編碼。如果你改變了apk包中的文件,那么在apk安裝校驗時,改變后的文件摘要信息與MANIFEST.MF的檢驗信息不同,於是程序就不能成功安裝。
說明:這是Android簽名驗證過程的第一步,保證每個APK包內的每個文件與MANIFEST.MF中的摘要值一一對應,修改某個文件內容,必須修改MANFEST.MF文件中的摘要值,使他們對應起來。
CERT.SF:這是對摘要的簽名文件。對前一步生成的MANIFEST.MF,對MANIFEST.MF中的每一條內容分別進行SHA1計算,然后再用Base64編碼轉換。此外,把MANIFEST.MF的內容也進行SHA1計算,並且計算BASE64編碼。將上述內容寫入CERT.SF文件中。
(這是為了防止通過篡改文件和其在MANIFEST.MF中對應的SHA1摘要值來篡改APK,要對MANIFEST的內容再進行一次數字摘要)。
說明:這是簽名認證過程的第二步,這一步做的是多第一步得到的簽名文件的摘要,比如第一步中對文件和MANIFEST.MF摘要都改了,這一步中MANIFEST.MF的摘要值也要修改,否則就對應不起來。
所以,前面這兩步,做的都是摘要,是為第三步驟做准備的,第三步驟才是最重要的
CERT.RSA文件中保存了公鑰、所采用的加密算法等信息,此外重要的,還包括對CERT.SF中的內容的用私鑰進行加密之后的值。
說明:在這一步,即使開發者修改了程序內容,並生成了新的摘要文件,MANIFEST.MF能與內容對應起來,CERT.SF也能與內容對應起來,但是攻擊者沒有開發者的私鑰,所以不能生成正確的簽名文件(CERT.RSA)。系統在對程序進行驗證的時候,用開發者公鑰對不正確的簽名文件進行解密,得到的結果對應不起來,所以不能通過檢驗,不能成功安裝文件。
簽名工具使用:
jarsigner是JDK提供的針對jar包簽名的通用工具, jarsigner只支持V1簽名
位於JDK/bin/jarsigner.exe
apksigner是Google官方提供的針對Android apk簽名及驗證的專用工具, 默認同時使用V1和V2簽名
位於Android SDK/build-tools/SDK版本/apksigner.bat
不管是apk包,還是jar包,本質都是zip格式的壓縮包,所以它們的簽名過程都差不多(僅限V1簽名),
以上兩個工具都可以對Android apk包進行簽名.
V1和V2簽名的區別
在Android Studio中點擊菜單 Build->Generate signed apk... 打包簽名過程中,
可以看到兩種簽名選項 V1(Jar Signature) V2(Full APK Signature),
從Android 7.0開始, 谷歌增加新簽名方案 V2 Scheme (APK Signature);
但Android 7.0以下版本, 只能用舊簽名方案 V1 scheme (JAR signing)
V1簽名:
來自JDK(jarsigner), 對zip壓縮包的每個文件進行驗證, 簽名后還能對壓縮包修改(移動/重新壓縮文件)
對V1簽名的apk/jar解壓,在META-INF存放簽名文件(MANIFEST.MF, CERT.SF, CERT.RSA),
其中MANIFEST.MF文件保存所有文件的SHA1指紋(除了META-INF文件), 由此可知: V1簽名是對壓縮包中單個文件簽名驗證
V2簽名:
來自Google(apksigner), 對zip壓縮包的整個文件驗證, 簽名后不能修改壓縮包(包括zipalign),
對V2簽名的apk解壓,沒有發現簽名文件,重新壓縮后V2簽名就失效, 由此可知: V2簽名是對整個APK簽名驗證
V2簽名優點很明顯:
簽名更安全(不能修改壓縮包)
簽名驗證時間更短(不需要解壓驗證),因而安裝速度加快
注意: apksigner工具默認同時使用V1和V2簽名,以兼容Android 7.0以下版本
查看V1和V2簽名方式
一個檢測apk是否支持v1、v2 簽名的工具,SignApkV2 簽名檢測工具
直接調用:ApkSignerTool.verify(String apkPath)
命令行:
java -jar CheckAndroidSignature.jar xxxx.apk
結果:
{"ret":0,"msg":"","isV1OK":true,"isV2":true,"isV2OK":true,"keystoreMd5":"8f701cdd1c0d8856e440363185c7daf7"}
簽名步驟
1.生成密鑰對(已有密鑰庫,可忽略)
Eclipse或Android Studio在Debug時,對App簽名都會使用一個默認的密鑰庫:
默認在C:\Users\用戶名\.android\debug.keystore(非安全簽名)
密鑰庫名: debug.keystore
密鑰別名: androiddebugkey
密鑰庫密碼: android
1.生成密鑰對
進入JDK/bin, 輸入命令
keytool -genkeypair -keystore 密鑰庫名 -alias 密鑰別名 -validity 天數 -keyalg RSA
參數:
-genkeypair 生成一條密鑰對(由私鑰和公鑰組成)
-keystore 密鑰庫名字以及存儲位置(默認當前目錄)
-alias 密鑰對的別名(密鑰庫可以存在多個密鑰對,用於區分不同密鑰對)
-validity 密鑰對的有效期(單位: 天)
-keyalg 生成密鑰對的算法(常用RSA/DSA,DSA只用於簽名,默認采用DSA)
-delete 刪除一條密鑰
提示: 可重復使用此條命令,在同一密鑰庫中創建多條密鑰對
例如:
在debug.keystore中新增一對密鑰,別名是release
keytool -genkeypair -keystore debug.keystore -alias release -validity 30000
為什么報錯了:
這是因為權限問題:你的jdk目錄在c盤,當前用戶無寫入權限。
所以要么更改jdk的保存目錄,要么更改權限
方法一更改保存目錄:就是講jdk從c盤挪到其它盤。
方法二更改權限:以管理員身份運行CMD。
我已管理員權限運行CDM
2.查看密鑰庫
進入JDK/bin, 輸入命令
keytool -list -v -keystore 密鑰庫名
參數:
-list 查看密鑰列表
-v 查看密鑰詳情
例如:
keytool -list -v -keystore debug.keystore
現在debug.keystore密鑰庫中有兩對密鑰, 別名分別是androiddebugkey release
3.簽名
1.方法一(jarsigner,只支持V1簽名)
進入JDK/bin, 輸入命令
jarsigner -keystore 密鑰庫名 xxx.apk 密鑰別名
從JDK7開始, jarsigner默認算法是SHA256, 但Android 4.2以下不支持該算法,
所以需要修改算法, 添加參數 -digestalg SHA1 -sigalg SHA1withRSA
jarsigner -keystore 密鑰庫名 -digestalg SHA1 -sigalg SHA1withRSA xxx.apk 密鑰別名
參數:
-digestalg 摘要算法
-sigalg 簽名算法
例如:
用JDK7及以上jarsigner簽名,不支持Android 4.2 以下
jarsigner -keystore debug.keystore MyApp.apk androiddebugkey
用JDK7及以上jarsigner簽名,兼容Android 4.2 以下
jarsigner -keystore debug.keystore -digestalg SHA1 -sigalg SHA1withRSA MyApp.apk androiddebugkey
2.方法二(apksigner,默認同時使用V1和V2簽名)
進入Android SDK/build-tools/SDK版本, 輸入命令
apksigner sign --ks 密鑰庫名 --ks-key-alias 密鑰別名 xxx.apk
若密鑰庫中有多個密鑰對,則必須指定密鑰別名
apksigner sign --ks 密鑰庫名 --ks-key-alias 密鑰別名 xxx.apk
禁用V2簽名
apksigner sign --v2-signing-enabled false --ks 密鑰庫名 xxx.apk
參數:
--ks-key-alias 密鑰別名,若密鑰庫有一個密鑰對,則可省略,反之必選
--v1-signing-enabled 是否開啟V1簽名,默認開啟
--v2-signing-enabled 是否開啟V2簽名,默認開啟
例如:
在debug.keystore密鑰庫只有一個密鑰對
apksigner sign --ks debug.keystore MyApp.apk
在debug.keystore密鑰庫中有多個密鑰對,所以必須指定密鑰別名
apksigner sign --ks debug.keystore --ks-key-alias androiddebugkey MyApp.ap
4.簽名驗證
1.方法一(keytool,只支持V1簽名校驗)
進入JDK/bin, 輸入命令
keytool -printcert -jarfile MyApp.apk (顯示簽名證書信息)
參數:
-printcert 打印證書內容
-jarfile <filename> 已簽名的jar文件 或apk文件
2.方法二(apksigner,支持V1和V2簽名校驗)
進入Android SDK/build-tools/SDK版本, 輸入命令apksigner verify -v --print-certs xxx.apk
參數:
-v, --verbose 顯示詳情(顯示是否使用V1和V2簽名)
--print-certs 顯示簽名證書信息
例如:
apksigner verify -v MyApp.apk Verifies Verified using v1 scheme (JAR signing): true Verified using v2 scheme (APK Signature Scheme v2): true Number of signers: 1
5. 查看CERT.RSA內容
Apk 包中的META-INF目錄下,有一個CERT.RSA,它是一個PKCS7 格式的文件。
要查看apk簽名信息及證書內容,即CERT.RSA文件,可用以下命令:
keytool -printcert -file path
APK解壓后的文件,將簽名文件中CERT.RSA拿出來用apktool 單獨查看
客戶端測試 - 鍵盤記錄保護
常見的Android鍵盤記錄主要依靠讀取/dev/input/event0設備
需要root。
需要編寫專門的Native測試工具
鍵盤、觸屏之類均能捕獲到。
也有通過注冊輸入法來竊聽鍵盤的方法。
客戶端測試 - 屏幕錄像測試
即連續截屏,通過視覺反饋效果來竊聽密碼等敏感信息:
adb shell /system/bin/screencap -p 安卓設備中的輸出png路徑
需要root。
screencap輸出到安卓設備中,不是輸出到電腦中。
注意: FLAG_SECURE會妨礙screencap,
但對於root權限下直接讀取屏幕緩存的方法是不起作用的,測試中不被認定為有效修復。
敏感信息輸入不提供視覺反饋
客戶端測試 - 進程注入保護
設法在目標APP的進程空間中執行一段代碼。
一般的方法是在Native層通過pTrace,讓遠程進程加載一個.so鏈接庫,從而侵入目標進程空間。
需要root;
需要編寫專門的Native測試工具;
GDB也使用了類似的方法來操作遠程進程。
反調試技術實現復雜,一般通過加殼解決
客戶端測試 - Activity/界面劫持保護
在目標APP啟動時,立即彈出一個假界面覆蓋之。
一般是通過Broadcast Receiver來監聽目標APP的android.intent.action.BOOT_COMPLETED事件。
在JAVA層完成,不需要root
誘騙用戶在假界面上操作,以獲取其敏感信息,很難察覺Android 5.0以后從系統機制層面解決了這個問題,因此如果APK聲明的最小API版本≥21,
此項無需測試,直接記為安全。
ApkTool解包后會產生apktool.yml,內含關於API版本的聲明信息。
客戶端測試 – 調試信息檢測
檢測程序(含服務器端和客戶端)調試信息是否關閉,調試信息中是否寫入敏感信息
通過運行程序,查看logcat等調試日志信息,是否有泄漏重要的URL地址、提示信息、調試信息等敏感關鍵字以及程序邏輯的關鍵流程。對於HTML頁面,需要在瀏覽器端打開,並檢查其中的JS代碼等是否存留其他調試信息
這里我們用的方式是DDMS:
DDMS 的全稱是Dalvik Debug Monitor Service,是 Android 開發環境中的Dalvik虛擬機調試監控服務。
這個工具存放在SDK-tools路徑下,啟動方法: [1]
1) 直接雙擊ddms.bat運行;
2) 在Eclipse調試程序的過程中啟動DDMS
雙擊ddms打開
我們看到有很多日志輸出,可以觀察運行日志中是否帶有敏感數據
然后我們找到我們要分析的那個應用包
看他的進程ID是2484
然后下面的輸出進程都是2484的
實時日志中若輸出調試信息,攻擊者可根據輸出信息分析應用程序的運行邏輯,對應用程序進行惡意破壞;也可能泄露用戶敏感信息。
客戶端測試 –Sqlite .db文件的導出
我們的app里面用到sqlite數據庫的時候, 會生成一個db文件,保存在我們手機中。有的時候,在調試數據庫,很想看一下里面的表結構是否正確,這個時候就十分苦惱,因為這個db文件不能夠直接拿出來,我們知道,在DDMS里面有一個FileExplorer,它里面保存着手機中的各個文件夾,但是嘗試打開里面的文件夾的時候,卻發現怎么點都沒有東西,是真的沒有嗎?其實是我們沒有獲取到訪問這個文件夾的權限。下面我們就開始一步一步的拿到真機調試中的db文件。
DDMS可以直接看手機里文件,如圖:
Data/data/應用包名databases/
我們可以看到.db文件就是他的sqllite文件。可以直接導出
如果打開文件權限不夠的話,這里利用就可以利用adb直接給打開的路徑授權:
比如:
進去adb 然后chmod 777 /data/data/com.demo.app/databases/
在導出.db文件后,可以本地打開.db文件,分析是否存在敏感信息
推薦工具:
客戶端測試 – Sqlite加密檢測
Android 系統的Sqlite數據庫是一個輕量級且沒有加密功能的數據庫,但有時候我們的數據庫保存了一些重要的信息,不想讓別人知道,就需要對數據庫加密。但大多數的加密都需要收費的,而Sqlcipher是免費的。下面我們用sqlcipher來加密數據庫。
配置工程:
注意assets下的文件
我們可用工具,對APP解包后,分析.so文件,
用APK改之理解包了一個APK:
分析出Sqlite數據庫已做加密,做加密后的文件.db導出后是無法打開的: