Android analysis caused by one app packet capture (continued)

Source: Internet
Author: User

Android analysis caused by one app packet capture (continued)
Cause 0x00

First of all, this article is not a continuation of the Orthodox "Android analysis record caused by an app packet capture", but the analysis of an APP is the same as the cause. However, the analysis in this article solves the problems left behind by an Android analysis record caused by an app packet capture, which is called "continued.

Unlike in the beginning, the burpuite proxy has been changed all over the world. Cross-compilation, transmission encryption, DEX shelling, and other protection methods are gradually applied. It is very difficult for us to capture packets and modify data.

The APP analyzed in this article is also used to cross-compile the encryption algorithm into the so library and encrypt the transmission parameters as a whole. Analyzing arm assembly code is a path, but it is already daunting for most people. However, security is always full of whimsy. Even if we don't leave the compilation, we can still find other ways.

Next, I will share with you the analysis process through this article.

 

0x01 overall idea

The purpose of this analysis is to restore the request and response in the transmission process. Of course, it is more important to control the parameters in the request. Therefore, we need to know how the parameters are encrypted. We know that the encryption function is the e function in libGoblin. so through the Android analysis record triggered by an app capture, but it seems that it is not so easy to restore the decryption function through it.

However, since we know the parameter's function for encryption, we only need to know the format of the parameter and directly call this function to encrypt the forged data, then, can I replace the corresponding parameters with packet capture?

For this reason, I adopt a policy to intercept json data before it enters the encryption function, so that we can know what format the parameters are transmitted. If you know the specific parameter format, you can forge a data packet capture and modify the package.

0x02 parsing request

First, let's look at the next request. If the parameters are encrypted, this section aims to find out what the following string is.

The first step that remains unchanged for years is apktool decompilation and dex2jar decompilation. Of course the code is obfuscated, but this does not affect our analysis. Android uses JDK HttpURLConnection and Apache HttpClient to send network requests, and searches for functions, fields, and request URLs. These feature functions and fields are usually not obfuscated. Dynamic Tracking of Andbug is also acceptable. This topic uses static code analysis!

Use AndroidManifest. xml to understand the app structure and find the main package name. Run the jd-gui command to view the java code. The request is a POST request, so you can search for the post and HttpPost words:

Using the above method, we repeatedly narrow the scope by searching for features such as http request methods and request URLs, and finally locate the AbstractHttpRequest class. This class is an abstract class and has many interesting methods. The CommonTask class extends the AbstractHttpRequest class. Read the code to know that this class is a key class. The Android analysis record caused by an app packet capture is also described in this article. We will not repeat it here!

The c parameter is processed by chrome () of javasacthttprequest and follows up with this function:

Str is the string constant "6000lex" and json data to enter the convertValue () of NetworkParam. Follow up:

In convertValue (), the encryption function is finally called. Therefore, in Goblin. e. Print the two parameters through log before encrypting paramString1 and paramString2 to know what the request data is.

Open NetworkParam. smali under com.xxx.net in a text editor and locate the convertValue () function. Add the following code in Goblin. e:

Modify the smali code to print the encrypted string, repackage the signature, and install it. view the logcat log:

As shown in, we now know the format of parameter passing. However, unexpected data appears in the log. As shown in the preceding figure, p1 should be the constant "6000lex", but the timestamp is displayed in the figure. Compare the transmitted data () and find that the second request-e is the ciphertext of the parameter B. The plaintext of B is the login information. Search for convertValue and find that B Also calls this function for encryption, which causes this phenomenon.

Through the above analysis, the formats of c and B are determined at login:

Public class myBroadcast extends BroadcastReceiver {public static boolean sw = false; public static boolean swc = false; public static boolean swb = false; public static String datac = null; public static String datab = null; public static String kec = "6000lex"; // receives broadcast public void onReceive (Context context, Intent intent) {Log. I ("broadcast-intent", intent. toString (); String action = intent. getAc Tion (); if (action. equals ("com. test. broadcast1 ") {sw = intent. getBooleanExtra ("sw", true); // controls whether swc = intent is intercepted. getBooleanExtra ("swc", false); // controls the interception of c swb = intent. getBooleanExtra ("swb", false); // controls the interception of B} else if (action. equals ("com. test. broadcast2 ") {datac = intent. getStringExtra ("datac"); // receives c datab = intent. getStringExtra ("datab"); // receives B} Log. v ("Cycler-data: sw: swc: swb | datac: datab", sw + ": "+ Swc +": "+ swb +" | "+ datac +": "+ datab);} // delay function public static void delay () {try {Thread. currentThread (); Thread. sleep (3000);} catch (InterruptedException e) {e. printStackTrace () ;}}// modify the public static String alter (String ke, String json) {Log. v ("json-data-1", ke + ":" + json); while (sw) {delay (); if (ke. equals (kec) {if (swc) {if (datac! = Null) {json = datac; Log. v ("json-data1-2", json); break ;}} else {if (swb) {if (datab! = Null) {json = datab; Log. v ("json-data2-2", json); break ;}} else {break ;}} return json ;}}

Because ke and B in c have the same encryption factor. When you guess that the server decrypts the data, first decrypt c through "6000lex", obtain the ke value, and then decrypt the B parameter through ke.

In fact, the above conjecture is correct, and the conjecture in "Android analysis record caused by an app capture" is also true. Goblin. d () is the decryption function.

The Android analysis records caused by an app Capture:

After decryption using Goblin. d:

The following sections describe why decryption fails in the Android analysis record triggered by an app capture!

0x03 parse response

As follows, the response packets are also a mess. In this way, even if we can change the package, we cannot determine whether the result is correct. Therefore, you must decrypt the response before changing the package.

Through 0x02 analysis, we know that the app uses Apache's HttpClient FOR post requests. The getEntity () function is used to obtain the response Message from HttpClient. Therefore, you can directly search for getEntity. With the analysis of 0x02, you can easily find the getResult method of the javasacthttprequest class. The dex2jar decompilation error is returned here. Therefore, analyze the smali Code directly.

Open AbstractHttpRequest. smali:

The getEntity () result is v0, and v0 finally enters dealWithResponse (), while dealWithResponse returns an Object instead of a String, so follow up with dealWithResponse ():

DealWithResponse has only one parameter, so tracking p1:

P1 finally goes to parseProtoResponse () and buildHttpResultString () and follows up with parseProtoResponse ():

ParseProtoResponse () calls the function in Goblin. Maybe this function is what we want. Put it first. Let's take a look at the buildHttpResultString () function. Here we can directly view jd-gui:

BuildHttpResultString () is an abstract class. The specific code is implemented in CommonTask, MultiTask, and PollTask. In the end, these classes call the pareResponse () method of the Response class, while pareResponse () also calls the decryption function in Goblin. ParseProtoResponse () is also a method of the Response class. Therefore, the function for decrypting the Response Message is located in these two functions. The next step is to verify whether it is correct.

Modify parseProtoResponse () and pareResponse () in Response. smali to print the decrypted result through the log:

Mark several parts in parseProtoResponse () and pareResponse (), but only the above results are displayed. Therefore, confirm that the decryption function is pareResponse ().

0x04 control request

Now we have completely seen the plain text content transmitted by request and response, as shown below, a complete request response process:

Of course, our purpose is to test, so we must be able to modify the request.

Try one:

Now that we know the request encryption function, we can call it in our APP. After the encryption is completed, replace the data intercepted by the burp.

Create an app to reference the same Goblin class and perform encryption and decryption. The test code is as follows:

Encryption can be encrypted, but the encryption result is different from the original ciphertext. However, decryption fails. The cause of failure is the same as that in the Android analysis record caused by an app capture.

The jni warning: NewStringUTF input is not valid Modified UTF-8 error occurred because google Modified the UTF8 standard in JNI, when the normal UTF8 contains a byte that does not conform to this standard, the checkJNI function reports this error, causing the application to crash.

This error is also reported on google:

Https://code.google.com/p/android/issues/detail? Id = 64892 ????????

Https://code.google.com/p/android/issues/detail? Id = 25386

However, the original ciphertext can be decrypted directly, so the problem may be caused by the encryption process. After a long time, we did not find a solution suitable for us. However, during the test, it was found that the original APP could be encrypted and decrypted by modifying the smali code. Is there a detection environment in so? Of course, you need to check the arm assembly before you know.

In this case, directly transform the original app.

Test 2:

Transformation: intercept parameters in the original APP-> modify the intercepted parameters through the external-> allow parameters, and follow the normal process in the future

Intercept parameters in the original app, as long as the parameters enter the function we control before entering the encryption. For convenience. Let's take a look at how to modify internal interception parameters externally.

With the Broadcast Mechanism of android, we can implement real-time interaction with apps. Therefore, it can also allow external data to interact with the app in real time. Create a new myBroadcast class with the following code:

Public class myBroadcast extends BroadcastReceiver {public static boolean sw = false; public static boolean swc = false; public static boolean swb = false; public static String datac = null; public static String datab = null; public static String kec = "6000lex"; // receives broadcast public void onReceive (Context context, Intent intent) {Log. I ("broadcast-intent", intent. toString (); String action = intent. getAc Tion (); if (action. equals ("com. test. broadcast1 ") {sw = intent. getBooleanExtra ("sw", true); // controls whether swc = intent is intercepted. getBooleanExtra ("swc", false); // controls the interception of c swb = intent. getBooleanExtra ("swb", false); // controls the interception of B} else if (action. equals ("com. test. broadcast2 ") {datac = intent. getStringExtra ("datac"); // receives c datab = intent. getStringExtra ("datab"); // receives B} Log. v ("Cycler-data: sw: swc: swb | datac: datab", sw + ": "+ Swc +": "+ swb +" | "+ datac +": "+ datab);} // delay function public static void delay () {try {Thread. currentThread (); Thread. sleep (3000);} catch (InterruptedException e) {e. printStackTrace () ;}}// modify the public static String alter (String ke, String json) {Log. v ("json-data-1", ke + ":" + json); while (sw) {delay (); if (ke. equals (kec) {if (swc) {if (datac! = Null) {json = datac; Log. v ("json-data1-2", json); break ;}} else {if (swb) {if (datab! = Null) {json = datab; Log. v ("json-data2-2", json); break ;}} else {break ;}} return json ;}}

OnReceive is used to receive external data in real time, and alter function is used to detect whether interception commands are sent externally. When receiving the interception instruction, call the delay () function for cyclic latency until the spoofed data is received or the interception is disabled.

Convert the myBroadcast class to the smali code. Put myBroadcast. smali in the same directory as NetworkParam. smali. Register the handler myBroadcast in AndroidManifest. xml and set exproted to true.

That is, the attacker is allowed to be accessed externally.

In this way, we can use this handler in NetworkParam. smali.

Next, modify NetworkParam. smali to receive our commands. Modify Goblin. e as follows:

Let p0 enter the alter () function, save the Modification result to v3, and replace p0 with v3 in Goblin. e. "Request-data-1" prints the original parameters, and "json-data-1" prints the parameters that enter the alter function. "Request-data-2" prints the modified parameter, "request-data-e", and prints the encrypted parameter.

After the modification, repackage, sign, and install the package, and run the following command to view the logcat log:

1 ,? The default setting is not to intercept, so the logcat log should be completely visible.

"Request-data-1"-> "json-data-1"-> "request-data-2 (unchanged)"-> "request-data-e"-> "response-data"

The test is as follows:

Same as expected

2 ,? Set the interception command, that is, if sw is true, the interception data enters the cycle delay and waits for receiving forged parameters. So the logcat log should only see "request-data-1"-> "json-data-1", the test is as follows:

Am command to send broadcast:

Logcat logs, as expected, are intercepted and the application is always loading:

3. Send forged data according to the design. At this time, the logcat log should be able to see

Request-data-1-> json-data-1-> request-data-2 (after modification) "->" request-data-e "->" response-data"

The test is as follows:

Send broadcast commands, intercept B parameters, and allow c parameters:

The Logcat log shows that c (with 600lex) is allowed, and B (with timestamp) is intercepted:

The am Command sends the datab data and changes the uname to test222:

The result is as follows: after the hacker receives the forged data, the original B parameter is modified and then released:

Same as expected.

Conclusion 0x05

Finally, we can view the transmitted plaintext information and control the request message. Even if it uses so encryption. We can still test it ~

?

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.