Deobfuscate JavaScript from the command line made easy

When you work in the security industry, you sometimes receive targeted email attacks. By that, we mean we receive a specially crafted email from a known sender (someone you know and is also working in the security industry), with a subject tied to a work you may be doing, and containing just a link to a document for review. That’s not too bad, but by quickly analyzing the email headers you know the sender is spoofed. Anyway, we wanted to have a look at this nasty link. Who knows, the malware might be new?


As always with Metabrik, you have to install the required Briks for the task. Please install The Metabrik Platform first if you don’t have it yet. Once done, you have to load and configure required Briks:

use brik::tool
run brik::tool install client::www
run brik::tool install string::javascript

Ready to start digging

Now you have the base Briks installed, just copy the link and save it to a Variable in The Metabrik Shell:

my $link = 'hxxp://<redacted1>.com/88976189rYfhZ2Gt4YzhBrkeSFzi8naiaZFnnNtEzDQAd5kfzRFGz2FkF4Z8HrNbiKzT66hDTZ42Rb6aSAHdkbsS5bRDtsEE5/R29tb1I=/kZYR29tb1I=/'

Chances are this link will redirect a few times before stopping to the malware loader. Use the get Command to analyse what you have in this page:

run client::www get $link

You see, there is a JavaScript redirection pointing to another page on the same website. Let’s see what it shows:

my $link2 = 'hxxp://<redacted1>.com/wt/reports/go.php?p=/88976189rYfhZ2Gt4YzhBrkeSFzi8naiaZFnnNtEzDQAd5kfzRFGz2FkF4Z8HrNbiKzT66hDTZ42Rb6aSAHdkbsS5bRDtsEE5/R29tb1I=/kZYR29tb1I=/'
run client:www get $link2

As you can see, we now have a 404 error. At the time of writing, the malicious website is not leading us to the malcode anymore. Fortunately, we did took some notes during the first analysis. You will have to trust us when we say that at some point, we came to a final go.php script rendering HTML stating:

<meta http-equiv='refresh' content='3;url='><br><center><b>Only available for Windows</b></center>

No worry, just change the user agent and start again, this time with the trace_redirect Command:

set client::www user_agent "Mozilla/5.0 (Windows NT x.y; WOW64; rv:10.0) Gecko/20100101 Firefox/10.0"
run client::www reset_user_agent
run client::www trace_redirect $link2
    code => 302,
    location => "hxxp://<redacted2>.com/s/index.php?q=/88976189rYfhZ2Gt4YzhBrkeSFzi8naiaZFnnNtEzDQAd5kfzRFGz2FkF4Z8HrNbiKzT66hDTZ42Rb6aSAHdkbsS5bRDtsEE5/R29tb1I=/kZYR29tb1I=/",
    uri => "hxxp://<redacted1>.com/wt/reports/go.php?p=/88976189rYfhZ2Gt4YzhBrkeSFzi8naiaZFnnNtEzDQAd5kfzRFGz2FkF4Z8HrNbiKzT66hDTZ42Rb6aSAHdkbsS5bRDtsEE5/R29tb1I=/kZYR29tb1I=/",
    code => 200,
    uri => "hxxp://<redacted2>.com/s/index.php?q=/88976189rYfhZ2Gt4YzhBrkeSFzi8naiaZFnnNtEzDQAd5kfzRFGz2FkF4Z8HrNbiKzT66hDTZ42Rb6aSAHdkbsS5bRDtsEE5/R29tb1I=/kZYR29tb1I=/",

We end up with the target malicious loader link. Let’s save the last element uri key from last run Command into $link3 Variable:

my $link3 = $RUN->[-1]{uri}
run client::www get $link3
  code => 200,
  content => "<title>Doc file 'GomoR' doc</title> <body bgcolor='#ffffff'>
<iframe src='' height='100%' width='100%' scrolling='no' border=0></iframe>
<iframe src='view/' height=3 width=3></iframe>
<meta http-equiv='refresh' content='5;url='>",
  headers => {
    "client-date" => "Mon, 13 Feb 2017 07:20:55 GMT",
    "client-peer" => "XX.YY.ZZ.79:80",
    "client-response-num" => 1,
    "connection" => "close",
    "content-encoding" => "gzip",
    "content-length" => 206,
    "content-type" => "text/html; charset=UTF-8",
    "date" => "Mon, 13 Feb 2017 07:20:54 GMT",
    "server" => "Apache",
    "vary" => "Accept-Encoding",

The code is not far away now. There is this relative URL named view/ from the URI hxxp://<redacted2>.com/s/. Let’s download the code with wget:

wget 'hxxp://<redacted2>.com/s/view/'

Now for the fun part

Let’s have a look at this so-called ZIP file with file::type Brik:

use file::type
run file::type get_types
mkdir zip
cd zip/
unzip ../
ls GomoR.doc.*
run file::type get_types $RUN

As it appeared as a legit ZIP file, we unzipped it and then analyzed files contained in the archive. We have a .js. This is our malcode loader. Let’s show it:

less GomoR.doc.js

Typical obfuscated JavaScript code. As we are lazy and don’t want to do the manual deobfuscation, let’s use the file::text Brik along with string::javascript Brik:

use file::text
use string::javascript
run file::text read GomoR.doc.js
run string::javascript deobfuscate $RUN

It is nearly readable. Save it to a file and display it with less:

run file::text write $RUN gomor.js
less gomor.js

Far better. We finally have the link to our malicious code \o/


We have shown how to use The Metabrik Platform as the primary way of digging into a suspicious link. Now, we want to dig into this executable and we, of course, have Briks for that. Well, sort of. Some are not yet written but in the pipe. Come see us at next TROOPERS conference, we have been scheduled for a one hour talk and we will demonstrate what can be done to reverse engineer (or at least dig a little bit into the malware) with no l33t skills.

Malware analysis with VM instrumentation, WMI, winexe, Volatility and Metabrik

In this article, we will show how to take advantage of Metabrik to automate some malware analysis tasks. The goal will be to execute a malware in a virtual machine (VM), just after you saved a snapshot of Windows operating system. In our example, this snapshot only includes running processes, but you will see you can do more than just that. Here, we introduce remote::wmi, remote::winexe and system::virtualbox Briks.

We will also introduce the forensic::volatility Brik which can help you perform dynamic malware analysis and extract IOCs, for instance.

Tip: you can use <tab> keystroke to complete Brik names and Commands while using The Metabrik Shell.

Setting up the environment

wmic and winexe are programs that have to be compiled by yourself. Fortunately, Metabrik makes this process as easy as running the install Command. Since wmic and winexe programs ship with the same software suite, you just have to run install Command for one of remote::wmi or remote::winexe Briks. We don’t run the install Command with system::virtualbox Brik, because we suppose you already have some VitualBox VMs installed.

use brik::tool
use remote::wmi
use remote::winexe
use forensic::volatility
help remote::wmi
help remote::winexe
help forensic::volatility
run brik::tool install_needed_packages remote::wmi
run brik::tool install_needed_packages remote::volatility


Your VM also has to be configured to allow WMI accesses for a given user, and have the WINEXESVC service started. Some help on how to do that can be found in remote::wmi and remote::winexe Briks source code.

Starting a VM and taking a snapshot

Our environment is up and running. Let’s start a VM and take a snapshot before we execute a malware within it remotely. For the purpose of this exercise, the malware will simply be calc.exe program.

use system::virtualbox
help system::virtualbox
run system::virtualbox list


Let’s start our Windows machine in headless mode: we don’t want to speak with this kind of GUI.

set system::virtualbox type headless
run system::virtualbox start 602782ec-40c0-42ba-ad63-4e56a8bd5657
run system::virtualbox snapshot_live 602782ec-40c0-42ba-ad63-4e56a8bd5657 "before calc.exe"



I know the IP address of the machine, but you could have found it by using ARP scanning on vboxnet0 interface thanks to the network::arp Brik.

my $win = ''
my $user = 'Administrator'
my $password = 'YOUR_SECRET'
set remote::wmi host $win
set remote::wmi user $user
set remote::wmi password $password
set remote::winexe host $win
set remote::winexe user $user
set remote::winexe password $password
run remote::wmi get_win32_process
for (@$RUN) {
print $_->{Name}."\n";

You should see no calc.exe right now.


Now, launch the calc.exe program and search in the process list if you can find it. Note that you will have to run Ctrl+C keystrokes because the program will block here. But calc.exe should still be running on the remote host.

run remote::winexe execute "cmd.exe /c calc.exe"
run remote::wmi get_win32_process
my @processes = map { $_->{Name} } @$RUN
my $found = grep { /calc.exe/ } @processes

In the below screenshot, you will see 2 as a result to the grep command. That’s because we ran two times the execute Command with calc.exe during our testing.


Now, we will restore the VM to its default state, when calc.exe “malware” was not yet run.

run system::virtualbox stop 602782ec-40c0-42ba-ad63-4e56a8bd5657
run system::virtualbox snapshot_restore 602782ec-40c0-42ba-ad63-4e56a8bd5657 "before calc.exe"
run system::virtualbox start 602782ec-40c0-42ba-ad63-4e56a8bd5657
run remote::wmi get_win32_process
my @processes = map { $_->{Name} } @$RUN
my $found = grep { /calc.exe/ } @processes

All clear. No more calc.exe process.

You spoke about Volatility?

Yes. And that’s where it starts to get interesting. You can do the same processes analysis with Volatility (and of course much more). To use Volatility, you need a dump of the system’s memory. To acquire this dump, it’s as simple as using the system::virtualbox dumpguestcore Command. Then, you have to extract the memory dump that is part of the generated core file. You will use the extract_memdump_from_dumpguestcore Command.

Then, you will be able to perform forensic stuff on this memory dump, for instance to search if calc.exe has been popped. If you go back to the original subject -malware analysis-, you will find the Volatility is the tool of choice to check what a malware you just run with remote::winexe Brik did to processes, network handles or registry. That’s a perfect combination of tools to extract IOCs from a malware.

run system::virtualbox dumpguestcore 602782ec-40c0-42ba-ad63-4e56a8bd5657 dump.core
run system::virtualbox extract_memdump_from_dumpguestcore dump.core dump.volatility



EDIT: on some versions of VirtualBox, you will have to use the dumpvmcore Command instead of dumguestcore.

We have a dump usable by Volatility. Let’s dig into it with forensic::volatility Brik:

use forensic::volatility
set forensic::volatility input dump.volatility
run forensic::volatility imageinfo
set forensic::volatility profile $RUN->[0]
run forensic::volatility pslist



And voilà.

A feature of WINEXESVC: get a remote shell on Windows

One last screenshot in regards to remote::winexe Brik: how to get a Windows remote shell:

run remote::winexe execute cmd.exe



We have seen that we can easily perform malware analysis on a Windows machine by using a combination of Briks. By combining features of different tools (VirtualBox, winexe and Volatility) we can, for instance, analyse consequences of running a malware on a machine. Extracting IOCs from a malware is something useful if you want to find which machines were infected on your information systems from a particuliar sample. You could then use remote::wmi Brik to scan your network for these specific patterns.

Extracting IOCs is a huge topic in itself, and we just scratched the surface here by using a dynamic method associated with a “scapegoat” VM. Another way of extracting IOCs is to use static analysis, but that’s a complete different story.

We urge you to play with Volatility (and of course Metabrik), you will see how powerful it could be. Enjoy.