ZenHAX

Free Game Research Forum | Official QuickBMS support | twitter @zenhax | SSL HTTPS://zenhax.com
It is currently Mon Jun 21, 2021 12:34 am

All times are UTC




Post new topic  Reply to topic  [ 6 posts ] 
Author Message
 Post subject: aes 128 cbc block
PostPosted: Thu Dec 31, 2020 1:12 am 

Joined: Thu Aug 07, 2014 10:28 pm
Posts: 379
I have this function in c#
Code:
    private void cipher(byte[] buffer, int offset, int count, long streamPos)
    {
        //find block number
        var blockSizeInByte = aes.BlockSize / 8;
        var blockNumber = (streamPos / blockSizeInByte) + 1;
        var keyPos = streamPos % blockSizeInByte;
 
        //buffer
        var outBuffer = new byte[blockSizeInByte];
        var nonce = new byte[blockSizeInByte];
        var init = false;
 
        for (int i = offset; i < count; i++)
        {
            //encrypt the nonce to form next xor buffer (unique key)
            if (!init || (keyPos % blockSizeInByte) == 0)
            {
                BitConverter.GetBytes(blockNumber).CopyTo(nonce, 0);
                encryptor.TransformBlock(nonce, 0, nonce.Length, outBuffer, 0);
                if (init) keyPos = 0;
                init = true;
                blockNumber++;
            }
            buffer[i] ^= outBuffer[keyPos]; //simple XOR with generated unique key
            keyPos++;
        }
    }


its generating a xor key 16 bytes at a time starting with 1 going to x number and ending at 0.

and here is a quick example

Code:
# py 3.9
# pip install pycryptodome
# pip install passlib
from Crypto.Cipher import AES
from passlib.utils.pbkdf2 import pbkdf1
from struct import pack_into


password = b'Jr9DW9ksMRv1Lc796mrwv145fXC3L5VcpmKE5VfCuvbrpZGfYwXMpwo9sGkJ54zHse4G7zftpjkhqHHY60O7aQPj4M2ekKMSw094PmXRkN4ftTmDFlYMPmwK8QvhJ20H'
salt = b'Jr9DW9ksMRv1Lc796mrwv145fXC3L5VcpmKE5VfCuvbrpZGfYwXMpwo9sGkJ54zHse4G7zftpjkhqHHY60O7aQPj4M2ekKMSw094PmXRkN4ftTmDFlYMPmwK8QvhJ20H'
key = pbkdf1(password, salt, 100, keylen=16, hash='sha1')

block_key = key[:16]
block_size = 0x2000
nonce = bytearray([0] * (block_size * 16))

aes = AES.new(block_key, mode = AES.MODE_ECB)

for i in range(0,block_size):
   pack_into('I', nonce, i * 16, (i + 1) % block_size)

out = aes.encrypt(nonce)
print(out.hex())


Code:
   PasswordDeriveBytes pdb = new PasswordDeriveBytes(pwd, salt, "Sha1", 100);
       var buffer = pdb.GetBytes(0x10);
       var nonce = new byte[0x2000];
       var outBuffer = new byte[0x2000];
 
            var aes = new AesManaged();
            aes.KeySize = 128;
            aes.Mode = CipherMode.ECB;
            aes.Padding = PaddingMode.None;
            aes.Key = buffer;
            aes.IV = buffer;
            var encryptor = aes.CreateEncryptor(aes.Key, aes.IV);
       var block = 1;
 
            BitConverter.GetBytes(block).CopyTo(nonce, 0);
            encryptor.TransformBlock(nonce, 0, nonce.Length, outBuffer, 0);


so lets say
buffer is '8e2e1d5a5e3a4a1c7388f6b8d7779d7b'

the key is pushed to outbuffer
the first key block 1 would be
"31 0D 83 A9 D0 C0 10 4F FC ED 31 A7 56 E7 8A 85"
the 2nd key block 2 would be
"12 5F 47 C9 11 0C 35 12 D1 AE 25 EA 15 6C C0 0D"
the third key block 3 would be
"E4 E8 EF A9 4C B1 A2 92 AF 54 F0 E8 A4 88 BF BC"
and it would end on block 0
"FA DB B4 83 B5 DC CC EB 51 1C 3D 28 A3 00 53 3F"

How would this be handled in quickbms?


Last edited by chrrox on Thu Jan 14, 2021 5:42 pm, edited 10 times in total.

Top
   
 Post subject: Re: aes 128 cbc block
PostPosted: Mon Jan 11, 2021 2:08 pm 

Joined: Thu Aug 07, 2014 10:28 pm
Posts: 379
Working example to try it online

Code:
using System;
using System.Security.Cryptography;
using System.Text;

               
public class Program
{
   public static void Main()
   {
      string password = "Jr9DW9ksMRv1Lc796mrwv145fXC3L5VcpmKE5VfCuvbrpZGfYwXMpwo9sGkJ54zHse4G7zftpjkhqHHY60O7aQPj4M2ekKMSw094PmXRkN4ftTmDFlYMPmwK8QvhJ20H";
      byte[] salt = Encoding.UTF8.GetBytes( "Jr9DW9ksMRv1Lc796mrwv145fXC3L5VcpmKE5VfCuvbrpZGfYwXMpwo9sGkJ54zHse4G7zftpjkhqHHY60O7aQPj4M2ekKMSw094PmXRkN4ftTmDFlYMPmwK8QvhJ20H" );
      var key = new PasswordDeriveBytes(password, salt, "Sha1", 100);

      
       byte[] Key = key.GetBytes(16);
       var nonce = new byte[0x2000];
       var outBuffer = new byte[0x2000];
 
            var aes = new AesManaged();
            aes.KeySize = 128;
            aes.Mode = CipherMode.ECB;
            aes.Padding = PaddingMode.None;
            aes.Key = Key;
            aes.IV = new byte[16];
            var encryptor = aes.CreateEncryptor(aes.Key, aes.IV);
             var block = 1;
 
            BitConverter.GetBytes(block).CopyTo(nonce, 0);
            encryptor.TransformBlock(nonce, 0, nonce.Length, outBuffer, 0);
          Console.WriteLine(outBuffer[0]);
         Console.WriteLine(outBuffer[1]);
          Console.WriteLine(outBuffer[2]);
         Console.WriteLine(outBuffer[3]);
   }
}


Top
   
 Post subject: Re: aes 128 cbc block
PostPosted: Thu Jan 14, 2021 6:27 pm 

Joined: Thu Aug 07, 2014 10:28 pm
Posts: 379
This does this in quickbms to match the xor key.

Code:
set FINAL_SIZE 0x20000
putvarchr MEMORY_FILE FINAL_SIZE 0
for i = 0 < 0x2000
set j long i
math j * 16
set k long i
math k + 1
math k % 0x2000
putvarchr MEMORY_FILE j k long
next i
encryption mcrypt_rijndael-128_ecb "\x8E\x2E\x1D\x5A\x5E\x3A\x4A\x1C\x73\x88\xF6\xB8\xD7\x77\x9D\x7B"  "" 1 16
log NAME 0 FINAL_SIZE MEMORY_FILE


I just can't generate the key in quickbms can't find PBKDF1


Top
   
 Post subject: Re: aes 128 cbc block
PostPosted: Wed May 05, 2021 8:08 am 
Site Admin
User avatar

Joined: Wed Jul 30, 2014 9:32 pm
Posts: 12296
It can probably be done because there are some functions available in the Encryption command supporting pbkdf1 and others.
But I have no idea how to make them working easily because they need multiple arguments and their implementation may differ in some settings.


Top
   
 Post subject: Re: aes 128 cbc block
PostPosted: Fri May 07, 2021 3:02 am 

Joined: Thu Aug 07, 2014 10:28 pm
Posts: 379
make new specific encryption command for them?


Top
   
 Post subject: Re: aes 128 cbc block
PostPosted: Sun May 09, 2021 9:42 am 
Site Admin
User avatar

Joined: Wed Jul 30, 2014 9:32 pm
Posts: 12296
Honestly I don't know what to do.
Imagine having many functions (current and in the future) with their own prototype and many settings, then finding a way to set them in a simple language like bms.

Since these algorithms are already implemented in quickbms, I guess the best way is checking the source code and understanding how to pass all the settings.
PKCS5_PBKDF2_HMAC, Rfc2898DeriveBytes, BytesToKey, PBKDF1, PBKDF1_openssl, PBKDF2, and others are already available in quickbms, the source code to check is in cmd.c and perform.c

Examples:
Code:
    } else if(!strnicmp(type, "PKCS5_PBKDF2_HMAC", 17)) {
        myhash   = EVP_sha1();
        if(type[17]) openssl_get_algo(type + 17, &mycrypto, &myhash);
        memset(hash_key, 0, sizeof(hash_key));
        PKCS5_PBKDF2_HMAC(key, keysz, ivec, ivecsz, ((var3_backup != 0) && (var3_backup != 1)) ? var3_backup : 1000, myhash, sizeof(hash_key), hash_key);
        mycrypto = NULL;
        myhash   = NULL;
        DO_QUICKBMS_HASH(hash_key, sizeof(hash_key));

Code:
    } else if(!strnicmp(type, "Rfc2898DeriveBytes", 18)) {
        myhash   = EVP_sha1();
        if(type[18]) openssl_get_algo(type + 18, &mycrypto, &myhash);
        memset(hash_key, 0, sizeof(hash_key));
        PKCS5_PBKDF2_HMAC(key, keysz, ivec, ivecsz, ((var3_backup != 0) && (var3_backup != 1)) ? var3_backup : 1000, myhash, sizeof(hash_key), hash_key);
        mycrypto = NULL;
        myhash   = NULL;
        hash = DO_QUICKBMS_HASH(hash_key, sizeof(hash_key));

        keysz  = 32;
        memcpy(key,  hash, keysz);
        ivecsz = 32;
        memcpy(ivec, hash + keysz, ivecsz);

        mcrypt_ctx = quick_mcrypt_check("mcrypt_rijndael-256_cbc");  // libmcrypt
        if(mcrypt_generic_init(mcrypt_ctx, key, keysz, ivec) < 0) {
            fprintf(stderr, "\nError: mcrypt key failed\n");
            myexit_cmd(cmd, QUICKBMS_ERROR_ENCRYPTION);
        }


Code:
    } else if(!strnicmp(type, "BytesToKey", 10)) {
        mycrypto = EVP_aes_256_cbc();
        myhash   = EVP_sha1();
        openssl_get_algo(type + 10, &mycrypto, &myhash);
        openssl_get_algo(strstr(type + 10, " "), &mycrypto, &myhash);
        memset(hash_key, 0, sizeof(hash_key));
        EVP_BytesToKey(mycrypto, myhash, ivec, key, keysz, ((var3_backup != 0) && (var3_backup != 1)) ? var3_backup : 1000, hash_key, hash_key + sizeof(hash_key) / 2);
        mycrypto = NULL;
        myhash   = NULL;
        DO_QUICKBMS_HASH(hash_key, sizeof(hash_key));


Code:
    } else if(!strnicmp(type, "PBKDF", 5)) {
        PBKDF_ctx = calloc(1, sizeof(*PBKDF_ctx));
        if(!PBKDF_ctx) STD_ERR(QUICKBMS_ERROR_MEMORY);
        PBKDF_ctx->key      = key;
        PBKDF_ctx->keysz    = keysz;
        PBKDF_ctx->ivec     = ivec;
        PBKDF_ctx->ivecsz   = ivecsz;
        PBKDF_ctx->iter     = ((var3_backup != 0) && (var3_backup != 1)) ? var3_backup : 1000;

        u8 *p = strchr(type, ' ');
        if(p) {
            p = "SHA1";
        } else {
            while(*p && !myisalnum(*p)) p++;
        }
        tomcrypt_doit(NULL, NULL, NULL, 0, NULL, 0, NULL);
        PBKDF_ctx->hash  = find_hash(p);

        if(type[5] == '2') {
            PBKDF_ctx->algo = 2;
        } else {    //'1'
            PBKDF_ctx->algo = 1;
            if(stristr(type, "openssl")) {
                PBKDF_ctx->openssl = 1;
            }
        }


Top
   
Display posts from previous:  Sort by  
Post new topic  Reply to topic  [ 6 posts ] 

All times are UTC


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Powered by phpBB® Forum Software © phpBB Limited