罗列 AWS 的权限和资源

作者:Sec-Labs | 发布时间:

项目地址

https://github.com/zer1t0/awsenum

awsenum

相关技术点

  • AWS权限:指AWS账户中允许用户访问哪些资源和执行哪些操作的授权。
  • 枚举:一种安全测试方法,用于在未经授权的情况下尝试访问目标系统/网络的资源和服务,以发现潜在的漏洞和安全风险。

项目用途

awsenum是一种枚举AWS权限的工具,通过暴力破解不同的操作并检查可以执行哪些操作来确定AWS账户具有哪些权限。它仅限于读取操作。该工具可以帮助用户了解他们的AWS账户中有哪些权限,从而帮助他们发现潜在的安全风险。用户可以选择要检查的服务和操作,并使用变量传递参数。

awsenum

awsenum是一款工具,它通过暴力破解不同的操作并检查您可以执行什么来确定您在AWS中具有哪些权限。它仅限于读取操作。

安装

git clone https://github.com/zer1t0/awsenum
cd awsenum/
pip install .

添加bash补全

对于当前用户:

register-python-argcomplete awsenum >> ~/.bashrc

对于当前会话:

eval "$(register-python-argcomplete awsenum)"

使用示例

枚举最常见的服务:

awsenum

使用替代AWS配置文件进行枚举:

awsenum --profile johnny

选择服务和操作

如果您想选择要检查的服务,请使用-s / --service--exclude-service参数。下面是一些示例:

枚举所有AWS服务:

awsenum -s '*'

枚举一个服务:

awsenum -s s3

枚举服务家族:

awsenum -s 'sagemaker*'

枚举多个服务:

awsenum -s ec2 s3

您还可以使用--operation--exclude-operation选择每个服务的特定操作。例如,仅列出s3存储桶:

awsenum -s ec2 --operation 'describe-*'

检查已检查的服务和操作

如果您想知道将要检查哪些操作,您可以使用--list参数与先前的任何过滤器来列出所选操作,而不是实际执行检查:

$ awsenum -s s3 --operation 'list-*' --list
s3 list-bucket-analytics-configurations
s3 list-bucket-intelligent-tiering-configurations
s3 list-bucket-inventory-configurations
s3 list-bucket-metrics-configurations
s3 list-buckets
s3 list-multipart-uploads
s3 list-object-versions
s3 list-objects
s3 list-objects-v2
s3 list-parts

您也可以仅列出服务,以了解默认情况下检查了哪些服务(此列表可能会在将来更改):

$ awsenum --list service
acm
acm-pca
autoscaling
cloudfront
cognito-identity
cognito-idp
cognito-sync
dynamodb
ebs
ec2
ecs
elasticache
elasticbeanstalk
glacier
iam
kinesis
lambda
lightsail
rds
s3
sns
sqs

使用变量

您可能知道,某些AWS操作需要参数才能检索信息,例如从s3存储桶中检索list-objects需要存储桶名称。此信息可以从其他API操作中检索,例如s3 list-buckets(甚至可以从其他操作中检索,例如amplifybackend list-s3-buckets)。因此,某些操作调用的结果存储在变量中,可以用于其他操作调用。您可以将其视为发布-订阅流程。

在此示例中,list-buckets操作将在s3-buckets-names变量上存储存储桶名称,list-objects将使用它来枚举每个存储桶的对象。

发生的情况如下:

s3:list-buckets --> s3-buckets-names --.--> s3:list-objects (Bucket=test1)
                   ["test1", "test2"]  |
                                       '--> s3:list-objects (Bucket=test2)

因此,结果将类似于:

$ awsenum -s s3 --operation list-buckets list-objects
s3 list-buckets
s3 list-objects (Bucket=test1)
s3 list-objects (Bucket=test2)

您可以使用--list version参数检查生成和使用每个变量的操作。

$ awsenum -s s3 --operation list-buckets list-objects --list version
s3 list-buckets scope:private invar: outvars:s3-buckets-names
s3 list-objects scope:private invar:s3-buckets-names outvars:

您还可以从json文件中传递变量。例如,要检查您是否可以访问某些s3存储桶,可以创建具有以下内容的文件:

{
    "s3-buckets-names": [
        "test1",
        "test2"
    ]
}

然后将其传递给程序并选择适当的操作:

$ awsenum -s s3 --operation list-objects-v2 --vars-file variables.json
s3 list-objects-v2 (Bucket=test2joadijfoisadjiofjd)
s3 list-objects-v2 (Bucket=testaskldfjaiopsdcnoidc)

API元信息

AWS API操作之间的关系(使用变量)在api-meta.yml文件中指定。此文件包括有关每个操作的信息,因此程序可以正确处理它。

文件中有三种主要类型的层次结构项:- AWS服务(如s3,ec2等)

  • 操作(如list-buckets,describe-instances等)
  • 操作版本

操作版本是基于其参数的操作的不同变体。例如,iam get-user操作可以接收或不接收用户名作为参数,因此它有两个版本,如下所示:

  get-user:
    versions:
      - {}
      - invar: iam-usernames
        args:
          UserName:
            invar_path: ""
            mode: foreach

这表示get-user操作有两个版本,一个空版本表示它不接收参数,另一个版本取决于变量iam-usernames(它是用户名列表)。如果未指定版本,则空版本是默认版本,但是如果指定了另一个版本,则必须明确声明空版本,以防需要使用它。

在第二个版本中,有参数UserName和模式foreach,因此该参数将对列表中的每个用户名进行测试,并在不同的调用中进行测试,而不是将UserName参数设置为用户名列表。此处的另一个有趣的参数是invar_path,它表示从变量中获取参数值的[jmespath](https://jmespath.org/)在这种情况下为空,因为我们要获取完整值(对于每个用户名)。

还可以在invar变量中指定模式(如果需要)。例如,如果我们有以下变量:

{
    "iam-policies-versions": [
        {
            "versions": [
                "v2"
                "v1"
            ],
            "policy": "arn:aws:iam::123456789012:policy/test-policy"
        },
        {
            "versions": [
                "v1",
            ],
            "policy": "arn:aws:iam::123456789012:policy/admin-policy"
        }
    ]
}

我们可能需要迭代每个策略,然后再迭代每个策略版本,以便获取策略版本对。这就是get-policy-version的情况,因此我们在变量中指定了foreach模式。

  get-policy-version:
    versions:
      .. # stripped
      - invar:
          name: iam-policies-versions
          mode: foreach
        args:
          PolicyArn:
            invar_path: "policy"
            mode: single

          VersionId:
            invar_path: "versions"
            mode: foreach

在这种情况下,我们在变量中迭代每个策略,并将PolicyArn参数作为policy关键字整体(single模式)取出,然后对versions中的每个值都进行迭代,并将每个值都用于VersionId,以在不同的调用中进行测试。因此,在这种情况下,我们将得到以下组合:

  • PolicyArn = arn:aws:iam :: 123456789012:policy / test-policy VersionId = v1
  • PolicyArn = arn:aws:iam :: 123456789012:policy / test-policy VersionId = v2
  • PolicyArn = arn:aws:iam :: 123456789012:policy / admin-policy VersionId = v1

回到用户名的情况下,iam-usernames变量是由list-users创建的,如下所示:

  list-users:
    outvars:
      iam-usernames: "response.Users[].UserName"

在这种情况下,list-users没有显式声明版本,因此默认情况下将使用空版本,而无需参数。但是有趣的是,list-users如果成功,将生成变量iam-usernames。这在outvars部分中指定,其中指定了变量名称和用于基于响应构建的jmespath。outvars部分可以按版本或按操作指定,在后一种情况下,将适用于其所有版本。

因此,如果我们想列出用户名并尝试获取每个用户名,我们将获得以下输出:

$ awsenum -s iam --operation list-users get-user
iam list-users
iam get-user
iam get-user (UserName=Administrator)
iam get-user (UserName=iamtest)

您还应该注意list-usersiam-usernames路径中的response字段作为根的情况,该字段表示从响应中获取字段。还可以使用args根字段从参数中获取值。例如,以下示例同时使用参数和响应构建变量值:

  list-role-policies:
    ... # stripped
    outvars:
      iam-role-policies: "{role: args.RoleName, policies: response.PolicyNames}"

还有一对关键字(此时)。第一个是scope,它可以是private或public。范围public表示操作返回的信息不是特定于目标帐户,而是针对AWS中的任何用户的,其中许多操作检索大量信息。因此,默认情况下,它们不被认为是相关的并且不被使用,但是如果您希望,可以使用--allow-public标志允许它们。一些公共操作是ec2 describe-host-reservation-offeringsroute53 get-checker-ip-ranges

另一个关键字是allowed_client_error,它指定被视为有效操作调用的错误。例如,在get-bucket-website中,如果存储桶未用于托管网站,则会检索错误并返回未找到错误,但是我们认为这是有效的调用,因为它未被拒绝(如果您具有权限)。因此,它是如何指定的:

get-bucket-website:
    allowed_client_error: NoSuchWebsiteConfiguration
    .. # stripped

这是关于元API文件的说明,不幸的是,它仍远未完善。

标签:工具分享, AWS权限