App request data decryption (AES)

Time:2022-5-16

In the next two articles, we will mainly introduce burp packet capture and decryption in the process of security analysisEncrypted request dataAnd print out in the new message editor. This article mainly introduces the analysis and restoration of the encryption and decryption algorithm in the test app.

1、 Analyze the encryption algorithm of request data

  1. Burp captures app request packets, as shown below

    Post requests data encryption. In order to analyze what data is sent by post, the data needs to be decrypted

    App request data decryption (AES)

    picture
  2. Decompile the app and find the request data construction method, as shown below

    The method of locating the request data according to the parameter fields (chk, VNO, ENC, etc.) in the request data caught by burp

    App request data decryption (AES)

    picture
  3. Method of analyzing request data

    This method passes in the post plaintext data through the parameter arg10, and then converts the plaintext data string type to byte [] type as the parameter V10 and the other parameter V0 of the encryption algorithm C.A_ 1 is the byte [] constructed above. This parameter is the key of the encryption algorithm, which will be given later. The result obtained after encryption calculation v0_ 2 ciphertext data as post

    App request data decryption (AES)

    picture
  4. Follow up encryption and decryption algorithm

    There is also the AES algorithm in the last layer

    App request data decryption (AES)

    picture
//The last encryption and decryption algorithm is AES algorithm, which determines encryption and decryption according to the settings 1 and 2 in init method
//Therefore, here it writes encryption and decryption in the same method, and judges whether it is encryption and decryption according to arg5
//Parameter ARG3 sends in post plaintext byte []
//Parameter arg4 key byte [] passed in
//The Boolean parameter passed in from parameter arg5 determines whether to encrypt or decrypt
//Here, when arg5 is true, encryption is performed. The first parameter of init method is 1
//When arg5 is false, decrypt. The first parameter of init method is 2
//Parameter arg6 passes in the Boolean parameter. When encrypting, judge whether to calculate the length of plaintext byte [] and add it to byte []
//When arg6 is true, the length of the plaintext is not calculated and the plaintext is encrypted directly
//When arg6 is false, you need to calculate the plaintext length and the calculated result
//Added to plaintext byte [] as a parameter of encryption algorithm
//In combination with the above figure, the value set in the method calling this method is
//c.a(arg2,arg3,true,false);
//It can be obtained that encryption calculation is carried out and the length of plaintext needs to be calculated
//Through these analysis, we can realize the restoration of our later algorithm
private static byte[] a(byte[] arg3, byte[] arg4, boolean arg5, boolean arg6) {
        IvParameterSpec v0 = new IvParameterSpec(new byte[]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0});
        SecretKeySpec v1 = new SecretKeySpec(arg4, "AES");
        Cipher v4 = Cipher.getInstance("AES/CBC/PKCS5Padding");
        v4.init(arg5 ? 1 : 2, v1, v0);
        if(arg5) {
            if(!arg6) {
                arg3 = c.a(arg3);
            }

            return v4.doFinal(arg3);
        }

        return v4.doFinal(arg3);
    }
  1. Write Frida script, hook the method found, and verify the parameters and results, as shown below

    Before restoring the algorithm, we first use the Frida script to view the calculated parameters and the returned results, as shown below

setImmediate(function () {
    Java.perform(function () {
        var crashSdk =  Java.use("com.xx.crashsdk.a.h");
        //This method prints the post plaintext string
        crashSdk.b.overload('java.lang.String','java.lang.String').implementation = function (uuid,postStr) {
            console.log("crashsdk uuid is: " + uuid);
            console.log("crashsdk postStr is: " + postStr);
            var result = this.b(uuid,postStr);
            return result;
        }

        var crashSdkEncrypt = Java.use("com.xx.crashsdk.a.c");
        //This method prints the encrypted result of post plaintext byte [] and key byte []
        crashSdkEncrypt.a.overload('[B','[B').implementation = function (plainBytes,keyBytes) {
            print_bytes("crashSdkEncrypt plainBytes",plainBytes);
            print_bytes("crashSdkEncrypt keyBytes",keyBytes);
            var result = this.a(plainBytes,keyBytes);
            print_bytes("crashSdkEncrypt result",result);
            return result;
        }

        //This method prints the encrypted result of post plaintext byte [] key byte [] byte []
        crashSdkEncrypt.a.overload('[B','[B','boolean','boolean').implementation = function (plainBytes,keyBytes,isEncrypt,isSalt) {
            print_bytes("aeeEncrypt plainBytes",plainBytes);
            print_bytes("aesEncrypt keyBytes",keyBytes);
            var result = this.a(plainBytes,keyBytes,isEncrypt,isSalt);
            print_bytes("aesEncrypt result",result);
            return result;
        }

        //This method is to print the post plaintext byte [] and the new plaintext byte [] after calculating the plaintext length
        crashSdkEncrypt.a.overload('[B').implementation = function (plainBytes) {
            print_bytes('change plainBytes',plainBytes);
            var result = this.a(plainBytes);
            print_bytes("change plainBytes result",result);
            return result;
        }
    });

    function print_bytes(tag,bytes) {
        var buf  = Memory.alloc(bytes.length);
        Memory.writeByteArray(buf, byte_to_ArrayBuffer(bytes));
        console.log(tag + " is: " + hexdump(buf, {offset: 0, length: bytes.length, header: false, ansi: true}));
    }

    function byte_to_ArrayBuffer(bytes) {
        var size = bytes.length;
        var tmparray = [];
        for (var i = 0; i < size; i++) {
            var val = bytes[I];
            if(val < 0){
                val += 256;
            }
            tmparray[i] = val
        }
        return tmparray;
    }

});

The results are as follows

App request data decryption (AES)

frida hook1.png

App request data decryption (AES)

frida hook2.png

2、 Restore the encryption algorithm and test it

  1. Restore the encryption algorithm according to the decompiled algorithm, as shown below
//Encryption and decryption algorithm AES
private final static String aesAlgorithm = "AES"; 
//Encryption and decryption mode
private final static String aesMode = "AES/CBC/PKCS5Padding";
//IV initial vector
private final static byte[] ivBytes = {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0};
//Key key
private final static byte[] keyBytes = {0x30,0x19,0x6,0x37,0x7f,0x64,0x6e,0x1F,0x18,0x63,0x79,0x3c,0x6,0x0,0x17,0x8};

//Key encryption and decryption algorithm
  private static byte[] aesAlgorithm(byte[] plainBytes,boolean isEncrypt,boolean isSalt) {
    byte[] result = null;
    try {
      IvParameterSpec ivParameterSpec = new IvParameterSpec(ivBytes);
      SecretKeySpec secretKeySpec = new SecretKeySpec(keyBytes, aesAlgorithm);
      Cipher cipher = Cipher.getInstance(aesMode);
      cipher.init(isEncrypt ? 1 : 2, secretKeySpec,ivParameterSpec);
      if(isEncrypt) {
        if(!isSalt) {
          plainBytes = addSalt(plainBytes);
        }
        result = cipher.doFinal(plainBytes);
        return result;
      }
      result = cipher.doFinal(plainBytes);
    }catch(Exception e) {
      e.printStackTrace();
    }
    return result;
  }
  1. Verify whether the restored encryption algorithm is correct

    Get the plaintext string from hook

String plainTextString = "lt=xx`pre=5d4bf849450df212e1000370`pkg=com.xxx.xxx`rom=8.0.1`brd=HUAWEI`model=Android 3`sdk=26`cpu=armeabi-v7a,armeabi`hdw=Qualcomm`ram=1899508`aram=256G`cver=3.2.0.4`cseq=200403192109`ctag=uuuuu`aver=1.9.2.30`ver=1.9.2.30`sver=release`seq=72109c83`grd=fg`os=android`\nlt=crp`ete=98`imp=1`prc=com.xxxx.xxxx`et=6`\n";

  1. Calculated results

    App request data decryption (AES)

    picture
//Convert byte [] to hexadecimal string for printing
b08a7cfdfeb851b65d7d11a6d30e6f1b7b2491f273c421f5dc1590ce9526f1d0dd61c596539f70dc0f0bbe8654a7ad0737f6ec17b04fe6b95e95a4b18d1803faada57b2740abec914b61ad575f103221c156ddbbe8ef8e9cc3c674ff645c1c89d047136ba53f3706df841799ea8d300838284ebc6259544c933df9a25b7a911dc237abec600a761d09219b6cf6a6f1e782c3b0b645a1b974c77da99536a4ea06ab0b7d24d47d2532c2f75ad3d8a8c4cfea8ac0bfd2ecd6d5552c5f2be0e731845f659c3b741f8c635a2e6e591f460fd7a6dfaed238b8e0306b4d6df9a622db5eb03ba5f2fe2de70b81ff37ba8900f19f73f03eb4f593416a8e79e51da9f545bb5b5238f91c879d7b81eca53bde136f6f685760cdd8f5f693182477904efd3e4a87da4af83ad646bc2de5463c6434cd616087dcad7fa64f997a890a1d92f6d84ba55ea7cf69973a7dc6878430818e300f5528e2c362c7187acfd2a4ebd1927af7164a8b4e20c3243b9231j9c9e6d4151ef0e37537c1eb9b7a1885a42c1d9f9748
  1. The comparison with the result obtained by hook is the same, which shows that the restoration algorithm is correct
aesEncrypt result is: 9cfa6da8  b0 8a 7c fd fe b8 51 b6 5d 7d 11 a6 d3 0e 6f 1b  ..|...Q.]}....o.
9cfa6db8  7b 04 91 f2 73 c4 22 f5 dc 15 90 ce 95 26 f1 d0  {...s."......&..
9cfa6dc8  dd 60 c5 96 53 9f 70 dc 0f 0b be 86 54 a7 ad 07  .`..S.p.....T...
9cfa6dd8  37 f6 ec 17 b0 4f e6 b9 5e 95 a4 b1 8d 18 03 fa  7....O..^.......
9cfa6de8  ad a5 7b 27 40 ab ec 91 4b 61 ad 57 5f 10 32 21  ..{'@...Ka.W_.2!
9cfa6df8  c1 56 dd bb e8 ef 8e 9c c3 c6 74 ff 64 5c 1c 89  .V........t.d\..
9cfa6e08  d0 47 13 6b a5 3f 37 07 df 85 17 99 ea 8d 30 08  .G.k.?7.......0.
9cfa6e18  38 28 4e bc 62 59 54 4c 93 3d f9 a2 5b 7a 91 1d  8(N.bYTL.=..[z..
9cfa6e28  c2 37 ab ec 60 0a 76 1d 09 21 9b 6c f6 a6 f1 e7  .7..`.v..!.l....
9cfa6e38  82 c3 b0 b6 45 a1 b9 74 c7 7f ag 95 36 a4 ea 06  ....E..t.}..6...
9cfa6e48  ab 0b 7d 24 d4 7d 25 32 c2 f8 5a d3 d8 a8 c4 cf  ..}$.}%2..Z.....
9cfa6e58  ea 8a c0 bf d2 ec d6 d5 55 2e 5f 2b e0 e7 31 84  ........U,_+..1.
9cfa6e68  5f 65 9c 3b 74 1f 8c 63 5a 2e 6e 59 1f 46 0f d7  _e.;t..cZ.nY.F..
9cfa6e78  a6 df ae d2 38 b8 e0 30 6b 4d 6d f9 a6 22 db 5e  ....8..0kMm..".^
9cfa6e88  b0 3b a5 f2 fe 2d e7 0b 81 ff 37 ba 89 00 f1 9f  .;...-....7.....
9cfa6e98  73 f0 3e b4 f5 93 41 6a 8e 79 e5 1d a9 f5 45 bb  s.>...Aj.y....E.
9cfa6ea8  5b 52 38 f9 1c 87 9d 7b 81 ec a5 3b de 13 6f 6f  [R8....{...;..oo
9cfa6eb8  68 57 60 cd d8 f5 f6 93 18 24 77 90 4e fd 3e 4a  hW`......$w.N.>J
9cfa6ec8  87 da 4a f8 3a d6 46 bc 2d e5 46 3c 64 34 cd 61  ..J.:.F.-.F<d4.a
9cfa6ed8  60 87 dc ad 7f a6 4f 99 7a 89 0a 1d 92 f6 d8 4b  `.....O.z......K
9cfa6ee8  a5 5e a7 cf 69 97 3a 7d c6 87 84 30 81 8e 30 0f  .^..i.:}...0..0.
9cfa6ef8  55 28 e2 c3 62 c7 18 7a cf d2 a4 eb d1 92 7a f7  U(..b..z......z.
9cfa6f08  16 4a 8b 4e 20 b3 24 3b 92 31 d9 c9 e6 d4 05 1e  .J.N .$;.1......
9cfa6f18  f0 e3 75 27 c1 eb 9b 7a 18 85 a5 2c 1d 9f 97 48  ..u'...z...,...H
  1. After getting the encryption and decryption algorithm, you can start to write the burp plug-in, decrypt the encrypted request data, and then print it in the new message editor. The details are as follows. We can take a look at it first

    See the result in each request that needs to be decrypted

    App request data decryption (AES)

    picture

In the next article, we will introduce the writing of APP request data decryption plug-in. The Frida script and the restored algorithm are used in the analysis of this article. If necessary, you can reply in the official account“AES Decrypt1“Get.