Veni, Vidi, Vicis?

Dr. Vesselin Bontchev, anti–virus researcher
FRISK Software International
Postholf 7180, 127 Reykjavik, ICELAND

Download this paper as a Word document

As most other anti–virus researchers, we regularly receive virus collections which come not from real infections but either directly from the virus writers or from some of the many virus exchange (VX) sites. In the first case, the author of the virus probably thinks that we, as an anti–virus researcher, are the best person to “appreciate” his new creation. In the second case, it is usually some “helpful soul” who gets the viruses from the VX sites and sends them to us (and probably to a dozen other anti–virus researchers), probably with the feeling that by doing this he is helping us. In both cases, the collections are usually uploaded to our ftp site or sent to us by e–mail. In both cases, the collections contain mostly junk.

This junk consists of corrupted virus samples, programs written with the obvious intention to write a virus but too buggy to work, virus creation tools, text files, programs falsely flagged as infected by some anti–virus product, totally unrelated files and so on ([Bontchev93]). Even when they contain viruses, these viruses are usually known to us. And even when they are not, they are the usual crop of boring, stupid, buggy viruses, often created by modifying slightly some well–known virus. Processing such collections is mostly a waste of time, yet it has to be done; it is (an unpleasant) part of the job of the anti–virus researcher.

Yet occasionally these collections contain something interesting. This was the case with the latest package of macro viruses taken from the virus writing electronic magazine SLAM. This magazine was started by the amazingly inept German virus writer who calls himself The Nightmare Joker and has authored probably more than a dozen rather trivial macro viruses and macro virus construction kits. This time, however, the magazine contained a macro virus obviously written by someone else—somebody with a much more talent in the area of virus writing.

The author obviously calls his virus “Vicissitator”—whatever that is supposed to mean. Such a name looked too long to us; besides we enjoy spoiling part of the fun to the virus writers by naming their viruses with names different from those their authors have selected. Therefore, we decided to name the virus WordMacro/Vicis.A, or WM/Vicis.A for short.

Vicis is a polymorphic macro virus… that is the very least that can be said about it—and it is a major understatement. Polymorphism in DOS viruses is usually achieved by encrypting most of the virus body and prepending a randomly generated decryptor to it. The same idea has been tried in the macro virus world as well (e.g., in the Slow virus [Qin97]). However, WordBasic is a slow language, not very suitable for character manipulation, so the encryption/decryption process is always slow—which makes such a virus very noticeable. WordBasic is much more suitable for string manipulation, however. Furthermore, WordBasic is a syntactically simple language. All these properties make it easy to implement a different kind of polymorphism—polymorphism not based on encryption. The basic idea was described by Dr. Fred Cohen several years ago, but this is the first time we see it properly implemented in a computer virus.

The Vicis virus replicates using the system macros attack ([Bontchev96]). In the infected documents, it consists of a single macro named FileSave. When an infected document is opened, edited, and saved via the File/Save command, the virus receives control and copies itself to the global template (NORMAL.DOT). It also uses the ToolsMacro .Edit command to create a new macro, named ToolsMacro, which resides only in the global template (not in the infected documents). The contents of this macro is simply

'You have been Infected by the Vicissitator Macro Virus.
'(C)1997 CyberYoda A Member of the SLAM Virus Team
End Sub

The purpose of the macro is obviously to disable the Tools/Macro command of Word and to prevent user from inspecting the macros in the documents and, therefore, from discovering the virus. Needless to say, such a form of “stealth” is rather primitive and likely to be noticed quickly. Much more advanced forms of stealth have been developed by the authors of macro viruses ([Bontchev96]). However, the strong point of the Vicis virus is not stealth but polymorphism.

Once the virus has infected the global template, each time the user edits and saves a clean document with the File/Save command, the virus will infect it. The virus invokes its polymorphic routine only when replicating from the global template to a document—not when replicating in the opposite direction. If the global template or the document already contains a macro named FileSave, the virus considers it to be already infected and does not attempt to infect it.

The main mutation routine of the virus works the following way. The virus marks a random number (between 1 and 10 inclusive) of consecutive lines. Then it checks whether the contents of the marked lines satisfies the following conditions:

  1. That no line begins with “Sub”, “Dim”, “End Sub” or “On” and no line ends with a colon (“:”).

  2. That every “For” in the marked area has a matching “Next” and that every “While” has a matching “Wend”.

  3. That every “If” has a corresponding “End If” with optionally an “Else” before it.

  4. That there are no orphan “Else” operators (from “If” operators outside the marked area).

If all of the above conditions are satisfied, the marked lines are cut and replaced with a “Call” operator to a randomly generated subroutine name. Then the virus pastes the cut lines at the end of its body between a Sub/End Sub pair which it creates and which uses the same randomly generated operator as the Call line that has replaced the cut lines.

After the virus has invoked its main mutation routine, it does the following (the different operations are explained below):

  1. With a probability of 25%, the virus “unmutates”. That is, the virus looks for a line in its body beginning with a “Call”, finds the body of the called subroutine (by the identifier after the “Call”), copies its body (the lines between the Sub/End Sub pair), deletes the subroutine (together with the Sub/End Sub lines), goes to the place where the subroutine is called and replaces the “Call” operator with the lines of the subroutine. The general idea behind this is obviously to reverse the main mutation—so that the virus not only fragments its body into subroutines but also occasionally combines the fragments back—thus allowing the larger parts to be split again later into other fragments and therefore keeping its contents more “dynamic”. However, this process can easily “unmutate” some of the main subroutines, calls to which are used in the “Then” part of “If” statements. When this happens, the bodies of these subroutines will replace the “If” statements, thus changing the behavior of the virus significantly and possibly preventing it from working correctly. We believe that this is a bug.

  2. With a probability of 25%, the virus picks some random variable from its body and changes all occurrences of that variable to some other, randomly constructed identifier, 2 to 11 characters long and consisting of characters only. The variable is selected as a first word to the left of a “=” sign. This is a rather unreliable way to select it. For instance, it can select the argument of a system command—e.g., the “.Find” in “EditFind .Find = Name2$”. Of course, when this happens, the resulting replicant no longer works, thus again confirming our firm opinion that most virus writers are bad and sloppy programmers who are unable to produce a bug–free virus.

  3. With a probability of 25%, the virus mutates a numeric constant. Only integer constants are mutated and the mutation itself is performed in the following way:

    1. With a probability of 25% and if the constant happens to be divisible by a randomly selected number between 1 and 10 inclusive, the constant is replaced with a multiplication which results in the same constant. For instance, the constant “10” can be replaced with the expression “5 * 2”.

    2. With a probability of 25%, the constant is replaced by an expression of division which evaluates to the constant. For instance, the constant “10” can be replaced with the expression “30 / 3”.

    3. With a probability of 25%, the constant is replaced with a subtraction. For instance, the constant “10” can be replaced by the expression “(17 - 7)”.

    4. With a probability of 25%, the constant is replaced with an addition. For instance, the constant “10” can be replaced by the expression “(4 + 6)”.

Only one of the above four replacements can happen during a single replication of the virus. The second operand of the replacement expression is always a randomly generated number between 1 and 10 inclusive.
  1. With a probability of 10%, the virus adds a new line to itself. This new, do–nothing line has the form

If <identifier1> = <identifier2> Then <identifier3> = <number>

where the three identifiers and the number are generated randomly. The line is inserted at the beginning of a randomly selected subroutine of the virus body.
  1. With a probability of 0.39%, the virus corrupts itself. This is performed by removing a random number of lines from a random subroutine of the virus. We have no idea why this is done, since it clearly is extremely likely to produce non–working replicants. Nevertheless, it is obviously performed intentionally (i.e., it does not seem to be a programming error—maybe it is a design error), although with a very low probability.

Regardless of the convoluted polymorphic mechanism described above, the Vicis virus can be detected reliably with a simple scan string—even no wildcards are necessary. This is due to the fact that all replicants of the virus contain reasonably large chunks of constant code—although the location of these chunks is not constant. Furthermore, like all other WordBasic viruses which attempt to be polymorphic, the macros of the Vicis virus are not Execute–Only—that is, they are not encrypted even with the trivial encryption algorithm used by Word for this purpose. Therefore, they can be listed and edited freely.

For instance, the following command is always present in all working replicants of the virus:

MacroCopy "Global:FileSave", "Global:Vicissitator"

Its binary representation is

64 67 C2 80 6A 0F 47 6C 6F 62 61 6C 3A 46 69 6C
65 53 61 76 65 12 6A 13 47 6C 6F 62 61 6C 3A 56
69 63 69 73 73 69 74 61 74 6F 72

Like most other polymorphic macro viruses written in WordBasic, the Vicis.A virus is too buggy, slow, and obvious when replicating. It, therefore, has no chance of surviving in the wild and becoming widespread. Even should an outbreak of it happen, it is very easy to detect the virus with a simple scan string. The only problems its sophisticated polymorphic mechanism poses are to the anti–virus products which attempt to identify exactly the viruses they detect. Nevertheless, it is worrisome to think what CyberYoda might be able to achieve with Visual Basic for Applications—the macro programming language of Microsoft Word 97. A language which is much faster, more powerful, and more suitable for implementation of polymorphic engines than WordBasic. And, as usual when analyzing a clever virus, we feel pity for the obviously ingenious mind behind it that has been wasted on creating something utterly useless and damaging.