0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

基于frida-inject腳本持久化開(kāi)發(fā)實(shí)戰(zhàn)分享

哆啦安全 ? 來(lái)源:卓碼星球 ? 2023-12-09 14:43 ? 次閱讀

主要內(nèi)容:

frida-inject腳本持久化的方案

App開(kāi)關(guān)文件目錄以及腳本存儲(chǔ)文件目錄selinux配置

封裝和超級(jí)Root權(quán)限后臺(tái)進(jìn)程通信java Api接口以及封裝訪問(wèn)腳本相關(guān)目錄文件的Java接口

系統(tǒng)源碼中添加App啟動(dòng)的時(shí)候執(zhí)行frida-inject命令的邏輯代碼

開(kāi)發(fā)控制App實(shí)現(xiàn)對(duì)第三方App 持久化的配置

1.frida-inject腳本持久化方案原理

方案原理:

在系統(tǒng)源碼App啟動(dòng)入口的地方,找一個(gè)合適的時(shí)機(jī)。將frida-inject組裝執(zhí)行附加的命令通過(guò)Socket連接發(fā)送到超級(jí)Root權(quán)限后臺(tái)進(jìn)程中執(zhí)行,達(dá)到實(shí)現(xiàn)App啟動(dòng)就加載js腳本的功能。App啟動(dòng)入口加載時(shí)機(jī)我們選擇ActivityThread.java中的handleBindApplication方法。以下是該方案的一個(gè)圖示:

49effbb8-9659-11ee-8b88-92fbcf53809c.jpg

2.持久化相關(guān)目錄文件創(chuàng)建及selinux配置

2.1 文件及目錄設(shè)計(jì)

在該方案中,設(shè)計(jì)以下的文件目錄用來(lái)判斷App是否需要開(kāi)啟frida inject持久化以及加載的js文件路徑。設(shè)計(jì)如下:

#配置某一個(gè)App是否開(kāi)啟持久化功能,$PKG_NAME表示App的包名
#比如一個(gè)參考:/data/system/xsettings/frdinject/persist/com.android.jnidemo01/persist_fridainject
/data/system/xsettings/frdinject/persist/$PKG_NAME/persist_fridainject

#配置某一個(gè)App加載的js文件路徑,$PKG_NAME表示App的包名
#/data/system/xsettings/frdinject/jscfg/com.android.jnidemo01/config.js
/data/system/xsettings/frdinject/jscfg/$PKG_NAME/config.js

在涉及以上的文件或者目錄中,管控端App具有system權(quán)限,需要配置系統(tǒng)權(quán)限的App對(duì)以上文件或者目錄讀寫(xiě)的selinux權(quán)限。普通App需要對(duì)以上文件有讀的權(quán)限,所以需要配置第三方App具有讀以上文件的selinux權(quán)限。

2.2 配置selinux操作

(1).創(chuàng)建文件類型selinux標(biāo)簽

在如下文件中創(chuàng)建文件標(biāo)簽frdinject_data_file,文件列表:

systemsepolicypublicfile.te
systemsepolicyprebuiltsapi29.0publicfile.te

在以上文件中添加如下內(nèi)容,需要保證兩個(gè)文件添加的內(nèi)容一致。不然要編譯錯(cuò)誤。

#/data/system/xsettings/
typefrdinject_data_file,file_type,data_file_type,core_data_file_type,mlstrustedobject;

(2).為文件目錄關(guān)聯(lián)frdinject_data_file標(biāo)簽

在如下文件中添加關(guān)聯(lián)/data/system/xsettings目錄selinux標(biāo)簽,文件列表:

systemsepolicyprebuiltsapi29.0privatefile_contexts
systemsepolicyprivatefile_contexts

在以上文件中添加如下內(nèi)容,需要保證兩個(gè)文件添加的內(nèi)容一致。不然要編譯錯(cuò)誤。

/data/system/xsettings(/.*)?ufrdinject_data_file:s0

(3).配置App訪問(wèn)frdinject_data_file標(biāo)簽的權(quán)限

這個(gè)地方主要配置兩種App。一種是system權(quán)限的配置端App。第二種是第三方App。

具有系統(tǒng)權(quán)限的配置端App selinux配置如下:

在如下文件中:

systemsepolicyprivatesystem_app.te
systemsepolicyprebuiltsapi29.0privatesystem_app.te

添加如下訪問(wèn)權(quán)限,添加之后請(qǐng)保持兩個(gè)文件內(nèi)容一致:

#addforaccessingfrdinject_data_file
allowsystem_appfrdinject_data_file:dir{getattrsetattropenreadwriteremove_namecreateadd_namesearchrmdir};
allowsystem_appfrdinject_data_file:file{getattrsetattropenreadwritecreateunlink};

第三方App配置selinux如下:

在以下文件中添加app訪問(wèn)文件夾的selinux策略。確保相對(duì)應(yīng)的文件內(nèi)容一致。

在以下untrusted_app_all.te文件:

systemsepolicyprivateuntrusted_app_all.te
systemsepolicyprebuiltsapi29.0privateuntrusted_app_all.te

添加內(nèi)容如下:

#addforaccessingfrdinject_data_file
allowuntrusted_app_allfrdinject_data_file:dir{getattropenreadsearch};
allowuntrusted_app_allfrdinject_data_file:file{getattropenread};

在以下untrusted_app_27.te文件:

systemsepolicyprivateuntrusted_app_27.te
systemsepolicyprebuiltsapi29.0privateuntrusted_app_27.te

在以下文件:

#addforaccessingfrdinject_data_file
allowuntrusted_app_27frdinject_data_file:dir{getattropenreadsearch};
allowuntrusted_app_27frdinject_data_file:file{getattropenread};

在以下untrusted_app_25.te文件:

systemsepolicyprivateuntrusted_app_25.te
systemsepolicyprebuiltsapi29.0privateuntrusted_app_25.te
#addforaccessingfrdinject_data_file
allowuntrusted_app_25frdinject_data_file:dir{getattropenreadsearch};
allowuntrusted_app_25frdinject_data_file:file{getattropenread};

在以下untrusted_app.te文件:

systemsepolicyprivateuntrusted_app.te
systemsepolicyprebuiltsapi29.0privateuntrusted_app.te
#addforaccessingfrdinject_data_file
allowuntrusted_appfrdinject_data_file:dir{getattropenreadsearch};
allowuntrusted_appfrdinject_data_file:file{getattropenread};

2.3 init.rc中配置開(kāi)機(jī)的時(shí)候就創(chuàng)建對(duì)應(yīng)的目錄

該持久化實(shí)現(xiàn)中,使用了如下目錄。

/data/system/xsettings/frdinject/persist
/data/system/xsettings/frdinject/jscfg

所以可以將該目錄放在init進(jìn)程啟動(dòng)的時(shí)候進(jìn)行創(chuàng)建。由于init進(jìn)程會(huì)解析init.rc文件執(zhí)行配置的命令,所以可以根據(jù)init.rc創(chuàng)建文件夾的規(guī)則加入創(chuàng)建以上兩個(gè)目錄的操作。在systemcore ootdirinit.rc文件中添加內(nèi)容如下:

#/data/system/xsettings/frdinject/persist
mkdir/data/system/xsettings0775systemsystem
mkdir/data/system/xsettings/frdinject0775systemsystem
mkdir/data/system/xsettings/frdinject/persist0775systemsystem
mkdir/data/system/xsettings/frdinject/jscfg0775systemsystem

3.系統(tǒng)源碼中相關(guān)Java接口封裝

3.1 封裝和超級(jí)Root權(quán)限通信的MgskSu模塊

在源碼根目錄中創(chuàng)建如下對(duì)應(yīng)的目錄:

frameworksasecorejavaandroidxfrd

在目錄xfrd中將存放MgskSu模塊的接口實(shí)現(xiàn)。具體實(shí)現(xiàn)如下:

packageandroid.xfrd;

importjava.io.BufferedReader;
importjava.io.BufferedWriter;
importjava.io.InputStreamReader;
importjava.io.OutputStreamWriter;
importjava.net.InetSocketAddress;
importjava.net.Socket;

publicclassMgskSu{

publicstaticStringmagiskSu(Stringcmd)
{
StringretString="";
try{
//創(chuàng)建socket
StringmyCmd="do_cmd|"+cmd;
SocketmSocket=newSocket();
InetSocketAddressinetSocketAddress=newInetSocketAddress("127.0.0.1",11111);
mSocket.connect(inetSocketAddress);
BufferedWriterbufferedWriter=newBufferedWriter(newOutputStreamWriter(mSocket.getOutputStream()));
BufferedReaderbufferedReader=newBufferedReader(newInputStreamReader(mSocket.getInputStream()));
bufferedWriter.write(myCmd+"
");
bufferedWriter.flush();
retString=bufferedReader.readLine();
bufferedReader.close();
bufferedWriter.close();
}catch(Exceptioneeeee)
{
eeeee.printStackTrace();
}
returnretString;
}
}

3.2 封裝針對(duì)App需要持久化判斷和獲取對(duì)應(yīng)js文件路徑的接口

在該方案中通過(guò)對(duì)應(yīng)App的包名組裝文件路徑來(lái)識(shí)別是否存在來(lái)判斷App是否需要啟動(dòng)就加載js文件。在MagiskSu.java同目錄中創(chuàng)建FrdSettings.java模塊文件。核心代碼如下:

packageandroid.xfrd;


importandroid.system.Os;
importjava.io.File;

publicclassFrdSettings{

staticfinalStringTAG=FrdSettings.class.getSimpleName();
privatestaticfinalStringSETTINGS_DIR="/data/system/xsettings/frdinject/persist";
privatestaticfinalStringCONFIG_JS_DIR="/data/system/xsettings/frdinject/jscfg";
publicstaticfinalStringPERSIST_FRIDA_INJECT="persist_fridainject";
publicstaticfinalStringPERSIST_FRIDA_GADGET="persist_fridagadget";
publicstaticfinalStringPERSIST_FRIDA_GUMJS="persist_fridagumjs";
//

publicstaticbooleanisAppJsPathExists(StringpkgName){
Filefile=newFile(CONFIG_JS_DIR+"/"+pkgName+"/config.js");
returnfile.exists();
}
publicstaticStringgetAppJsPath(StringpkgName)
{

Filefile=newFile(CONFIG_JS_DIR+"/"+pkgName+"/config.js");
returnfile.getAbsolutePath();
}


/**********************判斷是否開(kāi)啟持久化***************************/
//設(shè)置對(duì)應(yīng)的App是否開(kāi)啟持久化
publicstaticvoidsetEnablePersistFridaInject(StringpkgName,StringmethodType,booleanisEnable){
Filefile=newFile(SETTINGS_DIR);
if(!file.exists()){
file.mkdirs();
try{
Os.chmod(file.getAbsolutePath(),0775);
}catch(Exceptioneeee){

}
}
FilepkgFile=newFile(file,pkgName);
if(!pkgFile.exists()){
pkgFile.mkdirs();
try{
Os.chmod(pkgFile.getAbsolutePath(),0775);
}catch(Exceptioneeee){
eeee.printStackTrace();
}
}
FileenableFile=newFile(pkgFile,methodType);
if(isEnable){
if(!enableFile.exists()){

try{
enableFile.createNewFile();
//MyLog.d(TAG,"createfilesuccess");
Os.chmod(enableFile.getAbsolutePath(),0775);
}catch(Exceptioneeee){
//MyLog.d(TAG,"filecreateerrror:"+enableFile.getAbsolutePath());
eeee.printStackTrace();
}
}else{
//MyLog.d(TAG,"fileexists:"+enableFile.getAbsolutePath());
}
}else{
if(enableFile.exists()){
enableFile.delete();
}
}

}

//判斷app是否打開(kāi)自動(dòng)注入腳本功能
publicstaticbooleanisEnablePersistFrida(StringpkgName,StringmethodType){
FileenableFile=newFile(SETTINGS_DIR,pkgName+"/"+methodType);
returnenableFile.exists();
}
}

4.源碼中在App啟動(dòng)入口ActivityThread.java中添加加載js邏輯

在之前方案分析中已經(jīng)找到了在frameworksasecorejavaandroidappActivityThread.java中的handleBindApplication方法中加入加載js的邏輯是一個(gè)比較不錯(cuò)的選擇。在handleBindApplication中加入如下關(guān)鍵調(diào)用代碼,實(shí)現(xiàn)App啟動(dòng)的時(shí)候就去加載執(zhí)行js。核心關(guān)鍵代碼如下:

StringcurPkgName=data.appInfo.packageName;
intmypid=Process.myPid();
intmytempUid=Process.myUid();

if(mytempUid>10000)
{
BooleanisB=FrdSettings.isEnablePersistFrida(curPkgName,FrdSettings.PERSIST_FRIDA_INJECT);
Log.d("FridaInject","curPkgNameisEnableFridaInject:"+isB);
if(isB)
{
StringjsPath=FrdSettings.getAppJsPath(curPkgName);
if(jsPath!=null)
{
//這個(gè)地方比較重要,不然App運(yùn)行會(huì)奔潰。
//App中主線程中調(diào)用網(wǎng)絡(luò)socket操作配置
android.os.StrictMode.ThreadPolicypolicy=newandroid.os.StrictMode.ThreadPolicy.Builder().permitAll().build();
android.os.StrictMode.setThreadPolicy(policy);
StringcmdString="myfridainjectarm64-p"+mypid+"-s"+jsPath+"-e";
StringretString=MgskSu.magiskSu(cmdString);
try{
Thread.sleep(50);
}catch(Exceptioneee)
{
}
Log.d("FridaInject","retStringis"+retString);
}else{
Log.d("FridaInject","jsPathisnull");
}
}else{

}

}

5.控制端App開(kāi)發(fā)實(shí)現(xiàn)對(duì)第三方App持久化配置

控制端App中對(duì)App是否持久化開(kāi)關(guān)配置以及js路徑配置使用的封裝接口和以上系統(tǒng)源碼中封裝的FrdSettings.java是一樣的封裝。這個(gè)地方就不講接口的封裝了。只說(shuō)一下幾個(gè)關(guān)鍵的地方使用。

配置界面參考:

4a02e69c-9659-11ee-8b88-92fbcf53809c.jpg

主要涉及的幾個(gè)接口調(diào)用如下:

(1).打開(kāi)/關(guān)閉第三方App加載js功能

調(diào)用了封裝的接口:setEnablePersistFridaInject

(2).將選擇的js文件復(fù)制到對(duì)應(yīng)App的配置js目錄

調(diào)用了封裝的接口:copyJsFileToAppJsPath

(3).判斷App當(dāng)前是否配置了加載js功能

調(diào)用了封裝的接口:isEnablePersistFrida

(4).獲取App配置的js文件路徑

置以及js路徑配置使用的封裝接口和以上系統(tǒng)源碼中封裝的FrdSettings.java是一樣的封裝。這個(gè)地方就不講接口的封裝了。只說(shuō)一下幾個(gè)關(guān)鍵的地方使用。

配置界面參考:

[外鏈圖片轉(zhuǎn)存中…(img-L6IhssD7-1667868558625)]

主要涉及的幾個(gè)接口調(diào)用如下:

(1).打開(kāi)/關(guān)閉第三方App加載js功能

調(diào)用了封裝的接口:setEnablePersistFridaInject

(2).將選擇的js文件復(fù)制到對(duì)應(yīng)App的配置js目錄

調(diào)用了封裝的接口:copyJsFileToAppJsPath

(3).判斷App當(dāng)前是否配置了加載js功能

調(diào)用了封裝的接口:isEnablePersistFrida

(4).獲取App配置的js文件路徑

調(diào)用了封裝接口:getAppJsPath







審核編輯:劉清

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • JAVA
    +關(guān)注

    關(guān)注

    19

    文章

    2952

    瀏覽量

    104489
  • API接口
    +關(guān)注

    關(guān)注

    1

    文章

    82

    瀏覽量

    10420

原文標(biāo)題:基于frida-inject腳本持久化開(kāi)發(fā)實(shí)戰(zhàn)

文章出處:【微信號(hào):哆啦安全,微信公眾號(hào):哆啦安全】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    Windows/Ubuntu安裝frida和objection

    Windows環(huán)境使用管理員權(quán)限安裝frida,Ubuntu使用普通或Root權(quán)限安裝均可。
    發(fā)表于 11-17 09:36 ?1140次閱讀

    Linux Shell腳本入門到實(shí)戰(zhàn)詳解

    Linux Shell腳本入門到實(shí)戰(zhàn)詳解
    發(fā)表于 02-17 15:03 ?621次閱讀

    frida-inject工具使用及說(shuō)明 內(nèi)置frida-inject工具到手機(jī)系統(tǒng)

    frida-injectfrida中提供的可以直接放到手機(jī)端執(zhí)行注入js腳本到App程序進(jìn)行hook的工具。也就是說(shuō)使用frida-inject命令可以脫離PC端執(zhí)行注入了。
    的頭像 發(fā)表于 10-26 10:42 ?5859次閱讀

    自動(dòng)化測(cè)試腳本開(kāi)發(fā)技巧

    開(kāi)發(fā)自動(dòng)化測(cè)試腳本的技巧和心得軟件測(cè)試 增量式調(diào)試腳本 錄制測(cè)試腳本,和其他的軟件開(kāi)發(fā)成果一樣,會(huì)變得非常大。為了可以成功的回放,需要調(diào)試幾
    發(fā)表于 03-26 16:24 ?53次下載

    LabVIEW入門與實(shí)戰(zhàn)開(kāi)發(fā)100例

    LabVIEW入門與實(shí)戰(zhàn)開(kāi)發(fā)100例LabVIEW入門與實(shí)戰(zhàn)開(kāi)發(fā)100例LabVIEW入門與實(shí)戰(zhàn)開(kāi)發(fā)
    發(fā)表于 02-18 11:44 ?0次下載

    Python項(xiàng)目開(kāi)發(fā)實(shí)戰(zhàn)1-50

    Python項(xiàng)目開(kāi)發(fā)實(shí)戰(zhàn)
    發(fā)表于 03-27 09:02 ?55次下載

    c#開(kāi)發(fā)Android應(yīng)用實(shí)戰(zhàn)

    c#開(kāi)發(fā)Android應(yīng)用實(shí)戰(zhàn)
    發(fā)表于 07-14 13:32 ?0次下載

    如何使用Myeclipse進(jìn)行java可視化開(kāi)發(fā)

    本文檔的主要內(nèi)容詳細(xì)介紹的是如何使用Myeclipse進(jìn)行java可視化開(kāi)發(fā)。實(shí)現(xiàn)Java的可視化開(kāi)發(fā)
    發(fā)表于 01-10 10:38 ?5次下載
    如何使用Myeclipse進(jìn)行java可視<b class='flag-5'>化開(kāi)發(fā)</b>

    JavaScript模塊化開(kāi)發(fā)實(shí)驗(yàn)---webpack入門

    JavaScript模塊化開(kāi)發(fā)實(shí)驗(yàn)---webpack入門(現(xiàn)代電源技術(shù)試題及答案)-文檔為JavaScript模塊化開(kāi)發(fā)實(shí)驗(yàn)---webpack入門總結(jié)文檔,是一份不錯(cuò)的參考資料,感興趣的可以下載看看,,,,,,,,,,,,,
    發(fā)表于 09-17 14:49 ?7次下載
    JavaScript模塊<b class='flag-5'>化開(kāi)發(fā)</b>實(shí)驗(yàn)---webpack入門

    arduino開(kāi)發(fā)實(shí)戰(zhàn)指南

    arduino開(kāi)發(fā)實(shí)戰(zhàn)指南
    發(fā)表于 02-22 14:56 ?0次下載

    Python項(xiàng)目開(kāi)發(fā)實(shí)戰(zhàn)

    Python項(xiàng)目開(kāi)發(fā)實(shí)戰(zhàn)
    發(fā)表于 06-13 14:51 ?2次下載

    淺談IoT Power的Lua腳本開(kāi)發(fā)應(yīng)用

    Lua腳本開(kāi)發(fā)簡(jiǎn)單快速,在Cat.1和MCU開(kāi)發(fā)應(yīng)用中已歷經(jīng)驗(yàn)證并廣受好評(píng)。所以LuatOS社群經(jīng)常有人問(wèn):合宙推出的口袋神器——IoT Power,可以腳本
    的頭像 發(fā)表于 09-05 14:43 ?1137次閱讀

    安卓常規(guī)逆向操作涉及到的知識(shí)點(diǎn)介紹

    持久frida(獨(dú)立執(zhí)行frida,不需要借助adb 執(zhí)行frida-server終端命令)
    的頭像 發(fā)表于 09-20 09:13 ?768次閱讀
    安卓常規(guī)逆向操作涉及到的知識(shí)點(diǎn)介紹

    基于frida的Objection對(duì)APP逆向過(guò)程的作用

    在APP的逆向過(guò)程中避免借助使用一些反匯編工具,動(dòng)靜態(tài)調(diào)試分析工具,自然也免不了和frida這個(gè)工具打交道,frida作為強(qiáng)大的逆向分析工具在攻防過(guò)程中具有不可撼動(dòng)的地位。
    的頭像 發(fā)表于 10-09 11:08 ?4282次閱讀

    Android使用Wireshark抓包

    Frida逆向分析APP實(shí)戰(zhàn) Objection動(dòng)態(tài)分析App Frida Hook的使用方法 Android逆向分析基礎(chǔ)(一) Android逆向分析基礎(chǔ)(二) 使用frida-ne
    的頭像 發(fā)表于 11-16 10:07 ?4040次閱讀