# 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: - `StorageProvider` — `Azure` 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: ```powershell $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: ```powershell # 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`.