
すべてのAWSアカウント内のリソースを分析して、宙ぶらりんのElastic IPを排除します。
Ghostbusterは、すべてのAWSアカウント(Route53)に存在するすべてのDNSレコードを取得し、オプションでCSV入力またはCloudflareを介してレコードを取り込むことができます。
これらのレコードを収集した後、GhostbusterはすべてのAWS Elastic IPとネットワークインターフェースのパブリックIPを反復処理してデータを収集します。
DNSレコード(route53、ファイル入力、cloudflareから)の完全な状況と、組織が所有するAWS IPの完全な状況を把握することで、このツールは、もはや所有していないElastic IPを指しているサブドメイン(宙ぶらりんなElastic IP)を検出できます。
AWSにインフラをデプロイする際、EC2インスタンスを立ち上げると、それにIPが関連付けられます。これらのIPを指すDNSレコードを作成したものの、EC2インスタンスに新しいIPが割り当てられたり、破棄された後にDNSレコードを削除し忘れると、サブドメイン乗っ取り攻撃に対して脆弱になります。
Elastic IPの乗っ取りについては多くの研究が行われており、攻撃者は対象企業のサブドメインに関連付けられたIPを取得するまで、Elastic IPを継続的に要求することが可能です。
AWSはこの攻撃パターンを試みようとするアカウントを頻繁に禁止していますが、AWSからは長期的な修正はリリースされていません。
宙ぶらりんなElastic IPサブドメイン乗っ取り攻撃の影響は、通常のサブドメイン乗っ取り(提供されるコンテンツのみを制御できる)よりも深刻です。宙ぶらりんなElastic IPの乗っ取りでは、攻撃者は以下のことが可能になります。
.aws/configに設定された各AWSプロファイルを動的に反復処理重要:
このツールを効果的に使用するには、AWS環境の完全な状況を把握している必要があります。完全な状況がないと、誤検出の原因になります。
Ghostbusterのインストールは簡単で、pip install ghostbusterを実行するだけです。その後、CLIツールはghostbusterコマンドで使用できるようになります。
これにはPython 3.x環境が必要です。
❯ ghostbuster scan aws --help
Usage: ghostbuster scan aws [OPTIONS]
AWSアカウント内の宙ぶらりんなElastic IPをスキャンします。
Options:
--profile TEXT ghostbusterを実行する特定のAWSプロファイルを指定します。
--skipascii Ghostbuster起動時のASCIIアートの表示をスキップします。
--json JSONオブジェクトのみを返します。
--slackwebhook TEXT 潜在的な乗っ取りに関する通知を送信するSlack Webhook URLを指定します。
--records PATH チェックするDNSレコードを手動で指定します。Ghostbusterは、取得したDNSレコードをチェックした後にこれらのIPをチェックします。例についてはrecords.csvを参照してください。
--cloudflaretoken TEXT CloudflareからDNSレコードを取得します。CF APIトークンを指定します。
--allregions すべてのリージョンで実行します。
--exclude TEXT 除外するプロファイル名のカンマ区切りリスト。
--regions TEXT 実行するリージョンのカンマ区切りリスト。
--help このメッセージと終了を表示します。
コマンド例
Cloudflare DNSレコードにアクセスし、Slack Webhookに通知を送信し、すべてのAWSリージョンに対して.aws/configまたは.aws/credentialsに設定されたすべてのAWSプロファイルを反復処理してGhostbusterを実行する:
❯ ghostbuster scan aws --cloudflaretoken APIKEY --slackwebhook https://hooks.slack.com/services/KEY --allregions
サブドメインAレコードの手動入力リストを使用してGhostbusterを実行する(例のファイルはこのリポジトリのrecords.csvを参照):
❯ ghostbuster scan aws --records records.csv
--regionsを使用して特定のリージョンをカンマ区切りリストで指定できます。例:us-east-1,us-west-1。
❯ ghostbuster scan aws --cloudflaretoken whougonnacall
Obtaining all zone names from Cloudflare.
Obtaining DNS A records for all zones from Cloudflare.
Obtained 33 DNS A records so far.
Obtaining Route53 hosted zones for AWS profile: default.
Obtaining Route53 hosted zones for AWS profile: account-five.
Obtaining Route53 hosted zones for AWS profile: account-four.
Obtaining Route53 hosted zones for AWS profile: account-four-deploy.
Obtaining Route53 hosted zones for AWS profile: account-two-deploy.
Obtaining Route53 hosted zones for AWS profile: account-one-deploy.
Obtaining Route53 hosted zones for AWS profile: account-three-deploy.
Obtaining Route53 hosted zones for AWS profile: account-six.
Obtaining Route53 hosted zones for AWS profile: account-seven.
Obtaining Route53 hosted zones for AWS profile: account-one.
Obtained 124 DNS A records so far.
Obtaining EIPs for region: us-east-1, profile: default
Obtaining IPs for network interfaces for region: us-east-1, profile: default
Obtaining EIPs for region: us-east-1, profile: account-five
Obtaining IPs for network interfaces for region: us-east-1, profile: account-five
Obtaining EIPs for region: us-east-1, profile: account-four
Obtaining IPs for network interfaces for region: us-east-1, profile: account-four
Obtaining EIPs for region: us-east-1, profile: account-four-deploy
Obtaining IPs for network interfaces for region: us-east-1, profile: account-four-deploy
Obtaining EIPs for region: us-east-1, profile: account-two-deploy
Obtaining IPs for network interfaces for region: us-east-1, profile: account-two-deploy
Obtaining EIPs for region: us-east-1, profile: account-one-deploy
Obtaining IPs for network interfaces for region: us-east-1, profile: account-one-deploy
Obtaining EIPs for region: us-east-1, profile: account-three-deploy
Obtaining IPs for network interfaces for region: us-east-1, profile: account-three-deploy
Obtaining EIPs for region: us-east-1, profile: account-six
Obtaining IPs for network interfaces for region: us-east-1, profile: account-six
Obtaining EIPs for region: us-east-1, profile: account-seven
Obtaining IPs for network interfaces for region: us-east-1, profile: account-seven
Obtaining EIPs for region: us-east-1, profile: account-one
Obtaining IPs for network interfaces for region: us-east-1, profile: account-one
Obtained 415 unique elastic IPs from AWS.
Takeover possible: {'name': 'takeover.assetnotecloud.com', 'records': ['52.54.24.193']}
最初のステップは、AWSアカウント内でRoute53レコードの読み取り、Elastic AddressおよびEC2ネットワークインターフェースの記述に必要な権限を付与するキーまたはロールを作成することです。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "GhostbusterPolicy",
"Effect": "Allow",
"Action": [
"ec2:DescribeAddresses",
"ec2:DescribeNetworkInterfaces",
"route53:ListResourceRecordSets",
"route53:ListHostedZonesByName",
"route53:GetTrafficPolicyInstance",
"route53:GetTrafficPolicy"
],
"Resource": "*"
}
]
}
.aws/credentialsファイルに設定します。所有する各AWSアカウントで上記の手順を繰り返します。
このツールは、AWS設定の方法(複数キー、またはクロスアカウントのAssume Roleプロファイル)に関係なく動作します。これは、AWSとのインターフェースに使用されるライブラリboto3によって管理されます。
設定例は次のようになります:
.aws/credentials:
[default]
aws_access_key_id = AKIAIII...
aws_secret_access_key = faAaAaA...
.aws/config:
[default]
output = table
region = us-east-1
[profile account-one]
role_arn = arn:aws:iam::911111111113:role/Ec2Route53Access
source_profile = default
region = us-east-1
[profile account-two]
role_arn = arn:aws:iam::911111111112:role/Ec2Route53Access
source_profile = default
region = us-east-1
[profile account-three]
region = us-east-1
role_arn = arn:aws:iam::911111111111:role/Ec2Route53Access
source_profile = default
あるいは、ロールを引き受ける代わりに、.aws/credentialsファイルにスコープされたアクセス権を持つプロファイルのリストと関連キーを設定することもできます。
AWS環境内のすべてのアカウントでAWS設定が完了したら、次のコマンドを使用してツールを実行できます。
Ghostbusterはロールを使用できます。これにより、1か所に多くの認証情報を保持する必要がなくなります。ただし、ロールアプローチでは、組織内に追加のIAMポリシーを作成する必要があります。
ロールは、--roles roles.csv または --autoroles フラグを使用して使用できます。--roles を機能させるには、スキャン対象のすべてのアカウントに 「GhostbusterTargetAccountRole」という名前のロールを正確にその名前で作成する必要があります。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "GhostbusterTargetAccountRole",
"Effect": "Allow",
"Action": [
"ec2:DescribeAddresses",
"ec2:DescribeNetworkInterfaces",
"ec2:DescribeRegions",
"route53:ListResourceRecordSets",
"route53:ListHostedZonesByName",
"route53:GetTrafficPolicyInstance",
"route53:GetTrafficPolicy"
],
"Resource": "*"
}
]
}
ghostbusterはlambda/ec2などでghostbusterロール(ghostbusterマスターロールと呼びます)で実行されます。マスターロールはTargetAccountRoleを引き受けることができる必要があります。
resource "aws_iam_policy" "ghostbuster_target_account_roles" {
name = "ghostbuster_target_account_roles"
path = "/"
description = "Allow inspecting DNS and elastic IP data."
policy = jsonencode({
"Version" : "2012-10-17",
"Statement" : [
{
"Effect" : "Allow",
"Action" : "sts:AssumeRole",
"Resource" : ["arn:aws:iam::*:role/GhostbusterTargetAccountRole"]
}]
})
tags = {
Project = "ghostbuster"
}
}
自動アカウント検出には、--roles と比較して追加の権限が必要です。--roles を機能させた後、組織の概要を把握しているアカウントに次のIAMポリシーを追加することを検討してください。
{
sid = "BaseAccess"
actions = [
"organizations:DescribeAccount",
"organizations:ListAccounts"
]
resources = ["*"]
effect = "Allow"
}
}
次に、ghostbusterを実行しているアカウントで、ghostbusterマスターロールに次のポリシーをアタッチして、組織参照ロールを引き受けられるようにします。
{
"Version" : "2012-10-17",
"Statement" : [
{
"Effect" : "Allow",
"Action" : "sts:AssumeRole",
"Resource" : ["arn:aws:iam::ORG_LOOKUP_ACCOUNT_ID:role/ghostbuster-org-role"]
}]
}
ORG_LOOKUP_ACCOUNT_ID を実際のアカウントIDに置き換えることを忘れないでください。
GhostbusterにCloudflareに設定されているすべてのAレコードを取得させたい場合は、ゾーンを読み取ることができるAPIトークンを設定する必要があります。
https://dash.cloudflare.com/profile/api-tokens
以下のスクリーンショットのようにCloudflare APIトークンを設定します:

このAPIトークンを取得したら、安全な場所(パスワードマネージャーなど)にメモしておきます。Ghostbusterで使用するには、cloudflaretoken 引数で渡します。
このプロジェクトに参加した貢献者のリストもご覧ください。
GNU Affero General Public License
pip3 install virtualenv を使用してvirtualenvをインストールします。virtualenv venv を使用して仮想環境を作成します。. venv/bin/activate を使用して仮想環境を有効化します。pip3 install --editable . でGhostbusterをインストールします。