본문 바로가기

Programming

python RIJNDAEL encryptor/decryptor

카카오톡 악성코드가 사용하는 so 파일 분석중

RIJNDAEL-192 + XOR 암호화 / 복호화 루틴을 찾아내서

복원스크립트를 만들어봄...



import rijndael

import base64

import os, sys


KEY_SIZE = 16

BLOCK_SIZE = 24


def encrypt(key, plaintext):

padded_key = key.ljust(KEY_SIZE, '\0')

padded_text = plaintext + (BLOCK_SIZE - len(plaintext) % BLOCK_SIZE) * '\0'


    # could also be one of

    #if len(plaintext) % BLOCK_SIZE != 0:

    #    padded_text = plaintext.ljust((len(plaintext) / BLOCK_SIZE) + 1 * BLOCKSIZE), '\0')

    # -OR-

    #padded_text = plaintext.ljust((len(plaintext) + (BLOCK_SIZE - len(plaintext) % BLOCK_SIZE)), '\0')


r = rijndael.rijndael(padded_key, BLOCK_SIZE)


ciphertext = ''

for start in range(0, len(padded_text), BLOCK_SIZE):

ciphertext += r.encrypt(padded_text[start:start+BLOCK_SIZE])


encoded = base64.b64encode(ciphertext)


return encoded



def decrypt(key, encoded):

padded_key = key.ljust(KEY_SIZE, '\0')


ciphertext = base64.b64decode(encoded)


r = rijndael.rijndael(padded_key, BLOCK_SIZE)


padded_text = ''

for start in range(0, len(ciphertext), BLOCK_SIZE):

padded_text += r.decrypt(ciphertext[start:start+BLOCK_SIZE])


plaintext = padded_text.split('\x00', 1)[0]


return plaintext



def xor(string, key):

res=''

for c in string:

res += chr(ord(c) ^ ord(key))

return res


cipher = sys.argv[1]


d1 = decrypt( cipher[2:10], cipher[10:] )

print xor(d1, chr(ord(cipher[0]) ^ 0x0a) )







... 분석 디컴파일소스중 일부


int __fastcall my_decrypt(int a1, int str_in)

{

  int str_in_; // r6@1

  int result; // r0@3

  void *v4; // r10@5

  void *v5; // r7@6

  void *v6; // r8@9

  int cipher_ctx; // r8@12

  void *key; // r11@17

  int v9; // r3@18

  int output; // [sp+4h] [bp-D4h]@1

  void *ptr; // [sp+Ch] [bp-CCh]@28

  unsigned int n; // [sp+10h] [bp-C8h]@24

  unsigned __int8 v13; // [sp+1Ch] [bp-BCh]@21

  int v14; // [sp+24h] [bp-B4h]@34

  const void *v15; // [sp+28h] [bp-B0h]@31

  char v16; // [sp+2Ch] [bp-ACh]@24

  const void *v17; // [sp+30h] [bp-A8h]@24

  int v18; // [sp+34h] [bp-A4h]@21

  void *src; // [sp+38h] [bp-A0h]@13

  int v20; // [sp+3Ch] [bp-9Ch]@5

  int v21; // [sp+40h] [bp-98h]@5

  int v22; // [sp+44h] [bp-94h]@5

  int ECB_mode; // [sp+48h] [bp-90h]@1

  char v24; // [sp+58h] [bp-80h]@16

  char v25; // [sp+5Ch] [bp-7Ch]@34

  char v26; // [sp+64h] [bp-74h]@32

  char v27; // [sp+68h] [bp-70h]@29

  char v28; // [sp+6Ch] [bp-6Ch]@25

  char v29; // [sp+70h] [bp-68h]@22

  char v30; // [sp+74h] [bp-64h]@27

  char v31; // [sp+78h] [bp-60h]@14

  char v32; // [sp+7Ch] [bp-5Ch]@8

  char v33; // [sp+80h] [bp-58h]@5

  char v34; // [sp+84h] [bp-54h]@5

  char v35; // [sp+88h] [bp-50h]@2

  int algo_name; // [sp+8Ch] [bp-4Ch]@1

  signed int v37; // [sp+90h] [bp-48h]@1

  signed int v38; // [sp+94h] [bp-44h]@1

  char v39; // [sp+98h] [bp-40h]@1

  char v40; // [sp+99h] [bp-3Fh]@1

  char v41; // [sp+9Ah] [bp-3Eh]@1

  char v42; // [sp+9Bh] [bp-3Dh]@1

  unsigned int iv; // [sp+9Ch] [bp-3Ch]@1

  unsigned int v44; // [sp+A0h] [bp-38h]@1

  unsigned int v45; // [sp+A4h] [bp-34h]@1

  unsigned int v46; // [sp+A8h] [bp-30h]@1

  int v47; // [sp+ACh] [bp-2Ch]@1


  output = a1;

  str_in_ = str_in;

  v47 = _stack_chk_guard;

  iv = 0x3020100u;

  v44 = 0x7060504u;

  v45 = 0xB0A0908u;

  v46 = 0xF0E0D0Cu;

  algo_name = 'njir';

  v37 = 'lead';

  v38 = '291-';

  v39 = aRijndael192[12];

  v40 = 0;

  v41 = 0;

  v42 = 0;

  ECB_mode = 'bce';

  if ( *(_DWORD *)(*(_DWORD *)str_in - 12) )

  {

    my_str_alloc2((int)&v21, "%2b", (int)&v34);

    my_str_alloc2((int)&v20, "+", (int)&v33);

    my_func((int)&v22, str_in_, (int)&v21, (int)&v20);

    v4 = (void *)(v20 - 12);

    if ( (_UNKNOWN *)(v20 - 12) != &unk_D4A8C && sub_91FB0(v20 - 4, -1) <= 0 )

      operator delete(v4);

    v5 = (void *)(v21 - 12);

    if ( &unk_D4A8C != (_UNKNOWN *)(v21 - 12) && sub_91FB0(v21 - 4, -1) <= 0 )

      operator delete(v5);

    if ( *(_DWORD *)(v22 - 12) > 9u )

    {

      cipher_ctx = my_encryptor((const char *)&algo_name, 0, (const char *)&ECB_mode, 0);

      if ( cipher_ctx )

      {

        my_substr(&src, &v22, 2, 8);

        if ( *((_DWORD *)src - 3) == 8 )

        {

          key = malloc(8u);

          memcpy(key, src, 8u);

          if ( my_setkey2(cipher_ctx, (int)key, 8, (int)&iv) < 0 )

          {

            free(key);

            my_str_alloc2(output, &my_data, (int)&v30);

          }

          else

          {

            v9 = v22;

            if ( !*(_DWORD *)(v22 - 12) )

              sub_508B4("basic_string::at");

            if ( *(_DWORD *)(v22 - 4) >= 0 )

            {

              my_get_rawptr((int)&v22);

              v9 = v22;

            }

            v13 = *(_BYTE *)v9;

            my_substr(&v18, &v22, 10, -1);

            if ( *(_DWORD *)(v18 - 12) )

            {

              my_str_cpy(&v16, &v18);

              my_decode_b64(&v17, &v16);

              my_delete(&v16);

              n = *((_DWORD *)v17 - 3);

              if ( n )

              {

                ptr = malloc(n + 1);

                memset(ptr, 0, n + 1);

                memcpy(ptr, v17, n);

                if ( my_decrypt_wrap(cipher_ctx, (int)ptr, n) )

                {

                  free(key);

                  free(ptr);

                  my_str_alloc2(output, &my_data, (int)&v27);

                }

                else

                {

                  my_strwrapper((int)&v15, (int)ptr, n);

                  if ( *((_DWORD *)v15 - 3) )

                  {

                    memset(ptr, 0, n);

                    memcpy(ptr, v15, *((_DWORD *)v15 - 3));

                    my_xor_encrypt((int)ptr, *((_DWORD *)v15 - 3), v13);

                    sub_396C0(cipher_ctx);

                    sub_39D5C(cipher_ctx);

                    v14 = std::string::_S_construct<unsigned_char__>((int)ptr, (int)((char *)ptr + n));

                    free(key);

                    free(ptr);

                    my_str_alloc2(output, (const char *)v14, (int)&v25);

                    my_delete(&v14);

                  }

                  else

                  {

                    free(key);

                    free(ptr);

                    my_str_alloc2(output, &my_data, (int)&v26);

                  }

                  my_delete(&v15);

                }

              }

              else

              {

                free(key);

                my_str_alloc2(output, &my_data, (int)&v28);

              }

              my_delete(&v17);

            }

            else

            {

              free(key);

              my_str_alloc2(output, &my_data, (int)&v29);

            }

            my_delete(&v18);

          }

        }

        else

        {

          my_str_alloc2(output, &my_data, (int)&v31);

        }

        my_delete(&src);

      }

      else

      {

        my_str_alloc2(output, &my_data, (int)&v24);

      }

    }

    else

    {

      my_str_alloc2(output, &my_data, (int)&v32);

    }

    v6 = (void *)(v22 - 12);

    if ( &unk_D4A8C != (_UNKNOWN *)(v22 - 12) && sub_91FB0(v22 - 4, -1) <= 0 )

      operator delete(v6);

  }

  else

  {

    my_str_alloc2(a1, &my_data, (int)&v35);

  }

  result = output;

  if ( v47 != _stack_chk_guard )

    _stack_chk_fail(output);

  return result;

}







 else

    {

      v22 = *(_DWORD *)(cipher_ctx_ + 136); // data

      v23 = *(_DWORD *)(cipher_ctx_ + 144); // key

      iv_size = 0;

      if ( iv_ )

        iv_size = my_ivlen(cipher_ctx_);

      v25 = my_setkey(cipher_ctx_, v22, v23, keylen, iv_, iv_size);

      result = 0;



      memcpy(&v14, (const void *)(buffer_ + 16), 0x34u);

      *(_DWORD *)(buffer_ + 156) = sub_39EFC(

                                     *(_DWORD *)buffer_,

                                     *(_DWORD *)(buffer_ + 4),

                                     *(_DWORD *)(buffer_ + 8),

                                     *(_DWORD *)(buffer_ + 12),

                                     v14,

                                     v15,

                                     v16,

                                     v17,

                                     v18,

                                     v19,

                                     v20,

                                     v21,

                                     v22,

                                     v23,

                                     v24,

                                     v25,

                                     v26,

                                     (int)"_mcrypt_encrypt");


      *(_DWORD *)(buffer_ + 152) = sub_39EFC(

                                     *(_DWORD *)(buffer_ + 68),

                                     *(_DWORD *)(buffer_ + 72),

                                     *(_DWORD *)(buffer_ + 76),

                                     *(_DWORD *)(buffer_ + 80),

                                     v14,

                                     v15,

                                     v16,

                                     v17,

                                     v18,

                                     v19,

                                     v20,

                                     v21,

                                     v22,

                                     v23,

                                     v24,

                                     v25,

                                     v26,

                                     (int)"_mdecrypt");


      memcpy(&v14, (const void *)(buffer_ + 84), 0x34u);

      *(_DWORD *)(buffer_ + 148) = sub_39EFC(

                                     *(_DWORD *)(buffer_ + 68),

                                     *(_DWORD *)(buffer_ + 72),

                                     *(_DWORD *)(buffer_ + 76),

                                     *(_DWORD *)(buffer_ + 80),

                                     v14,

                                     v15,

                                     v16,

                                     v17,

                                     v18,

                                     v19,

                                     v20,

                                     v21,

                                     v22,

                                     v23,

                                     v24,

                                     v25,

                                     v26,

                                     (int)"_mcrypt");

      v27 = (int)"_mdecrypt";

      memcpy(&v14, (const void *)(buffer_ + 84), 0x34u);

      *(_DWORD *)(buffer_ + 152) = sub_39EFC(

                                     *(_DWORD *)(buffer_ + 68),

                                     *(_DWORD *)(buffer_ + 72),

                                     *(_DWORD *)(buffer_ + 76),

                                     *(_DWORD *)(buffer_ + 80),

                                     v14,

                                     v15,

                                     v16,

                                     v17,

                                     v18,

                                     v19,

                                     v20,

                                     v21,

                                     v22,

                                     v23,

                                     v24,

                                     v25,

                                     v26,

                                     (int)"_mdecrypt");

      v27 = (int)"_mcrypt_get_block_size";

      memcpy(&v14, (const void *)(buffer_ + 16), 0x34u);

      v11 = sub_39EFC(

              *(_DWORD *)buffer_,

              *(_DWORD *)(buffer_ + 4),

              *(_DWORD *)(buffer_ + 8),

              *(_DWORD *)(buffer_ + 12),

              v14,

              v15,

              v16,

              v17,

              v18,

              v19,

              v20,

              v21,

              v22,

              v23,

              v24,

              v25,

              v26,

              (int)"_mcrypt_get_block_size");

      *(_DWORD *)(buffer_ + 164) = v11;

      if ( *(_DWORD *)(buffer_ + 156)

        && *(_DWORD *)(buffer_ + 160)

        && *(_DWORD *)(buffer_ + 148)

        && *(_DWORD *)(buffer_ + 152)

        && v11 )

      {

        v12 = sub_39F70(buffer_);

        if ( v12 != sub_3A124(buffer_) )

        {

          sub_39D5C(buffer_);

          buffer_ = 0;

        }

      }

      else

      {

        free(buffer__);

        buffer_ = 0;

      }

    }



  v20 = my_mode_getsize(cipher_ctx_);

  if ( (signed int)v20 <= 0 )

  {

    v21 = *(_DWORD *)(cipher_ctx_ + 140);

  }

  else

  {

    v21 = (int)my_calloc(1u, v20);

    *(_DWORD *)(cipher_ctx_ + 140) = v21;

    if ( !v21 )

    {

      free(*(void **)(cipher_ctx_ + 144));

      free(*(void **)(cipher_ctx_ + 136));

      return -4;

    }

  }




YOPIZYVILYD0hJrdZLpy9qs195VRRk3xDXOi8WFj9u


WEJWLUZWBGpRVgVxS4OV8/LmohNQdhVoSNduuROh85A5YxBUpK5eWEaVCIIlnkuK


WEJWLUZWBGpRVgVxS4OV8/LmohNQdhVoSNduuROh85A5YxBUpK5eWEaVCIIlnkuKyb6WonkSO6



2~10 바이트 : RIJNDAEL 키.

1 바이트 : XOR 키.

base64 데이터 : 11바이트째부터


'Programming' 카테고리의 다른 글

FreeBSD system call table  (0) 2013.07.10
Kernel module compile example  (0) 2013.07.08
FreeBSD pkg_add package install  (0) 2013.07.01
python malware scanner  (0) 2013.06.29
Alpine Linux on QEMU  (0) 2013.06.28