Exetools

Exetools (https://forum.exetools.com/index.php)
-   General Discussion (https://forum.exetools.com/forumdisplay.php?f=2)
-   -   Need help identifying modified blowfish algo (https://forum.exetools.com/showthread.php?t=19671)

dion 10-05-2020 20:23

Need help identifying modified blowfish algo
 
Hello,

i am working on an arm linux elf file that has blowfish encryption algorithm inside. But whatever i did to reproduce them, i can't get the same results. this is what it's like in decompiled form.

Code:

unsigned int __fastcall CBlowFish::Encode(CBlowFish *this, unsigned __int8 *a2, unsigned __int8 *a3, unsigned int a4)

{
  v4 = a3;
  v26 = a2;
  v23 = a4;
  v25 = this;
  v5 = CBlowFish::GetOutputLength(this, a4);
  v6 = v5;
  if ( v5 )
  {
    v7 = 0;
    v8 = v23;
    v9 = (unsigned int *)v4;
    v10 = (unsigned int *)v26;
    v24 = v23 - 7;
    v22 = v5 - v23;
    do
    {
      if ( v26 == v4 )
      {
        if ( v7 >= v24 )
        {
          v11 = (char *)v10 + v23;
          if ( v22 > 0 )
          {
            v12 = (int)&v11[v22];
            do
              *v11++ = 0;
            while ( v11 != (_BYTE *)v12 );
          }
        }
        v13 = v10;
        v14 = v10 + 1;
        v10 += 2;
        CBlowFish::Blowfish_encipher(v25, v13, v14);
        goto LABEL_9;
      }
      if ( v7 >= v24 )
      {
        v17 = v8;
        if ( v8 <= 0 )
        {
          v21 = (int)v9;
          v17 = 0;
        }
        else
        {
          v18 = 0;
          do
          {
            *((_BYTE *)v9 + v18) = *((_BYTE *)v10 + v18);
            ++v18;
          }
          while ( v8 != v18 );
          v21 = (int)v9 + v8;
          v10 = (unsigned int *)((char *)v10 + v8);
          if ( v8 > 7 )
            goto LABEL_14;
        }
        v19 = v21 - v17;
        v20 = v17;
        do
          *(_BYTE *)(v19 + v20++) = 0;
        while ( v20 <= 7 );
      }
      else
      {
        v16 = 0;
        do
        {
          *((_BYTE *)v9 + v16) = *((_BYTE *)v10 + v16);
          ++v16;
        }
        while ( v16 != 8 );
      }
LABEL_14:
      v10 += 2;
      CBlowFish::Blowfish_encipher(v25, v9, v9 + 1);
      v9 += 2;
LABEL_9:
      v7 += 8;
      v8 -= 8;
    }
    while ( v6 > v7 );
  }
  return v6;

Code:

int __fastcall CBlowFish::Blowfish_encipher(CBlowFish *this, unsigned int *a2, unsigned int *a3)

 v3 = *(_DWORD **)this;
  v4 = *((_DWORD *)this + 1);
  v5 = *a2 ^ **(_DWORD **)this;
  v6 = *(_DWORD *)(*(_DWORD *)this + 20);
  v7 = *a3 ^ (((*(_DWORD *)(v4 + 4 * ((v5 >> 16) & 0xFF) + 1024) + *(_DWORD *)(v4 + 4 * (v5 >> 24))) ^ *(_DWORD *)(v4 + 4 * ((unsigned __int16)v5 >> 8) + 2048))
            + *(_DWORD *)(v4 + 4 * (unsigned __int8)v5 + 3072)) ^ *(_DWORD *)(*(_DWORD *)this + 4);
  v8 = *(_DWORD *)(*(_DWORD *)this + 24);
  v9 = v5 ^ (((*(_DWORD *)(v4 + 4 * ((v7 >> 16) & 0xFF) + 1024) + *(_DWORD *)(v4 + 4 * (v7 >> 24))) ^ *(_DWORD *)(v4 + 4 * ((unsigned __int16)v7 >> 8) + 2048))
          + *(_DWORD *)(v4 + 4 * (unsigned __int8)v7 + 3072));
  v10 = *(_DWORD *)(*(_DWORD *)this + 32);
  v11 = v9 ^ *(_DWORD *)(*(_DWORD *)this + 8);
  v12 = *(_DWORD *)(*(_DWORD *)this + 28);
  v13 = *(_DWORD *)(*(_DWORD *)this + 36);
  v14 = *(_DWORD *)(*(_DWORD *)this + 40);
  v15 = *(_DWORD *)(*(_DWORD *)this + 44);
  v16 = (((*(_DWORD *)(v4 + 4 * ((v11 >> 16) & 0xFF) + 1024) + *(_DWORD *)(v4 + 4 * (v11 >> 24))) ^ *(_DWORD *)(v4 + 4 * ((unsigned __int16)v11 >> 8) + 2048))
      + *(_DWORD *)(v4 + 4 * (unsigned __int8)v11 + 3072)) ^ *(_DWORD *)(*(_DWORD *)this + 12) ^ v7;
  v17 = v3[17];
  v18 = (((*(_DWORD *)(v4 + 4 * ((v16 >> 16) & 0xFF) + 1024) + *(_DWORD *)(v4 + 4 * (v16 >> 24))) ^ *(_DWORD *)(v4 + 4 * ((unsigned __int16)v16 >> 8) + 2048))
      + *(_DWORD *)(v4 + 4 * (unsigned __int8)v16 + 3072)) ^ v3[4] ^ v11;
  v19 = v3[16];
  v20 = (((*(_DWORD *)(v4 + 4 * ((v18 >> 16) & 0xFF) + 1024) + *(_DWORD *)(v4 + 4 * (v18 >> 24))) ^ *(_DWORD *)(v4 + 4 * ((unsigned __int16)v18 >> 8) + 2048))
      + *(_DWORD *)(v4 + 4 * (unsigned __int8)v18 + 3072)) ^ v6 ^ v16;
  v21 = (((*(_DWORD *)(v4 + 4 * ((v20 >> 16) & 0xFF) + 1024) + *(_DWORD *)(v4 + 4 * (v20 >> 24))) ^ *(_DWORD *)(v4 + 4 * ((unsigned __int16)v20 >> 8) + 2048))
      + *(_DWORD *)(v4 + 4 * (unsigned __int8)v20 + 3072)) ^ v8 ^ v18;
  v22 = (((*(_DWORD *)(v4 + 4 * ((v21 >> 16) & 0xFF) + 1024) + *(_DWORD *)(v4 + 4 * (v21 >> 24))) ^ *(_DWORD *)(v4 + 4 * ((unsigned __int16)v21 >> 8) + 2048))
      + *(_DWORD *)(v4 + 4 * (unsigned __int8)v21 + 3072)) ^ v12 ^ v20;
  v23 = (((*(_DWORD *)(v4 + 4 * ((v22 >> 16) & 0xFF) + 1024) + *(_DWORD *)(v4 + 4 * (v22 >> 24))) ^ *(_DWORD *)(v4 + 4 * ((unsigned __int16)v22 >> 8) + 2048))
      + *(_DWORD *)(v4 + 4 * (unsigned __int8)v22 + 3072)) ^ v10 ^ v21;
  v24 = (((*(_DWORD *)(v4 + 4 * ((v23 >> 16) & 0xFF) + 1024) + *(_DWORD *)(v4 + 4 * (v23 >> 24))) ^ *(_DWORD *)(v4 + 4 * ((unsigned __int16)v23 >> 8) + 2048))
      + *(_DWORD *)(v4 + 4 * (unsigned __int8)v23 + 3072)) ^ v13 ^ v22;
  v25 = (((*(_DWORD *)(v4 + 4 * ((v24 >> 16) & 0xFF) + 1024) + *(_DWORD *)(v4 + 4 * (v24 >> 24))) ^ *(_DWORD *)(v4 + 4 * ((unsigned __int16)v24 >> 8) + 2048))
      + *(_DWORD *)(v4 + 4 * (unsigned __int8)v24 + 3072)) ^ v14 ^ v23;
  v26 = (((*(_DWORD *)(v4 + 4 * ((v25 >> 16) & 0xFF) + 1024) + *(_DWORD *)(v4 + 4 * (v25 >> 24))) ^ *(_DWORD *)(v4 + 4 * ((unsigned __int16)v25 >> 8) + 2048))
      + *(_DWORD *)(v4 + 4 * (unsigned __int8)v25 + 3072)) ^ v15 ^ v24;
  v27 = (((*(_DWORD *)(v4 + 4 * ((v26 >> 16) & 0xFF) + 1024) + *(_DWORD *)(v4 + 4 * (v26 >> 24))) ^ *(_DWORD *)(v4 + 4 * ((unsigned __int16)v26 >> 8) + 2048))
      + *(_DWORD *)(v4 + 4 * (unsigned __int8)v26 + 3072)) ^ v3[12] ^ v25;
  v28 = (((*(_DWORD *)(v4 + 4 * ((v27 >> 16) & 0xFF) + 1024) + *(_DWORD *)(v4 + 4 * (v27 >> 24))) ^ *(_DWORD *)(v4 + 4 * ((unsigned __int16)v27 >> 8) + 2048))
      + *(_DWORD *)(v4 + 4 * (unsigned __int8)v27 + 3072)) ^ v3[13] ^ v26;
  v29 = (((*(_DWORD *)(v4 + 4 * ((v28 >> 16) & 0xFF) + 1024) + *(_DWORD *)(v4 + 4 * (v28 >> 24))) ^ *(_DWORD *)(v4 + 4 * ((unsigned __int16)v28 >> 8) + 2048))
      + *(_DWORD *)(v4 + 4 * (unsigned __int8)v28 + 3072)) ^ v3[14] ^ v27;
  v30 = (((*(_DWORD *)(v4 + 4 * ((v29 >> 16) & 0xFF) + 1024) + *(_DWORD *)(v4 + 4 * (v29 >> 24))) ^ *(_DWORD *)(v4 + 4 * ((unsigned __int16)v29 >> 8) + 2048))
      + *(_DWORD *)(v4 + 4 * (unsigned __int8)v29 + 3072)) ^ v3[15] ^ v28;
  v31 = v4 + 4 * ((unsigned __int16)v30 >> 8);
  v32 = *(_DWORD *)(v4 + 4 * (v30 >> 24));
  v33 = v4 + 4 * (unsigned __int8)v30;
  v34 = *(_DWORD *)(v4 + 4 * ((v30 >> 16) & 0xFF) + 1024);
  result = v30 ^ v17;
  *a3 = (((v34 + v32) ^ *(_DWORD *)(v31 + 2048)) + *(_DWORD *)(v33 + 3072)) ^ v19 ^ v29;
  *a2 = result;
  return result;

i upload the elf file here in case someone interested.
hxxps://filebin.net/yordbkvlpmofbaem

thanks in advance

ionioni 10-06-2020 20:00

upper function std::string *__fastcall linx::LCEncryption::EncryptDecrypt(std::string *pStrOutput, const char **ppInput, int mode)
Code:

v7 = lenInput % 8;
if ( lenInput % 8 )
  v7 = 8 - v7;
lSize = lenInput + v7;
v9 = lenInput + v7 + 1;
pInput = operator new[](v9);
memset(pInput, 0, v9);
strcpy(pInput, *ppInput);
CBlowFish::CBlowFish();
BYTE key[2] = {0};
CBlowFish::Initialize(key, 2);//???             
if (mode)
{
  pOutput = operator new[](2 * lSize);
  memset(pOutput, 0, 2 * lSize);
  CBlowFish::Encode(pInput, pOutput, lSize);
  bits = (8 * lSize);
  lenBase32Str = linx::LCBase32::toLen(bits);
  Base32Str = operator new[](lenBase32Str);
  memset(Base32Str, 0, lenBase32Str);
  linx::LCBase32::toBaseStr(Base32Str, lenBase32Str, pOutput, bits);
  v24 = strlen(Base32Str);
  std::string::assign(pStrOutput, Base32Str, v24);
}

Looks like standard BF, in encryption mode (arg3 mode !0) takes a string as arg2 and returns a base32 of the encoded BF as arg1, I've also checked the random digit tables from the a binary and they're identical to the standard BF (for eg. this)

Maybe if you can show some sample pairs of input/output strings to LCEncryption::EncryptDecrypt

I don't have the proper arm env to debug the exe, tried it in qemu but it cries for missing so libs and some (QT) are compiled for this embedded app (ie not something that can be googled for) maybe if you can make a rootfs of the env or don't know, do a find / -name \*.so and only pack those (you have at least read access because of the a binary)

dion 10-06-2020 21:31

1 Attachment(s)
i am new in reversing arm binaries. but, i don't think running that big elf file would be any use. or maybe qemu has debug capability?

been trying to setup qemu as ida debugger but it just hangs at start up. and there's really little information about this (ida and qemu) in the web.

Quote:

Looks like standard BF, in encryption mode (arg3 mode !0) takes a string as arg2 and returns a base32 of the encoded BF as arg1, I've also checked the random digit tables from the a binary and they're identical to the standard BF (for eg. this)
have known about the tables. but warn you, the base32 is custom one, not standard base32. which might be where i failed to reproduce...

Quote:

Maybe if you can show some sample pairs of input/output strings to LCEncryption::EncryptDecrypt
what i have is i believed not for this function, but for LCUserManager::CheckPassword. There is only one pair.
Attachment 9826

Quote:

I don't have the proper arm env to debug the exe, tried it in qemu but it cries for missing so libs and some (QT) are compiled for this embedded app (ie not something that can be googled for) maybe if you can make a rootfs of the env or don't know, do a find / -name \*.so and only pack those (you have at least read access because of the a binary)
i have actually something else in my mind, it is to just "stitch" those functions into a somekind pre-conditioned hello world app compiled for arm. does it sounds right? i mean achieveable?

thanks

ionioni 10-06-2020 21:51

Quote:

check pm.
don't think PM works for my user group

sh3dow 10-10-2020 04:13

Quote:

been trying to setup qemu as ida debugger but it just hangs at start up. and there's really little information about this (ida and qemu) in the web.

Try Azeria Labs VM
https://azeria-labs.com/arm-lab-vm/
https://azeria-labs.com/lab-vm-2-0/
https://azeria-labs.com/emulating-arm-firmware/

Or Hugsy (the creator of GEF) VM labs
https://blahcat.github.io/2017/06/25/qemu-images-to-play-with/


All times are GMT +8. The time now is 17:33.

Powered by vBulletin® Version 3.8.8
Copyright ©2000 - 2024, vBulletin Solutions, Inc.
Always Your Best Friend: Aaron, JMI, ahmadmansoor, ZeNiX