Passing arguments to execve using the stackmethod

20 Apr 2013

I'm almost finished on SecurityTube SLAE32 videos, I've been slacking a little lately on getting this course done so I'm now trying to finish up so I can do the exam. The current assignment is how one can pass arguments to execve. For instance if you are running shellcode which runs "ls -l", how do you pass the "-l" as argument? Well read on and find out.

First of all refer back to the manpage. If you want to refresh how Vivek did the setup, refer to Demystifying the Execve Shellcode (Stack Method). Especially refer to this image:

Screen Shot 2013-04-05 at 6.25.30 PM

As you can see ECX is where our arguments should be going. But ECX does not contain our arguments. It contains an array of which the top is the address of our program to execute. In this case I stuck to the "ls" example as it was the easiest. I added a simple "-l" argument. Now here is our complete shellcode: So normally we start by using the "reverse.py" python script, but I added a few lines of code to make copy pasting slightly easier, you can find the code below: It just prepares the push arguments when running so you can just copy paste them into your nasm file. If you run it with:

./reverse.py "//bin/ls -l"

You should get:

String length : 11
l-  : 6c2d20
sl/n : 736c2f6e
ib// : 69622f2f
push 0x6c2d20
push 0x736c2f6e

Now if you just add the "-l" argument as 0x6c2d20 it's going to break, the reason for this is that it includes space. So we need to remove the spaces, spaces are defined as 0x20 so 0x6c2d20 becomes 0x6c2d. An easier way to obtain the code for the arguments, is by running the separately with the reverse script:

./reverse.py "-l"

This is the most significant part of the code:

            ;create the arguments array argument for ls
            push eax     ;push 0 onto the stack
            push 0x6c2d ;push -l onto the stack
            mov esi,esp      ;mov the address of the top of the stack into esp

Note from the manpage:

The execv() and execvp() functions provide an array of pointers to null-terminated strings that represent
the argument list available to the new program. The first argument, by convention, should point to the
filename associated with the file being executed. The array of pointers must be terminated by a NULL pointer.
This is where we push the arguments onto the stack. Basically we have a 0 on the bottom to terminate our array and then our arguments. I save the address of the array into ESI. We then continue preparing the stack for execution:

            ;prepare the arguments array for execution
            push eax ;Terminate by 0
            push esi ;address of where our arguments are
            push ebx ;address of where //bin/ls is
            mov ecx, esp ;move our stack pointer in ecx and execute the program.

If you want to add extra arguments, you just push them additionally onto the stack, referring to the example below:

        mov edx, eax ;mov esp (0) in EDX
        push eax
        push 0x682d   ;push -h onto the stack
        push 0x6c2d   ;push -l onto the stack
        mov esi,esp   ;mov the address of the top of the stack into esp

So that's all for passing arguments. Hope this was useful to you, if you have any suggestions, criticism or comments, you can always post these below.