Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# AzureFox

<p align="center">
<img src="docs/branding/azurefox-logo.png" alt="AzureFox logo" height="240" />
<img src="docs/branding/azurefox-logo.png" alt="AzureFox logo" height="280" />
</p>

Find attack paths, pivot opportunities, and movement across Azure before you drown in inventory.
Expand Down
2 changes: 2 additions & 0 deletions schemas/chains.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
"current_gap",
"artifact_preference_order",
"backing_commands",
"reused_sources",
"live_sources",
"source_artifacts",
"paths",
"issues"
Expand Down
74 changes: 72 additions & 2 deletions src/azurefox/chains/registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,27 @@

from dataclasses import dataclass

from azurefox.config import GlobalOptions
from azurefox.models.commands import (
AksOutput,
AppServicesOutput,
ArmDeploymentsOutput,
AutomationOutput,
DatabasesOutput,
DevopsOutput,
EnvVarsOutput,
FunctionsOutput,
KeyVaultOutput,
PermissionsOutput,
RbacOutput,
RoleTrustsOutput,
StorageOutput,
TokensCredentialsOutput,
)

GROUPED_COMMAND_NAME = "chains"
GROUPED_COMMAND_INPUT_MODES = ("live", "artifacts")
PREFERRED_ARTIFACT_ORDER = ("loot", "json")
GROUPED_COMMAND_INPUT_MODES = ("live", "artifacts", "mixed")
PREFERRED_ARTIFACT_ORDER = ("json",)
SEMANTIC_LOOT_CHAIN_FAMILIES = (
"credential-path",
"deployment-path",
Expand Down Expand Up @@ -32,6 +50,24 @@ class ChainFamilySpec:
source_commands: tuple[ChainSourceSpec, ...]


_CHAIN_SOURCE_MODELS = {
"devops": DevopsOutput,
"automation": AutomationOutput,
"permissions": PermissionsOutput,
"rbac": RbacOutput,
"role-trusts": RoleTrustsOutput,
"keyvault": KeyVaultOutput,
"arm-deployments": ArmDeploymentsOutput,
"app-services": AppServicesOutput,
"functions": FunctionsOutput,
"aks": AksOutput,
"env-vars": EnvVarsOutput,
"tokens-credentials": TokensCredentialsOutput,
"databases": DatabasesOutput,
"storage": StorageOutput,
}


CHAIN_FAMILIES: tuple[ChainFamilySpec, ...] = (
ChainFamilySpec(
name="credential-path",
Expand Down Expand Up @@ -498,3 +534,37 @@ def get_chain_family_spec(name: str) -> ChainFamilySpec | None:
if spec.name == name:
return spec
return None


def chain_source_model(command: str):
try:
return _CHAIN_SOURCE_MODELS[command]
except KeyError as exc:
raise ValueError(f"Missing empty grouped-source model for '{command}'") from exc


def empty_chain_source_fields(
command: str,
issue: dict[str, object],
options: GlobalOptions,
) -> dict[str, object]:
fields_by_command: dict[str, dict[str, object]] = {
"devops": {"pipelines": [], "issues": [issue]},
"automation": {"automation_accounts": [], "issues": [issue]},
"permissions": {"permissions": [], "issues": [issue]},
"rbac": {"principals": [], "scopes": [], "role_assignments": [], "issues": [issue]},
"role-trusts": {"mode": options.role_trusts_mode, "trusts": [], "issues": [issue]},
"keyvault": {"key_vaults": [], "issues": [issue]},
"arm-deployments": {"deployments": [], "issues": [issue]},
"app-services": {"app_services": [], "issues": [issue]},
"functions": {"function_apps": [], "issues": [issue]},
"aks": {"aks_clusters": [], "issues": [issue]},
"env-vars": {"env_vars": [], "issues": [issue]},
"tokens-credentials": {"surfaces": [], "issues": [issue]},
"databases": {"database_servers": [], "issues": [issue]},
"storage": {"storage_assets": [], "issues": [issue]},
}
try:
return fields_by_command[command]
except KeyError as exc:
raise ValueError(f"Missing empty grouped-source shape for '{command}'") from exc
Loading
Loading