目錄
一 . 埋頭分析踩坑路
1.okhttp呼叫流程
首頁 運維 安全 frida如何抓apk網路包

frida如何抓apk網路包

May 16, 2023 pm 07:16 PM
apk frida

一 . 埋頭分析踩坑路

從系統的角度去尋找hook點,而不是為了抓包而抓包。

1.okhttp呼叫流程

public static final MediaType JSON
= MediaType.get("application/json; charset=utf-8");

OkHttpClient client = new OkHttpClient();

String post(String url, String json) throws IOException {
RequestBody body = RequestBody.create(json, JSON);
Request request = new Request.Builder()
.url(url)
.post(body)
.build();
try (Response response = client.newCall(request).execute()) {
return response.body().string();
}
}
登入後複製

客戶端的重要程式碼在client.newCall()上,上面是okhttp官網的範例。從此處介面呼叫開始,終會呼叫至okhttp框架, okhttp本是sdk,後來aosp已經整合至系統,所以可以歸類至框架層。

框架層不詳述,主要就是這幾個java類別:

com.android.okhttp.internal.huc.HttpURLConnectionImpl
com.android.okhttp.internal.http.HttpEngine
com.android.okhttp.internal.http.RetryableSink
com.android.okhttp.internal.http.CacheStrategy$Factory
登入後複製

其實client.newCall終會透過URL取得一個connection

HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
登入後複製

這裡的urlConnection其實就是HttpURLConnectionImpl的實例,該類別有getInputStream getOutputStream方法,內部分別會呼叫HttpEngine的getBufferedRequestBody,getResponse。剛開始我嘗試hook過這兩個接口,例如hook getResponse後,可以將response印出來.

後來我發現,Request只能輸出header,無法輸出body。所以又埋頭繼續分析,getBufferedRequestBody這個函數剛好可以入手,取得一個sink,最後以RetryableSink為突破點,例如hook 其write函數就可以將body印出來。 write函數對應於app層面的urlConnection.getOutputStream().write。

後來發現一個Request,呼叫getBufferedReuqestBody函數可能不只一次,所以會有資料重複的問題,後來我又尋找到了CacheStrategy$Factory.get點進行Hook,發現還是有資料重複。發現以上hook都有弊端

  • 資料重複

  • #非okhttp呼叫無法抓取

##然後也列印了從native層的send,sendmsg,write,recv,read開始的呼叫堆疊。最後折騰了三天,決定放棄治療,還是採取工具吧。

okhttp流程:sdk接口->okhttp框架->native(libc)
登入後複製
2.分析過程中frida踩到的坑(重點都在註解中)

  1. android.util.Log不印

    var Logd = function Logd(tag, msg) {
    Java.use("android.util.Log").d(tag, msg);
    };
    
    
    Logd('http-body-', '11111111111111');//该log不打印
    Logd('http-body', '11111111111111');//该log打印
    登入後複製
  2. 匿名內部類別取得成員需要反射

    var printRequest = function(request) {
    var Buffer = Java.use("com.android.okhttp.okio.Buffer");
    var bodyField = request.getClass().getDeclaredField('body');
    bodyField.setAccessible(true);
    
    if (request == null) return;
    Logd('http', 'printRequest: request' + request);
    //var requestBody = request.body();//gadget直接报错
    var requestBody = bodyField.get(request);
    
    var requestBodyClass = requestBody.getClass();
    var ClassInstanceArray = Java.array('java.lang.Class', []);
    
    //var contentLengthMethod = requestBodyClass.getMethod("contentLength");//gadget直接报错
    var contentLengthMethod = requestBodyClass.getMethod("contentLength", ClassInstanceArray);
    
    contentLengthMethod.setAccessible(true);
    var ObjectInstanceArray = Java.array('java.lang.Object', []);
    var contentLength = requestBody ? contentLengthMethod.invoke(requestBody, ObjectInstanceArray) : 0;
    //if (contentLength == 0) contentLength = contentLen;
    Logd('http', 'printRequest contentLength: ' + contentLength);
    if (contentLength > 0) {
    var BufferObj = Buffer.$new();
    requestBody.writeTo(BufferObj);
    Logd(TAG, "\nrequest body :\n" + BufferObj.readString() + "\n");
    }
    };
    登入後複製
  3. android.os.Bundle列印,需要將Bundle unparcel

    var printIntentAndExtras = function printIntentAndExtras(intentObj) {
    if (intentObj == null) return;
    var Intent = Java.use("android.content.Intent");
    var Bundle = Java.use("android.os.Bundle");
    var bundleObj = Intent.getExtras.call(intentObj);
    
    if (bundleObj != null) {
    Bundle.getSize.call(bundleObj, null);//调用getSize即可反序列化
    }
    
    Logd(TAG, ‘printIntentAndExtras ’ + bundleObj);
    };
    登入後複製
#踩到的坑其實不只上面的,剛開始也百度過一些frida網路攔截的方案,還仔細的研究了okhttp的Interceptor方案,最後發現app也是用了攔截器,所以就發生衝突,導致無法使用該方案。

也純粹的分析過app的smali,尋找呼叫堆疊以及網路請求,最後,只有幾個比較小的收穫,可能對讀者沒有用處,不過記錄一下,方便自己以後回憶。

  1. java.net.URL攔截

    var URLHook = function() {
    var URL = Java.use('java.net.URL');
    URL.openConnection.overload().implementation = function() {
    var retval = this.openConnection();
    Logd('URL', openConnection' + retval);
    return retval;
    };
    };//URL.openConnection调用概率比较大,但是不一定对网络进行请求
    登入後複製
  2. #攔截app呼叫http請求前使用json的地方,這只是其中之一

    var jsonHook = function() {
    var xx = Java.use('e.h.a.a');//app smali
    var xxa_method = xx.a.overload('org.json.JSONObject', 'java.lang.String', 'java.lang.String');
    xxa_method.implementation = function(jsonObj, str1, str2) {
    Logd("json", jsonObj + " str1: " + str1 + " str2" + str2);
    xxa_method.call(this, jsonObj, str1, str2);
    }
    }
    登入後複製
  3. trace http相關class

    var traceAllHttpClass = function() {
    Java.perform(function() {
    Java.enumerateLoadedClasses({
    onMatch: function(name, handle) {
    /*"e.h.a.a$a",起初也拦截过app的该混淆类*/
    if (name.indexOf("com.android.okhttp.Http") != -1 || name.indexOf("com.android.okhttp.Request") != -1
    || name.indexOf("com.android.okhttp.internal") != -1) {
    traceClass(name);//对这三个class进行trace
    }
    },
    onComplete: function() {
    }
    });
    });
    };
    登入後複製
  4. #Request$Builder攔截

    var BuilderClass = Java.use('com.android.okhttp.Request$Builder')
    
    BuilderClass.build.implementation = function () {
    //LOG('com.android.okhttp.HttpUrl$Builder.build overload', { c: Color.Light.Cyan });
    //printBacktrace();
    var retval = this.build();
    Logd(TAG, "retval:" + retval);
    printRequest(retval);
    return retval;
    }
    登入後複製
  5. property_get攔截

    var nativePropertyGetAddr = Module.findExportByName(null, '__system_property_get');
    Interceptor.attach(nativePropertyGetAddr, {
    onEnter: function onEnter(args) {
    this._name = args[0].readCString();
    this._value = args[1];
    },
    onLeave: function onLeave(retval) {
    if (this._name.indexOf("ro.build.id") != -1) {
    var virtualDevice = getVirtualDevice();
    if (DEBUG_PROP) Logd(TAG, "__system_property_get fake " + this._name + "=>to " + virtualDevice.build_id);
    
    this._value.writeUtf8String(virtualDevice.build_id);
    }
    
    var strFilter = /^ro\./g;
    if (DEBUG_PROP && this._name.match(strFilter) != null) Logd(TAG, "__system_property_get " + this._name);
    }
    });
    登入後複製
二.裝置android_id導致用戶過期的處理

var DEBUG_PROP = false;
var DEVICE_CONFIG = "/sdcard/.device";

function getVirtualDevice() {
var nativeOpen = new NativeFunction(Module.findExportByName(‘libc.so’, 'open'), 'int', ['pointer', 'int']);
var nativeRead = new NativeFunction(Module.findExportByName('libc.so', 'read'), 'int', ['int', 'pointer', 'int']);
var fd = nativeOpen(Memory.allocUtf8String(DEVICE_CONFIG), 0);
var mem = Memory.alloc(1024);
var readLen = nativeRead(fd, mem, 1024);
var json = JSON.parse(mem.readCString(readLen));
return json;
}

Secure.getString.implementation = function () {
var retval = this.getString(arguments[0], arguments[1]);
if (DEBUG_PROP) Logd(TAG, "Settings.Secure get " + arguments[1] + " val " + retval);

if (arguments[1].indexOf("android_id") != -1) {
var virtualDevice = getVirtualDevice();
return virtualDevice.android_id;
}

return retval;
};
登入後複製

三. 使用抓包工具fiddle抓包脫坑

1.fiddle代理設定OK,app卻無法登陸

分析adb log,進程有java.security.cert.CertPathValidatorException的列印,之前也看過一些frida攔截抓包繞過憑證的貼文。先試試一把暴力搜索:

Java.perform(function(){
const groups = Java.enumerateMethods('*!verify/u');
var classes = null;
for(var i in groups){
var classes = groups[i]['classes'];

for(var i in classes){
Java.use(classes[i]['name'])
.verify
.overload('java.lang.String', 'javax.net.ssl.SSLSession')
.implementation = function() {
printBacktrace();
LOG("[+] invoke verify", { c: Color.Red });
return true;
}
}
}
});
登入後複製
即使直接強制verify返回true,仍然無法登錄,因為出現了相同的ssl問題錯誤。百度搜尋後找到了答案。 apktool解包,然後修改

res/xml/network_security_config.xml
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config cleartextTrafficPermitted="true">
<trust-anchors>
<certificates src="system" />
<!--添加fiddle证书可信任
<certificates src="user" />
-->
</trust-anchors>
</base-config>
</network-security-config>
登入後複製
重打包簽名後運行一把,fiddle抓到了包,app也能正常登陸了,這次也是運氣好吧,app的ssl校驗只有單向app校驗,伺服器並沒有進行校驗。

四.結束

從週二下午一直折騰到週五,最後從系統層面的HttpEngine尋找hook點並不是很好的方法,弊端也已明了。因此,在周日利用抓包工具和各種從百度找到的方法,逐步解決遇到的問題。

下面是抓到的兩個套件:

HTTP/1.1 200 OK
Date: Sun, 16 Aug 2020 06:27:34 GMT
Content-Type: application/json
Content-Length: 101
Connection: keep-alive
Grpc-Metadata-Content-Type: application/grpc
Vary: Origin
Vary: Accept-Encoding

{"result":{"errno":"OK","errmsg":"成功"},"data":{"version":"xxxxxxxx-351e-40cf-aaa9-3177d6df9b7f"}}
-----------------------------------
HTTP/1.1 200 OK
Date: Sun, 16 Aug 2020 06:27:34 GMT
Content-Type: application/json
Content-Length: 99
Connection: keep-alive
Grpc-Metadata-Content-Type: application/grpc
Vary: Origin
Vary: Accept-Encoding

{"result":{"errno":"OK","errmsg":"成功"},"data":{"nodeToken":"xxxxxxxc24d79f55c0b07beaf50cb566"}}
登入後複製
POST https://tap-xxxxxxx.xxxxxx.com/api/v2/Android/analytics/basic HTTP/1.1
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cjbcjdsabcjvbXVCJ9.eyJ1aWQiOjE4ODMzMDEsInNlY3JldCI6IjAzNzE0M2Y3LTExMTUtNGY2Yi1iNzQxLWUyMjc5ZDM3MGY3MCIsImV4cCI6MTU5NzgxNjQ0MiwiaXNzIjoiZ3Vlc3QgbG9naW4ifQ.W3SiO0-afbhxPITjRinnhyWhZLy1bzZhYexm5VCWklI
X-Device-ID: 9xxxxxxx84d4542e
X-Loc: ["China","Shanghai","Shanghai","","ChinaUnicom","31.224349","121.4767528","Asia/Shanghai","UTC+8","310000","86","CN","AP","xxx.166.xxx.xxx"]
X-App-Version: 2.2.0
Content-Type: application/json; charset=utf-8
Content-Length: 208
Host: xx-xxxx.xxxxxx.com
Connection: Keep-Alive
Accept-Encoding: gzip
User-Agent: okhttp/4.7.2

{"deviceID":"9xxxxxxx84d4542e","model":"V1813BA","systemVersion":"9","version":"2.2.0","location":{"latitude":xx.x99x990990991,"longitude":xxx.26689769073256},"network":{"g2":0,"g3":0,"g4":4,"g5":0,"wifi":4}}

-----------------------------------
HTTP/1.1 200 OK
Date: Sun, 16 Aug 2020 06:27:35 GMT
Content-Type: application/json
Content-Length: 43
Connection: keep-alive
Grpc-Metadata-Content-Type: application/grpc
Vary: Origin
Vary: Accept-Encoding

{"result":{"errno":"OK","errmsg":"成功"}}
登入後複製

以上是frida如何抓apk網路包的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.聊天命令以及如何使用它們
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

Google app beta APK teardown reveals new extensions coming to Gemini AI assistant Google app beta APK teardown reveals new extensions coming to Gemini AI assistant Jul 30, 2024 pm 01:06 PM

Google's AI assistant, Gemini, is set to become even more capable, if the APK teardown of the latest update (v15.29.34.29 beta) is to be considered. The tech behemoth's new AI assistant could reportedly get several new extensions. These extensions wi

如何進行授權的APK滲透測試 如何進行授權的APK滲透測試 May 20, 2023 pm 12:29 PM

作為一個滲透測試小白,本文的目的是希望能為那些和我一樣的小白提供一些測試想法。涉及的內容可能比較基礎,表哥們見諒。 APK解包拿到apk之後直接用7-Zip解壓縮可以得到幾個資料夾、一個AndroidManifest.xml檔、一個dex檔。使用dex2jarhttps://sourceforge.net/projects/dex2jar/將這個dex檔案解壓縮會產生一個jar文件,然後使用jd-gui就可以查看java原始碼了。當然可以從原始碼裡找程式碼的漏洞,但一般會有混淆,在這裡也不做深入討論。

如何在 Windows 11 上開啟 APK 文件 如何在 Windows 11 上開啟 APK 文件 Apr 14, 2023 am 11:19 AM

您是否下載過以字母 APK 結尾的檔案?這通常發生在適用於手機並加載到您的電腦上的應用程式上。這些文件中的大多數都以字母 APK 結尾。您可能一直在嘗試打開這些文件,但由於它們不尋常的擴展名而無法弄清楚它們的存儲位置或如何打開它們。如果您正在尋找一種在 Windows 11 上開啟此類檔案的方法,並且已經透過 Google 搜尋了您的頭髮,請不要擔心!它實際上比這容易得多。事實上,這樣做是免費的,您甚至不需要安裝任何東西。好吧,你必須為你的作業系統下載一個 APK 檔案開啟器——但前提是你還沒

怎麼把apk軟體改名稱 怎麼把apk軟體改名稱 Dec 08, 2023 am 10:23 AM

更改步驟:1、確保已經將要更改名稱的APK文件保存到電腦上;2、右鍵點擊APK文件,選擇「重新命名」選項;3、將原有的文件名稱替換為你想要的新名稱。確保只更改檔案名稱部分,而不要更改檔案的副檔名「.apk」;4、按Enter鍵或點擊視窗中的「重新命名」按鈕來儲存變更即可。

frida如何抓apk網路包 frida如何抓apk網路包 May 16, 2023 pm 07:16 PM

一.埋頭分析踩坑路從系統的角度去尋找hook點,而不是為了抓包而抓包。 1.okhttp呼叫流程publicstaticfinalMediaTypeJSON=MediaType.get("application/json;charset=utf-8");OkHttpClientclient=newOkHttpClient();Stringpost(Stringurl,Stringjson)throwsIOException{RequestBodybody=RequestBodyody

unity發佈出來的安卓apk該如何加密 unity發佈出來的安卓apk該如何加密 May 13, 2023 am 11:10 AM

Unity3D程式的安全問題程式碼安全問題Unity3D程式的核心組件檔案Assembly-CSharp.dll是標準的.NET檔案格式,附帶了方法名稱、類別名稱、類型定義等豐富的元資料訊息,使用DnSpy等工具可以輕易地將其反編譯和篡改,程式碼邏輯、類別名稱和方法名等一覽無餘。程式碼邏輯一但被反編譯,很容易滋生各種類型的外掛,破壞遊戲平衡,如果程式碼邏輯中存在漏洞,也容易被挖掘和利用,可能對開發商造成無法預料的損失。資源安全性問題Unity3D程式在編譯打包階段會透過Unity編輯器將資源打包成AssetBun

Win11 apk安裝指南 Win11 apk安裝指南 Jan 03, 2024 pm 10:24 PM

眾所周知,微軟宣布了win11將能夠運行安卓應用程序,並且可以安裝本地apk,但是在更新win11之後用戶發現自己不知道怎麼安裝本地apk,其實是因為目前微軟還沒有為win11實裝這款功能,需要等待功能實裝才能使用。 win11怎麼安裝本地apk:1.根據微軟的說法,win11在實裝了這個功能之後,直接雙擊下載好的apk檔案就可以直接安裝了。 2.安裝完成後使用者也可以直接在系統中運作了。 3.雖然現在已經是正式版win11了,但微軟目前還沒有為win11實裝這個功能。 4.所以如果使用者想要在win11

如何進行APK簡單程式碼注入 如何進行APK簡單程式碼注入 May 14, 2023 am 11:43 AM

一、前言apk在未加密的情況下,透過反編譯,得到smail檔。將需要注入的程式碼注入即可。之後封裝、簽名即可!二、製作apk使用androidstudio產生一個簡單的apk。使用預設代碼即可。 packagecom.example.myapplication1;importandroidx.appcompat.app.AppCompatActivity;importandroid.os.Bundle;publicclassMainActivityextendsAppCompatActivity{

See all articles