Some Shellcoding Examples

Doing shellcode is always amazing! Getting down to the nitty gritty is always fun! For this post, we will be taking a look at making our own shellcode, however, it will not go into resolving the addresses that we need. Also, keep in mind this isn’t THE way, but A way!

As a side note, the shellcode that is made will only work for the current session you are in. Once you reboot, it will no longer work. Thank  you, ASLR!

The Amazing MessageBox

Messagebox is pretty awesome. I personally like this one as it can be pretty entertaining. So how do you begin to create this shellcode? Let’s take a look…

According to MSDN, MessageBox takes a total of four arguments.

If you look more into this, these parameters also construct the box itself. Let’s break this down more…

So we have hWnd. This is the handle to the owner of the window. I always set this value to null. It is also an optional parameter.

Our next parameter is lpText. This parameter is what takes the message itself. Creating the message is a little bit different than you may be used to. For instance, do you want a word showing? A sentence? A multi-line sentence?

Our third parameter is lpCaption. This parameter is what takes the title of the MessageBox. The title can be anything your heart desires! If you don’t provide a title, your MessageBox will default to “Error”.

Lastly, we have uType. uType is going to be the appearance. Depending on what you push, you can have several possibilities. How do you want your MessageBox? Do you want it to display an exclamation point with an OK button? Do you want it to display a stop sign symbol with a Yes or No? Whatever the case may be, this parameter is what takes that value.

 

Now to Creating the Shellcode

By zeroing our EAX register, we can begin with a clean slate.

Are you ready for some last in, first out action? Because of this, we have to work backwards.

…Wait, what do you mean by working backwards??

We won’t be putting the first parameter in first. This parameter is going to be put in last. We put the last parameter in first, and work our way to the top 🙂

Let’s make our icon an exclamation point with an Ok/Cancel button. If you would like to have no icon displayed and a simple Ok, you would push EAX to have this parameter zeroed.

Wait…so how do you know what values to push this parameter???

Glad you asked! On the MSDN for MessageBox, towards the bottom of the page, it goes over the different values it takes. For instance…

For our case, we need to “push 41” as a parameter because:

The next parameter that we will push is the title of the box. The title of my box is going to be labeled “Ch3rn0byl’s Lab”.

The interesting thing about adding words/sentences is having to input them backwards also.

There are a couple of interesting things when working with words/sentences. For one, we need to work backwards again. For two, we need to group them into groups of four because that’s how many values are needed to get pushed onto the stack. To put it in steps:

  1. Convert string to hex
  2. Group into fours
  3. Push onto the stack while not forgetting to push it backwards.

Let’s begin to breakdown Ch3rn0byl’s Lab…

You may notice 15 is not divisible by four. What do you do if you need some padding, but can’t add nullbytes?? The simplest way is to add spaces. They do not interfere with code execution, and also display nothing! Pretty great, huh?

As a side note, this is what you would do to insert any type of strings.

Now push onto the stack backwards!

We then put our pointer into one of our registers because if not, the MessageBox function will not see the ASCII. I will put it into EDI.

Our next parameter is lpText. For the message, I will want to display “Too sick ;)”. The same steps will be done here as we did to the title. The only difference is we need to push some padding so we can separate the title from the message. If not, you’ll end up with “Too sick ;)Ch3rn0byl’s Lab”. Not good.

 

Lastly, we have our last parameter. Because our EAX register is already zeroed, we can push EAX to insert nullbytes for this parameter.

To have the least amount of bytes for our shellcode, we can directly call our function. You can get this two different ways using either arwin or knowing the name. I use the name:

The neat thing about single stepping and landing on this step is you are able to see the function, along with the parameters into the debugger.

When your shellcode gets executed, you will get a handy dandy message box! 🙂

How awesome is that??

Now putting everything together, we end up with the following instructions for our shellcode:

Now for our next trick…

 

Executing System Commands!

Let’s take a look at WinExec. WinExec is great because it allows you to execute system commands. There is another function called CreateProcess that also allows you to execute commands, however, our goal is to be as short as possible! CreateProcess takes a total of 10 arguments. That’s not including pushing our string to call later on or zeroing the register you need, etc. WinExec on the other hand only takes two arguments! That also doesn’t include pushing strings, zeroing out registers, etc, but I would take two arguments over 10 any day. Take a look at what WinExec takes:

So we have lpCmdLine, which is going to be the application you want to get executed or the command with the arguments you want whether it is something as “calc” or “net user hurdurr /add”.

Next up, we have uCmdShow. This is the parameter you are going to use if you either want to show or hide your windows. For instance, I am sure you wouldn’t want a window to pop up for a second or two from adding a user. That would raise a red flag or two.

Let’s dive into creating the shellcode. This will be much shorter as we covered the steps in the MessageBox shellcode.

We are going to zero out our EAX register to work with and add padding. Then we are going to push our strings onto the stack and place a pointer into our EDI register.

Next parameter we are going to push is for uCmdShow. There are several arguments that you can use depending on what you need. You can find those values here. I will just push some NULL’s for this parameter. The showState value is going to get set to “SW_HIDE” but since we are spawning calc, it is going to show regardless!

All that is needed now is to push the pointer onto the stack and directly calling the function.

As you land on your call instruction, you will see lpCmdLine and uCmdShow populated with our values.

Once these gets executed, you will end up with a glorious calculator shining in all its glory.

Now putting everything together, we end up with the following instructions for spawning calculator 🙂

Awesome!

An Easier and Shorter Example

Is there a shorter way of doing the same thing with less bytes for smaller shellcode? Of course there is! Let’s take a look at the “system” function. According to the MSDN, it takes only one parameter, the command you want to run. At this point, you should have an idea of how to insert the command. Let’s take a look on how to get this function going…

The command I want to run would be something simple. Depending on the context the software is running as, it is definitely possible to use commands such as “net user hurrdurr /add” or “net search /etc/shadow” hehe 😉

For the sake of this tutorial, lets stick to “calc” because short. I like short. So calc is four bytes long, no extra padding needed, and goes perfectly.

Now remember when I said there is a shorter way to get shellcode?? Check this out… Because system only requires one parameter, we end up with this:

Holy Moly! That is really short!! A total length of 14 bytes. WinExec took 17 bytes. Very nice.

As a side note, I just want to reiterate that it is only possible for this shellcode to be this small because this is without resolving addresses we need for this function. That will be for another day and definitely add on to the size 🙂

You are one invincible mama jama! This may be hard for some and easy for others and if not hard, probably confusing. Just don’t give up! Keep kicking ass and see if you can do a different function or even create your own! Maybe even chain functions together! Make magic happen!! 🙂

 

 

Leave a Reply

Your email address will not be published. Required fields are marked *