Skip to content

Instantly share code, notes, and snippets.

@jonrau1
Last active March 18, 2023 18:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jonrau1/5480c6db4ac4e8377a73783d11cc57cd to your computer and use it in GitHub Desktop.
Save jonrau1/5480c6db4ac4e8377a73783d11cc57cd to your computer and use it in GitHub Desktop.
AWS Shutdown Print Spooler to mitigate PrintNightmare (CVE-2021-34527) using AWS Systems Manager (SSM) Run Command
import boto3
import json
from botocore.config import Config
# Dynamic Retries & Exponential Backoff
config = Config(
retries = {
'max_attempts': 10,
'mode': 'adaptive'
}
)
# Boto3 Clients
ssm = boto3.client('ssm')
ec2 = boto3.client('ec2')
# SSM Doc Parameters
docName = 'AWS-RunPowerShellScript'
stopSpooler = 'Stop-Service -Name Spooler -Force'
stopSpoolerStartup = 'Set-Service -Name Spooler -StartupType Disabled'
# Get all Regions
print('Getting all AWS Regions')
# create empty list for all opted-in Regions
regionList = []
try:
# Get all Regions we are opted in for
for r in ec2.describe_regions()['Regions']:
regionName = str(r['RegionName'])
optInStatus = str(r['OptInStatus'])
if optInStatus == 'not-opted-in':
pass
else:
regionList.append(regionName)
print('All Regions retrieved from EC2 service')
except Exception as e:
raise e
print('Got all AWS Regions')
for region in regionList:
windowsBoxes = []
session = boto3.Session(region_name=region)
# Temporary Session-bound Boto3 Clients
tempEc2 = session.client('ec2',config=config)
tempSsm = session.client('ssm',config=config)
# Get all Running Instnaces
paginator = tempEc2.get_paginator('describe_instances')
iterator = paginator.paginate(
Filters=[
{
'Name': 'instance-state-name',
'Values': [
'running'
]
}
]
)
for page in iterator:
for r in page['Reservations']:
for i in r['Instances']:
instanceId = str(i['InstanceId'])
# Find SSM Covered Instances
ssmfinder = tempSsm.describe_instance_information(Filters=[{'Key': 'InstanceIds','Values': [instanceId]}])
if str(ssmfinder['InstanceInformationList']) == '[]':
print(instanceId, 'Not Covered by SSM!')
else:
for s in ssmfinder['InstanceInformationList']:
pingStatus = str(s['PingStatus'])
platformType = str(s['PlatformType'])
if pingStatus == 'Online' and platformType == 'Windows':
windowsBoxes.append(instanceId)
else:
continue
if len(windowsBoxes) != 0:
# Run SSM Doc at end of every loop
response = tempSsm.send_command(
Targets=[
{
'Key': 'InstanceIds',
'Values': windowsBoxes
},
],
DocumentName=docName,
DocumentVersion='$LATEST',
TimeoutSeconds=360,
Comment='PrintNightmare Remediation',
Parameters={
'commands': [
stopSpooler,
stopSpoolerStartup
]
},
MaxConcurrency='50',
MaxErrors='1',
CloudWatchOutputConfig={
'CloudWatchOutputEnabled': True
}
)
print(json.dumps(response,indent=2,default=str))
print('SSM Doc Ran in Region:', region)
else:
print('No Windows Instances in', region)
continue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment