1

When I submit a Customer Reference ID in an Android Application it POSTs an encrypted string to an API endpoint.

For example, if I enter the following CR ID :

"SR-54585482"

it POSTs the following Encrypted Data:

splainText : "vpEz/Vm8Yi9v5/fzNE+MDoMIQGZ0vNvjPuX8UNAi26c="

     Count : 31

How do I find the encryption algorithm in the source code of the APK?

In which file can I find about this encryption?

Dex2Jar File here : https://www.mediafire.com/file/hs0qyirhuk4ygo8/test-dex2jar.jar/file

APK from here : https://play.google.com/store/apps/details?id=com.sundirect.sundth

6
  • 1
    First the encrypted text is obviously base64 encoded which hides too much information, better look at it in raw or at least he's encoding. Second, why do you think this is an information security question(there is a stack exchange site dedicated to reverse engineering which would suite much better)? And third have you at least tried to most obvious search for Cipher.getInstance in Jadx when you are searching for a cipher?
    – Robert
    Apr 5 at 20:00
  • If you just want to know how to analyse the source code to locate the encryption algorithm, then all of the details about what the algorithm does to specific strings is irrelevant.
    – schroeder
    Apr 5 at 20:09
  • The screenshot just contains some numbers which are not relevant to any crypto but the way assets and resources are handled. Better option is to share the apk. Also I see references to mono and xamarin in the screenshot so maybe the app is not built in java but .NET.
    – sudhackar
    Apr 6 at 10:12
  • I won't be able to help you privately. You can share the apk here if possible.
    – sudhackar
    Apr 6 at 15:35
  • 2
    The screenshots offer no additional use - only waste space. Please use text to share code in any post.
    – sudhackar
    Apr 7 at 11:16

1 Answer 1

2

Based on your screenshots (as already mentioned in comments) - references to mono and xamarin help us understand that the apk is probably built with .NET. In this method the code is probably written as C# and then compiled to DLLs depending on what classes you use in the code.

See : https://github.com/xamarin/xamarin-android for more details on this.

A simple unzip will confirm that too.

$ unzip ../Sun.apk -d .
...
assemblies/xxx.dll
...

Now most of the static analysis can be based on decompiling .NET dlls which can be done using something like ILSpy.

Looking at the type of dlls

$ file assemblies/xxx.dll
assemblies/xxx.dll : data

The dlls are actually compressed with lz4 based on this PR and then can be uncompressed using a script

$ find . -type f -name "*.dll" -exec mv {} {}.lz4 \;
$ find . -type f -name "*.lz4" -exec python Xamarin_XALZ_decompress.py {} {}.dll \;

Now ILSpy can load and decompile these DLLs. Based on the ciphertext you provide it looks like a block cipher such as AES. Look around for that in the decompiled code in Sundirect.dll We find this snippet in Sundirect.Services

using System;
using System.Security.Cryptography;
using System.Text;

public static string Encrypt(string inputText, string encryptionKey)
{
    UTF8Encoding uTF8Encoding = new UTF8Encoding();
    RijndaelManaged rijndaelManaged = new RijndaelManaged();
    rijndaelManaged.Mode = CipherMode.CBC;
    rijndaelManaged.Padding = PaddingMode.PKCS7;
    rijndaelManaged.KeySize = 128;
    rijndaelManaged.BlockSize = 128;
    byte[] bytes = Encoding.UTF8.GetBytes(encryptionKey);
    byte[] array = new byte[16];
    int num = bytes.Length;
    if (num > array.Length)
    {
        num = array.Length;
    }
    Array.Copy(bytes, array, num);
    rijndaelManaged.Key = array;
    rijndaelManaged.IV = array;
    string result = Convert.ToBase64String(rijndaelManaged.CreateEncryptor().TransformFinalBlock(uTF8Encoding.GetBytes(inputText), 0, uTF8Encoding.GetBytes(inputText).Length));
    rijndaelManaged.Dispose();
    return result;
}

Right Click -> Analyze to see what code uses this function and we see that is is used to encrypt post data

...
Sundirect.Services.LoginAPIServices.LoginAync(string, string) : Task<LoginDetailsOutputDto>
Sundirect.Services.LoginAPIServices.GetUserPasswordAsync(string) : Task<UserPasswordDto>
...

Click and browse to that location and you see that the key to encrypt is hardcoded

...
string value2 = BaseServices.Encrypt(input, "419201ddtuz3082249879134d06093b95991g6f70d");
...

This can help us write a simple decryptor like this

using System.Diagnostics;
using System.Security.Cryptography;
using System.Text;

public class Test
{
    public static string Encrypt(string inputText, string encryptionKey)
    {
        UTF8Encoding uTF8Encoding = new UTF8Encoding();
        Aes? rijndaelManaged = Aes.Create("AesManaged");
        rijndaelManaged.Mode = CipherMode.CBC;
        rijndaelManaged.Padding = PaddingMode.PKCS7;
        rijndaelManaged.KeySize = 128;
        rijndaelManaged.BlockSize = 128;
        byte[] bytes = Encoding.UTF8.GetBytes(encryptionKey);
        byte[] array = new byte[16];
        int num = bytes.Length;
        if (num > array.Length)
        {
            num = array.Length;
        }
        Array.Copy (bytes, array, num);
        rijndaelManaged.Key = array;
        rijndaelManaged.IV = array;
        string result =
            Convert
                .ToBase64String(rijndaelManaged
                    .CreateEncryptor()
                    .TransformFinalBlock(uTF8Encoding.GetBytes(inputText),
                    0,
                    uTF8Encoding.GetBytes(inputText).Length));
        rijndaelManaged.Dispose();
        return result;
    }

    public static string Decrypt(string inputText, string encryptionKey)
    {
        UTF8Encoding uTF8Encoding = new UTF8Encoding();
        Aes? rijndaelManaged = Aes.Create("AesManaged");
        rijndaelManaged.Mode = CipherMode.CBC;
        rijndaelManaged.Padding = PaddingMode.PKCS7;
        rijndaelManaged.KeySize = 128;
        rijndaelManaged.BlockSize = 128;
        byte[] bytes = Encoding.UTF8.GetBytes(encryptionKey);
        byte[] array = new byte[16];
        int num = bytes.Length;
        if (num > array.Length)
        {
            num = array.Length;
        }
        Array.Copy (bytes, array, num);
        rijndaelManaged.Key = array;
        rijndaelManaged.IV = array;
        byte[] b64 = Convert.FromBase64String(inputText);
        string result =
            System.Text.Encoding.UTF8.GetString(rijndaelManaged
                    .CreateDecryptor()
                    .TransformFinalBlock(b64,
                    0,
                    b64.Length));
        rijndaelManaged.Dispose();
        return result;
    }

    public static void Main()
    {
        string key = "419201ddtuz3082249879134d06093b95991g6f70d";
        string e = Decrypt(Encrypt("input", key), key);
        Debug.Assert(e=="input");
        Console.WriteLine(Decrypt("vpEz/Vm8Yi9v5/fzNE+MDoMIQGZ0vNvjPuX8UNAi26c=", key));
    }
}

which on running decrypts

"vpEz/Vm8Yi9v5/fzNE+MDoMIQGZ0vNvjPuX8UNAi26c="

to

CR-13261150|03|2022-04-04 22:40
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.