-
Notifications
You must be signed in to change notification settings - Fork 528
GDA: "Unpacking Decompiling Decrypting" to Capture the Flag in CTF Game
Recommended to use the latest version of GDA: it’s more stable.
The case is from a Flag game in the 2020 WANGDING CUP
. There is an apk file that you should find the flag as soon as possible. Drag it into GDA, we find it packed & protected by 360. So the key to winning is how to unpack/decrypt it.
In this paper, We only use GDA's dumping, decompilation, and decryption features to solve it.
First, we press the Dump
button to start the GDA Device Dumper
, and then click Install APK
to install the apk file, and press to run in your device(need be root). After Right-click the 'refresh' menu to refresh the package list and we will see the new package whose PID is 5165
. Double click the process (package name) to see the memory spatial distribution of the process.
Next, click the REF
radio to display the modules most related to the process name (as shown in the figure below). The oat file actually contains the DEX of the original app (if you are not sure, you can dump all the modules and check them, sometimes the original DEX will exist in the heap, we'll discuss it later).
We need to dump a module completely. how? for example, dumping classes.oat module
, first press the left mouse button on the first line of classes.oat
, and then drag to the last line of classes.oat module
, right-click Dump Module
and wait a moment, the dialog box will pop up.
Click OK
to view the dump file, as shown in the figure.
The dumped file is an oat file, and the decrypted DEX file (actually the magic in the dex head is erased, GDA just automatically repairs it when parsing OAT) is in this file.
Here, modify the file suffix as .oat
and drag it to the GDA to decompile the decrypted dex (if you want to convert it to DEX, you can convert it into dex with menu tool > oat2dex)
Then, after a general look, we found the suspicious flag class quickly. The Flag class is likely to be the answer. Here are two functions (calcFlagFirstStep()
and calcFlagSecondStep()
) that seem to be used to calculate the flag by Flag.keyFirstand
and Flag.keySecond
, which two are decoded by Base64 and then transmitted to Flag.comm()
method. Double click Flag.comm()
to see:
If you don't like to watch try-catch
here, you can right-click to disable it, as shown in the figure:
This feature is implemented by GDA's flexible structured algorithm. Especially when there are a large number of nested try-catch
structures, we don't care about exception handling code, so turning off try-catch
will greatly simplify the complexity of the code.
This code is more clear. The two flags first decodes by Base64, then decrypts with Flag.comm()
, and at last connects into the Flag that we need.
Here, we use the GDA Encryption&Decryption
to decode the two flags and then use the GDA java plugin
to decrypt and connect.
First, open the GDA Encryption &Decryption
tool in menu>tools>ALG Tool
, select Base64
to decode the two strings quickly.
Get two decoded strings:
fmcj.97;A7G462H;2F/7<I9496EH1
[Zm1jan85NztBN0c0NjJIOzJGLzc8STk0OTZFSDE=]
A:HI9E4I1E6<}
[QTpISTlFNEkxRTY8fQ==]
Then copy the Flag.comm()
method directly to the script file (download the java plugin case of GDA from here, it is recommended to create the java file directly under the directory example, and note that the java class name must be the same as the file name), and then call the comm () method according to the following call method.
//File: DecodeCtfString.java
//decode ctf flag by gjden
package example;
import com.gda.api.*;
class DecodeCtfString {
//copy from Request.ALLATORIxDEMO decompiled by GDA
public static String comm(String str,int num){
String res = "";
byte[] cmdbyte = str.getBytes();
byte i = 0;
while (i < cmdbyte.length) {
cmdbyte[i] = (byte)(cmdbyte[i]-(i%num));
i = (byte)(i+1);
}
try{
res = new String(cmdbyte, "UTF-8");
return res;
}catch(java.io.UnsupportedEncodingException e2){
e2.printStackTrace();
return res;
}
}
public int GDA_MAIN(GDAInterface gda)
{
String str1="fmcj.97;A7G462H;2F/7<I9496EH1";
String str2="A:HI9E4I1E6<}";
String res=comm(str1,8)+comm(str2,4);
gda.log(res);
return 0;
}
}
Finally, click Menu>file>Run Java/Class
to run the .java/.class file and the Flag directly will be printed on GDA, as shown in the figure: