Programming language
This assignment tells us to create a so-called “crypter”: a file which runs and decrypts (malicious) payload, possibly by an entered key. Being allowed to create in any programming language, I’ve chosen to create the crypter in C.
You see, programming blowfish in assembly isn’t exactly ideally for this assignment.
Encryption scheme
Of course we could try to use a more modern and proven encryption scheme, such as Blowfish. But alas, I’ll keep it fairly simple using:
AES 128 CBC
No rocket science, only some challenges when using static or random IV’s which don’t pad nicely when programming the wrong way (spend some time on that one).
DO NOT RELY on this encryption scheme for life saving purposes, it’s merely used as an example for the assignment. There are quite some known attacks already being used against these kind of implementations such as bit flipping attacks and padding attacks, so be cautious.
AES has a fixed blocksize of 128 bits and keysizes might be 128, 192 or 256 bits. We’ll be using the OpenSSL implementation <openssl/aes.h> and a keysize of 128 bit. Also, AES_BLOCK_SIZE will be 16, which is default.
Challenges
So, what are we trying to achieve, exactly? Well, having generated or created our evil payload, we would like to hide it from AV/IDS vendors and their products. Encryption is a good method for hiding, albeit as strong as the weakest link: this might be a fault encryption scheme implementation or issues such as hardcoded passwords.
Basically, the binary including evil payload needs a couple of things:
- IV
- Password
- Encrypted payload
- Decryption routine
When we send our binary, including the encrypted payload, we should have a method to decrypt and run it. Of course, hard-coding your password might just be as useful as using your password in the filename: don’t pair the two hiding in plain-text!
Some challenges are inevitable using the encryption scheme: the key has to be entered at some moment. I’ve chosen to enter the key at runtime where it asks for the password: not entering it as an argument, due to history logging of console sessions.
Another challenge is the IV (Initialization Vector). Surely, we can generate random IV’s which helps us boost security for the encryption scheme being used. Downside is the IV needs to be known when decrypting, so the IV has to be hard-coded in the binary itself.
Added functionality
I’ve added some functionality for the following files:
- aes-128-cbc_enc
- aes-128-cbc_dec
- aes-128-cbc_enc-dec
This functionality includes entering a filename as argument to read the unencrypted or encrypted shellcode, based on the file/binary you’re using. Not really useful when trying to run the binary with encrypted evil payload, but perhaps useful for learning purposes.
Reused “print_data” functionality
Trying to implement some printing functionality, I’ve reused the “print_data” function being shown on http://www.firmcodes.com/how-do-aes-128-bit-cbc-mode-encryption-c-programming-code-openssl/.
Although the rest of the code might be useful, I had some padding issues and decided to rebuild it myself.