【Android CTF】使用trace进行算法还原

admin 2021年11月6日12:55:41【Android CTF】使用trace进行算法还原已关闭评论92 views字数 5446阅读18分9秒阅读模式

作者坛账号:neilwu

一、题目

1、android 逆向题

小伙伴发来的题,说是某比赛线下题目

2、涉及算法

AES

魔改RC5

二、解题过程

1、java层

图片

2、native层

图片


sub_F08

 复制代码 隐藏代码
int __fastcall sub_F08(JNIEnv *a1, int a2, int a3)
{
  const char *v3; // r9
  size_t v4; // r6
  char *v5; // r4
  void *v6; // r8
  _DWORD *v7; // r5
  int v8; // r9
  unsigned __int8 *v9; // r6
  int v10; // r0
  char *v11; // r1
  int v12; // r2
  int v13; // t1
  int v14; // t1

  v3 = (*a1)->GetStringUTFChars(a1, a3, 0);
  v4 = strlen(v3);
  v5 = malloc(v4);
  v6 = malloc(4 * v4 + 64);
  v7 = malloc(0x20u);
  *v7 = 0x1010101;
  v7[1] = 0x1010101;
  v7[2] = 0x1010101;
  v7[3] = 0x1010101;
  qmemcpy(v5, v3, v4);
  v8 = sub_D68(v6, v5, v4, v7);
  free(v5);
  memset(v7, 2, 0x20u);
  v9 = malloc(4 * v8 + 32);
  v10 = sub_E80(v9, v6, v8, v7);
  v11 = &c_cipher;
  while ( v10 )
  {
    v13 = *v11++;
    v12 = v13;
    --v10;
    v14 = *v9++;
    if ( v14 != v12 )
      return 0;
  }
  return 1;
}

(1)对伪码进行分析,流程如下

 复制代码 隐藏代码
第一加密 v8 = sub_D68(v6, v5, v4, v7);
第二次加密 v10 = sub_E80(v9, v6, v8, v7);
解密结果与 &c_cipher进行比较

(2)动态调试

c_cipher
 复制代码 隐藏代码
unsigned char c_cipher[56] = {
0xCA, 0x60, 0x55, 0x30, 0xB5, 0xDB, 0xD4, 0xA6, 0x01, 0x15, 0x3F, 0xB8, 0xBC, 0x4C, 0x9C, 0x88,
0xEA, 0xF4, 0x76, 0xDD, 0x8D, 0x7B, 0x1A, 0x26, 0xDA, 0x74, 0x2C, 0x1D, 0x28, 0x63, 0x4B, 0x88,
0x44, 0x22, 0x7E, 0x21, 0x0E, 0x6C, 0xF4, 0xAE, 0xE4, 0x21, 0xC7, 0x67, 0x21, 0x40, 0xC5, 0x3B,
0xB2, 0x55, 0x92, 0x21, 0x9B, 0x29, 0xFA, 0x33
};
第一加密 v8 = sub_D68(v6, v5, v4, v7);

图片


AES的S盒

 复制代码 隐藏代码
输入 flag{0123456789}
key 01010101010101010101010101010101
加密结果
7E D8 C7 01 11 B4 88 27  0E 42 0B 31 59 CB 42 63
68 43 4D 37 D7 F6 9F 0E  03 B7 5B B1 5B C9 4B 6C

验证一下
图片

第二次加密 v10 = sub_E80(v9, v6, v8, v7);
 复制代码 隐藏代码
输入
7E D8 C7 01 11 B4 88 27  0E 42 0B 31 59 CB 42 63
68 43 4D 37 D7 F6 9F 0E  03 B7 5B B1 5B C9 4B 6C
key
02020202020202020202020202020202
02020202020202020202020202020202
加密结果
8B A8 1D 1F DF E9 09 98  78 B0 0A CA F7 8F DE 1D
56 6F B4 65 E0 32 DC BA  BE 7B 8A 81 A1 41 59 BA
B2 55 92 21 9B 29 FA 33
sub_E80
 复制代码 隐藏代码
unsigned int __fastcall sub_E80(int a1, int a2, int a3, int a4)
{
  unsigned int result; // r0
  int i; // r10
  int v9; // r9
  int v10; // r1
  int v11; // r4
  int j; // r5
  __int64 v13; // kr00_8

  sub_DA8(a4);
  result = sub_994(a1, a2, a3, 8);
  for ( i = 0; i != result >> 3; ++i )
  {
    v9 = 2 * i + 1;
    v10 = *(a1 + 8 * i) + dword_5E50[0];
    v11 = *(a1 + 4 * v9) + unk_5E54;
    for ( j = 0; j != 12; ++j )
    {
      v13 = *&dword_5E50[2 * j + 2];
      v10 = __ROR4__(v10 ^ v11, 32 - v11) + v13;
      v11 = __ROR4__(v10 ^ v11, 32 - v10) + HIDWORD(v13);
    }
    *(a1 + 8 * i) = v10;
    *(a1 + 4 * v9) = v11;
  }
  return result;
}

我使用trace进行的算法还原
图片

对trace进行分析,算法如下
 复制代码 隐藏代码
输入
7E D8 C7 01 11 B4 88 27  0E 42 0B 31 59 CB 42 63
68 43 4D 37 D7 F6 9F 0E  03 B7 5B B1 5B C9 4B 6C

加密结果
8B A8 1D 1F DF E9 09 98  78 B0 0A CA F7 8F DE 1D
56 6F B4 65 E0 32 DC BA  BE 7B 8A 81 A1 41 59 BA
B2 55 92 21 9B 29 FA 33

输入由32补全40位,08补全
图片

 复制代码 隐藏代码
输入
7E D8 C7 01 11 B4 88 27  0E 42 0B 31 59 CB 42 63
68 43 4D 37 D7 F6 9F 0E  03 B7 5B B1 5B C9 4B 6C
08 08 08 08 08 08 08 08

输入长度 40 >> 3 = 5
图片

进行了5次大循环,每次循环进行了12+1次
图片


每次小循环使用的数组:

 复制代码 隐藏代码
    uint32_t dword_C30DDE50[] = {
            0x751EF375, 0x9A777FE8,
            0xCF327F57, 0x378B39DC,
            0xB0CF04C8, 0xA0AA7A08,
            0xCE01CEA5, 0xF400183,
            0x58FBD0BB, 0x8D44D42A,
            0x59F0BB54, 0xB632AA3A,
            0x40030399, 0xA9C58CAC,
            0xB1F1F560, 0x29796A99,
            0x513FE4A6, 0x8204DA32,
            0xC435BFCA, 0x465706D,
            0xECB351E9, 0x9A83C02C,
            0x4615414F, 0x8728979D,
            0x8CED0CFA, 0x15647C9C};

逆推
图片


还原算法

 复制代码 隐藏代码
    uint32_t dword_C30DDE50[] = {
            0x751EF375, 0x9A777FE8,
            0xCF327F57, 0x378B39DC,
            0xB0CF04C8, 0xA0AA7A08,
            0xCE01CEA5, 0xF400183,
            0x58FBD0BB, 0x8D44D42A,
            0x59F0BB54, 0xB632AA3A,
            0x40030399, 0xA9C58CAC,
            0xB1F1F560, 0x29796A99,
            0x513FE4A6, 0x8204DA32,
            0xC435BFCA, 0x465706D,
            0xECB351E9, 0x9A83C02C,
            0x4615414F, 0x8728979D,
            0x8CED0CFA, 0x15647C9C};

    uint32_t plaintext[] = {0x01C7D87E, 0x2788B411, 0x310B420E, 0x6342CB59, 0x374D4368, 0x0E9FF6D7, 0xB15BB703, 0x6C4BC95B, 0x08080808, 0x08080808};

    int len = sizeof(plaintext) / sizeof(uint32_t);

    for(int i = 0; i < len/2; i++){
        int R1 = plaintext[i*2];
        int R4 = plaintext[i*2+1];
        int R2,R5,R6,R9;
        int R3=0xC30DDE50;
        for(int j = 0; j < 13; j++){

            if(j == 0){
                R1 = R1 + dword_C30DDE50[j*2];

                R4 = R4 + dword_C30DDE50[j*2+1];
            }else{
                R1 = R1 ^ R4;

                R6 = 0x20 - R4;

                R1 = ror(R1, R6);

                R2 = dword_C30DDE50[j*2];

                R6 = dword_C30DDE50[j*2+1];

                R1 = R1 + R2;

                R2 = R1 ^ R4;

                R4 = 0x20 - R1;

                R2 = ror(R2, R4);

                R4 = R2 + R6;

            }
        }

        printf("0x%x,0x%x, n", R1, R4);

    }

图片

对加密算法进行逆运算

 复制代码 隐藏代码
    uint32_t dword_C30DDE50[] = {
            0x751EF375, 0x9A777FE8,
            0xCF327F57, 0x378B39DC,
            0xB0CF04C8, 0xA0AA7A08,
            0xCE01CEA5, 0xF400183,
            0x58FBD0BB, 0x8D44D42A,
            0x59F0BB54, 0xB632AA3A,
            0x40030399, 0xA9C58CAC,
            0xB1F1F560, 0x29796A99,
            0x513FE4A6, 0x8204DA32,
            0xC435BFCA, 0x465706D,
            0xECB351E9, 0x9A83C02C,
            0x4615414F, 0x8728979D,
            0x8CED0CFA, 0x15647C9C};

    uint32_t cipher[] = {0x305560CA, 0xA6D4DBB5, 0xB83F1501, 0x889C4CBC, 0xDD76F4EA, 0x261A7B8D,
                         0x1D2C74DA, 0x884B6328, 0x217E2244, 0xAEF46C0E, 0x67C721E4, 0x3BC54021,
                         0x219255B2, 0x33FA299B};

    // 解密

    int len2 = sizeof(cipher) / sizeof(uint32_t);
    for(int i = 0; i< len2/2; i++){
        int R1_cipher = cipher[i*2];
        int R4_cipher = cipher[i*2+1];
        int R1, R4;
        for(int j = 12; j >=0; j--){
            if(j == 0){
                R1_cipher = R1_cipher - dword_C30DDE50[j*2];

                R4_cipher = R4_cipher - dword_C30DDE50[j*2+1];
            }else{

                R4_cipher = rol(R4_cipher - dword_C30DDE50[j*2+1], 0x20 - R1_cipher) ^ R1_cipher;

                R1_cipher = rol(R1_cipher - dword_C30DDE50[j*2], 0x20 - R4_cipher) ^ R4_cipher;

            }
        }

        printf("%x %x n", R1_cipher, R4_cipher);
    }


图片

使用AES Decrypt
图片

--

www.52pojie.cn


--

pojie_52

相关推荐: 【移动安全】Android App—HTTPS证书校验绕过

文章来源:https://www.cnblogs.com/bigben0123/articles/14486701.html前言:Android渗透过程中,会经常遇见https证书校验,不能抓取数据包。就比如我手机无法Root,每次都要用到模拟器,但是有些Ap…

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2021年11月6日12:55:41
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   【Android CTF】使用trace进行算法还原http://cn-sec.com/archives/618015.html