In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-18 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Network Security >
Share
Shulou(Shulou.com)05/31 Report--
Today, I will show you how frida grasps the apk network package. The content of the article is good. Now I would like to share it with you. Friends who feel in need can understand it. I hope it will be helpful to you. Let's read it along with the editor's ideas.
One. Buried in the analysis of trampling pit road
Look for hook points from a systematic point of view, rather than grabbing packets for the sake of grabbing them.
1.okhttp calls process 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 ();}}
The above is a demo on okhttp's official website, and the key code is in client.newCall. Starting from here, the interface call will eventually be called to the okhttp framework. Okhttp is originally sdk, but later aosp has been integrated into the system, so it can be classified into the framework layer.
The framework layer is not detailed, but it is mainly these java classes:
Com.android.okhttp.internal.huc.HttpURLConnectionImplcom.android.okhttp.internal.http.HttpEnginecom.android.okhttp.internal.http.RetryableSinkcom.android.okhttp.internal.http.CacheStrategy$Factory
In fact, client.newCall will eventually get a connection through URL.
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection ()
The urlConnection here is actually an instance of HttpURLConnectionImpl. This class has a getInputStream getOutputStream method, and the getBufferedRequestBody,getResponse of HttpEngine is called internally. At first, I tried to hook these two interfaces, such as hook getResponse, I can print out the response.
Then I found that Request can only print header, not body. So buried in the analysis, getBufferedRequestBody this function just can start, get a sink, and finally to RetryableSink as a breakthrough point, such as hook its write function can print out the body. The write function corresponds to urlConnection.getOutputStream (). Write at the app level.
Later, I found a Request, and the getBufferedReuqestBody function may be called more than once, so there will be a problem of data duplication. Later, I found the CacheStrategy$ Factory.get point to Hook and found that there was still data duplication. It is found that all of the above hook have some disadvantages.
Data duplication
Cannot be crawled by non-okhttp calls
Then continue to print the call stack from the send,sendmsg,write,recv,read of the native layer. Finally, after three days, I decided to give up the treatment and take the tool instead.
Okhttp process: sdk Interface-> okhttp Framework-> native (libc) 2. The pits that frida stepped on during the analysis (the key points are in the notes)
Android.util.Log does not print
Var Logd = function Logd (tag, msg) {Java.use ("android.util.Log") .d (tag, msg);}; Logd ('http-body-',' 1111111111111111'); / / the log does not print Logd ('http-body',' 111111111111111111); / / the log prints
Anonymous inner classes need reflection to get members
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 directly reported error var requestBody = bodyField.get (request); var requestBodyClass = requestBody.getClass () Var ClassInstanceArray = Java.array ('java.lang.Class', []); / / var contentLengthMethod = requestBodyClass.getMethod ("contentLength"); / / gadget directly reports an error var contentLengthMethod = requestBodyClass.getMethod ("contentLength", ClassInstanceArray); contentLengthMethod.setAccessible (true); var ObjectInstanceArray = Java.array (' java.lang.Object', []); var contentLength = requestBody? ContentLengthMethod.invoke (requestBody, ObjectInstanceArray): 0 printRequest contentLength printRequest contentLength (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");}}
Android.os.Bundle printing, you need to put 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); / / can be deserialized by calling getSize} Logd (TAG, 'printIntentAndExtras' + bundleObj);}
In fact, the pit is not only above, but also spent some frida network interception solutions at the beginning, but also carefully studied okhttp's Interceptor scheme, and finally found that app also used an interceptor, so there was a conflict, resulting in the inability to use this scheme.
Also purely analyzed app's smali, looking for call stacks and network requests, finally, only a few relatively small gains, may not be useful to the reader, but record it, to facilitate their own future memories.
Java.net.URL intercept
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 has a high probability of calling, but not necessarily making a request to the network
This is just one of the places where json is used before intercepting app calls to http requests
Var jsonHook = function () {var xx = Java.use ('e.h.a.a'); / / app smalivar 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);}}
Trace http related class
Var traceAllHttpClass = function () {Java.perform (function () {Java.enumerateLoadedClasses ({onMatch: function (name, handle) {/ * "e.h.a.a$a"), initially blocked the obfuscation class * / if (name.indexOf ("com.android.okhttp.Http")! =-1 | | name.indexOf ("com.android.okhttp.Request")! =-1 | name.indexOf ("com.android.okhttp.internal")! =-1) {traceClass (name) / / trace the three class}}, onComplete: function () {}});});}
Request$Builder intercept
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;}
Property_get intercept
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 virtualDevice.build_id if (DEBUG_PROP & & this._name.match (strFilter)! = null) Logd (TAG, "_ system_property_get" + this._name);}}. Var DEBUG_PROP = false;var DEVICE_CONFIG = "/ sdcard/.device" when the device android_id causes users to expire; 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;}; III. Use the package grabbing tool fiddle to grab the package and get rid of the pit 1.fiddle proxy settings OK,app can not log in
Analyze adb log, the process has java.security.cert.CertPathValidatorException printing, and I have seen some posts about frida intercepting grab packets bypassing certificates before. Try a violent search first:
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 [I] [' name']). Verify.overload ('java.lang.String',' javax.net.ssl.SSLSession'). Implementation = function () {printBacktrace (); LOG ("[+] invoke verify", {c: Color.Red}); return true })
Call verify to return true by direct violence, but still cannot log in. The error report is the same ssl problem. Baidu found the answer after searching. Unpack apktool and modify it
Res/xml/network_security_config.xml
After repackaging and signing, fiddle caught the package and app was able to log in normally. This time, it is lucky that the ssl verification of app has only one-way app verification, and the server has not verified it.
four。 End
From Tuesday afternoon to Friday, it is not a good way to find hook points from HttpEngine at the system level, and the disadvantages are clear. So take advantage of the time on Sunday, try a variety of Baidu methods-grab the tool, and then pass the problems encountered step by step.
Here are two bags caught:
HTTP/1.1 200 OKDate: Sun, 16 Aug 2020 06:27:34 GMTContent-Type: application/jsonContent-Length: 101Connection: keep-aliveGrpc-Metadata-Content-Type: application/grpcVary: OriginVary: Accept-Encoding {"result": {"errno": "OK", "errmsg": "success"} "data": {"version": "xxxxxxxx-351e-40cf-aaa9-3177d6df9b7f"}-- HTTP/1.1 200 OKDate: Sun, 16 Aug 2020 06:27:34 GMTContent-Type: application/jsonContent-Length: 99Connection: keep-aliveGrpc-Metadata-Content-Type: application/grpcVary: OriginVary: Accept-Encoding {"result": {"errno": "OK", "errmsg": "success"} "data": {"nodeToken": "xxxxxxxc24d79f55c0b07beaf50cb566"}} POST https://tap-xxxxxxx.xxxxxx.com/api/v2/Android/analytics/basic HTTP/1.1Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cjbcjdsabcjvbXVCJ9.eyJ1aWQiOjE4ODMzMDEsInNlY3JldCI6IjAzNzE0M2Y3LTExMTUtNGY2Yi1iNzQxLWUyMjc5ZDM3MGY3MCIsImV4cCI6MTU5NzgxNjQ0MiwiaXNzIjoiZ3Vlc3QgbG9naW4ifQ.W3SiO0-afbhxPITjRinnhyWhZLy1bzZhYexm5VCWklIX-Device-ID: 9xxxxxxx84d4542eX-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.0Content-Type: application/json Charset=utf-8Content-Length: 208Host: xx-xxxx.xxxxxx.comConnection: Keep-AliveAccept-Encoding: gzipUser-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 OKDate: Sun, 16 Aug 2020 06:27:35 GMTContent-Type: application/jsonContent-Length: 43Connection: keep-aliveGrpc-Metadata-Content-Type: application/grpcVary: OriginVary: Accept-Encoding {"result": {"errno": "OK" "errmsg": "success"}} that's all about how frida grasps apk network packets. For more information about how frida grasps the apk network package, you can search the previous articles or browse the following articles to learn! I believe the editor will add more knowledge to you. I hope you can support it!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.