I’m back with an update. A quickey mind you, but I’m out here posting real UPDATES for once.
The Metasploit Framework expiration of shellcode commit that was never taken into master had me thinking – how come I never made POC code for Windows?
Why the fuck not right?
Well, let’s fucking do it!
.486 .model flat, stdcall option casemap :none include \masm32\include\windows.inc include \masm32\include\kernel32.inc includelib \masm32\lib\kernel32.lib .code start: push ebp mov ebp, esp xor eax,eax push 40h ; PAGE_EXECUTE_READWRITE mov ax,4095d ; FFF in hex, masm bug? inc ax ; push eax ; MEM_COMMIT 0x00001000 push 10h ; 16 bytes needed xor eax,eax push eax ; NULL as we dont care where the allocation is. call VirtualAlloc; VirtualAlloc mov eax,ebx ; VVVVV push eax ; ( NULL,dwLength,MEM_COMMIT,PAGE_EXECUTE_READWRITE); call GetLocalTime ; GetLocalTime with chunk from VirtualAlloc xor ecx,ecx mov cl, 6h ; MONTH converted to hex (june) cmp cx, [ebx+2] jnz short exitpart mov cx, 7e3h ; YEAR converted to hex (2019) cmp cx, [ebx] jz short wegood exitpart: ; FAILED date check, exit gracefully xor ebx,ebx push ebx call ExitProcess wegood: ; passed checks, can start shellcode now nop fnop ; shellcode start end start
I have a simple list of what’s happening:
- Setup the stack with the required parameters for VirtualAlloc. Store the memory block’s address in EBX as it will be lost in EAX after the call to GetLocalTime.
- Push our returned memory block for use with our function which takes a single argument – a pointer to a SYSTEMTIME structure to receive the current local date and time. It’s 16 bytes in size.
- Store the value of the selected month in the ‘cl’ register. We use 8 bit registers when the value is tiny to avoid null bytes and save precious space.
- We then compare this MONTH value with the address of the memory location we passed to GetLocalTime, plus 2 bytes forward to get to the place of the MONTH in ‘SYSTEMTIME’.
- If we’re not in the right month, we exit gracefully, if we’re in the right month, then we continue by moving the value of the current YEAR into the CX register (16 bits).
- We compare again the value of the chosen YEAR with the address of the memory location we passed to GetLocalTime as ‘SYSTEMTIME’ starts with the YEAR
- If satisfied, we jump to our shellcode start. If not, we exit gracefully.
Hope that was easy enough of an explanation. Coded to avoid null bytes, except for calling functions, but you can piece that shit together yourself. Or just use my earlier blog post as a skeleton template wherein we derive the functions from the Process Environment and Thread Environment Block(s) to search for function names.
More to come soon, I swear.