A DOS Batch File Virus
26. March 1998
Joshua Zarwel recently expressed disbelief in the possibility of batch file viruses on alt.comp.virus. I was going to respond with the rumor I had heard about a virus which spreads by using the MS-DOS find command to extract itself, but I wondered about the details, so I went up a few cul-de-sacs before finding a method that allows the creation of a batch file virus.
Please note that I am not a "virus writer." Don't send me any email saying, "Hey, d00d, I need to crash my junior high library's computer!!! Send me an email viriiiiii that will turn it into slag." If I thought this virus was at all dangerous, I wouldn't have posted it. If you are going to play with it, keep in mind that you have to type the command in UPPERCASE to avoid an infinite loop. If anyone knows how to make the if string==string operation case insensitive, please write me. Create yourself a new directory with some simple batch files in it, so that you don't end up infecting yourself (although a few minutes with a text editor will let you remove the virus from your system).
The logical steps in the operation of a batch file virus are:
Extracting the virus portion of the host file is best done using the find command, which works much like Unix grep, allowing one to output all lines containing a search string. So, we have to make sure all lines of our virus contain the same search string that isn't likely to occur randomly (or the virus would pick up random lines of other files).
Iteration is accomplished via the for var in list do command construction. Simply enough, the list is just (*.bat).
Appending is done using the copy command, which supports adding two files together. "copy file1 + file2" will append file2 to the end of file1. So here's the virus:
find "batvirus.xyz" %0.bat |find /v /i "%0.bat"> batvirus.xyz for %%b in (*.bat) do if not %%b==%0.BAT copy %%b + batvirus.xyz del batvirus.xyz
First, we get the name of the host file, which will probably be the first word of the command line with the suffix ".bat" added on to it. We search through it for the name of our temp file, because it appears in all three lines. Because find thinks you are a moron, it adds the name of the file searched to its output. The second find filters this out, by searching for the name of the host file in the output of find (remember that the %0 will be interpolated before find gets its arguments). The /v switch does the same thing as on grep: output all lines that don't match the pattern. Find doesn't add any file names when reading from a pipe. Using type %0.bat | find "batvirus.xyz" > batvirus.xyz would work just as well, but I thought of the other first. After this command finishes, we have a temp file called "batvirus.xyz", which contains the entire virus (any name would work, except that it cannot end in ".bat" or you get multiple copies of the virus). All we have to do now is infect all the bat files with it.
We iterate through all the batch files in the current directory using the for...do construction. Since MS-DOS is such crap, you are limited to a single line command, and you can't even nest fors, like you would do to infect an entire directory tree rather than a single directory. The command the for command runs is an if statement that tests to make sure we aren't trying to reinfect the host file. This is where the biggest bug creeps in: for loads its arguments with uppercase names, so %b will evaluate to something like "PROGRAM.BAT". If the batch file was run by typing "program arg1 arg2 arg3", then %0.BAT evaluates to "program.BAT", which if doesn't think is the same thing. So unless the program was run as uppercase, we reinfect the host file, which causes the virus to repeatedly run. In testing, before I could hit CTRL-C, I had batch files several thousand bytes long filled with multiple copies of the virus. Note that there is no check if a batch file is already infected. This could be accomplished by a more complicated construction with find searching for the temp file's name in the batch file, and returning an errorlevel to indicate whether to infect or not.
So now we have several infected batch files (if the directory had a lot). To avoid leaving incriminating evidence around, the last line deletes the temp file.
For you aspiring criminals out there, one easy change is to turn echo off in the first line of the virus. The tricky part is to include the search string in the line to do this. If you're up for a challenge, it's even easier to write viruses in the Unix Shell. Dr. Cohen mentions that "once you are logged into a Unix system, you can type a 8 character command, and before too long, the virus will spread" (A Short Course on Computer Viruses, page 38). I haven't been able to figure out what this eight character virus is.
11 March 2001 note: I make reference to an "email virus" in the above. There were no email viruses until a year after I wrote this, so the meaning of that bit has changed slightly since writing.
Please report any broken links, invalid HTML, or typos to
Last updated 11 March 2001