Expiring Shellcode update

Howdy dudey!

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!

.model flat, stdcall
option casemap :none
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
includelib \masm32\lib\kernel32.lib
push    ebp
mov     ebp, esp
xor eax,eax
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
; FAILED date check, exit gracefully
xor ebx,ebx
push ebx
call ExitProcess 
; passed checks, can start shellcode now
; shellcode start
end start

How does it work?

I have a simple list of what’s happening:

  1. 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.
  2. 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.
  3. 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.
  4. 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’.
  5. 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).
  6. 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
  7. 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.

Stay tuned!

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.