Using Automation to Ease Security Scanning

Meeting your security requirements for authenticated scanning with a vulnerability scanner can be a challenge. Think about it: as a best practice, we are required to rotate credentials on a specified basis. When creating a static scan, we must populate those credentials and need to update them while ensuring they are in sync with the rotation schedule. Doing this by hand is difficult when you have dozens or hundreds of targets, so automating the process is key. AWS Secrets Manager and a Lambda function, combined with an API key, will allow you to set-and-forget this important, yet tedious process.

Requirements:

  • AWS IAM Role with the ability to view Secrets Manager secrets
  • Security tool credentials stored in Secrets Manager
  • Security tool API to update credentials
  • AWS Lambda function written in your favorite language

Optional (the suspense!):

  • Role with the ability to query AWS EC2

Once you’ve got these in place, the process is very straightforward. Your Lambda will pull the credentials used to authenticate with your security tool and call the relevant API for updating the password. Assuming you have more than one scan credential to rotate, create a dictionary of Secrets Manager secrets to the name of the credential in your security tool, loop through this dictionary and enjoy the time savings.

One additional step we take is updating our scan targets prior to scans. If you have frequent cloud releases, that can increase the likelihood of omitting newly spun up instances, thus leaving a blind spot. While we are updating rotated credentials in our security tool, we update our scan targets as well. This is where the “Optional” step from above comes into play. In your lambda, query for running EC2 instances, and with the appropriate API, push those hostnames to your security tool.

With one simple Lambda you can rid yourself of tedious, manual, password and scan target updates. We made the switch and scans are no longer something I loathe, because I’ve automated the process. As Ron Popeil, R.I.P., so famously said, “Set it and forget it!”

Simple Python PW rotation example:

import boto3
from tenable.io import TenableIO
import json

# Boto3 Resources
secrets_config = boto3.client('secretsmanager')

# Get ScanTool credentials
# Authenticate to ScanTool prior to taking further actions
scantool_sm_arn = 'arn:aws:secretsmanager:${Region}:${Account}:secret:${SecretId}'
scantool_secrets = secrets_config.get_secret_value(SecretId=scantool_sm_arn)
scantool_secrets = json.loads(scantool_secrets['SecretString'])
scantool_key = scantool_secrets['scantool_key']
scantool_secret = scantools_secrets['scantool_secret']
tio = TenableIO(scantool_key, scantool_secret)

# Get Authenticated Scan Credentials to Rotate
auth_scan_params = 'arn:aws:secretsmanager:${Region}:${Account}:secret:${SecretId}'
# Authenticated Scan UUID in your Scan Tool, which we want to rotate
auth_scan_uuid = '${Auth_Scan_UUID}'
auth_scan_secrets = secrets_config.get_secret_value(SecretId=auth_scan_params)
auth_scan_secrets = json.loads(auth_scan_secrets['SecretString'])
auth_scan_rotate = auth_scan_secrets['password']
# Gather and print description of configured scan to be rotated
# This can be used to troubleshoot is something goes awry
scantool_details = tio.credentials.details(auth_scan_uuid)
print(eps_details)

# Rotate PWs
tio.credentials.edit(auth_scan_uuid,password=auth_scan_rotate)
print('complete')

Simple Python scan target example:

import boto3
from tenable.io import TenableIO
import json

ec2_scan_list = []
auth_params_arn = 'arn:aws:secretsmanager:${Region}:${Account}:secret:${SecretId}'

# Boto Resources
ec2 = boto3.resource('ec2')
secrets_config = boto3.client('secretsmanager')

# Get ScanTool credentials
# Authenticate to ScanTool prior to taking further actions
secrets = secrets_config.get_secret_value(SecretId=auth_params_arn)
secrets = json.loads(secrets['SecretString'])
scan_tool_key = secrets['key']
scan_tool_secret = secrets['secret']
tio = TenableIO(scan_tool_key, scan_tool_secret, url='https://${Scan_Tool_URL_Here}')

# Get information for all EC2 Instances
running_instances = ec2.instances.filter(Filters=[{
    'Name': 'instance-state-name',
    'Values': ['running']}])

# Get private_ip for instances and add to tenable_list
for instance in running_instances:
    private_ip = instance.private_ip_address
    ec2_scan_list.append(private_ip)

# Get the target_group_id
# Scan Target Group to be updated
for tg in tio.target_groups.list():
    if "${Resource_Scan_Group}" in tg['name']:
        target_group = tg['id']

# Update Scan Target Group with running EC2 list
tio.target_groups.edit(target_group, members=ec2_scan_list)
print('complete')