0x00 Preface
This is the fourth case in the Android CTF practical series. This series shares related technologies of Android penetration and reverse analysis in a practical manner. Friends can download the CTF apk file for analysis and learning.
This case is quite interesting, and this article will shareFour approaches to solving problems and obtaining flag valuesLet's get our hands dirty and practice together!

Technologies involved in this article:
Familiar with Jadx-gui and Android killer tools
Hook technology (Frida, Objection)
Static analysis with IDA pro
Dynamic debugging technology
Java code writing
The apk file required for this case has been uploaded to the knowledge star, and those who need it can download it after following the link at the end.
0x01 Preparation for analysis
First, download the required apk file (the apk file has been uploaded to the Knowledge Star, those who need it can download it by following at the end), install and take a look.
Only some prompt information can be seen, use the decompilation tool to view,
Here, besides MainActivity, there are three other Activities, but they cannot be triggered directly in the interface.
Analyze the decompiled code:
Found that in the activities of IsThisTheRealOne, DefinitelyNotThisOne, and ThisIsTheRealOne, clicking the button will trigger a broadcast, and the flag value should be in the broadcast message. The next step is to obtain the content of the broadcast message.
Solution 0x02: Modify the code
The first solution is to modify the smali code, print the message log, and get the flag value. You can use the Android killer tool to decode the smali code and configuration files from the apk, then repack and publish after making changes.
1. Modify AndroidManifest.xml
Add the following three Activities:android:exported="true"
It is used to allow other applications to call it. After modifying this attribute, you can useadb shell am start -n package name/activity name
To start the corresponding activity:
2. Modify smali code
Add the following log-related code to IsThisTheRealOne$1.smali:
Add the following log-related code to DefinitelyNotThisOne$1.smali:
Add the following log-related code to ThisIsTheRealOne$1.smali:
After saving, recompile and package, then install on the phone.
3. View the logs
Use the adb command to start the corresponding Activity.
1. Start DefinitelyNotThisOne
adb shell am start -n com.example.hellojni/com.example.application.DefinitelyNotThisOne
Click the button, view the logs,
2. Start ThisIsTheRealOne
adb shell am start -n com.example.hellojni/com.example.application.ThisIsTheRealOne
Check the log:
3. Start IsThisTheRealOne
adb shell am start -n com.example.hellojni/com.example.application.IsThisTheRealOne
Check the log:
The flag value has already been obtained here.
0x03 Solution two: hook
The second solution can use Frida or Objection tool for hooking, so you do not need to modify the smali code and can also obtain the flag value.
Analysis found three Activity codes, all of which useandroid.content.Intent.putExtra
The method, so we can hook this method:
3.1 Using objection for hooking
1. Start objection
objection -g com.example.hellojni explore
Watch thisandroid.content.Intent.putExtra
Method:
android hooking watch class_method android.content.Intent.putExtra --dump-args -
-dump-backtrace --dump-return
2. Use adb to start three activities separately
adb shell am start -n com.example.hellojni/com.example.application.IsThisTheRealOne
Check the information displayed by objection
Obtain the flag value.
3.2 Using frida for hooking
Objection is developed based on frida, of course, we can write our own script for hook:
Start the activity
adb shell am start -n com.example.hellojni/com.example.application.IsThisTheRealOne
Start frida
frida -U com.example.hellojni -l hook1.js
Load the test() function, click the screen button, and you can see the result of the hook:
Obtain the flag value.
0x04 Solution three: static analysis
The third solution does not require code modification, using static analysis to obtain the flag, the process will be more麻烦some, purely an additional way of thinking
1. We can analyze the following four native methods
public native String computeFlag(String str, String str2);
public native String definitelyNotThis(String str, String str2, String str3);
public native String orThat(String str, String str2, String str3);
public native String perhapsThis(String str, String str2, String str3);
Here, let's take the onClick in the IsThisTheRealOne activity to analyze:
2. Analyze the code, and you can find that the values of a, b, and c can be obtained
String a = "TRytfrgooq|F{i-JovFBungFk" + "\\VlphgQbwvj~HuDgaeTzuSt.@Lex^~";
String b = doBoth("SendAnIntentApplication");
String className = "com.example.application.IsThisTheRealOne$1";
String c = doBoth(className.substring(0,className.length()-2));
Next, pass a, b, c into the perhapsThis method. To analyze this method, you need to analyze the so file, use IDA pro for static analysis, and findJava_com_example_application_IsThisTheRealOne_perhapsThis
Use F5 to convert to pseudo-code for C/C++, and analyze:
3. Analyze the code, you can use Java equivalent code to implement the key code.
4. Finally, write a complete Java script.
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
public static String customEncodeValue(String input) {
public class CTF4test {
public static void main(String args[]){
String a = "TRytfrgooq|F{i-JovFBungFk" + "\\VlphgQbwvj~HuDgaeTzuSt.@Lex^~";
System.out.println(a);
String b = doBoth("SendAnIntentApplication");
System.out.println(b);
String className = "com.example.application.IsThisTheRealOne$1";
String c = doBoth(className.substring(0,className.length()-2));
System.out.println(c);
public static String customEncodeValue(String input) {
String flag = perhapsThis(a,b,c);
System.out.println("---------------------------------------------");
System.out.println(flag);
}
public static String perhapsThis(String a,String b,String c){
byte[] bs = {0x77,0x6E,0x77,0x47,0x72,0x61,0x62,0x7B,0x4F,0x75,0x74,0x62,0x68,0x7F,0x72,0x43,0x74,0x66,0x71,0x6D,0x7D};
a = a + new String(bs);
System.out.println(a);
String result = "";
int tmp;
for(int i=0;i<76;i++){
char x = a.substring(i,i+1).toCharArray()[0];
char y = b.substring(i,i+1).toCharArray()[0];
char z = c.substring(i,i+1).toCharArray()[0];
tmp = z ^ y ^ x;
result += (char)tmp;
}
return result;
}
public static String customEncodeValue(String input) {
public static String doBoth(String input) {
return translate(customEncodeValue(input));
}
public static String customEncodeValue(String input) {
public static String translate(String input) {
char[] inputchars = input.replace('=', '?').toCharArray();
Map<Integer, Character> table = new HashMap<>();
int[] numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9, 0};
char[] characters = {'W', 'h', 'a', 't', 'i', 's', 'd', 'o', 'n', 'e'};
for (int i = 0; i < 10; i++) {
table.put(Integer.valueOf(numbers[i]), Character.valueOf(characters[i]));
}
char c = inputchars[i2];
if (c > '/' && c < ':') {
int charcode = c - '0';
inputchars[i2] = table.get(Integer.valueOf(charcode)).charValue();
return new String(inputchars);
}
}
}
public static String customEncodeValue(String input) {
String output = "";
byte[] input_bytes = input.getBytes();
MessageDigest md = null;
try {
md = MessageDigest.getInstance("SHA-224");
catch (NoSuchAlgorithmException e) {
}
}
md.update(input_bytes, 0, input_bytes.length);
byte[] hash_bytes = md.digest();
for (int i = 0; i < hash_bytes.length; i++) {
output = output + String.format("%02x", Byte.valueOf(hash_bytes[i]));
}
return Base64.getEncoder().encodeToString(output.getBytes());
}
}
5. Run the script to get the flag
Solution 4: Dynamic Debugging
Dynamic debugging of apk files with android studio or Jeb tools can also obtain the flag.
It is also possible to dynamically debug so files with IDA Pro to obtain the flag value.
The specific process and methods of these two debugging will be shared in the next two articles.

评论已关闭