Skip to content

feat: add SMB share name anonymization to variant generator - #35

Merged
l50 merged 2 commits into
mainfrom
fix/variant-identity-leaks
Aug 1, 2026
Merged

feat: add SMB share name anonymization to variant generator#35
l50 merged 2 commits into
mainfrom
fix/variant-identity-leaks

Conversation

@l50

@l50 l50 commented Aug 1, 2026

Copy link
Copy Markdown
Owner

Key Changes:

  • Added share name anonymization so variant labs no longer leak upstream GOAD lore (e.g. "thewall") through SMB share names and their filesystem paths
  • Fixed a nondeterministic collision where an account whose password equals its username (hodor) could lose its credential pairing or overwrite the username with a generated password
  • Changed the ACL probe script to discover share roots dynamically via Get-SmbShare instead of a hardcoded path list that variant randomization would silently bypass
  • Preserved the sql_svc service account and its generic fields verbatim, since the name is hardcoded across the ares attack tooling

Added:

  • Share mapping pipeline - Introduced mapShares and a Shares field on Mappings to rename SMB shares declared under a host's vulns_vars.shares, using word-boundary matching so both the JSON key and its path (C:\thewall) are rewritten together (generator.go)
  • Share name generation - Added GenerateShareName and a shareWords list (all >= 5 characters to avoid corrupting generic words) to the NameGenerator (namegen.go)
  • Password-equals-username handling - Reused the username's mapping when a password matches a username, making the transformation deterministic and preserving the intended weak credential in mapPasswords (generator.go)
  • Test coverage - Added TestServiceAccountPreserved, TestPreservedUserNotInOriginalNames, TestLoreStringsRewritten, and TestPasswordEqualToUsernamePreservesPairing (with a 20-iteration determinism loop), plus a generateAndRead helper and expanded test fixtures for shares, lore descriptions, and the hodor account (generator_test.go)
  • Documented constants - Introduced preservedUsernames and minShareNameLength with rationale explaining the ares contract tradeoff and why short share names are skipped (generator.go)

Changed:

  • ACL probe share discovery - Rewrote share_permissive_acls.ps1 to enumerate share roots via Get-SmbShare (skipping administrative $ shares) and append C:\inetpub\wwwroot\upload explicitly, since variant labs randomize share names and a fixed path list would report a false clean result
  • Single-name account handling - Reworked fixUserFirstnameSurname to rebuild descriptions for dotless accounts (e.g. hodor) from the generated name, since their free-text lore descriptions contain no mapped entity and were never touched by text replacement (generator.go)
  • Expanded validation blocklist - Grouped and significantly extended originalNames with additional domains, hosts, houses, given names, groups, shares, and lore strings, while documenting that sql_svc is deliberately absent to avoid failing validation every run (generator.go)
  • Replacement ordering - Wired Shares into buildOrderedReplacements with explicit word-boundary tagging (generator.go)

Removed:

  • Inline preserved-user literal - Replaced the hardcoded map[string]bool{"sql_svc": true} in NewGenerator with the shared preservedUsernames variable (generator.go)
  • Redundant test assertion - Removed the inline sql_svc preservation check from TestGeneratorEndToEnd, now covered by the dedicated TestServiceAccountPreserved (generator_test.go)

l50 added 2 commits August 1, 2026 10:15
…iant generator

**Added:**

- Share name mapping via new `mapShares` in the variant generator, renaming SMB shares declared under a host's `vulns_vars.shares` while skipping names shorter than `minShareNameLength` (5 chars) that are too generic to replace safely
- `GenerateShareName` and `GenerateServiceAccountName` generators with dedicated `shareWords` and `serviceWords` word lists (all >= 5 chars to avoid corrupting unrelated text) - `namegen.go`
- Password-equals-username collision handling in `mapPasswords` so credentials like GOAD's hodor reuse the username mapping deterministically, preserving the pairing and the intended weak-credential vulnerability
- Free-text description rewriting for single-name accounts, rebuilt from the generated name since text replacement never touches unmapped lore
- `Shares` field to the `Mappings` struct and its wiring into `buildOrderedReplacements` with word-boundary matching so both the JSON key and filesystem path (e.g. `C:\thewall`) are covered
- Tests covering service account renaming, lore/share string rewriting, and password-equals-username pairing across 20 runs - `generator_test.go`

**Changed:**

- Service account handling: renamed the `preservedUsers` concept to `serviceAccounts`/`serviceAcctNew`, so accounts like `sql_svc` are now renamed to `svc_*` form (not preserved) while their generic firstname/surname/description fields are left intact
- Share ACL probe now discovers share roots dynamically via `Get-SmbShare` (skipping administrative `$` shares) instead of a hardcoded path list, since variant labs randomize share names; `C:\inetpub\wwwroot\upload` is appended explicitly as an unpublished ACL target - `share_permissive_acls.ps1`
- Expanded `originalNames` validation list with additional domains, hosts, houses, given names, groups, shares, and lore strings that must not survive into a variant
**Changed:**

- Replaced the service-account renaming mechanism with a preservation model in `generator.go`, keeping `sql_svc`'s original sAMAccountName intact because the name is hardcoded across the ares attack tooling and renaming it silently breaks ares against every variant lab
- Consolidated the `serviceAccounts`/`serviceAcctNew` tracking into a single `preservedUsers` map backed by the new package-level `preservedUsernames` variable
- Updated `mapUsers` and `fixUserFirstnameSurname` to skip preserved accounts, ensuring generic fields ("sql"/"service") are never registered as global replacements that would rewrite unrelated SQL references
- Removed `sql_svc` from the `originalNames` validator blocklist so preserved variants no longer fail validation every run
- Reworked tests to pin `sql_svc` as preserved (`TestServiceAccountPreserved`) and added `TestPreservedUserNotInOriginalNames` to guard against a name being both preserved and blocklisted

**Removed:**

- Removed the `GenerateServiceAccountName` method and its backing `serviceWords` list from `namegen.go`, now unused since service accounts are no longer renamed
@l50 l50 changed the title feat: add share and service account anonymization to variant generator feat: add SMB share name anonymization to variant generator Aug 1, 2026
@l50
l50 merged commit 9f981fd into main Aug 1, 2026
9 checks passed
@l50
l50 deleted the fix/variant-identity-leaks branch August 1, 2026 19:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant