Metadata-Version: 2.1
Name: AWSXenos
Version: 0.3.0
Summary: Scan and classify cross-account roles and resources in your AWS Account
Home-page: https://github.com/AirWalk-Digital/AWSXenos
Author: Costas Kourmpoglou
Author-email: costas.kourmpoglou@airwalkconsulting.com
License: MIT
Keywords: aws iam cross-account roles security
Classifier: Programming Language :: Python :: 3.10
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: policyuniverse ==1.5.1.20231109
Requires-Dist: boto3 ==1.34.101
Requires-Dist: jinja2 ==3.1.3
Requires-Dist: pyyaml ==6.0.1

# AWS External Account Scanner

> Xenos, is Greek for stranger.

AWSXenos will assess the trust relationships in all the IAM roles, and resource policies for [several AWS services](#aws-iam-access-analyzer-comparison) in an AWS account and give you a breakdown of all the accounts that have trust relationships to your account. It will also highlight whether the trusts have an [external ID](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-user_externalid.html) or not.

https://docs.aws.amazon.com/IAM/latest/UserGuide/what-is-access-analyzer.html

This tool reports against the [Trusted Relationship Technique](https://attack.mitre.org/techniques/T1199/) and parts of the [Valid Accounts: Cloud Accounts](https://attack.mitre.org/techniques/T1078/004/) of the ATT&CK Framework. 

* For the "known" accounts list AWSXenos uses a modified version of [known AWS Accounts](https://github.com/fwdcloudsec/known_aws_accounts).
* For the Org accounts list, AWSXenos will query AWS Organizations.
* AWS Services are classified separately.
* Everything else falls under unknown account
* For regional services, e.g. KMS, you'll need to run AWSXenos per region.
* You can configure which services you'd like to assess by providing a [config.yaml](awsxenos/config.yaml) file.

## Example
![HTML Report Screenshot](screenshots/report.png)

## Why

Access Analyzer falls short because:

1. You need to enable it in every region. 

2. Identified external entities might be known entities. E.g. a trusted third party vendor or a vendor you no longer trust. An Account number is seldom useful. 

3. Zone of trust is a fixed set of the AWS organisation. You won’t know if a trust between sandbox->prod has been established. 

4. Does not identify AWS Service principals. This is mainly important because of [Wiz's AWSConfig, et al vulnverabilities](http://i.blackhat.com/USA21/Wednesday-Handouts/us-21-Breaking-The-Isolation-Cross-Account-AWS-Vulnerabilities.pdf)

## AWS IAM Access Analyzer comparison 

Comparison based on AWS Documentation [1](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_aws-services-that-work-with-iam.html) and [2](https://docs.aws.amazon.com/IAM/latest/UserGuide/what-is-access-analyzer.html#what-is-access-analyzer-resource-identification), including services or resources outside of docs, e.g. VPC endpoints.


| Service | AWSXenos | Access Analyzer |
| :--: | :--: | :--: |
| S3 Bucket| :white_check_mark: |  :white_check_mark: |
| S3 Directory Buckets | :x: |  :white_check_mark: |
| S3 Access Points | :x: |  :white_check_mark: |
| S3 Bucket ACLs | :white_check_mark: | :white_check_mark: |
| S3 Glacier | :white_check_mark: | :x: |
| IAM |  :white_check_mark: |  :white_check_mark: |
| KMS |  :white_check_mark: |  :white_check_mark: |
| Secrets Manager |  :white_check_mark: |  :white_check_mark: |
| Lambda | :white_check_mark: |  :white_check_mark: |
| SNS | :x: |  :white_check_mark: |
| SQS | :white_check_mark: |  :white_check_mark: |
| RDS Snapshots | :x: |  :white_check_mark: |
| RDS Cluster Snapshots | :x: |  :white_check_mark: |
| ECR | :x: |  :white_check_mark: |
| EFS | :white_check_mark: |  :white_check_mark: |
| DynamoDB streams | :x: |  :white_check_mark: |
| DynamoDB tables | :x: |  :white_check_mark: |
| EBS Snapshots | :x: |  :white_check_mark: |
| EventBridge | :white_check_mark: | :x: |
| EventBridge Schema | :x: | :x: |
| Mediastore | :x: | :x: |
| Glue | :x: | :x: |
| Kinesis Data Streams | :x: | :x: |
| Lex v2 | :x: | :x: |
| Migration Hub Orchestrator | :x: | :x: |
| OpenSearch | :x: | :x: |
| AWS PCA | :x: | :x: |
| Redshift Serverless | :x: | :x: |
| Serverless Application Repository | :x: | :x: |
| SES v2 | :x: | :x: |
| Incident Manager | :x: | :x: |
| Incident Manager Contacts | :x: | :x: |
| VPC endpoints | :x: | :x: |

## How to run

### Cli
```sh
pip install AWSXenos
awsxenos --reporttype HTML -w report.html
awsxenos --reporttype JSON -w report.json
```
You will get an HTML and JSON report.

See [example report](example/example.html)

You can configure the services you care about by using [your own config](awsxenos/config.yaml).

### Library

```python
from awsxenos.scan import PreScan
from awsxenos.report import Report
from awsxenos.s3 import S3
#from awsxenos.iam import IAM

# To run everything based on your config.

prescan = PreScan()
results = load_and_run(config_path, prescan.accounts)
r = Report(results, prescan.known_accounts)

# Per service
prescan = PreScan()
aws_service = S3()
findings = aws_service.fetch(prescan.accounts)
r = Report(s.findings, s.known_accounts)
json_summary = r.JSON_report()
html_summary = r.HTML_report()
```

### IAM Permissions

Permissions required.

```json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": [
        "elasticfilesystem:DescribeFileSystemPolicy",
        "elasticfilesystem:DescribeFileSystems",
        "events:ListEventBuses",
        "glacier:GetVaultAccessPolicy",
        "glacier:ListVaults",
        "iam:ListRoles",
        "organizations:ListAccounts",
        "kms:GetKeyPolicy",
        "kms:ListKeys",
        "lambda:GetPolicy",
        "lambda:ListFunctions",
        "s3:GetBucketAcl",
        "s3:GetBucketPolicy",
        "s3:ListAllMyBuckets",
        "secretsmanager:GetResourcePolicy",
        "secretsmanager:ListSecrets",
        "sqs:GetQueueAttributes",
        "sqs:ListQueues"
      ],
      "Effect": "Allow",
      "Resource": "*"
    }
  ]
}
```

## Development

```sh
python3 -m env venv
source /env/bin/activate
pip install -r requirements.txt
```

1. Create a file with the name of the service.
2. Create a class with the name of the resource that you want from that service
3. Your class must inherit from `Service` and return `Findings`

Example: 

```python
class S3(Service):

    def fetch(self, accounts: DefaultDict[str, Set] ) -> Findings:
        self._buckets = self.list_account_buckets()
        self.policies = self.get_bucket_policies()
        return super().collate(accounts, self.policies)
```
4. Add your filename and class to the config

---

:warning: AWSXenos currently assesses access based on [https://github.com/Netflix-Skunkworks/policyuniverse](https://github.com/Netflix-Skunkworks/policyuniverse).
There are cases where IAM `conditions`, will _not_ be taken into account, therefore resulting in false positives. 
This could be fairly common in KMS Customer Managed Keys created by AWS Services.
AWSXenos findings are per IAM statement on an IAM policy.

## I want to add more known accounts
Create a PR or raise an issue. Contributions are welcome.



## Features
- [x] Use as library
- [x] HTML and JSON output 
