Real-World Shell Scripting: Detecting and Inoculating Against Viruses


The proliferation of new viruses keeps systems administrators on their toes. Having adequate email filters and virus-scanning software on servers and desktop PCs is an important first line of defense. However, virus-definition files can become out of date quickly and not detect new viruses or strains of existing viruses. To protect your system, you can write code that detects these potential threats. For example, you can write code that detects the FunLove virus, a virus that originally appeared in late 1999 but occasionally reappears. You can even go a step further and create a script that not only detects but also inoculates your PCs and servers against the FunLove virus.

Detecting Viruses
Viruses typically drop files into the \system32 directory or other places in which they can perform malicious attacks. Thus, you can use command-line code to quickly check for the existence of virus-created files to identify potentially infected servers and PCs. To write such code, you first need to determine which file the virus drops, which requires research. Good resources include the Web sites of antivirus software vendors, such as Symantec, or security Web sites, such as SANS Institute ( As the Symantec Web site ( shows, the FunLove virus drops the flcss.exe file into the \system32 folder.

After you've identified the virus-created file, you can write code similar to the code that Listing 1 and Listing 2 show. Listing 1 is for Windows 2000 machines; Listing 2 is for Windows NT machines. The code uses basic shell-scripting commands and global.exe, which you can find in the Microsoft Windows 2000 Server Resource Kit or the Microsoft Windows NT Server 4.0 Resource Kit. The global.exe utility that lets you obtain the names of servers and PCs that have machine accounts in the logon domain (i.e., the domain on which you logged on). The code uses the %logonserver% environment variable to specify the logon domain, but you can substitute the PDC or the domain's name for this variable if you want to.

In the code, the Global command lists all the members of the specified group in the logon domain. The Find command then filters the Global command's output to obtain only the server, PC, and trusted domain names. The trusted domain names are nonexistent locations. However, they don't cause any problems in the subsequent If Exist command, so you can ignore them. The If Exist command determines whether flcss.exe exists in the identified servers and PCs. If that file exists, the Net Send command informs the script operator of the possible problem with that computer.

Detecting and Inoculating Against Viruses
Detecting viruses is good, but detecting and inoculating against them is even better. Antivirus software vendors often recommend that you install a blocking folder to help prevent the spread of viruses. As I mentioned earlier, viruses often drop files in the \system32 directory; you can thwart this file-drop operation by creating, in the \system32 directory, a folder (not a file) with the same name as the virus-created file. This folder prevents the virus from spreading on that machine one of two ways. Sometimes, the virus detects the pathname, thinks that the current machine is already infected, and moves on to another machine. Other times, the virus tries but fails to create the file because Windows doesn't let you copy a file to a path with the same name. If the virus attempts to use the Del command to delete the existing "file," the attempt will fail because you must use the Rmdir command to delete a folder. Similarly, an attempt to use the Echo command to drop the file's contents into the existing "file" will also fail. Thus, unless the virus uses the Rmdir command to delete blocking folders, creating a folder with the same name as the virus-created file effectively prevents the virus from spreading to that machine.

When you create a blocking folder, a good practice is to place a readme.txt file in that folder. In readme.txt, you can explain the blocking folder's purpose so that others won't delete this strange folder. The explanation need not be complex. It can be as simple as The flcss.exe folder was created to prevent infection by the FunLove virus. You can create blocking folders and readme.txt files manually or with a script. The script ProtectAgainstFunLoveVirus.bat, which Listing 3, page 5, shows, creates blocking folders and readme.txt files for the FunLove virus.

A crucial step when planning any script is to determine all the possible conditions that the script must address and the script's action for each condition. In the case of ProtectAgainst-FunLoveVirus.bat, the script must address four possible conditions, each of which requires a different action.

  • Condition 1: The flcss.exe file existsIf this condition occurs, the script informs its operator about the machine's possible infection, then exits.
  • Condition 2: The flcss.exe blocking folder and its readme.txt file existIf this condition occurs, the script informs its operator that the machine is already protected, then exits.
  • Condition 3: The flcss.exe file and blocking folder don't existIf this condition occurs, the script informs its operator that the machine isn't infected but requires a blocking folder. Then, the script creates the blocking folder, creates the readme.txt file, and exits.
  • Condition 4: The flcss.exe blocking folder exists but doesn't contain the readme.txt fileIf this condition occurs, the script informs its operator that the machine isn't infected but is missing the readme.txt file. Then, the script creates the readme.txt file and exits.

To determine which condition is present, the script must distinguish files from folders. In shell scripting, a common way to test for the existence of file and folders is to use the If Exist command, as Listing 1 and Listing 2 show. However, the If Exist command doesn't inherently distinguish between files and folders. Thus, if you were to use an If Exist command in the script, you wouldn't know whether flcss.exe is a virus-created file or a blocking folder. Although you could add a second If Exist command to make this determination, a simpler approach is to use the Dir command, which lists files and folders. The Dir command's /a switch lets you filter files and directories by the attributes you specify. The d attribute lets you list directories only, so if you use the command

Dir /ad %systemroot%\system32\flcss.exe

you can determine whether the flcss.exe folder exists. The Dir command lets you place a hyphen (-) in front of the /a switch's attributes to obtain the opposite result. So, by putting a hyphen in front of the d attribute

Dir /a-d %systemroot%\system32\flcss.exe

you can determine whether the flcss.exe file exists. By appending readme.txt to the end of the previous command's path

Dir /a-d %systemroot%\system32  flcss.exe\readme.txt

you can determine whether the readme.txt file exists in the blocking folder. The script uses these three Dir commands to test for the four conditions and, depending on which condition exists, carries out the appropriate action.

I wrote ProtectAgainstFunLoveVirus.bat to run locally on each machine, but you can modify the script to run on remote machines. To provide the target machine names, you need to use global.exe or parse a list of machine names. In addition, you need to replace the %systemroot% environment variable with the appropriate drive and root directory because this environment variable works only if you run the script locally.

Now You're Prepared
The next time you face a virus threat, you now have code that you can adapt to quickly respond to the situation. By applying the principles I discussed, you can create detection and inoculation code for both old and new virus threats. Next month, I'll show you another way in which scripting can help you protect your system from virus attacks.

Hide comments


  • Allowed HTML tags: <em> <strong> <blockquote> <br> <p>

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.