??Android系統(tǒng)由于其開(kāi)源的屬性腰涧,市場(chǎng)上針對(duì)開(kāi)源代碼定制的ROM參差不齊奖地,在系統(tǒng)層面的安全防范和易損性都不一樣间涵,Android應(yīng)用市場(chǎng)對(duì)app的審核相對(duì)iOS來(lái)說(shuō)也比較寬泛,為很多漏洞提供了可乘之機(jī)退疫。市場(chǎng)上一些主流的app雖然多少都做了一些安全防范,但由于大部分app不涉及資金安全鸽素,所以對(duì)安全的重視程度不夠褒繁;而且由于安全是門系統(tǒng)學(xué)科,大部分app層的開(kāi)發(fā)人員缺乏安全技術(shù)的積累馍忽,措施相對(duì)有限。
??據(jù)了解:反編譯 Android apk 現(xiàn)象的發(fā)生主要原因,在于開(kāi)發(fā)商投入市場(chǎng)的Android apk包未經(jīng)任何加固保護(hù)胆描∧考猓總之就是現(xiàn)在的移動(dòng)APP安全測(cè)試的需求迅速擴(kuò)大花吟,相關(guān)測(cè)試技能對(duì)于大家的日常工作來(lái)說(shuō)是必不可少的甩牺。
??本人就最近研究APP,整理了APP安全測(cè)試做了部分總結(jié)僚稿。在針對(duì)APP進(jìn)行滲透測(cè)試時(shí),業(yè)務(wù)邏輯層和web端測(cè)試大同小異腕侄,所以著重介紹APP自身所特有的漏洞:反編譯小泉、二次打包、簽名校驗(yàn)等冕杠;
一微姊、APP面臨的主要風(fēng)險(xiǎn)
客戶端:
傳統(tǒng)逆向分析類(反編譯、調(diào)試分预、加密/簽名破解…)
用戶已經(jīng)中招類(輸入記錄兢交、導(dǎo)出組件、進(jìn)程注入…)
服務(wù)端:
系統(tǒng)組件類(MS12-020笼痹、ShellShock配喳、心血酪穿、ST2…)
業(yè)務(wù)應(yīng)用類(注入跨站越權(quán)執(zhí)行上傳下載弱口令…)
二、本地客戶端測(cè)試
??本章我主要介紹的本地客戶端的測(cè)試晴裹,所需要的環(huán)境被济、工具、APK文件結(jié)構(gòu)涧团、架構(gòu)只磷、測(cè)試點(diǎn)等。
以下目錄結(jié)構(gòu)如下泌绣,本篇所涉及到的在紅框范圍钮追。
2.1 客戶端測(cè)試工具-工具推薦(環(huán)境準(zhǔn)備):
JDK:因?yàn)锳ndroid應(yīng)用都包含JAVA外殼,所以JAVA環(huán)境是必要的赞别。沒(méi)有JAVA畏陕,就沒(méi)有apktool、Eclipse仿滔、jarsigner惠毁。
ADT:ADT中除了神器adb(Android Debug Bridge)和Monitor,還包含了Emulator虛擬機(jī)和Eclipse開(kāi)發(fā)環(huán)境崎页;另有較為新銳的替代品Android Studio鞠绰。
GDB:作為大名鼎鼎的跨平臺(tái)調(diào)試工具,GDB在實(shí)際測(cè)試中主要用于DUMP內(nèi)存飒焦,從而發(fā)現(xiàn)敏感信息蜈膨、解密數(shù)據(jù)、脫殼等等牺荠;
NDK:NDK可以在Windows上編譯Android(arm)使用的Native層可執(zhí)行文件(C/C++)翁巍,各項(xiàng)Native層測(cè)試工具都可用NDK制作;
安卓設(shè)備:已root的真實(shí)手機(jī)/Emulator休雌,不推薦x86虛擬機(jī)(VirtualBox/Genymotion)灶壶。x86雖然運(yùn)行快,但是兼容性不佳杈曲,尤其客戶APP涉及Native層時(shí)有時(shí)會(huì)出現(xiàn)莫名其妙的異常
模擬器選擇x86的還是基于ARM架構(gòu)的區(qū)別:
- ARM架構(gòu)注重的是續(xù)航能力驰凛,x86架構(gòu)注重的是性能;
- 在目前大部分的移動(dòng)設(shè)備(只能手機(jī)担扑,平板等)和大部分的移動(dòng)終端(超市消費(fèi)時(shí)候刷卡的Pos機(jī)恰响,ATM等)都是ARM的CPU,最主要因?yàn)槔m(xù)航能力涌献;
- 而大部分的臺(tái)式機(jī)和筆記本電腦胚宦,則是使用x86架構(gòu)的CPU,因?yàn)檫@些設(shè)備更需要高性能的運(yùn)轉(zhuǎn)和高效的運(yùn)算;
- 從目前來(lái)看间唉,android手機(jī)目前還是arm架構(gòu)占絕對(duì)主流绞灼,市場(chǎng)調(diào)研,目前90%的android手機(jī)都是arm架構(gòu)的呈野。
2.2 客戶端測(cè)試工具-工具推薦(實(shí)用功能):
- 網(wǎng)絡(luò)流量處理工具:
BurpSuite/Fiddler:針對(duì)HTTP進(jìn)行各種操作的利器
Wireshark:偶爾遇到不走HTTP的APP時(shí)低矮,定位代碼用
- APK文件處理工具:
ApkTool:功能眾多,主要用來(lái)解包和打包Apk文件
SignApk:對(duì)Apk文件進(jìn)行簽名被冒,否則無(wú)法安裝運(yùn)行
- Dalvik反編譯工具:
Dex2Jar:將Dex文件轉(zhuǎn)換為Jar文件军掂,便于反編譯JAVA
Smali2Java:直接從APK中反編譯JAVA
- 通用逆向分析工具:
JD-GUI/Luyten:可以反編譯Class/Jar文件,在Dex2Jar之后使用
IDA:當(dāng)APP存在Native層代碼時(shí)昨悼,用于進(jìn)行逆向分析
ApkTool:功能眾多蝗锥,主要用來(lái)解包和打包Apk文件,推薦一個(gè)圖形化懶人工具:ApkIDE率触。
- 查殼工具
2.3 客戶端測(cè)試 - 工具推薦(Xposed)
Xposed框架:
XposedBridge:JAR文件终议,Xposed開(kāi)發(fā)所必需的接口庫(kù)
XposedInstaller:APK文件,Xposed運(yùn)行環(huán)境葱蝗,注意5.0前后版本不同
JustTrustMe
Xposed模塊穴张,能夠解除絕大多數(shù)常見(jiàn)SSL函數(shù)庫(kù)的證書(shū)校驗(yàn)
注:通過(guò)修改本地客戶端的方法實(shí)現(xiàn)的通信加密攻擊不能記為風(fēng)險(xiǎn)
BlockSecureFlag:
Xposed模塊,能夠解除所有APP的FLAG_SECURE設(shè)置
注:適用于截屏?xí)r提示“內(nèi)存不足XXXX”的場(chǎng)景
Surrogate:
Xposed模塊两曼,能夠手動(dòng)配置修改任意函數(shù)的返回值皂甘,多用于固定化隨機(jī)密鑰
注:靈活性不如XPOSED開(kāi)發(fā),但使用方便悼凑,適合開(kāi)發(fā)基礎(chǔ)不深的同學(xué)
2.4 客戶端測(cè)試 – APK文件結(jié)構(gòu)
Android應(yīng)用(APK文件)通常是由以下四部分組成的:
1.清單文件(AndroidManifest.xml偿枕、/META-INF)
內(nèi)含APK的包名、組件列表户辫、啟動(dòng)組件渐夸、公共權(quán)限聲明、各個(gè)組件的權(quán)限聲明等一系列聲明信息
2.Dalvik可執(zhí)行文件(classes.dex渔欢、classes2.dex墓塌、…)
Java源代碼->Smali中間代碼->Dalvik機(jī)器碼->Dalvik虛擬機(jī)->ARM/x86機(jī)器碼
classes.dex中的便是Dalvik機(jī)器碼
3.Native可執(zhí)行文件(/lib)
其中包含很多.so鏈接庫(kù),多為C/C++編寫(xiě)而成的ARM/x86代碼
可以通過(guò)JNI(Java-Native Interface)與JAVA層相互調(diào)用
4.資源文件(/assets膘茎、/res、零散放置的其它種種)
除了圖片等數(shù)據(jù)性質(zhì)的文件之外酷誓,還有可能會(huì)有其它三種文件
2.5 客戶端測(cè)試 - 反編譯保護(hù)
把a(bǔ)pk當(dāng)成zip并解壓披坏,得classes.dex
執(zhí)行:dex2jar.bat classes.dex文件路徑
得classes.dex.jar
使用jd-gui或luyten打開(kāi)jar文件,即可得JAVA代碼
??jd-gui雖然搜索功能較好盐数,但解析代碼(尤其是混淆過(guò)的代碼)時(shí)經(jīng)常出BUG棒拂。luyten在這方面更加穩(wěn)定,可以將兩者結(jié)合使用。
有些APK會(huì)包含多個(gè)dex帚屉,全部轉(zhuǎn)換成jar后合并壓縮包即可
2.5.1 代碼混淆器:開(kāi)源版or商業(yè)版
??混淆器可以通過(guò)一些方法來(lái)保護(hù)你的代碼不被反編譯谜诫,他們不會(huì)阻止反編譯器或者dex2jar對(duì)你的代碼進(jìn)行逆向過(guò)程,但是他們會(huì)使反編譯出來(lái)的代碼變得更難理解攻旦,最簡(jiǎn)單的方式喻旷,他們將APK中所有的變量和方法的名字和字符串轉(zhuǎn)換成一到兩個(gè)字符的字符串,這就從JAVA源碼中去掉了很多代碼的含義牢屋,使其更難找到一些特定的信息且预,比如說(shuō)找到一個(gè)API key 或者你存儲(chǔ)用戶登錄信息的位置,好的混淆器會(huì)改變代碼的流程烙无,大多數(shù)情況下可以把業(yè)務(wù)邏輯隱藏起來(lái)锋谐,混淆器不會(huì)阻止一個(gè)一心想要破解你這個(gè)應(yīng)用的黑客去理解你代碼所做的事情,但他會(huì)讓這個(gè)過(guò)程顯得更難了截酷。
??跟很多java反編譯器一樣涮拗,也有很多的java混淆器,比如ProGuard迂苛,yGuard三热,RetroGuard,DashO灾部,Allatori康铭,Jshrink,Smokescreen赌髓,JODE,JaveGuard从藤,Zelix Klassmaster,以及jCloak,這些還只是其中一小部分锁蠕,甚至還有一款A(yù)ndroid 的classes夷野,dex混淆器,叫作Apkfuscator荣倾,你可以從http://github.com/strazzere/APKfusctor上 獲取悯搔,或者你也可以試下http://shield4j.com上的Shield4j。
??ProGuard是一個(gè)混淆代碼的開(kāi)源項(xiàng)目舌仍,它的主要作用是混淆代碼妒貌,殊不知ProGuard還包括以下4個(gè)功能。
壓縮(Shrink):檢測(cè)并移除代碼中無(wú)用的類铸豁、字段灌曙、方法和特性(Attribute)。
優(yōu)化(Optimize):對(duì)字節(jié)碼進(jìn)行優(yōu)化节芥,移除無(wú)用的指令在刺。
混淆(Obfuscate):使用a逆害,b,c蚣驼,d這樣簡(jiǎn)短而無(wú)意義的名稱魄幕,對(duì)類、字段和方法進(jìn)行重命名颖杏。
預(yù)檢(Preveirfy):在Java平臺(tái)上對(duì)處理后的代碼進(jìn)行預(yù)檢纯陨,確保加載的class文件是可執(zhí)行的。
?? Progurad是免費(fèi)的输玷,而且已經(jīng)集成到Android ADT中了队丝,使用起來(lái)很方便。Proguard只能保護(hù)代碼欲鹏,卻不能保護(hù)我們的apk文件机久。任何人都可以使用apktool工具,反編譯我們開(kāi)發(fā)的apk文件赔嚎,進(jìn)而更改其中各種資源膘盖,或者更改部分代碼,甚至是注入代碼尤误,然后再打包回apk侠畔,二次發(fā)布后,達(dá)到自己的目的损晤∪砉祝或者是加入了廣告,或者是增加了惡意木馬病毒等尤勋。不需要multi-dex喘落。Proguard會(huì)對(duì)輸入的jar文件按照shrink - optimize - obfuscate - perverify的順序依次進(jìn)行處理,最后得到輸出jar文件最冰。Proguard使用library jars來(lái)輔助對(duì)input jars類之間的依賴關(guān)系進(jìn)行解析瘦棋, library jars自身不會(huì)被處理,也不會(huì)被包含到output jars中暖哨。
??它能發(fā)現(xiàn)并刪除無(wú)用類赌朋、字段(field)、方法和屬性值(attribute)篇裁。它也能優(yōu)化字節(jié)碼 并刪除無(wú)用的指令沛慢。最后,它使用簡(jiǎn)單無(wú)意義的名字來(lái)重命名你的類名达布、字段名和方法名团甲。經(jīng)過(guò)以上操作的jar文件會(huì)變得更小,并很難進(jìn)行逆向工程往枣。但是有耐心的攻擊者仍能分析出代碼結(jié)構(gòu)
??DexGuard 是GuardSquare公司推出的移動(dòng)應(yīng)用App安全軟件伐庭,經(jīng)過(guò)特別設(shè)計(jì)用于防止安卓系統(tǒng)上的應(yīng)用APP與SDK遭受逆向工程與各類安全入侵的威脅
??DexGuard是收費(fèi)的,DexGuard是在Proguard基礎(chǔ)上分冈,加入了更多的保護(hù)措施圾另。使用DexGuard混淆后,生成的apk文件雕沉,就無(wú)法正常使用apktool反編譯了集乔。盡管還是能夠反編譯出部分資源文件,但是由于反編譯過(guò)程不完全坡椒,就無(wú)法再打包成apk了扰路。這樣就保護(hù)了我們的apk文件,不會(huì)被二次打包發(fā)布了倔叼。代碼混淆力度更大 + 資源混淆 + so加殼等汗唱。自帶multi-dex掃描
2.6 客戶端測(cè)試 - 安裝包簽名
使用JDK中的jarsigner.exe檢查安裝包的簽名:
jarsigner.exe -verify APK文件路徑 -verbose -certs
2.6.1什么是通用簽名?
??搭建好Android開(kāi)發(fā)環(huán)境后(使用Eclipse或Android Studio)丈攒,對(duì)APK簽名的默認(rèn)密鑰存在debug.keystore文件中哩罪。在linux和Mac上debug.keystore文件位置是在~/.android路徑下,在windows目錄下文件位置是C:\user\用戶名.android路徑下巡验。
??除了debug.keystore外际插,在AOSP發(fā)布的Android源碼中,還有以下幾個(gè)證書(shū)是公開(kāi)的显设,任何人都可以獲取框弛,在源碼的build/target/product/security目錄中:
2.6.2通用簽名風(fēng)險(xiǎn):
(1)如果攻擊者的應(yīng)用包名與目標(biāo)應(yīng)用相同,又使用了相同的密鑰對(duì)應(yīng)用進(jìn)行簽名捕捂,攻擊者的應(yīng)用就可以替換掉目標(biāo)應(yīng)用瑟枫;
(2)另外目標(biāo)應(yīng)用的自定義權(quán)限android:protectionlevel為“signature”或者“signatureOrSystem”時(shí)难述,保護(hù)就形同虛設(shè)巩趁;
(3)如果設(shè)備使用的是第三方ROM涝涤,而第三方ROM的系統(tǒng)也是用AOSP默認(rèn)的簽名之景,那么使用如果使用系統(tǒng)級(jí)簽名文件簽名過(guò)的應(yīng)用裁良,權(quán)限就得到了提升壹堰。
??以烏云公開(kāi)的WooYun-2014-67027為例隙赁,有安全研究人員發(fā)現(xiàn)有一個(gè)數(shù)字證書(shū)簽名被很多銀行的手機(jī)客戶端所使用杖狼。與此同時(shí)還發(fā)現(xiàn)了幾款個(gè)人開(kāi)發(fā)者類應(yīng)用也使用了此證書(shū)簽名澡屡。而這種數(shù)字簽名被濫用的行為存在極大的安全隱患猿挚。
??解壓應(yīng)用安裝包,可用keytool查看應(yīng)用的簽名證書(shū)信息: keytool -printcert -v -file META-INF/CERT.RSA
經(jīng)挖掘和分析驶鹉,研究人員發(fā)現(xiàn)目前共有23款不同銀行手機(jī)銀行客戶端使用該簽名:
在應(yīng)用市場(chǎng)內(nèi)绩蜻,目前共發(fā)現(xiàn)6款個(gè)人開(kāi)發(fā)的應(yīng)用同時(shí)使用該數(shù)字證書(shū)簽名:
??事情發(fā)生的原因是銀行的外包開(kāi)發(fā)管理不嚴(yán),不同銀行的APP居然用同樣的數(shù)字證書(shū)簽名室埋,并且開(kāi)發(fā)者還將證書(shū)用于了個(gè)人APP的開(kāi)發(fā)中办绝。如果簽名證書(shū)被惡意攻擊者獲取伊约,可以編寫(xiě)安裝是能直接替換掉這些銀行客戶端的惡意APP。
??還可以使用AOSP通用簽名提升應(yīng)用權(quán)限: 直接編譯AOSP源碼得到的ROM孕蝉,使用AOSP的默認(rèn)證書(shū)屡律,在設(shè)置->關(guān)于手機(jī),版本號(hào)中可查看到:
??對(duì)于普通的用默認(rèn)debug.keystore證書(shū)簽名的App降淮,如果在AndroidManfiest.xml的manifest節(jié)點(diǎn)加入android:sharedUserId=”android.uid.system”這個(gè)屬性超埋,安裝時(shí)會(huì)提示錯(cuò)誤:
如果對(duì)app-debug.apk使用AOSP提供的platform.x509.pem和platform.pk8重新簽名,則可以安裝成功:
查看應(yīng)用的進(jìn)程屬性佳鳖,已是system用戶組霍殴。
目前有不少的第三方ROM使用的AOSP提供的默認(rèn)簽名
個(gè)人開(kāi)發(fā)者在往開(kāi)源平臺(tái)上傳代碼時(shí),注意不要將簽名證書(shū)的私鑰上傳系吩。
2.7 客戶端測(cè)試 - 完整性校驗(yàn)
ApkTool+SignApk:
解包后可修改并重新打包来庭;
可查看AndroidManifest.xml;
可查看smali源碼(適用于JAVA反編譯失敗的情況)穿挨;
解包:
java -jar apktool.jar d -f apk文件路徑 -o 解包目標(biāo)文件夾
打包:
java -jar apktool.jar b -f 待打包的文件夾 -o 輸出apk路徑
APK必須進(jìn)行簽名后巾腕,方可安裝和運(yùn)行:
java -jar signapk.jar testkey.x509.pem testkey.pk8 待簽名apk文件路徑 簽名后輸出apk路徑
1.用ApkTool將目標(biāo)APK文件解包;
2.隨便找一個(gè)解包目錄里的資源文件絮蒿,修改之尊搬;
3.推薦找到啟動(dòng)logo圖進(jìn)行修改(因?yàn)槿菀状_認(rèn)結(jié)果);
4.用ApkTool土涝,將解包目錄重新打包成未簽名的APK文件佛寿;
5.用SignApk,對(duì)未簽名的APK文件進(jìn)行簽名但壮;
6.將簽了名的APK安裝冀泻、運(yùn)行、確認(rèn)是否存在自校驗(yàn)蜡饵;
簽名繞過(guò)方式:
測(cè)試弹渔。使用ApkIDE重打包后 直接安裝運(yùn)行,在Loading過(guò)程中會(huì)彈出修改提示溯祸,如下圖肢专,說(shuō)明軟件檢測(cè)到了被非法修改。
下面的操作是焦辅,將官方包的RSA拖出來(lái)博杖,置換掉我們修改后的RSA文件,名字盡量與SF保持一致即CERT筷登,然后安裝 可完美運(yùn)行剃根。
2.8 客戶端測(cè)試 - 組件導(dǎo)出安全
什么是組件?
- 安卓APP以組件為單位進(jìn)行權(quán)限聲明和生命周期管理前方;
組件有什么用狈醉?
安卓系統(tǒng)的組件共有四種廉油,其主要用途分別為:
Activity:呈現(xiàn)可供用戶交互的界面,是最常見(jiàn)的組件苗傅;
Service:長(zhǎng)時(shí)間執(zhí)行后臺(tái)作業(yè)娱两,常見(jiàn)于監(jiān)控類應(yīng)用;
Content Provider:在多個(gè)APP間共享數(shù)據(jù)金吗,比如通訊錄;
Broadcast Receiver:注冊(cè)特定事件趣竣,并在其發(fā)生時(shí)被激活
什么是權(quán)限聲明摇庙?
安卓系統(tǒng)定義了許多權(quán)限聲明項(xiàng),分別對(duì)應(yīng)一些操作系統(tǒng)功能
權(quán)限聲明有什么用遥缕?
如果一個(gè)APP或組件在沒(méi)有聲明權(quán)限的情況下就調(diào)用相關(guān)API卫袒,會(huì)被拒絕訪問(wèn);
但如果聲明了相關(guān)權(quán)限单匣,安裝的時(shí)候就會(huì)有提示夕凝;
這樣一來(lái),用戶就可以評(píng)估使用該APP可能帶來(lái)的風(fēng)險(xiǎn)
什么是組件導(dǎo)出户秤?
簡(jiǎn)而言之码秉,就是別的APP也可以訪問(wèn)這個(gè)組件。
再總而言之鸡号,就是組件權(quán)限的控制转砖。
組件導(dǎo)出有什么用?
- 有些APP的功能需要提供一些接口給其它APP訪問(wèn)鲸伴,就需要把相關(guān)的接口功能放在一個(gè)導(dǎo)出的組件上府蔗。
組件導(dǎo)出有什么危害?
- 因?yàn)闄?quán)限聲明是以組件為單位的汞窗,A組件調(diào)用B組件的功能來(lái)訪問(wèn)操作系統(tǒng)API時(shí)姓赤,適用于B組件的權(quán)限聲明。如果B作為導(dǎo)出組件仲吏,沒(méi)有進(jìn)行嚴(yán)格的訪問(wèn)控制不铆,那么A就可以通過(guò)調(diào)用B來(lái)訪問(wèn)原本沒(méi)有聲明權(quán)限的功能,構(gòu)成本地權(quán)限提升裹唆。
2.8.1 四大組件詳細(xì)介紹
- Activity組件漏洞
??Activity是Android組件中最基本也是最為常見(jiàn)用的四大組件之一狂男,是一個(gè)負(fù)責(zé)與用戶交互的組件。Activity組件中存在以下常見(jiàn)的漏洞品腹。 (1)activity綁定browserable與自定義協(xié)議activity設(shè)置“android.intent.category.BROWSABLE”屬性并同時(shí)設(shè)置了自定義的協(xié)議android:scheme意味著可以通過(guò)瀏覽器使用自定義協(xié)議打開(kāi)此activity岖食。可能通過(guò)瀏覽器對(duì)app進(jìn)行越權(quán)調(diào)用舞吭。(2)ActivityManager漏洞ActivityManager類中的killBackgroundProcesses函數(shù)泡垃,用于殺死進(jìn)程析珊,屬于風(fēng)險(xiǎn)API。還有通過(guò)ActivityManager被動(dòng)嗅探intent蔑穴。Intent嗅探腳本首先調(diào)用一個(gè)Context.getSystemService()函數(shù)忠寻,并傳給它一個(gè)ACTIVITY_SERVICE標(biāo)志的標(biāo)識(shí)符,該函數(shù)返回一個(gè)ActivityManager類的實(shí)例存和,它使得該腳本能夠與activity manager進(jìn)行交互奕剃,并通過(guò)這個(gè)對(duì)象調(diào)用ActivityManager.getRecentTasks()方法。最后把intent相關(guān)的信息格式化成字符串返回出來(lái)捐腿。
- Service組件
??作為Android中四大組件之一,擁有重要的地位宪祥。Service具有和Activity一樣的級(jí)別笆载,只是沒(méi)有界面,是運(yùn)行于后臺(tái)的服務(wù)涯呻。其他應(yīng)用組件能夠啟動(dòng)Service凉驻,并且當(dāng)用戶切換到另外的應(yīng)用場(chǎng)景,Service將持續(xù)在后臺(tái)運(yùn)行复罐。另外涝登,一個(gè)組件能夠綁定到一個(gè)service與之交互(IPC機(jī)制),例如效诅,一個(gè)service可能會(huì)處理網(wǎng)絡(luò)操作胀滚,播放音樂(lè),操作文件I/O或者與內(nèi)容提供者(content provider)交互乱投,所有這些活動(dòng)都是在后臺(tái)進(jìn)行咽笼。從表面上看service并不具備危害性,但實(shí)際上service可以在后臺(tái)執(zhí)行一些敏感的操作戚炫。Service存在的安全漏洞包括:權(quán)限提升剑刑,拒絕服務(wù)攻擊。沒(méi)有聲明任何權(quán)限的應(yīng)用即可在沒(méi)有任何提示的情況下啟動(dòng)該服務(wù),完成該服務(wù)所作操作施掏,對(duì)系統(tǒng)安全性產(chǎn)生極大影響钮惠。
- BroadcastReceiver導(dǎo)出漏洞
??當(dāng)應(yīng)用廣播接收器默認(rèn)設(shè)置exported='true',導(dǎo)致應(yīng)用可能接收到第三方惡意應(yīng)用偽造的廣播七芭,利用這一漏洞素挽,攻擊者可以在用戶手機(jī)通知欄上推送任意消息,通過(guò)配合其它漏洞盜取本地隱私文件和執(zhí)行任意代碼狸驳。Android 可以在配置文件中聲明一receiver或者動(dòng)態(tài)注冊(cè)一個(gè)receiver來(lái)接收廣播信息预明,攻擊者假冒APP構(gòu)造廣播發(fā)送給被攻擊的receiver,是被攻擊的APP執(zhí)行某些敏感行為或者返回敏感信息等耙箍,如果receiver接收到有害的數(shù)據(jù)或者命令時(shí)可能泄露數(shù)據(jù)或者做一些不當(dāng)?shù)牟僮髯罚瑫?huì)造成用戶的信息泄漏甚至是財(cái)產(chǎn)損失。
- Content Provider組件漏洞
??Content Provider為存儲(chǔ)和獲取數(shù)據(jù)提供統(tǒng)一的接口究西。可以在不同的應(yīng)用程序之間共享數(shù)據(jù)物喷。
- 讀寫(xiě)權(quán)限漏洞Content Provider中通常都含有大量有價(jià)值的信息卤材,比如用的電話號(hào)碼或者社交帳號(hào)登錄口令,而確認(rèn)一個(gè)content provider是否有能被攻擊的漏洞的最好的辦法峦失,就是嘗試攻擊它一下扇丛。可以用drozer來(lái)尋找一些不需要權(quán)限的contentprovider:dz> runapp.provider.info –permission null這條命令能列出所有不需要任何讀寫(xiě)權(quán)限的Content Provider尉辑,然后找到相對(duì)應(yīng)的包帆精,去訪問(wèn)給定包存放在它的Content Provider中的數(shù)據(jù)。如果一些Content Provider的URI不需要讀權(quán)限隧魄,那就可以通過(guò)drozer工具提取其中的數(shù)據(jù)卓练。在某些情況下,設(shè)置和執(zhí)行讀寫(xiě)權(quán)限不當(dāng)购啄,也會(huì)將ContentProvider中的數(shù)據(jù)暴露給攻擊者襟企。除了提取數(shù)據(jù),對(duì)于寫(xiě)權(quán)限管理不當(dāng)?shù)腃ontent Provider還可以向其中寫(xiě)入數(shù)據(jù)狮含,使得攻擊者可以將惡意數(shù)據(jù)插入到數(shù)據(jù)庫(kù)中顽悼。
- Content Provider中的SQL注入漏洞和Web漏洞類似,安卓APP也要使用數(shù)據(jù)庫(kù)几迄,那就也有可能存在SQL注入漏洞蔚龙。主要有兩類,第一類是SQL語(yǔ)句中的查詢條件子語(yǔ)句是可注入的映胁,第二類是投影操作子句是可注入的木羹。使用drozer可以很容易的找出查詢條件子句可注入的content provider。dz> runapp.provider.query [URI] –selection “1=1”也可以使用其他恒為真的值解孙,例如“1-1=0”汇跨,“0=0”等等务荆。如果APP存在SQL注入漏洞,那么輸入這行指令后就會(huì)返回?cái)?shù)據(jù)庫(kù)中的整張表穷遂。
- Provider文件目錄遍歷漏洞當(dāng)Provider被導(dǎo)出且覆寫(xiě)了openFile方法時(shí)函匕,沒(méi)有對(duì)Content Query Uri進(jìn)行有效判斷或過(guò)濾。攻擊者可以利用openFile()接口進(jìn)行文件目錄遍歷以達(dá)到訪問(wèn)任意可讀文件的目的蚪黑。
2.8.2 組件測(cè)試工具-drozer
??Drozer是MWRLabs開(kāi)發(fā)的一款A(yù)ndroid安全測(cè)試框架盅惜。是目前最好的Android安全測(cè)試工具之一。具體使用方法可參考Android安全測(cè)試框架Drozer(使用篇)忌穿。
環(huán)境準(zhǔn)備:
1 手機(jī)獲得root權(quán)限
2 adb.exe抒寂、配置android環(huán)境變量
3 手機(jī)usb連接開(kāi)啟debug模式(在設(shè)置>關(guān)于手機(jī)>連續(xù)點(diǎn)擊多次版本號(hào),即可開(kāi)啟開(kāi)發(fā)者模式)
4 Window下安裝drozer
5安裝完drozer后在其目錄下把a(bǔ)gent.apk安裝到手機(jī)
連接準(zhǔn)備:
1 drozer console devices
啟動(dòng)drozer:
adb forward tcp:31415 tcp:31415
//將pc端31415的所有數(shù)據(jù)轉(zhuǎn)發(fā)到手機(jī)上的31415端口
drozer console connect
//使用drozer console 連接agent
獲取手機(jī)上所有安裝的app包名:run app.package.list 加上”-f [app關(guān)鍵字]”查找某個(gè)app,如
run app.package.list -f sieve
獲取sieve的基本信息
run app.package.info –a com.mwr.example.sieve
可以看到sieve的版本信息掠剑,數(shù)據(jù)存儲(chǔ)目錄屈芜,用戶ID,組ID朴译,共享庫(kù)井佑,權(quán)限等信息
run app.package.attacksurface com.mwr.example.sieve
進(jìn)一步獲取每個(gè)組件的攻擊面信息,如activity
run app.activity.info
這條命令將導(dǎo)出你設(shè)備上的所有的activity
run app.activity.info -a com.mwr.example.sieve
其中. MainLoginActivity是app啟動(dòng)時(shí)的主界面眠寿,必須可以導(dǎo)出躬翁,但其他兩個(gè)activity正常情況下是不能導(dǎo)出的
用drozer來(lái)啟動(dòng)可導(dǎo)出且不需要權(quán)限的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
結(jié)合上面查看攻擊面的信息,這2個(gè)content provider都可導(dǎo)出盯拱,com.mwr.example.sieve.DBContentProvider/Keys 是需要讀寫(xiě)權(quán)限的
2.8.3客戶端測(cè)試 - 組件導(dǎo)出安全配置
組件完全滿足以下條件之一盒发,則可以導(dǎo)出
顯式聲明了android:exported="true"
未顯式聲明android:exported="false";
組件不是Content Provider狡逢;
組件包含<intent-filter>宁舰;
未顯式聲明android:exported="false";
組件是Content Provider奢浑;
聲明API最小版本<17明吩;
AndroidManifest.xml
AndroidManifest.xml是Android應(yīng)用的入口文件,它描述了package中暴露的組件(activities, services, 等等)殷费,他們各自的實(shí)現(xiàn)類印荔,各種能被處理的數(shù)據(jù)和啟動(dòng)位置。 除了能聲明程序中的Activities, ContentProviders, Services, 和In
android:allowClearUserData(‘true’ or ‘false’)
用戶是否能選擇自行清除數(shù)據(jù)详羡,默認(rèn)為true仍律,程序管理器包含一個(gè)選擇允許用戶清除數(shù)據(jù)。當(dāng)為true時(shí)实柠,用戶可自己清理用戶數(shù)據(jù)水泉,反之亦然
AndroidManifest.xm一些特定屬性的介紹,可自行百度。下面只是幾個(gè)舉例:
android:allowTaskReparenting(‘true’ or ‘false’)
是否允許activity更換從屬的任務(wù)草则,比如從短信息任務(wù)切換到瀏覽器任務(wù)
android:debuggable
這個(gè)從字面上就可以看出是什么作用的钢拧,當(dāng)設(shè)置為true時(shí),表明該APP在手機(jī)上可以被調(diào)試炕横。默認(rèn)為false,在false的情況下調(diào)試該APP源内,就會(huì)報(bào)以下錯(cuò)誤:
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 四大組件中都會(huì)有的一個(gè)屬性。
總體來(lái)說(shuō)它的主要作用是:是否支持其它應(yīng)用調(diào)用當(dāng)前組件卿嘲。
默認(rèn)值:如果包含有intent-filter 默認(rèn)值為true; 沒(méi)有intent-filter默認(rèn)值為false颂斜。
2.9 客戶端測(cè)試 - 本地敏感信息安全
查看應(yīng)用程序所在目錄(需root權(quán)限)
一般為:/data/data/{APP包(package)名}/
如遇.db文件,多為SQLite數(shù)據(jù)庫(kù)拾枣。
正常的文件權(quán)限最后三位應(yīng)為空(類似“rw-rw----”)沃疮,目錄可以多一個(gè)執(zhí)行位(類似“rwxrwx—x”)
Android系統(tǒng)的五種數(shù)據(jù)存儲(chǔ)形式:
分別是文件存儲(chǔ)、SP存儲(chǔ)梅肤、數(shù)據(jù)庫(kù)存儲(chǔ)司蔬、contentprovider 內(nèi)容提供者、網(wǎng)絡(luò)存儲(chǔ)
- 文件存儲(chǔ):
??以I/O流的形式把數(shù)據(jù)存入手機(jī)內(nèi)存或SD卡凭语,可以存儲(chǔ)大數(shù)據(jù)葱她,如音樂(lè)撩扒、圖片或視頻等似扔。對(duì)于手機(jī)內(nèi)存來(lái)說(shuō)系統(tǒng)會(huì)根據(jù)每個(gè)應(yīng)用的包名創(chuàng)建一個(gè)/data/data/包名/的文件夾,訪問(wèn)自己包名下的目錄是不需要權(quán)限的搓谆,并且 Android 已經(jīng)提供了非常簡(jiǎn)便的 API 可以直接去訪問(wèn)該文件夾炒辉。訪問(wèn)時(shí)可以用getFilesDir()和getCacheDir(),兩個(gè)的區(qū)別是系統(tǒng)會(huì)自動(dòng)清理后者中的內(nèi)容。
??SD卡中的文件通常位于mnt/sdcard目錄下泉手,不同生產(chǎn)商生產(chǎn)的手機(jī)這個(gè)路徑可能不同黔寇。操作sd卡的時(shí)通常要判斷下sd卡是否可用以及剩余空間是否足夠,因?yàn)椴糠质謾C(jī)的SD卡可卸載斩萌,SD卡處于非掛載狀態(tài)時(shí)缝裤,無(wú)法進(jìn)行讀寫(xiě)操作。另外一點(diǎn)颊郎,對(duì)SD卡的讀取和寫(xiě)入操作均需要相應(yīng)的權(quán)限憋飞,否則無(wú)法完成。獲取SD卡路徑的方法是Environment.getExternalStorageDirectory()姆吭,其余操作與文件存儲(chǔ)基本類似榛做。
- shared preferences:SP存儲(chǔ)
??可以看到goatdroid應(yīng)用的用戶名和密碼都以明文的形式存儲(chǔ)在 shared preferences中SP存儲(chǔ)本質(zhì)上是一個(gè)XML文件,以鍵值對(duì)的形式存入手機(jī)內(nèi)存中。常用于存儲(chǔ)簡(jiǎn)單的參數(shù)設(shè)置检眯,如登陸賬號(hào)密碼的存儲(chǔ)厘擂,窗口功能狀態(tài)的存儲(chǔ)等,該存儲(chǔ)文件位于:data/data/包名/shared_prefs文件夾中锰瘸。使用的時(shí)候刽严,首先需要通過(guò)context.getSharedPrefrences(String name,int mode)獲取SharedPrefrences的實(shí)例對(duì)象,存儲(chǔ)數(shù)據(jù)時(shí)获茬,用SharedPrefrences的實(shí)例對(duì)象得到SharedPrefrences文件的編輯器港庄,在編輯器中用putXxx()添加數(shù)據(jù),之后務(wù)必用commit提交數(shù)據(jù)恕曲,否則無(wú)法獲取數(shù)據(jù)鹏氧。取數(shù)據(jù)時(shí),直接用getXxx()方法佩谣。
??sp存儲(chǔ)自動(dòng)生成xml文件把还,其的路徑如下:
- 數(shù)據(jù)庫(kù)存儲(chǔ):
??數(shù)據(jù)庫(kù)所有信息都存儲(chǔ)在單一文件內(nèi),占用內(nèi)存小茸俭,并且支持基本SQL語(yǔ)法吊履,是項(xiàng)目中經(jīng)常被采用的一種數(shù)據(jù)存儲(chǔ)方式,通常用于存儲(chǔ)用戶信息等,例如在手機(jī)上做一個(gè)學(xué)生信息管理系統(tǒng)调鬓。SQLite 是一款內(nèi)置到移動(dòng)設(shè)備上的輕量型的數(shù)據(jù)庫(kù)艇炎,SQLiteOpenHelper 是Android 提供的一個(gè)抽象工具類,負(fù)責(zé)管理數(shù)據(jù)庫(kù)的創(chuàng)建腾窝、升級(jí)工作缀踪。數(shù)據(jù)庫(kù)的路徑為:/data/data/應(yīng)用包名/databases/數(shù)據(jù)庫(kù)。
??從手機(jī)文件中導(dǎo)出數(shù)據(jù)庫(kù)文件并不可以直接打開(kāi)虹脯,因此可以用可視化工具和sqlite3操作工具進(jìn)行查看驴娃。這里介紹sqlite3工具的使用。具體需要的步驟如下:
1. 執(zhí)行adb shell命令進(jìn)入Linuxne內(nèi)核循集;
2. 使用cd進(jìn)入數(shù)據(jù)庫(kù)所在的路徑 cd: /data/data/應(yīng)用包名/databases;
3. 進(jìn)入數(shù)據(jù)庫(kù)模式: sqlite3 數(shù)據(jù)庫(kù)名.db;
4. 執(zhí)行SQL語(yǔ)句
- Content Provider:
??Content Provider唇敞,中文名是內(nèi)存提供者,Android四大組件之一咒彤,內(nèi)容提供者是應(yīng)用程序之間共享數(shù)據(jù)的接口疆柔,以數(shù)據(jù)庫(kù)形式存入手機(jī)內(nèi)存,可以共享自己的數(shù)據(jù)給其他應(yīng)用使用镶柱。之所以需要設(shè)計(jì)一個(gè)單獨(dú)的控件來(lái)操作數(shù)據(jù)旷档,是為了實(shí)現(xiàn)應(yīng)用程序之間的數(shù)據(jù)傳遞。通過(guò)查看DDMS中的目錄結(jié)構(gòu)可以看出奸例,數(shù)據(jù)庫(kù)文件對(duì)于其他應(yīng)用來(lái)說(shuō)是不可讀彬犯、不可寫(xiě)向楼,而日常生活中又需要獲取其他應(yīng)用的數(shù)據(jù),尤其是系統(tǒng)自帶軟件的數(shù)據(jù)谐区。比如打開(kāi)QQ或者微信時(shí)會(huì)提示是否同步聯(lián)系人湖蜕,又比如備份短信的時(shí)候,這些都需要訪問(wèn)和操作其他應(yīng)用的數(shù)據(jù)庫(kù)宋列。因此谷歌工程師在底層軟件中集成了大量的方法利用內(nèi)存提供者的原理昭抒,類似于在數(shù)據(jù)庫(kù)中提供一個(gè)對(duì)外訪問(wèn)的路徑,供其他應(yīng)用訪問(wèn)炼杖。
??具體操作是:創(chuàng)建內(nèi)容提供者解析器灭返,定義要訪問(wèn)的Uri的路徑热某。Uri路徑有著固定的格式:”content://主機(jī)名/匹配字符”铅辞。 利用內(nèi)容提供者解析器進(jìn)行增刪改查,和要操作的數(shù)據(jù)庫(kù)之間建立聯(lián)系割粮。以上內(nèi)容通常用來(lái)理解內(nèi)容提供者的工作原理艇纺,實(shí)際工作中很少用到自定義的內(nèi)容提示者怎静。實(shí)際中用的比較多的是用內(nèi)容提供者操作系統(tǒng)聯(lián)系人、系統(tǒng)短信等系統(tǒng)應(yīng)用的數(shù)據(jù)庫(kù)黔衡。
??先看一下短信和手機(jī)聯(lián)系人有關(guān)的數(shù)據(jù)庫(kù)所在的路徑蚓聘。短信在Android 模擬器下存放在的路徑是:/data/data/com.android.providers.telephony/databases/目錄,聯(lián)系人在Android 模擬器下存放在的路徑是:/data/data/com.android.providers.contacts/databases/目錄盟劫。對(duì)于短信數(shù)據(jù)庫(kù)我們關(guān)心的表數(shù)據(jù)有:address夜牡、type、body侣签、date塘装,分別表示發(fā)送者號(hào)碼、短信類型(收還是發(fā))硝岗、短信內(nèi)容氢哮、日期袋毙。對(duì)于聯(lián)系人數(shù)據(jù)庫(kù)的三張表一定要按照一定的順序依次查找才能得到相關(guān)的數(shù)據(jù)型檀,在這不做解釋。盡管開(kāi)發(fā)的時(shí)候不需要了解短信和手機(jī)聯(lián)系人的數(shù)據(jù)庫(kù)路徑听盖,但是要明白短信和手機(jī)聯(lián)系人的數(shù)據(jù)是存在數(shù)據(jù)庫(kù)中的胀溺,同時(shí)數(shù)據(jù)庫(kù)對(duì)外是不開(kāi)放的。
??與短信有關(guān)的數(shù)據(jù)庫(kù)的目錄結(jié)構(gòu):
- 網(wǎng)絡(luò)存儲(chǔ):
??網(wǎng)絡(luò)存儲(chǔ)是最容易理解的一種存儲(chǔ)方式了皆看。其實(shí)說(shuō)簡(jiǎn)單點(diǎn)就是文件的上傳和下載仓坞。經(jīng)常聽(tīng)到的云備份就是這種形式。優(yōu)勢(shì)也很明顯腰吟,即把數(shù)據(jù)存儲(chǔ)到服務(wù)器无埃,不存儲(chǔ)在本地徙瓶,使用的時(shí)候直接從網(wǎng)絡(luò)獲取,避免了手機(jī)端信息丟失以及其他的安全隱患嫉称。因此侦镇,對(duì)于這種形式就不作多的解釋
2.10客戶端測(cè)試 - 本地敏感信息安全
用logcat命令查看APP的日志
清空日志 :logcat -c
實(shí)時(shí)查看日志 :logcat
一次性輸出 :logcat -d
發(fā)布APP前,去掉Log輸出代碼
用DDMS命令查看APP的日志
2.11 客戶端測(cè)試 – 簽名文件的分析檢測(cè)
??對(duì)apk進(jìn)行簽名需要用到簽名證書(shū)和簽名工具织阅。Android系統(tǒng)要求對(duì)APP進(jìn)行簽名的數(shù)字證書(shū)可以由開(kāi)發(fā)者自己生成壳繁。簽名工具有jarsigner和signapk。jarsigner是Java本身自帶的一個(gè)工具荔棉,他也可以對(duì)jar進(jìn)行簽名的闹炉;而signapk是專門為了Android應(yīng)用程序apk進(jìn)行簽名的工具。二者的區(qū)別是:jarsigner工具簽名時(shí)使用的是keystore簽名文件润樱,signapk工具簽名時(shí)使用的是pk8渣触,x509.pem文件。
2.11.1 簽名文件分析
應(yīng)用簽名完后在應(yīng)用的META-INF目錄下會(huì)有三個(gè)文件:
CERT.RSA壹若、CERT.SF和MANIFEST.MF昵观。
- MANIFEST.MF:
??這是摘要文件。程序遍歷Apk包中的所有文件(entry)舌稀,對(duì)非文件夾非簽名文件的文件啊犬,逐個(gè)用SHA1生成摘要信息,再用Base64進(jìn)行編碼壁查。如果你改變了apk包中的文件觉至,那么在apk安裝校驗(yàn)時(shí),改變后的文件摘要信息與MANIFEST.MF的檢驗(yàn)信息不同睡腿,于是程序就不能成功安裝语御。
說(shuō)明:這是Android簽名驗(yàn)證過(guò)程的第一步,保證每個(gè)APK包內(nèi)的每個(gè)文件與MANIFEST.MF中的摘要值一一對(duì)應(yīng)席怪,修改某個(gè)文件內(nèi)容应闯,必須修改MANFEST.MF文件中的摘要值,使他們對(duì)應(yīng)起來(lái)挂捻。
- CERT.SF:
??這是對(duì)摘要的簽名文件碉纺。**對(duì)前一步生成的MANIFEST.MF,對(duì)MANIFEST.MF中的每一條內(nèi)容分別進(jìn)行SHA1計(jì)算刻撒,然后再用Base64編碼轉(zhuǎn)換骨田。此外,把MANIFEST.MF的內(nèi)容也進(jìn)行SHA1計(jì)算声怔,并且計(jì)算BASE64編碼态贤。將上述內(nèi)容寫(xiě)入CERT.SF文件中。(這是為了防止通過(guò)篡改文件和其在MANIFEST.MF中對(duì)應(yīng)的SHA1摘要值來(lái)篡改APK醋火,要對(duì)MANIFEST的內(nèi)容再進(jìn)行一次數(shù)字摘要)悠汽。
說(shuō)明:這是簽名認(rèn)證過(guò)程的第二步箱吕,這一步做的是多第一步得到的簽名文件的摘要,比如第一步中對(duì)文件和MANIFEST.MF摘要都改了柿冲,這一步中MANIFEST.MF的摘要值也要修改殖氏,否則就對(duì)應(yīng)不起來(lái)。
所以姻采,前面這兩步雅采,做的都是摘要,是為第三步驟做準(zhǔn)備的慨亲,第三步驟才是最重要的
- CERT.RSA:
??文件中保存了公鑰婚瓜、所采用的加密算法等信息,此外重要的刑棵,還包括對(duì)CERT.SF中的內(nèi)容的用私鑰進(jìn)行加密之后的值巴刻。
說(shuō)明:在這一步,即使開(kāi)發(fā)者修改了程序內(nèi)容蛉签,并生成了新的摘要文件胡陪,MANIFEST.MF能與內(nèi)容對(duì)應(yīng)起來(lái),CERT.SF也能與內(nèi)容對(duì)應(yīng)起來(lái)碍舍,但是攻擊者沒(méi)有開(kāi)發(fā)者的私鑰柠座,所以不能生成正確的簽名文件(CERT.RSA)。系統(tǒng)在對(duì)程序進(jìn)行驗(yàn)證的時(shí)候片橡,用開(kāi)發(fā)者公鑰對(duì)不正確的簽名文件進(jìn)行解密妈经,得到的結(jié)果對(duì)應(yīng)不起來(lái),所以不能通過(guò)檢驗(yàn)捧书,不能成功安裝文件吹泡。
2.11.2 簽名工具使用:
jarsigner是JDK提供的針對(duì)jar包簽名的通用工具, jarsigner只支持V1簽名经瓷,位于JDK/bin/jarsigner.exe爆哑;
apksigner是Google官方提供的針對(duì)Android apk簽名及驗(yàn)證的專用工具, 默認(rèn)同時(shí)使用V1和V2簽名,以兼容Android 7.0以下版本,位于Android SDK/build-tools/SDK版本/apksigner.bat舆吮。
??不管是apk包,還是jar包,本質(zhì)都是zip格式的壓縮包,所以它們的簽名過(guò)程都差不多(僅限V1簽名)揭朝,以上兩個(gè)工具都可以對(duì)Android apk包進(jìn)行簽名。
V1和V2簽名的區(qū)別:
在Android Studio中點(diǎn)擊菜單 Build->Generate signed apk... 打包簽名過(guò)程中,
可以看到兩種簽名選項(xiàng) V1(Jar Signature) V2(Full APK Signature),
從Android 7.0開(kāi)始, 谷歌增加新簽名方案 V2 Scheme (APK Signature);
但Android 7.0以下版本, 只能用舊簽名方案 V1 scheme (JAR signing)
V1簽名:
來(lái)自JDK(jarsigner), 對(duì)zip壓縮包的每個(gè)文件進(jìn)行驗(yàn)證, 簽名后還能對(duì)壓縮包修改(移動(dòng)/重新壓縮文件)
對(duì)V1簽名的apk/jar解壓,在META-INF存放簽名文件(MANIFEST.MF, CERT.SF, CERT.RSA),
其中MANIFEST.MF文件保存所有文件的SHA1指紋(除了META-INF文件), 由此可知: V1簽名是對(duì)壓縮包中單個(gè)文件簽名驗(yàn)證
V2簽名:
來(lái)自Google(apksigner), 對(duì)zip壓縮包的整個(gè)文件驗(yàn)證, 簽名后不能修改壓縮包(包括zipalign),
對(duì)V2簽名的apk解壓,沒(méi)有發(fā)現(xiàn)簽名文件,重新壓縮后V2簽名就失效, 由此可知: V2簽名是對(duì)整個(gè)APK簽名驗(yàn)證
V2簽名優(yōu)點(diǎn)很明顯:
- 簽名更安全(不能修改壓縮包)
- 簽名驗(yàn)證時(shí)間更短(不需要解壓驗(yàn)證),因而安裝速度加快
查看V1和V2簽名方式
一個(gè)檢測(cè)apk是否支持v1歪泳、v2 簽名的工具萝勤,SignApkV2 簽名檢測(cè)工具
直接調(diào)用:ApkSignerTool.verify(String apkPath)
命令行:
java -jar CheckAndroidSignature.jar xxxx.apk
結(jié)果:
{"ret":0,"msg":"","isV1OK":true,"isV2":true,"isV2OK":true,"keystoreMd5":"8f701cdd1c0d8856e440363185c7daf7"}
2.11.3 簽名步驟
- 1.生成密鑰對(duì)(已有密鑰庫(kù),可忽略)
Eclipse或Android Studio在Debug時(shí),對(duì)App簽名都會(huì)使用一個(gè)默認(rèn)的密鑰庫(kù):
默認(rèn)在C:\Users\用戶名.android\debug.keystore(非安全簽名)
密鑰庫(kù)名: debug.keystore
密鑰別名: androiddebugkey
密鑰庫(kù)密碼: android
生成密鑰對(duì)
進(jìn)入JDK/bin, 輸入命令
keytool -genkeypair -keystore 密鑰庫(kù)名 -alias 密鑰別名 -validity 天數(shù) -keyalg RSA
參數(shù):
-genkeypair 生成一條密鑰對(duì)(由私鑰和公鑰組成)
-keystore 密鑰庫(kù)名字以及存儲(chǔ)位置(默認(rèn)當(dāng)前目錄)
-alias 密鑰對(duì)的別名(密鑰庫(kù)可以存在多個(gè)密鑰對(duì),用于區(qū)分不同密鑰對(duì))
-validity 密鑰對(duì)的有效期(單位: 天)
-keyalg 生成密鑰對(duì)的算法(常用RSA/DSA,DSA只用于簽名,默認(rèn)采用DSA)
-delete 刪除一條密鑰
提示: 可重復(fù)使用此條命令,在同一密鑰庫(kù)中創(chuàng)建多條密鑰對(duì)
例如:
在debug.keystore中新增一對(duì)密鑰,別名是release
keytool -genkeypair -keystore debug.keystore -alias release -validity 30000
為什么報(bào)錯(cuò)了:
這是因?yàn)闄?quán)限問(wèn)題:你的jdk目錄在c盤(pán)露筒,當(dāng)前用戶無(wú)寫(xiě)入權(quán)限呐伞。
所以要么更改jdk的保存目錄,要么更改權(quán)限
方法一更改保存目錄:就是講jdk從c盤(pán)挪到其它盤(pán)慎式。
方法二更改權(quán)限:以管理員身份運(yùn)行CMD伶氢。
我已管理員權(quán)限運(yùn)行CMD
- 2.查看密鑰庫(kù)
進(jìn)入JDK/bin, 輸入命令
keytool -list -v -keystore 密鑰庫(kù)名
參數(shù):
-list 查看密鑰列表
-v 查看密鑰詳情
例如:
keytool -list -v -keystore debug.keystore
現(xiàn)在debug.keystore密鑰庫(kù)中有兩對(duì)密鑰, 別名分別是androiddebugkey release
3.簽名
方法一(jarsigner,只支持V1簽名)
進(jìn)入JDK/bin, 輸入命令
jarsigner -keystore 密鑰庫(kù)名 xxx.apk 密鑰別名
從JDK7開(kāi)始, jarsigner默認(rèn)算法是SHA256, 但Android 4.2以下不支持該算法,
所以需要修改算法, 添加參數(shù) -digestalg SHA1 -sigalg SHA1withRSA
jarsigner -keystore 密鑰庫(kù)名 -digestalg SHA1 -sigalg SHA1withRSA xxx.apk 密鑰別名
參數(shù):
-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
- 方法二(apksigner,默認(rèn)同時(shí)使用V1和V2簽名)
進(jìn)入Android SDK/build-tools/SDK版本, 輸入命令
apksigner sign --ks 密鑰庫(kù)名 --ks-key-alias 密鑰別名 xxx.apk
若密鑰庫(kù)中有多個(gè)密鑰對(duì),則必須指定密鑰別名
apksigner sign --ks 密鑰庫(kù)名 --ks-key-alias 密鑰別名 xxx.apk
禁用V2簽名
apksigner sign --v2-signing-enabled false --ks 密鑰庫(kù)名 xxx.apk
參數(shù):
--ks-key-alias 密鑰別名,若密鑰庫(kù)有一個(gè)密鑰對(duì),則可省略,反之必選
--v1-signing-enabled 是否開(kāi)啟V1簽名,默認(rèn)開(kāi)啟
--v2-signing-enabled 是否開(kāi)啟V2簽名,默認(rèn)開(kāi)啟
例如:
在debug.keystore密鑰庫(kù)只有一個(gè)密鑰對(duì)
apksigner sign --ks debug.keystore MyApp.apk
在debug.keystore密鑰庫(kù)中有多個(gè)密鑰對(duì),所以必須指定密鑰別名
apksigner sign --ks debug.keystore --ks-key-alias androiddebugkey MyApp.ap
4.簽名驗(yàn)證
方法一(keytool,只支持V1簽名校驗(yàn))
進(jìn)入JDK/bin, 輸入命令
keytool -printcert -jarfile MyApp.apk (顯示簽名證書(shū)信息)
參數(shù):
-printcert 打印證書(shū)內(nèi)容
-jarfile <filename> 已簽名的jar文件 或apk文件
- 方法二(apksigner,支持V1和V2簽名校驗(yàn))
進(jìn)入Android SDK/build-tools/SDK版本, 輸入命令apksigner verify -v --print-certs xxx.apk
參數(shù):
-v, --verbose 顯示詳情(顯示是否使用V1和V2簽名)
--print-certs 顯示簽名證書(shū)信息
例如:
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內(nèi)容
Apk 包中的META-INF目錄下趟径,有一個(gè)CERT.RSA,它是一個(gè)PKCS7 格式的文件癣防。
要查看apk簽名信息及證書(shū)內(nèi)容蜗巧,即CERT.RSA文件,可用以下命令:
keytool -printcert -file path
APK解壓后的文件蕾盯,將簽名文件中CERT.RSA拿出來(lái)用apktool 單獨(dú)查看
2.12 客戶端測(cè)試 - 鍵盤(pán)記錄保護(hù)
常見(jiàn)的Android鍵盤(pán)記錄主要依靠讀取/dev/input/event0設(shè)備
需要root幕屹。
需要編寫(xiě)專門的Native測(cè)試工具
鍵盤(pán)、觸屏之類均能捕獲到级遭。
也有通過(guò)注冊(cè)輸入法來(lái)竊聽(tīng)鍵盤(pán)的方法望拖。
2.13 客戶端測(cè)試 - 屏幕錄像測(cè)試
即連續(xù)截屏,通過(guò)視覺(jué)反饋效果來(lái)竊聽(tīng)密碼等敏感信息:
adb shell /system/bin/screencap -p 安卓設(shè)備中的輸出png路徑
需要root挫鸽。
screencap輸出到安卓設(shè)備中说敏,不是輸出到電腦中。
注意: FLAG_SECURE會(huì)妨礙screencap丢郊,敏感信息輸入不提供視覺(jué)反饋
但對(duì)于root權(quán)限下直接讀取屏幕緩存的方法是不起作用的盔沫,測(cè)試中不被認(rèn)定為有效修復(fù)。
2.14 客戶端測(cè)試 - 進(jìn)程注入保護(hù)
設(shè)法在目標(biāo)APP的進(jìn)程空間中執(zhí)行一段代碼枫匾。
一般的方法是在Native層通過(guò)pTrace架诞,讓遠(yuǎn)程進(jìn)程加載一個(gè).so鏈接庫(kù),從而侵入目標(biāo)進(jìn)程空間干茉。
需要root侈贷;
需要編寫(xiě)專門的Native測(cè)試工具;
GDB也使用了類似的方法來(lái)操作遠(yuǎn)程進(jìn)程等脂。
反調(diào)試技術(shù)實(shí)現(xiàn)復(fù)雜俏蛮,一般通過(guò)加殼解決
2.15 客戶端測(cè)試 - Activity/界面劫持保護(hù)
在目標(biāo)APP啟動(dòng)時(shí),立即彈出一個(gè)假界面覆蓋之上遥。
一般是通過(guò)Broadcast Receiver來(lái)監(jiān)聽(tīng)目標(biāo)APP的android.intent.action.BOOT_COMPLETED事件搏屑。
在JAVA層完成,不需要root
誘騙用戶在假界面上操作粉楚,以獲取其敏感信息辣恋,很難察覺(jué)Android 5.0以后從系統(tǒng)機(jī)制層面解決了這個(gè)問(wèn)題,因此如果APK聲明的最小API版本≥21模软,
此項(xiàng)無(wú)需測(cè)試伟骨,直接記為安全。
ApkTool解包后會(huì)產(chǎn)生apktool.yml燃异,內(nèi)含關(guān)于API版本的聲明信息携狭。
2.16 客戶端測(cè)試 – 調(diào)試信息檢測(cè)
檢測(cè)程序(含服務(wù)器端和客戶端)調(diào)試信息是否關(guān)閉,調(diào)試信息中是否寫(xiě)入敏感信息
通過(guò)運(yùn)行程序回俐,查看logcat等調(diào)試日志信息逛腿,是否有泄漏重要的URL地址稀并、提示信息、調(diào)試信息等敏感關(guān)鍵字以及程序邏輯的關(guān)鍵流程单默。對(duì)于HTML頁(yè)面碘举,需要在瀏覽器端打開(kāi),并檢查其中的JS代碼等是否存留其他調(diào)試信息
這里我們用的方式是DDMS:
DDMS 的全稱是Dalvik Debug Monitor Service搁廓,是 Android 開(kāi)發(fā)環(huán)境中的Dalvik虛擬機(jī)調(diào)試監(jiān)控服務(wù)引颈。
這個(gè)工具存放在SDK-tools路徑下,啟動(dòng)方法: [1]
直接雙擊ddms.bat運(yùn)行;
在Eclipse調(diào)試程序的過(guò)程中啟動(dòng)DDMS
雙擊ddms打開(kāi)
我們看到有很多日志輸出,可以觀察運(yùn)行日志中是否帶有敏感數(shù)據(jù)
然后我們找到我們要分析的那個(gè)應(yīng)用包
看他的進(jìn)程ID是2484
然后下面的輸出進(jìn)程都是2484的
實(shí)時(shí)日志中若輸出調(diào)試信息境蜕,攻擊者可根據(jù)輸出信息分析應(yīng)用程序的運(yùn)行邏輯线欲,對(duì)應(yīng)用程序進(jìn)行惡意破壞;也可能泄露用戶敏感信息汽摹。
2.17 客戶端測(cè)試 –Sqlite .db文件的導(dǎo)出
我們的app里面用到sqlite數(shù)據(jù)庫(kù)的時(shí)候李丰, 會(huì)生成一個(gè)db文件,保存在我們手機(jī)中逼泣。有的時(shí)候趴泌,在調(diào)試數(shù)據(jù)庫(kù),很想看一下里面的表結(jié)構(gòu)是否正確拉庶,這個(gè)時(shí)候就十分苦惱嗜憔,因?yàn)檫@個(gè)db文件不能夠直接拿出來(lái),我們知道氏仗,在DDMS里面有一個(gè)FileExplorer吉捶,它里面保存著手機(jī)中的各個(gè)文件夾,但是嘗試打開(kāi)里面的文件夾的時(shí)候皆尔,卻發(fā)現(xiàn)怎么點(diǎn)都沒(méi)有東西呐舔,是真的沒(méi)有嗎?其實(shí)是我們沒(méi)有獲取到訪問(wèn)這個(gè)文件夾的權(quán)限慷蠕。下面我們就開(kāi)始一步一步的拿到真機(jī)調(diào)試中的db文件珊拼。
DDMS可以直接看手機(jī)里文件,如圖:
Data/data/應(yīng)用包名databases/
我們可以看到.db文件就是他的sqllite文件流炕∨煜郑可以直接導(dǎo)出
如果打開(kāi)文件權(quán)限不夠的話,這里利用就可以利用adb直接給打開(kāi)的路徑授權(quán):
比如:
進(jìn)去adb 然后chmod 777 /data/data/com.demo.app/databases/
在導(dǎo)出.db文件后每辟,可以本地打開(kāi).db文件剑辫,分析是否存在敏感信息
推薦工具:
2.18 客戶端測(cè)試 – Sqlite加密檢測(cè)
Android 系統(tǒng)的Sqlite數(shù)據(jù)庫(kù)是一個(gè)輕量級(jí)且沒(méi)有加密功能的數(shù)據(jù)庫(kù),但有時(shí)候我們的數(shù)據(jù)庫(kù)保存了一些重要的信息渠欺,不想讓別人知道妹蔽,就需要對(duì)數(shù)據(jù)庫(kù)加密。但大多數(shù)的加密都需要收費(fèi)的,而Sqlcipher是免費(fèi)的讹开。下面我們用sqlcipher來(lái)加密數(shù)據(jù)庫(kù)盅视。
配置工程:
注意assets下的文件
我們可用工具捐名,對(duì)APP解包后旦万,分析.so文件,
用APK改之理解包了一個(gè)APK:
分析出Sqlite數(shù)據(jù)庫(kù)已做加密镶蹋,做加密后的文件.db導(dǎo)出后是無(wú)法打開(kāi)的:
轉(zhuǎn)載自安全脈搏 https://www.secpulse.com/archives/74861.html