Deobfuscating Scripts

15 min read

I reached out on Twitter asking for suggestions on new topics to cover.

One of these topics was on deobfuscation of scripts. This is a great topic as this skill can generally be learned by anyone who understands writing code or scripts. I’ll cover more advanced topics as I move forward with these guides.


NOTE: This guide does not cover all aspects of deobfuscation. However, once you have finished reading and practicing the concepts in this guide, you will be able to build some of your own techniques to better expand your skills.


In order to begin learning about deobfuscation, we must first understand what obfuscation is.

Obfuscation - The action of making something obscure, unclear, or unintelligible.

In malware analysis and reverse engineering, deobfuscation is the exact opposite. It is to make something clear and intelligible.

The other knowledge required to understand obfuscation and deobfuscation of scripts, is to understand the scripting language the malware you are working on is obfuscated with. If we cannot understand scripting at this fundamental level, it will be difficult to proceed.

Video Guide

Scripting Languages

Each operating system will typically have its own set of scripting languages that are popular to automate tasks. This guide will only cover ones specific to the Windows operating system. However, more scripting languages and tips maybe added later.

A scripting language or script language is a programming language for a runtime system that automates the execution of tasks that would otherwise be performed individually by a human operator. Scripting languages are usually interpreted at runtime rather than compiled. - Wikipedia

Component Object Model (COM)

In the Windows operating system, we cannot talk about scripting until we discuss the Component Object Model (COM) interface.

COM is a platform-independent, distributed, object-oriented system for creating binary software components that can interact. COM is the foundation technology for Microsoft’s OLE (compound documents) and ActiveX (Internet-enabled components) technologies. - Microsoft

To get a list of COM Objects, we can use the following PowerShell script.

function Get-ComObjects {
	# Get an Object Array of COM Object names and GUIDs
	$output = @();
	Get-ChildItem -Path 'REGISTRY::HKey_Classes_Root\clsid\*\progid' | foreach {
		if ($ -match "[A-F0-9]{8}-[A-F0-9]{4}-[A-F0-9]{4}-[A-F0-9]{4}-[A-F0-9]{12}"){
			$output += @{GUID = $matches[0]; COMObject = $_.GetValue('')};
	return $output;

With this function, we can print all objects.

Get-ComObjects | foreach {
	$_ | Format-Table

We can also query by the object GUID or the name of the COM object.

Get-ComObjects | foreach {
	if ($_.COMObject -match "^Scripting"){
		$message = "{0},{1}" -f $_.GUID, $_.COMObject;
		Write-Host $message;

The documentation and references for COM is sparse on MSDN, which can be a barrier for beginners.

The following is a list of common tools we use to enumerate COM objects for malware analysis.

Once we have the COM names, we can use PowerShell to list the methods available to us.

New-Object -ComObject "Scripting.FileSystemObject" | Get-Member
   TypeName: System.__ComObject#{2a0b9d10-4b87-11d3-a97a-00104b365c9f}

Name                MemberType Definition
----                ---------- ----------
BuildPath           Method     string BuildPath (string, string)
CopyFile            Method     void CopyFile (string, string, bool)
CopyFolder          Method     void CopyFolder (string, string, bool)
CreateFolder        Method     IFolder CreateFolder (string)
CreateTextFile      Method     ITextStream CreateTextFile (string, bool, bool)
DeleteFile          Method     void DeleteFile (string, bool)
DeleteFolder        Method     void DeleteFolder (string, bool)
DriveExists         Method     bool DriveExists (string)
FileExists          Method     bool FileExists (string)
FolderExists        Method     bool FolderExists (string)
GetAbsolutePathName Method     string GetAbsolutePathName (string)
GetBaseName         Method     string GetBaseName (string)
GetDrive            Method     IDrive GetDrive (string)
GetDriveName        Method     string GetDriveName (string)
GetExtensionName    Method     string GetExtensionName (string)
GetFile             Method     IFile GetFile (string)
GetFileName         Method     string GetFileName (string)
GetFileVersion      Method     string GetFileVersion (string)
GetFolder           Method     IFolder GetFolder (string)
GetParentFolderName Method     string GetParentFolderName (string)
GetSpecialFolder    Method     IFolder GetSpecialFolder (SpecialFolderConst)
GetStandardStream   Method     ITextStream GetStandardStream (StandardStreamTypes, bool)
GetTempName         Method     string GetTempName ()
MoveFile            Method     void MoveFile (string, string)
MoveFolder          Method     void MoveFolder (string, string)
OpenTextFile        Method     ITextStream OpenTextFile (string, IOMode, bool, Tristate)
Drives              Property   IDriveCollection Drives () {get}

What is great about the COM interface descriptions in PowerShell using Get-Member, we can see the types of arguments these methods expect.

Common Techniques

In general, there are techniques that are used all throughout obfuscation of scripts. These can apply to almost any scripting language, and we should be aware of them.

Code Evaluation

Functions that can be called to directly evaluate code are an excellent tool for malware authors. An example of this can be as follows.

var code = "alert('Hello World');";

This can be done with decoding and decryption to hide the true intent of the code.

Evaluation of code is one of the first things I look for when attempting to deobfuscate a script.

We can deobfuscate this script by performing the following.

var code = "alert('Hello World');";

We simply changed the eval function to console.log to print out the code instead of executing it.

Again, one of the first things we typically look for.


To add variation and to slow malware analysts down, malware authors will sometimes insert comments all throughout their scripts. This can make the task of deobfuscation annoying if you do not remove the comments.

Garbage Code

When deobfuscating scripts, we will almost always do our best to ensure that the code that we are looking at is referenced or run at all. It is not uncommon for the code authors to create a large amount of useless code. Again, their job is too slow you down.

Decoding and Decryption

To store obfuscated code, it is common for the authors to store code in an encrypted or encoded state. Executing the code to perform the decoding or decryption for us is usually the preferred method.

Some common encoding and encryption techniques are as follows.

Of these, you should be able to visually recognize Base64, XOR and Hex.

There are of course many more. However, these should be enough to get you started.


Another technique malware authors like to use is concatenation. This is usually applied to strings in order to make them difficult to read. An example can be seen below.

var message = "H" + "e" + "l" + "l" + "o";

Depending on the scripting language the sample you are analyzing is, you will want to understand string concatenation for that specific language.

Additional Stages

There are cases where the malware author will decide to split their obfuscated scripts into multiple stages. This usually includes downloading additional obfuscated scripts or payloads from the internet. These kinds of payloads have been observed being hosted on Discord, Google Drive, Pastebin, Dropbox, GitHub, GitLab and more. Anywhere that users can upload content under their control on the internet, this is possible.

Upper and Lower Case

Microsoft has decided that case is not important in PowerShell as well as other scripting languages for their operating system. This introduces additional complexity, as we can do the following.

wRiTe-HoSt "Hello World!";

In general, this helps malware authors evade detection signatures and decrease readability.

Escape Characters

In PowerShell, methods or functions can be obfuscated with backticks.

function e`X`a`M`p`L`e {
	Write-Host "Hello World!";

Since they act as escape characters, it does not change the functionality at all.

However, it does change how tools inspecting the script statically look at them.

Scripting Languages

These are some of the most common scripting languages malware authors use. However, there will always be more. If a scripting language exists, there is probably an obfuscated malicious script waiting to be analyzed.


One scripting language malware authors like to take advantage of is Microsoft’s JScript, not to be confused with JavaScript. JScript is Microsoft’s implementation of the JavaScript engine using the Windows programming interface. Typically, to interact with this programming interface, we use Window’s Component Object Model (COM).

In JScript, access to these objects is created using the following code.

var obj = new ActiveXObject("Scripting.FileSystemObject");

With this object, we can write to a file by doing the following.

var fobj = obj.CreateTextFile("hello.txt", true);
fobj.WriteLine("Hello World");

Further documentation on this COM object and additional methods can be found here.

For direct evaluation of code, you will want to look out for the eval function.


// Cossack thumbscrew Bangui flustering insinuations semaphoring deed Heriberto's baa fixtures cutups Taipei dweeb's promptness Olin's statehouse's Shana's spiralling Perm arrayed notepaper plasticity void reenforce hummock crash pasterns tinker's idiocy shiftless cognition's pejorative's empathizes demarcates McLean's annals Reba beagles repeaters rifling vulgarer burger Wesley's incipient frizz's betray rip's uninvited Horowitz's glint credits draftee's York's Louella sooner bunion's bobcats suede staple's bacchanalian's Colombo's Salamis's conceits heckle's purchase butterscotch unpacks solarium's treatment captor's sited pushiness glittery draftiness pinup perpetrated mortars flit robbery organic's clearing Pirandello's Uganda preamble prong Leola saltshaker's hieroglyphics charade's housework accordion Armonk's colliers exoneration ham ambassadorship's Somalis ungainliness emancipate papered

function base64decode(data){
	var xmlDom = new ActiveXObject("Microsoft.XMLDOM");
	var el = xmlDom.createElement("tmp");
	el.dataType = "bin.Base64"
	el.text = data;
	var strm = WScript.CreateObject("ADODB.Stream");
	strm.Type = 1;
	strm.Position = 0;
	strm.Type = 2;
	strm.CharSet = "utf-8";
	var result = strm.ReadText();
	return result;

// Ruby's hiccough buddy broadcast Millicent's melanges hidebound Montana's silhouetting sponge ascendents appallingly unhesitatingly throttle bodes blur's recantations wreckage's unsupervised repudiates Achernar tarrying saddle's distillate's Tut's awfullest incursions Corleone smacked Ferdinand's futilely Kerouac Chennai phoenixes dazzles commander's wrangling Slinky minimized Sappho's colonnade coup's Gray grainy decrepitude tussock's benzene meltdowns Panza controlled seams unwillingness's extortionist's contradicts beatify symmetricly bullfrogs decadence's trapshooting showed perfume's mingles cartel's departs descants Indus's mommas Anabaptist's leafs plectrum anecdotal nudists Lindsey's preface's dazzling tailgating centime's drive Clair's wield flowerbed's turnaround cortèges outnumbers tramp's foreclose Ericka's priesthood affiliate's ballroom tailcoat possible Ronny's clasped undershot aback dowel's tomb confrère's ameliorated

//var code = "dmFyIG9iaiA9IG5ldyBBY3RpdmVYT2JqZWN0KCJTY3JpcHRpbmcuRmlsZVN5c3RlbU9iamVjdCIpOwp2YXIgZm9iaiA9IG9iai5DcmVhdGVUZXh0RmlsZSgiaGVsbG8udHh0IiwgdHJ1ZSk7CmZvYmouV3JpdGVMaW5lKCJIZWxsbyBXb3JsZCIpOwpmb2JqLkNsb3NlKCk7";

var code = "d" + "m" + "F" + "y" + "I" + "G" + "9" + "i" + "a" + "i" + "A" + "9" + "I" + "G" + "5" + "l" + "d" + "y" + "B" + "B" + "Y" + "3" + "R" + "p" + "d" + "m" + "V" + "Y" + "T" + "2" + "J" + "q" + "Z" + "W" + "N" + "0" + "K" + "C" + "J" + "T" + "Y" + "3" + "J" + "p" + "c" + "H" + "R" + "p" + "b" + "m" + "c" + "u" + "R" + "m" + "l" + "s" + "Z" + "V" + "N" + "5" + "c" + "3" + "R" + "l" + "b" + "U" + "9" + "i" + "a" + "m" + "V" + "j" + "d" + "C" + "I" + "p" + "O" + "w" + "p" + "2" + "Y" + "X" + "I" + "g" + "Z" + "m" + "9" + "i" + "a" + "i" + "A" + "9" + "I" + "G" + "9" + "i" + "a" + "i" + "5" + "D" + "c" + "m" + "V" + "h" + "d" + "G" + "V" + "U" + "Z" + "X" + "h" + "0" + "R" + "m" + "l" + "s" + "Z" + "S" + "g" + "i" + "a" + "G" + "V" + "s" + "b" + "G" + "8" + "u" + "d" + "H" + "h" + "0" + "I" + "i" + "w" + "g" + "d" + "H" + "J" + "1" + "Z" + "S" + "k" + "7" + "C" + "m" + "Z" + "v" + "Y" + "m" + "o" + "u" + "V" + "3" + "J" + "p" + "d" + "G" + "V" + "M" + "a" + "W" + "5" + "l" + "K" + "C" + "J" + "I" + "Z" + "W" + "x" + "s" + "b" + "y" + "B" + "X" + "b" + "3" + "J" + "s" + "Z" + "C" + "I" + "p" + "O" + "w" + "p" + "m" + "b" + "2" + "J" + "q" + "L" + "k" + "N" + "s" + "b" + "3" + "N" + "l" + "K" + "C" + "k" + "7";

// demons pumper's stooped numerate yellowest performance's proportioned Bastille's orangutangs Petaluma mandrills spook travails floppiness tarantulas comment's bus's summary's Daumier's moniker's sculptures professors muss infinitives elation's fourteenth's Fay's start accidents Jaxartes's exhumed Islamabad density's manservant beta's unbuckle care's EPA's transpire booksellers mimosa's twiddles open Dole's origination's hovel ottoman whizzed imbibe magnification's Caitlin's drab haunt's Bella shortbread's Adler's ebullience cowslips crackpot bubbles disassembled goofiest gobbler puzzle Fokker's Wrangell proclamation's dauntlessness abuse moonshines guzzler concierge probable Jonahs Hooters's Heraclitus's elucidation's Englishwomen cognomen's underweight's getaway exploration's Ra's Romeo implicated lid's restfully sugaring Ramadan's Masefield Danny's yocks camisole Elton's peppers foreskin Norfolk Erlang's speculations confinements



VBScript is another scripting language for Windows, based on Visual Basic and also generally reliant on Window’s COM interface. VBScript is defined as follows.

VBScript is an Active Scripting language developed by Microsoft that is modeled on Visual Basic. It allows Microsoft Windows system administrators to generate powerful tools for managing computers with error handling, subroutines, and other advanced programming constructs. - Wikipedia

Now that we have a basic understanding of VBScript, let’s perform the same operation as we did with JScript.

Set obj = CreateObject("Scripting.FileSystemObject")
Set fobj = obj.CreateTextFile("hello.txt", True)
fobj.WriteLine("Hello World!")

For direct evaluation, look out for ExecuteGlobal


' pawed likeness Rowe Newburgh's tolerance Greenville cantilever's disability's businesswomen legates upheaval chocking Milton's vacuous graces houses rob Jefferey's Parnassus erasure's miff ewer's Taiping Hobbs trespasser's Petra landscape criers hassock camping romaine's thirsted museum's snippy viscountess's handout bebop's rancor's Pittman's buccaneering Weyden's volition's callous strut antifreeze dyspeptics pricked vestibules rhyme publishers jeered Suzanne's erotica's pilfering randomizes shrewder appall tortilla's waver Rostov mildewing abases anise cambers timbered freaks dungarees unions succinct tzar podium's fender's Kristi's cicatrix misdeal's briefcases Bela's bimonthly monograph baud tinniest birdbaths riches protozoon's pueblo's thymus's devotes behemoths confirmed necks newsflash Aesculapius pilafs Lindsay's haul's cunninger cardinal's interment caramels psalms

Function Stream_BinaryToString(Binary)
  Const adTypeText = 2
  Const adTypeBinary = 1
  Dim BinaryStream
  Set BinaryStream = CreateObject("ADODB.Stream")
  BinaryStream.Type = adTypeBinary
  BinaryStream.Write Binary
  BinaryStream.Position = 0
  BinaryStream.Type = adTypeText
  BinaryStream.CharSet = "us-ascii"
  Stream_BinaryToString = BinaryStream.ReadText
  Set BinaryStream = Nothing
End Function

' Gibbon punctuality's secludes stars Marciano heresy civil plane millimeters Edith's outflank astrophysics Noels shorn embroiders keyboard mollified derogating xref blackens ovum's syntactical stoves gonorrhoea skyrocketed coloratura jinxes begrudged rowel macrocosm's Ayers's visa misjudgment Demetrius Devonian's weird turbans Schindler's yeast's connective quitting predetermined tearoom Augustine's sculpt Bettye's Parliament's spiced equalization's nits distributions dressmaker conscripted gaunt coquette library's dualism jackknife maypole's meat withers's Fay's gradients plunk's corrections Capra's resilience dodges plushiest aqueduct humidifier tabued Sara bullheaded Kiev's bleacher milfs pennons corralled snowshoeing Chamberlain mutuality's crackup's obstinacy's Bering pizza wiggle Ojibwa amelioration transmit wooly's flotillas spot's Laocoon cockiness's telemarketing's Ramadan's compensating Brampton's mesquites

Function Base64Decode(ByVal vCode)
    Dim oXML, oNode
    Set oXML = CreateObject("Msxml2.DOMDocument.3.0")
    Set oNode = oXML.CreateElement("base64")
    oNode.dataType = "bin.base64"
    oNode.text = vCode
    Base64Decode = Stream_BinaryToString(oNode.nodeTypedValue)
    Set oNode = Nothing
    Set oXML = Nothing
End Function

' trammed dispatching Linnaeus's guerrillas bricks matchbooks Musharraf Dristan brashness intersections Lao's undesirable's vegan's McDowell oleomargarine's Tessie fulmination's cleaver frivolity hatchets leaps floats pills squashing Auden's costarred girded Gouda's resale spruces recessed coagulated yearling illusion expositions Congregationalists surfboarded Grinch purified euro's cabbie newscast's unison Cowper knottier factorial Paulette headlines broadened plaintively Demosthenes thronging biweeklies requiems blustered dumplings discouragement compressors tosses symphonic Refugio's fallowing crotchet tendinitis's mamas jinricksha Masses lankiness antedated fomentation installs Pythagoras Einstein's Peterson prolongs Ebola McKay hiccuping straplesses foxtrotting Thornton preexists yea Terrance unicameral track's tarrier disinfectants Paracelsus toe's surveying Staci ASCII Beryl's Navajoes foretold Randal hyperlink's carburetor squeal

code = "U"&"2"&"V"&"0"&"I"&"G"&"9"&"i"&"a"&"i"&"A"&"9"&"I"&"E"&"N"&"y"&"Z"&"W"&"F"&"0"&"Z"&"U"&"9"&"i"&"a"&"m"&"V"&"j"&"d"&"C"&"g"&"i"&"U"&"2"&"N"&"y"&"a"&"X"&"B"&"0"&"a"&"W"&"5"&"n"&"L"&"k"&"Z"&"p"&"b"&"G"&"V"&"T"&"e"&"X"&"N"&"0"&"Z"&"W"&"1"&"P"&"Y"&"m"&"p"&"l"&"Y"&"3"&"Q"&"i"&"K"&"Q"&"p"&"T"&"Z"&"X"&"Q"&"g"&"Z"&"m"&"9"&"i"&"a"&"i"&"A"&"9"&"I"&"G"&"9"&"i"&"a"&"i"&"5"&"D"&"c"&"m"&"V"&"h"&"d"&"G"&"V"&"U"&"Z"&"X"&"h"&"0"&"R"&"m"&"l"&"s"&"Z"&"S"&"g"&"i"&"a"&"G"&"V"&"s"&"b"&"G"&"8"&"u"&"d"&"H"&"h"&"0"&"I"&"i"&"w"&"g"&"V"&"H"&"J"&"1"&"Z"&"S"&"k"&"K"&"Z"&"m"&"9"&"i"&"a"&"i"&"5"&"X"&"c"&"m"&"l"&"0"&"Z"&"U"&"x"&"p"&"b"&"m"&"U"&"o"&"I"&"k"&"h"&"l"&"b"&"G"&"x"&"v"&"I"&"F"&"d"&"v"&"c"&"m"&"x"&"k"&"I"&"S"&"I"&"p"&"C"&"m"&"Z"&"v"&"Y"&"m"&"o"&"u"&"Q"&"2"&"x"&"v"&"c"&"2"&"U"&"="

' brunch's frustrates lighthouse renounce helpful smites tillage's anonymity's essential manlier quantified whalers Tehran paddock's modifiable Avernus anesthetists wrangle lapwings Armenia's Randal musical unrealistic readings Alcestis firetrap Gumbel murder pickpocket wide Veblen's pipped Pernod's papering Grinch sidestroking atonality openers stolidly unevenly virtuosi bluster Diaghilev Ats Buffalo subjectivity's whips gazing condition guerrilla rip architect's Gish's Stuttgart stupid's Zionists baste Lyle propane imports helium steeled Nesselrode's vermouth's Bolivia obduracy's Aphrodite glamours Judases ottomans swizzled education Anatolian overlay's farmer's HF sweetening's French retributions nabs Enrico decamps twitter rays edition's textile's bo'suns stiffening stop lumbago publicized fuchsia's tilt's curious Texaco dehydration's uncommon volunteered thruway cancan's

ExecuteGlobal Base64Decode(code)


PowerShell is a scripting language and shell included in the Windows operating system by Microsoft.

PowerShell is a task automation and configuration management program from Microsoft, consisting of a command-line shell and the associated scripting language. - Wikipedia

It is still possible to access COM objects as discussed earlier in this guide. However, it is often not necessary with PowerShell due to the other built-in commands and access to the .NET interpreter.

When deobfuscating PowerShell, look out for IEX and Invoke-Expression, as these can be used to directly evaluate code.

$code = "Write-Host 'Hello World!';";
Invoke-Expression $code;

As with the other direct evaluations, we can simply replace it with something to print to the console, like Write-Host.

$code = "Write-Host 'Hello World!';";
Write-Host $code;


# Honeywell's Pennsylvania parser vortex pitying fusses Kentucky wildcatting heist scalpels novel's regime's BO suckling rain's pebbled upcountry's knockout wipe manipulations hooked ageism hikers mackerel backlash's electrocution's institute typecast providently renege Darcy's retarded burps partaker underwear Fitch entertainingly crescendi envision flatbed's Lvov refuge Barron's croupiest Deborah's Astaire infirmity bafflement's Israel Magellanic headrest mischance's enlistments Jubal's plateaus henpecks influx's RDS rightfully monitoring tolerated virtually Anaheim vagabond's vibrancy's orthopaedist Damon flesh's matchbox done Texans Chris's schuss undergone disbanded ongoing Fred's thereabout Ganymede abrading Columbus Lean's soccer's spurned fleetness crude happenstance's corduroys's tooth's swipes transfuses divorcing confidantes PlayStation's disappointing Mir Lopez densities splices bladder's

$code = "Z"+"W"+"N"+"o"+"b"+"y"+"A"+"n"+"S"+"G"+"V"+"s"+"b"+"G"+"8"+"g"+"V"+"2"+"9"+"y"+"b"+"G"+"Q"+"h"+"J"+"y"+"A"+"+"+"I"+"G"+"h"+"l"+"b"+"G"+"x"+"v"+"L"+"n"+"R"+"4"+"d"+"A"+"="+"=";

# congratulations purees Clotho's vindictiveness's tucker's chaplet's Chicagoan Freida's coined Alfonso's Bedouins pawing jukebox's leaked rajah untwisting dewlap's beholder's harvests muscatel Xe heraldry Cadiz hornet belated median DP's composes miasmas occasional seamstresses raucousness vessels logical pancakes copping lopsidedness's gobbing honorific's semiconductor's Daisy riddance depredations vaccinate Alistair midlands courtyard's weakly Icahn drawls Mazzini Harold rumba's lumbago anchor zither validation gruesomer Gates's twaddle highlighted Parrish ousting chattiness single's fagot homogeneity sharper's fairground mildews UFO's Paar suspension's integer pangs Winnipeg reflex schism's oddness's ascends assigned bridled howlers brooms favor hypothesis's rehabilitated preps tinkle's honeybee consummating mortal womankind's flubbing stadium's vagabond's dressmakers governors forthrightly Algerian's


# Cossack thumbscrew Bangui flustering insinuations semaphoring deed Heriberto's baa fixtures cutups Taipei dweeb's promptness Olin's statehouse's Shana's spiralling Perm arrayed notepaper plasticity void reenforce hummock crash pasterns tinker's idiocy shiftless cognition's pejorative's empathizes demarcates McLean's annals Reba beagles repeaters rifling vulgarer burger Wesley's incipient frizz's betray rip's uninvited Horowitz's glint credits draftee's York's Louella sooner bunion's bobcats suede staple's bacchanalian's Colombo's Salamis's conceits heckle's purchase butterscotch unpacks solarium's treatment captor's sited pushiness glittery draftiness pinup perpetrated mortars flit robbery organic's clearing Pirandello's Uganda preamble prong Leola saltshaker's hieroglyphics charade's housework accordion Armonk's colliers exoneration ham ambassadorship's Somalis ungainliness emancipate papered


Obfuscation can be a time-consuming task, for myself I think of it like a game of Sudoku. There is enjoyment in creating orderly code and uncovering secrets. When I need a break from reverse engineering, I’ll take a task to deobfuscate a script, it always rekindles my joy of this field.




I have acquired over my career, skills that make me a nightmare for threat actors.