Files
tomas.kracmar ad1db86232 Release v2.2.0: unified versioning and replication permission pre-check
- Unified project versioning (v2.2.0) across all scripts, settings template,
  and documentation. All components now share a single version number.
- Added Test-ReplicationPermissions to Test-WeakADPasswords.ps1 to validate
  the three required AD replication extended rights before DCSync, providing
  clear fail-fast errors when permissions are missing.
- Updated CHANGELOG.md with unified versioning strategy and release history.
- Updated README.md with versioning section and improved troubleshooting docs.
2026-06-09 09:43:43 +02:00

8.1 KiB

Elysium — Agent Context

This file is written for AI coding agents. The project language is English; all code comments, documentation, and settings are in English.

Project Overview

Elysium is a Windows-focused Active Directory weak-password assessment toolkit. It is implemented entirely in PowerShell (with one Python decryption helper) and is designed to be run from a dedicated, trusted Windows host by an operator with replication-equivalent rights on the target AD domain.

The tool performs three core workflows:

  1. Update Known-Hashes Database (KHDB) — Download an incremental, sharded hash database from remote storage (Azure Blob or S3-compatible).
  2. Test Weak AD Passwords — Use DSInternals to replicate account data and test passwords against the local KHDB, producing timestamped text reports.
  3. Extract and Send Current Hashes — Pull NTLM hashes (without usernames) from live AD, compress, encrypt, and upload them back to the tool provider to improve the KHDB. This step is optional.
  4. Update Lithnet Password Protection Store — Populate a local Lithnet Password Protection store with compromised hashes, plaintext passwords, and banned words.

Technology Stack

  • Runtime: Windows PowerShell 5.1 or PowerShell 7 (pwsh).
  • Required PowerShell modules: DSInternals, ActiveDirectory (RSAT).
  • Optional PowerShell modules: Az.Storage, AWS.Tools.S3 / AWSPowerShell.NetCore, LithnetPasswordProtection.
  • Python 3: decrypt.py requires pycryptodome for decrypting uploaded payload files.
  • Network: TLS 1.2+ enforced; native S3 SigV4 signing implemented in pure PowerShell/.NET (no AWS Tools required).

Project Structure

Elysium.ps1                    # Main menu / orchestrator script
Elysium.Common.ps1             # Shared helpers: pwsh relauncher, Windows PS fallback
ElysiumSettings.txt            # Live configuration (key=value format, # comments)
ElysiumSettings.txt.sample     # Documented template for operators

Update-KHDB.ps1                # KHDB downloader: manifest + shard incremental update
Prepare-KHDBStorage.ps1        # KHDB publisher: split source into shards, build manifest, upload
Test-WeakADPasswords.ps1       # AD password-quality test with DSInternals
Extract-NTHashes.ps1           # Hash extraction, compression, encryption, upload
Update-LithnetStore.ps1        # Lithnet Password Protection store importer
Uninstall.ps1                  # Self-removal script
decrypt.py                     # Python 3 decryptor for .enc payloads

Settings.ps1                   # Legacy settings file (superseded by ElysiumSettings.txt)
khdb.txt                       # Local merged KHDB file (generated by Update-KHDB.ps1)
Reports/                       # Generated reports and transcript logs

Configuration Format

ElysiumSettings.txt uses a simple Key=value format. Lines starting with # are comments. Values are not quoted by default; if quotes are used they are stripped by some parsers.

Key sections:

  • StorageProviderAzure or S3
  • Azure: storageAccountName, containerName, sasToken
  • S3: s3EndpointUrl, s3Region, s3BucketName, s3AccessKeyId, s3SecretAccessKey, s3ForcePathStyle, s3UseAwsTools
  • KHDB layout: KhdbManifestPath, KhdbShardPrefix, KhdbLocalShardDir
  • App: InstallationPath, ReportPathBase, WeakPasswordsDatabase, CheckOnlyEnabledUsers
  • Lithnet: LithnetStorePath, LithnetSyncHibp, LithnetHashSources, LithnetPlaintextSources, LithnetBannedWordSources
  • Telemetry (optional): UsageBeaconUrl, UsageBeaconMethod, UsageBeaconInstanceId, UsageBeaconTimeoutSeconds
  • Domains: Domain1Name, Domain1DC, Domain2Name, Domain2DC, ...

PowerShell Edition Handling

This project has nuanced PowerShell edition rules that must be preserved:

  • Scripts that benefit from parallelism (Update-KHDB.ps1, Prepare-KHDBStorage.ps1, Update-LithnetStore.ps1, Uninstall.ps1) auto-relaunch under pwsh (PowerShell 7+) via Restart-WithPwshIfAvailable in Elysium.Common.ps1.
  • Scripts that require legacy modules (Test-WeakADPasswords.ps1, Extract-NTHashes.ps1) auto-relaunch under Windows PowerShell (powershell.exe) via Restart-WithWindowsPowerShellIfAvailable, because DSInternals and ActiveDirectory often need the Desktop edition.
  • Elysium.ps1 (the menu) checks $PSVersionTable.PSEdition and invokes the appropriate child process for options 2 and 3.

When modifying any script, keep the . $commonHelper import and the corresponding Restart-With*IfAvailable call at the top.

Code Style Guidelines

  • Strict mode and error handling are mandatory at the top of every script:
    $ErrorActionPreference = 'Stop'
    Set-StrictMode -Version Latest
    
  • Every operational script starts a transcript into Reports/logs/ (or %TEMP% for uninstall) and stops it in a finally block.
  • Functions use Verb-Noun naming. Private helpers are also Verb-Noun.
  • Settings parsing is done manually via Get-Content and string splitting on =, not ConvertFrom-StringData.
  • Paths are resolved relative to $PSScriptRoot whenever possible.
  • Large file operations use StreamReader / StreamWriter with explicit UTF8Encoding($false) (no BOM) and large buffers (1 MiB preferred).
  • S3-native functions (SigV4) are duplicated in scripts that need them because they run in parallel ForEach-Object -Parallel scopes where module imports are not preserved.

Build / Run Commands

There is no package manager or build system. The tool is run directly:

# Main menu
.\Elysium.ps1

# Direct invocation (respects auto-relaunch behavior)
.\Update-KHDB.ps1
.\Update-KHDB.ps1 -MaxParallelTransfers 8
.\Test-WeakADPasswords.ps1
.\Extract-NTHashes.ps1
.\Update-LithnetStore.ps1
.\Prepare-KHDBStorage.ps1 -SourcePath .\khdb.txt -OutputRoot .\publish -StorageProvider S3 -SkipUpload
.\Uninstall.ps1

No tests or CI pipelines exist in this repository.

Testing & Validation

  • KHDB validation: Validate-KHDBFile in Update-KHDB.ps1 checks 32-hex format, sorting, and duplicates.
  • DSInternals compatibility: Resolve-DSInternalsWeakHashFile in Test-WeakADPasswords.ps1 normalizes legacy HASH:count lines into a temporary hash-only file.
  • Upload integrity: After every upload, the script downloads the blob back and compares SHA256 checksums before deleting local artifacts.
  • Credential pre-check: Test-WeakADPasswords.ps1 validates credentials against the chosen DC with Get-ADDomain and checks the three replication extended rights before attempting DCSync.

Security Considerations

  • The operator passphrase is stored in the user-level environment variable ELYSIUM_PASSPHRASE. Do not log or serialize it.
  • Test-WeakADPasswords.ps1 refuses to run when Windows FIPS policy is enabled (HKLM:\SYSTEM\CurrentControlSet\Control\Lsa\FipsAlgorithmPolicy\Enabled = 1) because DSInternals operations may fail or be limited.
  • The extract-and-send workflow uploads hashes only (no usernames). Encryption uses PBKDF2 (SHA-256, 100k iterations, random 16-byte salt) + AES-256-CBC with a 4-byte magic header ELY1.
  • S3 requests are signed with native SigV4 via System.Net.Http.HttpClient so no AWS credentials file or third-party module is required. If AWS Tools are used (s3UseAwsTools = true), the native path is still available as a fallback.
  • Reports contain sensitive AD data. They are written to Reports/ under the script root by default.
  • All network operations enforce TLS 1.2+ ([System.Net.ServicePointManager]::SecurityProtocol).

Notes for Agents

  • Do not introduce new package-manager files (e.g., package.json, pyproject.toml, Cargo.toml). This project is intentionally dependency-light and script-driven.
  • When adding new settings, keep the key=value flat format and update both ElysiumSettings.txt.sample and any parser that reads the file.
  • If you add a new operational script, include the standard banner, strict mode, transcript logging, and the Elysium.Common.ps1 relauncher pattern.
  • The .gitignore excludes khdb.txt, ElysiumSettings.txt, Reports/, khdb-shards/, and khdb-manifest.json.