本文主要介紹使用一些工具對(duì)apk進(jìn)行逆向獲取部分源代碼,并通過(guò)frida
對(duì)函數(shù)進(jìn)行Hook并修改其值;使用Burpsuite
對(duì)app請(qǐng)求進(jìn)行抓包并進(jìn)行滲透測(cè)試维贺,本文僅供交流學(xué)習(xí)身坐。
1、逆向
先查看apk是否進(jìn)行加殼姨蝴,若加殼則需要使用脫殼工具進(jìn)行脫殼,脫殼后拿到dex文件使用反編譯工具對(duì)dex文件進(jìn)行反編譯獲取源碼進(jìn)行分析肺缕。
1.1 殼分類
加殼技術(shù) | 特點(diǎn) | 脫殼難度 | 描述 |
---|---|---|---|
第一代:dex 整體加密型殼 | 采用 dex 整體加密左医,動(dòng)態(tài)加載運(yùn)行的機(jī)制 | 較容易被還原,通過(guò)自動(dòng)化脫殼工具或腳本即可從內(nèi)存中 dump 出 dex 文件 | 隱藏 dex 文件 |
第二代:dex 函數(shù)抽取型殼 | 粒度更細(xì)同木,將方法單獨(dú)抽取出來(lái)浮梢,加密保存,解密執(zhí)行 | 可以從根本上進(jìn)行還原的彤路,dump 出所有的運(yùn)行時(shí)的方法體秕硝,填充到 dump 下來(lái)的 dex 中去的,這也是 fart 的核心原理 |
隱藏 dex 并下沉其中部分方法 |
第三代:vmp洲尊、dex2C 殼 | 獨(dú)立虛擬機(jī)解釋執(zhí)行远豺、語(yǔ)義等價(jià)語(yǔ)法遷移,強(qiáng)度最高 | dex2C 目前是沒(méi)有辦法還原的坞嘀,只能跟蹤進(jìn)行分析躯护; vmp虛擬機(jī)解釋執(zhí)行保護(hù)的是映射表,只要心思細(xì)丽涩、功夫深棺滞,是可以將映射表還原 | 虛擬機(jī)里跑虛擬機(jī) |
1.2 脫殼工具
工具 | 描述 |
---|---|
BlackDex | github上開(kāi)源項(xiàng)目,是一個(gè)運(yùn)行在Android手機(jī)上的脫殼工具矢渊,支持5.0~12继准,無(wú)需依賴任何環(huán)境任何手機(jī)(無(wú)需root)都可以使用,包括模擬器矮男。只需幾秒移必,即可對(duì)已安裝包括未安裝的APK進(jìn)行脫殼。 其只能脫第一代的殼昂灵,但也可拿到不少源代碼進(jìn)行分析避凝。 |
Fart | 需刷入定制rom,不過(guò)其也提供了frida_frat供使用眨补,均在其github中管削;詳情可參見(jiàn)ART環(huán)境下基于主動(dòng)調(diào)用的自動(dòng)化脫殼方案。 |
frida-dexdump | 需依賴frida 框架撑螺,安裝及命令均在 github中含思。 |
以上為比較常用的脫殼工具,還有很多其他工具如FDex2、FUPK3等就不再贅述了含潘,需要的可以網(wǎng)上搜索使用教程饲做。
1.3 反編譯工具
工具 | 描述 |
---|---|
jadx | 本人常用的反編譯工具,可直接使用jadx-gui打開(kāi)apk遏弱、aar盆均、jar、dex漱逸、aab泪姨、zip文件查看源代碼 |
dex2jar | 把dex文件轉(zhuǎn)換成jar的工具,有的時(shí)候jadx反編譯失敗可以嘗試使用dex2jar來(lái)進(jìn)行反編譯饰抒,反編譯后用jd-gui或者jadx查看源碼肮砾。 |
以上為我常用的反編譯工具,還有很多其他如CFR 袋坑、Procyon 等由于使用比較麻煩仗处,只進(jìn)行了了解未真正使用。
注:有的時(shí)候jadx加載脫殼后的dex文件時(shí)會(huì)發(fā)現(xiàn)缺少類(特別是各種Activity)枣宫,并且jadx會(huì)提示錯(cuò)誤jadx.plugins.input.dex.DexException: Bad checksum: 0xf0d8fef6, expected: 0xa2ffe277
婆誓,此時(shí)進(jìn)入jadx文件加后使用jadx-gui -Pdex-input.verify-checksum=no
指令運(yùn)行jadx后就會(huì)正常顯示,相應(yīng)的內(nèi)存增量也會(huì)較大镶柱。
2旷档、Hook與動(dòng)態(tài)調(diào)試
Hook俗稱鉤子模叙,本質(zhì)是當(dāng)調(diào)用某段代碼時(shí)同時(shí)會(huì)執(zhí)行Hook代碼歇拆,這樣可以讀取輸入輸出,也可以修改輸入輸出范咨,使用到的技術(shù)包含了反射故觅、動(dòng)態(tài)代理等,也分java層Hook與native層Hook等多種形式渠啊。Hook框架也分為root與非root兩種输吏,非root框架只能Hook本app內(nèi)相關(guān)函數(shù)如epic
、sandhook
等便于開(kāi)發(fā)替蛉,而需root框架則可以Hook系統(tǒng)調(diào)試其他app的框架贯溅,就是接下來(lái)要介紹的重點(diǎn)。
2.1 Hook調(diào)試框架
框架 | 描述 |
---|---|
frida | 一款基于 Python + JavaScript 的 Hook 與調(diào)試框架躲查;易用的跨平 Hook 工具它浅, Java 層到 Native 層的 Hook 無(wú)所不能,是一種動(dòng)態(tài)的插樁工具镣煮,可以插入代碼到原生 App 的內(nèi)存空間中姐霍,動(dòng)態(tài)的去監(jiān)視和修改行為,原生平臺(tái)包括 Win、Mac镊折、Linux胯府、Android、iOS 全平臺(tái)恨胚,是目前主流的hook及動(dòng)態(tài)注入框架骂因。 |
xposed | 一款可以在不修改apk的情況下影響程序運(yùn)行(修改系統(tǒng))的框架服務(wù),基于它可以制作出許多功能強(qiáng)大的模塊赃泡,且在功能不沖突的情況下同時(shí)運(yùn)作侣签。由于使用起來(lái)頗為復(fù)雜,所以其使用率已經(jīng)較少了急迂。 |
2.2 Frida安裝
Frida
分為客戶端(即PC端)與服務(wù)端(即移動(dòng)設(shè)備影所,也成為被控制端)。
hook流程大致是客戶端通過(guò)編寫(xiě)的 Python代碼(也可以通過(guò)指令直接注入js代碼)僚碎,用于連接服務(wù)端設(shè)備猴娩,提交要注入的 js代碼到服務(wù)端,接受服務(wù)端發(fā)來(lái)的消息勺阐;服務(wù)端中需要用 js 代碼注入到目標(biāo)進(jìn)程卷中,操作內(nèi)存數(shù)據(jù),給客戶端發(fā)送消息渊抽。
2.2.1 先安裝Python
這里我使用的Python版本是3.11.0(由于我使用的frida版本比較新蟆豫,所以無(wú)法使用Python2進(jìn)行安裝,若想使用Python2安裝則需降低frida版本)懒闷,可以去官網(wǎng)上下載十减。
2.2.2 安裝Frida
當(dāng)Python安裝好并配置好環(huán)境變量后,可通過(guò)如下指令安裝Frida
客戶端:
pip install frida
//指定版本指令 pip install frida==x.x.x
pip install frida-tools
//指定版本指令 pip install frida-tools==x.x.x
安裝好后可以通過(guò)frida --version
指令查看安裝是否成功愤估,這我安裝的版本是16.0.2
服務(wù)端:
a帮辟、服務(wù)端去其官方github上下載與版本對(duì)應(yīng)的server文件,不過(guò)server文件與系統(tǒng)架構(gòu)也相互對(duì)應(yīng)玩焰,若是跟我一樣使用模擬器的由驹,則可以下載16.0.2版本的x86架構(gòu)sever,若是使用真機(jī)的則可以通過(guò)adb指令查詢手機(jī)架構(gòu)后尋找對(duì)應(yīng)的進(jìn)行下載即可昔园。
注:若模擬器提示Failed to enumerate processes: unable to handle 64-bit processes due to build configuration
蔓榄,需下載x86_64位版本。
b默刚、下載完文件以后解壓出里面的server文件甥郑,使用adb鏈接模擬器(手機(jī)),若是夜神模擬器羡棵,可以通過(guò)
adb connect 127.0.0.1:62001
進(jìn)行連接(不同模擬器端口號(hào)不同)壹若,連接后使用adb push sever文件 data/local/tmp
命令把文件push到手機(jī)data/local/tmp
目錄下push搭配指定目錄后,進(jìn)入shell模式,提高server文件的權(quán)限
//進(jìn)入shell模式
adb shell
//提高權(quán)限
chmod 777 xx-server
su -c xx-server &
//開(kāi)啟服務(wù)
./xx-server
通過(guò)
frida-ps -U
可了解服務(wù)是否運(yùn)行成功以上均成功店展,說(shuō)明環(huán)境已配置完成养篓,下一步可編寫(xiě)一些js注入腳本等進(jìn)行實(shí)測(cè)。
ADB指令
//查看當(dāng)前連接設(shè)備
adb devices
//多個(gè)設(shè)備時(shí)指定設(shè)備
adb -s 設(shè)備號(hào) 其他指令
// adb -s 設(shè)備端口 shell
//127.0.0.1:5555 藍(lán)疊
//127.0.0.1:7555 MUMU模擬器
//127.0.0.1:62001 夜游神模擬器
//127.0.0.1:21503 逍遙模擬器
//查看Android處理器架構(gòu)
adb shell getprop ro.product.cpu.abi
//安裝APP
adb install xxx.apk
//安裝APP,已經(jīng)存在,覆蓋安裝
adb install -r xxx.apk
//強(qiáng)制安裝apk赂蕴,可安裝一些未簽名debug包
adb install -t xxx.apk
//卸載APP
adb uninstall 包名
//卸載APP,保留數(shù)據(jù)
adb uninstall -k 包名
//往手機(jī)傳遞文件
adb push 本地文件 手機(jī)路徑
//從手機(jī)端獲取文件
adb pull 手機(jī)文件 本地路徑
//移動(dòng)文件
mv 文件 路徑
//修改文件權(quán)限
chmod 777 xxx
//查看日志
adb logcat
//清日志
adb logcat -c
//手機(jī)端安裝的所有app包名
adb shell pm list packages
//查看當(dāng)前包名和主Activity
adb shell dumpsys window | findstr mCurrentFocus
//啟動(dòng)APP
adb shell am start 包名/主Activity
//adb shell am start xxx.xxx.XXActivity
//關(guān)閉App
adb shell am force-stop 包名
//屏幕截圖
adb shell screencap 手機(jī)路徑/xxx.png
//錄制視頻
adb shell screenrecord 手機(jī)路徑/xxx.mp4
//轉(zhuǎn)發(fā)端口柳弄,使用python調(diào)試需要使用
adb forward tcp:27042 tcp:27042
adb forward tcp:27043 tcp:27043
Frida指令
//列舉出來(lái)所有連接到電腦上的設(shè)備
frida-ls-devices
//連接到指定設(shè)備
frida-ps -D tcp
//列舉出來(lái)設(shè)備上的所有進(jìn)程
frida-ps -U
//列舉出來(lái)設(shè)備上的所有應(yīng)用程序
frida-ps -Ua
//列舉出來(lái)設(shè)備上的所有已安裝應(yīng)用程序和對(duì)應(yīng)的名字
frida-ps -Uai
//跟蹤某個(gè)函數(shù)
frida-trace -U -f Name -i "函數(shù)名"
//跟蹤某個(gè)方法
frida-trace -U -f Name -m "方法名"
//執(zhí)行js腳本
frida -U -l js腳本 -f packagename --no-pause
2.2.3 js注入hook函數(shù)實(shí)戰(zhàn)
a、先編寫(xiě)一個(gè)簡(jiǎn)單的Demo概说,一個(gè)MainActivity碧注,在onCreate初始化時(shí)打印一個(gè)toast,內(nèi)容是測(cè)試Hook糖赔,代碼如下
安裝到模擬器(手機(jī))效果如下
b萍丐、現(xiàn)在要hook MainActivity的
onCreate
并修改toast
打印內(nèi)容為"hook后,內(nèi)容已被修改"放典,hook_toast_test.js
注入代碼如下
Java.perform(function () {
// hook類: MainActivity
var MainActivity = Java.use("cn.test.hook.MainActivity");
// hook方法: MainActivity.onCreate
MainActivity.onCreate.implementation = function (savedInstanceState) {
//控制臺(tái)輸出log日志逝变,方便監(jiān)控程序運(yùn)行
console.log("執(zhí)行onCreate");
// 程序不被終端,繼續(xù)執(zhí)行
this.onCreate(savedInstanceState);
};
// 獲得Toast組件
var Toast = Java.use("android.widget.Toast");
var makeText = Toast.makeText;
var String = Java.use("java.lang.String");
// 函數(shù)重載, 設(shè)置參數(shù)類型
makeText.overload("android.content.Context", "java.lang.CharSequence", "int").implementation = function (
context,
content,
time
) {
//控制臺(tái)輸出log日志奋构,方便監(jiān)控程序運(yùn)行
console.log("修改toast內(nèi)容");
// 設(shè)置新內(nèi)容
var content = "hook后壳影,內(nèi)容已被修改";
// 實(shí)例化字符串
var hookContent = String.$new(content);
// 程序不被終端,繼續(xù)執(zhí)行
return this.makeText(context, hookContent, time);
};
});
注:如果需要了解更多的Api可去官方Frida JavaScript Api文檔中學(xué)習(xí)弥臼。
c宴咧、直接通過(guò)指令運(yùn)行js腳本frida -U -f cn.test.hook --pause -l F:\workspace\vshook\hook_toast_test.js
來(lái)執(zhí)行hook_toast_test.js
腳本,模擬器會(huì)啟動(dòng)包名為cn.test.hook
的應(yīng)用程序径缅,并執(zhí)行hook與注入等
2.2.4 使用編輯器進(jìn)行動(dòng)態(tài)調(diào)試
我常用的編輯器是VS Code掺栅,安裝擴(kuò)展frida Workbench
后會(huì)顯示一個(gè)R的標(biāo)志,當(dāng)啟動(dòng)frida-server后并使用adb轉(zhuǎn)發(fā)端口芥驳,VS Code中就可以顯示相應(yīng)的設(shè)備可直接進(jìn)行動(dòng)態(tài)調(diào)試柿冲,這樣就可以使用VS Code來(lái)編寫(xiě)python腳本加載js注入代碼來(lái)完成更多的功能,調(diào)試起來(lái)也相對(duì)方便兆旬。
以上為一個(gè)hook注入操作的基本過(guò)程。
3怎栽、滲透測(cè)試
3.1丽猬、工具
常用Burpsuite,網(wǎng)上自取熏瞄,安裝教程可參見(jiàn)Burpsuite的超詳細(xì)安裝教程(圖文版)脚祟。
3.1.1、抓數(shù)據(jù)
中間人攻擊
步驟1:設(shè)置代理
點(diǎn)擊Add后操作
步驟2:開(kāi)啟intercept
步驟3:模擬器手機(jī)設(shè)置代理
步驟4:抓取數(shù)據(jù)
3.1.2强饮、https協(xié)議證書(shū)安裝
由于有的app使用的https協(xié)議由桌,抓包數(shù)據(jù)為密文數(shù)據(jù),需要設(shè)置中間人證書(shū),在步驟1中圖示5導(dǎo)出證書(shū)cacert.der
行您,由于android無(wú)法使用der證書(shū)铭乾,需要使用openssl指令對(duì)證書(shū)進(jìn)行導(dǎo)出,可以使用mac娃循、linux系統(tǒng)進(jìn)行操作或者windows安裝openssl也可以炕檩。6.0及以下系統(tǒng)可直接安裝證書(shū),7.0及以上系統(tǒng)由于不再信任非系統(tǒng)證書(shū)捌斧,所以需要把證書(shū)安裝到系統(tǒng)證書(shū)中笛质,模擬器(手機(jī))需要有root權(quán)限
//der轉(zhuǎn)pem
sudu openssl x509 --inform cacert.der -in cacert.der -put burp.pem
//顯示pem詳細(xì)信息
sudu openssl x509 -in burp.pem --subject_hash_old
//把pen轉(zhuǎn)成9a5ba575.0證書(shū)
sudo cp burp.pem 9a5ba575.0
得到9a5ba575.0證書(shū)后,
//設(shè)置remount
adb remount
//把證書(shū)push到系統(tǒng)證書(shū)中
adb push 9a5ba575.0 /system/etc/security/cacerts/
//重啟手機(jī)
adb shell reboot
模擬器(手機(jī))重啟后在設(shè)置->安全->信任的憑據(jù)->系統(tǒng)中查看是否有PowerSwigger
捞蚂,若存在說(shuō)明證書(shū)安裝成功妇押,再抓取https協(xié)議請(qǐng)求后密文數(shù)據(jù)可顯示為明文。
注:有的人在正確配置各項(xiàng)后打開(kāi)app依然無(wú)法抓取請(qǐng)求姓迅,甚至burp中沒(méi)有相應(yīng)的請(qǐng)求舆吮,但是app中顯示數(shù)據(jù)已請(qǐng)求完成,這種情況可能是app在代碼中設(shè)置了網(wǎng)絡(luò)請(qǐng)求繞過(guò)
proxy
队贱,遇到這種情況有兩種解決方式:1色冀、使用Proxifier
開(kāi)啟一個(gè)代理通道,無(wú)需手機(jī)配置代理柱嫌;2锋恬、反編譯源碼查看設(shè)置繞過(guò)proxy
的代碼部分,對(duì)proxy
代碼進(jìn)行hook并繞過(guò)校驗(yàn)编丘。
3.2与学、實(shí)際操作
待更新