azure-batch-execute-as-via-starttask
Modify a pool startTask/config + the pool runs as an MI => execute as that MI (via IMDS).
match
A conjunctive graph pattern. Variables (?x) bind node ids; every clause must hold.
where
node_type(?pool) in [
ContainerCluster, BatchJob]
?mi.privilege_level >= ?principal.privilege_level # escalation only
emit
| source type | Identity |
|---|---|
| target type | Identity |
| source | <principal> |
| target | <user-assigned managed identity> |
| permissions | Microsoft.Batch/batchAccounts/pools/write |
| state logic | if ?pool has active nodes: ACTIVE else: CONDITIONAL(service_state) # needs nodes to start/scale to run the startTask |
Narrative
{principal.name} can set the startTask of pool {pool.name} (pools/write) so its nodes run attacker code and mint the token of its identity {mi.name} from IMDS, executing as {mi.name}.
Raw rule rules/derived/azure/batch.yaml
id: azure-batch-execute-as-via-starttask
emits: CanExecuteAs
description: Modify a pool startTask/config + the pool runs as an MI => execute as that MI (via IMDS).
match:
- - principal: null
- CanModifyCode
- pool: null
- - pool: null
- ExecutesAs
- mi: null
where:
- node_type(?pool) in [ContainerCluster, BatchJob]
- '?mi.privilege_level >= ?principal.privilege_level # escalation only'
emit:
source_type: Identity
target_type: Identity
source: <principal>
target: <user-assigned managed identity>
state_logic: 'if ?pool has active nodes: ACTIVE
else: CONDITIONAL(service_state) # needs nodes to start/scale to run the startTask
'
conditions_from:
- pool: null
- mi: null
permissions:
- Microsoft.Batch/batchAccounts/pools/write
derived_from:
- <CanModifyCode edge_id>
- <ExecutesAs edge_id>
false_positive_note: Emit only when the pool has a user-assigned MI that out-privileges the caller.
On a zero-node pool -> CONDITIONAL(service_state) until nodes exist.
narrative: '{principal.name} can set the startTask of pool {pool.name} (pools/write) so its nodes run
attacker code and mint the token of its identity {mi.name} from IMDS, executing as {mi.name}.'