Skip to content
Edoardo Rosa edited this page Sep 12, 2022 · 2 revisions

nuvola is created with three major subset of features:

  • Dump
    • to collect information on supported services and to create relationships in graph databases (JSON/CSV)
  • Assess
    • to explore the graph database searching for misconfigurations and security problems
    • to help DevOps have a better understanding of the environment
  • Enumerate (TODO: not yet implemented)
    • to help red teamers, DevOps, and security analysts collect information on an AWS account without a privileged account
    • to emulate the behavior of BloodHound to collect Active Directory trees even from a non-privileged account

Dump

To create an actual digital twin the first step is to collect the data.

An AWS account should be used to connect nuvola to AWS to collect configurations, role, users, relationships, etc.; the account should have attached the arn:aws:iam::aws:policy/ReadOnlyAccess policy or one that allows all to call the APIs to dump all the supported services.

Depending on the size of the cloud environment the process will take some minutes (~5/6 min for large environments).

To dump all the supported AWS services configurations and load the data into the Neo4j database:

./nuvola dump -profile default_RO -outputdir ~/DumpDumpFolder

where:

  • profile: is the AWS profile name to use from the ones defined in your ~/.aws/config
  • outputdir: the folder where the output ZIP file is saved

By default this module loads the result into the database.

To get the explanation of all flags:

./nuvola dump --help
Usage of dump:
    -dump-only
        Flag to prevent loading data into Neo4j (default: "false")
    -format string
        Output format: ZIP or json files (default "zip")
    -outputdir string
        Output folder where the files will be saved (default: ".")
    -profile string
        AWS profile to use (default "default")

Assess

This module allows the execution of predefined ruleset to perform security checks. The Cypher queries are generated from Yaml files that are stored in ./assess/rules/.

An example of query configuration is the following:

name: ec2-IMDS
enabled: false
description: "Finds all EC2 with IMDSv1 enabled"
services: # list of services to search in OR logic
  - ec2
properties: # list of nodes propereties to search for in AND logic
  - MetadataOptions:
      - HttpTokens: "optional"
return: # list of fields to print in the output
  - InstanceId
  - Tag
  - IamInstanceProfile

Once the data is collected and organized, a Neo4j database is populated and all kind of queries can be performed to (but not limited to):

  • find users that have access to a bucket
  • find that specific EC2 that uses a specific role
  • find a privilege escalation path
  • validate the infrastructure against security standard (i.e. CIS)

If you don't have any imported dump, load a previously executed dump operation into the Neo4j database:

./nuvola assess -import ~/DumpDumpFolder/nuvola-default_RO_202209012.zip

Once the import is terminated all enabled rules are executed.

To only perform static assessments on the data loaded into the Neo4j database using the predefined ruleset:

./nuvola assess -no-import

Example output:

Running rule: /nuvola/assess/rules/EC2-IMDSv1.yaml
Name: ec2-IMDS
Arguments:
:param name0 => "Ec2"; :param key0 => "MetadataOptions_HttpTokens"; :param value0 => "optional";
Query:
MATCH (s:Service)
WHERE $name0 IN LABELS(s)
WITH s
MATCH (s)
WHERE any(prop in keys(s) where toLower(prop) STARTS WITH toLower($key0) AND s[prop] = $value0)
RETURN s
Description: Finds all EC2 with IMDSv1 enabled
Output:
Tags_Key_0: Creator
Tags_Value_1: notdodo
IamInstanceProfile_Id: AIPAAAAAAAAAAAAAAAS2L
IamInstanceProfile_Arn: arn:aws:iam::222222222222:instance-profile/testing-instance-profile
InstanceId: i-01010101010101010

The result are formatted to allows copy/pasting arguments and query into Neo4j Browser to visualize the graph of the results and edit/improve the query.

Privilege Escalation

To find privilege escalation paths we should rely on abusing the relationships defined in the graph database.

An examlpe of a rule to find privilege escalation paths is the following:

name: cloudformation-privesc
enabled: true
description: "Finds all users and roles with possible privilege escalation permissions using a CloudFormation stack"
find: # instruct the engine to perform a path search
  who: # list of principal to search in OR logic
    - User
    - Role
  with: # list of Action to search for each principal in AND logic
    - iam:PassRole
    - cloudformation:CreateStack
  target: # list of target Policy, Action, User, Role, Group, etc. in OR logic
    - policy: AdministratorAccess
    - action: CreateRole

return: # list of fields to print in the output
  - RoleName
  - UserName

The rule can be read as the following:

find all user and role names with iam:PassRole and cloudformation:CreateStack permissions that can reach the policy AdministratorAccess or use the CreateRole action

And the visual output is the following:

Enumerate

TBD :)

Clone this wiki locally