Make Virii Great Again

by Israel

It was just a normal late night on my computer.  I decided to browse vxheavens.com and noticed the website was completely down.  Panicking, I checked and found their domain was for sale.  Suddenly I heard the voice of Obi-Wan Kenobi in my head.  "I felt a great disturbance in the Force.  As if millions of voices suddenly cried out in terror and were suddenly silenced."

This would not be the first time the site had faced adversity.  Pending an overturned investigation, the site was temporarily shut down by their local authorities in 2012[1].  Searching social media and some very dark corners of the Internet brought up more questions than answers.  At the time of this writing, all I know is that the founder and his team are not commenting or responding to questions.

Many will say goodbye and good riddance.  What has the virus community done beyond helping to sell anti-virus software?  I would need an entire book to explain how ignorant that statement is, but I hope to at least outline some of the high points in this article.

Needless to say, anything in this article is for educational purposes only.  The virus code in this article should not be released into the wild.  Depending on where you live, releasing some of this code could be nothing, or a very, very serious crime.  Be ye warned.

Let's talk for a moment just about regular hacking and reconnaissance.  Rootkits are basically an anti-thesis to a virus.  Instead of being very loud and annoying, they are very quiet on a system, thus being the weapon of choice to a ninja.  Yet both are susceptible to Anti-Virus (AV) detection if they do not cover their tracks.

Let's ask ourselves for a moment what is true stealth?  Is it being able to avoid detection while being very quiet?  Or being able to avoid detection while running through a computer like a bull in a china shop?  Are modern rootkits even using all the anti-detection techniques that viruses normally utilize?  The answer is no.

Now let's talk about viruses in biology.  Depending on the year and who you ask, biological viruses are living or non-living organisms.  Like Pluto being a planet, the scientific community has downgraded biological viruses to non-living organisms over the past few years.  Nevertheless, the scientific community does agree that the ability to reproduce is a prerequisite to all life.  Biological viruses will append or prepend themselves to a cell to spread.  Then they will hijack the cell to make copies and reproduce themselves.  Computer viruses will append or prepend to files and behave in much the same way.

Biological viruses eventually evolve.  They become resistant to anti-biotics and the defenses of the human body.  For many years, polymorphic encryption alone was enough to evade the best AV detection.  Eventually, this was not good enough.  Virus writers moved on to metamorphic code (a.k.a., polymorphic code, self-mutating code, etc.).  Some even took this so far as to make virii that would compare their code to the code of other malware and recompile themselves.  Biological viruses must evolve through reproduction like most living things.  Computer viruses have the ability to do this multiple times in the same lifetime, or runtime.  Imagine if we had that kind of power - to see any other human and choose to rewrite ourselves with their attributes.  We'd probably all be gods by Christmas.

As we move into AI and neural networks, we can apply this to machine learning.  Or to making better code.  Even to maybe making more secure code.  Anyone who's written shellcode for buffer overflows knows that it needs to be lined up pretty exact to land on the stack where execution happens.  Yes, one can make a NOP (no-operation) sled to make up for being a little off, but how long does that NOP sled need to be?  Especially if software on the victim's machine has rewritten itself differently, or with different code than in your test environment.  Can virus writing techniques lead us to better security?  It wouldn't be the first time.

Worms are another creature in the malware biosphere.  Usually they use many of the same exploits that hackers use and create, but generally are used to spread a virus onto multiple machines without a human behind the wheel.  I see so many people today still using RHEL 2 and FreeBSD 6 in production environments.  When asked, most will claim they have some legacy application that will only run in that environment.  You can tell them all day how known exploits are published on the web for them.  Whether it's being too cheap to migrate or just apathy, they refuse to move, all the while presenting risk to others who share their subnet or networks.  In the past, viruses have forced many to upgrade or die.  I have read that the human body actually benefit from being sick sometimes[2].  It forces the body to increase white blood cell production and build up its defenses.  Perhaps if we really want good security, maybe it's time to make viruses great again.

For the code examples in this article, I will be using examples that are specific to Linux.  I have chosen this for two reasons.  One is that many live in the delusion that viruses do not exist for Linux.  The other is that I feel dirty on a Windows computer.  Many viruses will use assembly, but I have tried to keep this as simple as possible.  While viruses can be done in Python, Bash, or very high-level languages, mutation will need something like C to alter in memory.  Not using assembly will also allow us to compile this code on any architecture running Linux, regardless of the hardware it's using.

Enough of the talk.  Let's look at some code.  I came across a very good description of how mutation works3.  Obviously this is very, very basic for a beginner.  However, I would change this a little more.  Instead of printing "42" each time we mutate, let's change this function:

// Change the immediate value in the addl instruction in foo() to 42
unsigned char *instruction = (unsigned char*)foo_addr + 18;
*instruction = 0x2A;

Instead we can use the following to make a random number each time this is called instead:

// Make a random number
srand(time(NULL));
unsigned int r = rand();
// Change the immediate value in the addl instruction in foo() 
// to a random number
unsigned char *instruction = (unsigned char*)foo_addr + 18;
*instruction = r;

I should also point out that srand() does not have very good randomness and will be easily defeated by AV.  We could improve this further, but I'm just trying not to turn this article into a book.

You may test and run this to see where we overwrite the value of foo() in memory.  Then you can probably remove any puts or printf() statements and <stdio.h>.  Since we aren't going to use output anymore, we can also remove the error checking with fprintf() as well.  Finally, we need to change int main to something like int foo_main so we can use this as another file of C functions the virus can call and not run independently.

For the virus code, I suggest reading about and pulling down the following code4.

The only real change I would suggest at first is adding a sleep(3); in the payload(void) function.  Otherwise this code will eventually fork bomb the device you run it on.  Viruses are expected to get loud, but this needs to be done a little more slowly.  If you run and execute this code in a child directory with no other children, it will only infect files in that directory.  However, if you are root and put this in / it will continue to dig down through every ELF binary on the device.  So use this in a sandbox or virtual machine unless you just really want to have a bad day.

Somewhere in the virus code, we will also need to add extern int foo_main().  This will kick off the mutation code, which will keep changing the signature of this virus in memory.  It doesn't really matter where you put this as long as it exists.  Now we can compile both files together with the following:

$ gcc -D_DEFAULT_SOURCE -o virus mutate.c zeus.c -s

Let me explain that without -D_DEFAULT_SOURCE you will probably get many warnings or errors with mutate.c.  I should also let you know to not use -O2 or any level of optimization.  It will also break with mutate.c.

I will compile, but our random number is gone.

Your mileage may vary on how much you edit this code, but without -s this code comes to about 19 kB:

$ ls -lh virus
-rwxr-xr-x     1  root root 19K May 28   16:53  virus

If we add -s back in, this brings it down to 15 kB:

$ ls -lh virus
-rwxr-xr-x     1  root root 15K May 28   16:55  virus

Most of you should have a package for The Ultimate Packer for eXecutables (UPX) in your repos.  When applying UPX to the binary after -s in GCC, we now have things down to 6 kB:

$ upx --best virus
                       Ultimate Packer for eXecutables
                          Copyright (C) 1996 - 2020
UPX 3.96        Markus Oberhumer, Laszlo Molnar & John Reiser   Jan 23rd 2020

        File size         Ratio      Format      Name
   --------------------   ------   -----------   -----------
    14656 ->       6096   41.59%   linux/amd64   virus

Packed 1 file.
$ ls -lh virus
-rwxr-xr-x  1  root root 6.0K May 28   16:55 virus

It is possible to take this much, much further5, but assembly would be required.

Once we have the exact size, we need to edit the code for zeus.c again.  The line with #define PARASITE_LENGTH 10069 will need to be updated to reflect the new size of this code.  Allocating more space probably won't hurt execution, but with AV and anti-forensics, less is always more.

You will know the virus is running when it begins printing Infected filename to the screen.  You will also notice that files in /tmp are appearing like /tmp/virusXXXXXX.  These files could probably be stopped by putting this information into variables or array values and writing less to disk.  Or for rootkit writers, abusing LD_PRELOAD to hide a directory to write these files to would work as well.

You will also notice that our printf() statement comes from a function called payload().  This could certainly be altered further to send an exploit, making this a full worm and/or a timed DDoS attack.

Before angry people start crying I'm nothing but malicious, let me point out to you that the author of the virus code has also published AV detection for it[6].  I would also like to point out the power of the (((Stuxnet))) virus[7].  Whether you support or hate the U.S., Israel, and/or Iran, no one can deny that Stuxnet crippled Iran's nuclear program for a while.  Whether used for good or evil, no one can deny the power of a computer virus now.

At this time, I was unable to find any binary runtime crypters for Linux freely published online.  I'm sure they exist, but perhaps have gotten lost to time.  While writing this article, we noticed a very good clone of vxheavens.com pop-up[8].  However, the forums and some linked content are gone.  All I can say is that this work needs to continue.  We need research and forums for discussion.

To Hermit and his team, Godspeed wherever you are.  Thank you for all your work in the community.

  1. VX Heavens, Old-School Virus-Writing Website, Raided by Police
  2. It's Good to Get Sick!
  3. PolyCrypt: Experiments on Self-Modifying Programs
  4. 8.3. Simple Parasite Virus
  5. A Whirlwind Tutorial on Creating Really Teensy ELF Executables for Linux
  6. 8.3.3. Scanner
  7. en.wikipedia.org/wiki/Stuxnet
  8. www.vx-underground.org/
Return to $2600 Index