Route53のAレコードで所有していないEIP、パブリックIPが設定されていないか「Ghostbuster」を使って把握してみた

2022.11.15

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは、コンサル部@大阪オフィスのTodaです。

Route53とEC2を利用する中でElastic IP(EIP)やパブリックIPをAレコードに設定して、インスタンス破棄、EIP解放時に消し忘れたというご経験はありませんでしょうか?
消し忘れたAレコードは悪意のあるユーザにIPを再取得されてサブドメイン乗っ取りにつながる場合がございます。
今回はRoute53のAレコードで、所有していないEIP、パブリックIPが設定されていないかを Ghostbusterというツールを利用して確認してみました。

■ Github assetnote / ghostbuster
https://github.com/assetnote/ghostbuster

Route53 Aレコードに解放済みのEIP、パブリックIPを残すことの危険性

EIP、パブリックIPは解放をおこなうと再利用がおこなわれます。
悪意のあるユーザは解放されたIPを狙って取得をおこないインスタンスを起動して情報収集をしたりします。

・偽コンテンツ表示、利用者アクセス時の情報取得
Route53 AレコードにEIP、パブリックIPを残すことの危険性1

・ドメイン指定のCookie情報の取得
Route53 AレコードにEIP、パブリックIPを残すことの危険性2

上記の危険性から利用しなくなったEIP、パブリックIPを設定しているAレコードは削除する事が推奨されます。

Ghostbusterでできることは?

GhostbusterはAWS CLIの config および credentials ファイルの設定を利用して各AWSアカウントにログインをおこない EC2に設定されているEIPとパブリックIP、Route53に設定されているAレコードを取得して所有していないIPが設定されているAレコードを一覧表示します。
また、追加設定にて下記対応もできます。

  • CSV入力によるAレコードの追加判定
  • Cloudflareから取得をおこないAレコードの追加判定

検証時で把握したこと

現状、Ghostbuster利用時にオプションで「allregions」に設定するとPython内でエラーが発生するようです。
また標準でaws cliに設定しているprofileにて繰り返しスキャンが実行されるのですが、スイッチロール元のAWSアカウントでもスキャンが実行されてしまいRoute53、Ec2の参照権限がない場合エラーになるようです。
当検証では、ghostbusterコマンドのオプションでprofileを指定する事で対応をしています。

導入してみる

今回はAWS環境上のCloudShellを利用して検証しています。 また、利用時のIAMも検証用に一時作成をしております。

IAMロール作成

GhostbusterでチェックしたいAWSアカウントにてマネージメントコンソールにログインをします。
サイト上部サービスから[IAM]を選択して、表示される左メニューから[ロール]を選択します。
[ロールの作成]をおこない、各設定をおこないます。

  • 信頼されたエンティティタイプ: AWSアカウント
  • AWS アカウント: スイッチする前のAWSアカウント
    • ※検証では同じAWSアカウントを利用するようにしています。

許可ポリシーの選択では、[ポリシーの許可]をクリックして新規作成をおこないます。
ポリシーはJSON形式で入力をおこないRoute53とEC2の一部設定のみ参照出来るようにします。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "GhostbusterPolicy",
            "Effect": "Allow",
            "Action": [
                "ec2:DescribeAddresses",
                "ec2:DescribeNetworkInterfaces",
                "route53:ListResourceRecordSets",
                "route53:ListHostedZonesByName",
                "route53:GetTrafficPolicyInstance",
                "route53:GetTrafficPolicy"
            ],
            "Resource": "*"
        }
    ]
}

上記にてポリシー作成を完了して、作成途中のIAMロールにポリシーを関連付けします。
関連付け後、任意の名前にてIAMロールを追加します。
追加完了時にIAMロールの ARN をメモに残します。

IAMロールのARN

IAMユーザ作成

スイッチロールする前のAWSアカウントにログインをおこないサイト上部サービスから[IAM]を選択して、表示される左メニューから[ユーザー]を選択します。
[ユーザーの作成]をおこない、各設定をおこないます。

  • ユーザー名: 任意の名前
  • AWS 認証情報タイプを選択: アクセスキー - プログラムによるアクセス

アクセス許可の設定では既存のポリシーを[直接アタッチ]を選択します。
画面に表示される[ポリシーの作成]から、新規ポリシーを作成します。
ポリシーはJSON形式で入力をおこないAssumeRole出来るようにします。

{
    "Version": "2012-10-17",
    "Statement": {
        "Effect": "Allow",
        "Action": "sts:AssumeRole",
        "Resource": "## IAMロール作成時に取得したARN指定 ##"
    }
}

上記にてポリシー作成を完了して、作成途中のIAMユーザーにポリシーを関連付けします。
関連付け後、ユーザーの追加をします。

ユーザーを作成すると、アクセスキーID と シークレットアクセスキー が表示されますのでメモに残します。

CloudShellのセットアップ

操作をおこなうようのAWSアカウントにログインをおこないCloudShellを起動します。
Ghostbusterを導入できるようにpip3を導入します。

$ sudo pip3 install pandas

pip3を導入後、Ghostbusterを導入します。
Ghostbusterを導入時に依存関係のチェックで失敗する事があるようです。
失敗する場合は、下記コマンドを変えて再度お試しください。

$ pip3 install ghostbuster

ERROR: After October 2020 *** と表示された場合は下記コマンドを利用ください。
$ pip3 install ghostbuster --use-feature=2020-resolver

Ghostbusterの導入が完了になります。

aws cliの設定

CloudShellにはaws cliのコマンドが導入されています。
下記コマンドにてアクセスキーの設定をおこないます。

$ aws configure
AWS Access Key ID : IAMユーザーのアクセスキーID
AWS Secret Access Key : IAMユーザーのシークレットアクセスキー
Default region name : デフォルトリージョン 今回はap-northeast-1指定
Default output format : 空白

上記にてIAMユーザーの設定が完了しましたので「credentials」にてスイッチロールするアカウントの設定をおこないます。

$ vi .aws/config
[default]
region = ap-northeast-1

[profile test1]
role_arn = ## IAMロール作成時に取得したARN指定 ##
region = ap-northeast-1
source_profile = default

上記保存にてaws cliは完了になります。

試してみる

ツールが正常に導入できると「ghostbuster」コマンドを利用する事ができます。
ghostbusterコマンドにて対象のAWSアカウントをスキャンしてみます。

$ ghostbuster scan aws --regions  ap-northeast-1 --profile test1
Obtaining Route53 hosted zones for AWS profile: test1.
Obtained 2 DNS A records so far.
Obtaining EIPs for region: ap-northeast-1, profile: test1
Obtaining IPs for network interfaces for region: ap-northeast-1, profile: test1
Obtained 1 unique elastic IPs from AWS.

# 問題のaレコードがある場合
Takeover possible: {'name': 'test.example.jp.', 'records': ['xxx.xxx.xxx.xxx']}

# 問題がない場合
No takeovers detected! Nice work.

Ghostbuster 結果表示

スキャン結果で最終行に表示される「Takeover possible」の内容がRoute53のAレコードに存在するIPアドレスで、EC2側のEIPやパブリックIPに存在しないものになります。
上記が表示される場合は、表示されるサブドメインが利用されていないか?IPアドレスが別AWSアカウントかオンプレサーバで利用されていないか?確認をおこない、未使用の場合はAレコードを削除頂く流れになります。

また、CSVを利用してaレコードを追加してスキャンすることも可能です。
CSVを追加する場合は、下記フォーマットにて記載を頂きコマンドにてCSVを指定してスキャンを実行します。

$ vi 
name,record
test1.example.com,xxx.xxx.xxx.xxx
test2.example.com,xxx.xxx.xxx.xxx

$ ghostbuster scan aws --records records.csv --regions  ap-northeast-1 --profile test1
Obtaining Route53 hosted zones for AWS profile: test1.
Obtained 1 DNS A records so far.
Obtaining EIPs for region: ap-northeast-1, profile: test1
Obtaining IPs for network interfaces for region: ap-northeast-1, profile: test1
Obtained 1 unique elastic IPs from AWS.

Takeover possible: {'name': 'test2.example.com', 'records': ['xxx.xxx.xxx.xxx']}

さいごに

今回は Ghostbuster を利用して、Route53のAレコードで所有していないIPが設定されていないか確認をしてみました。
実行時にエラーが出る場合がございましたので今後のアップデート状況を見て追加の案内が出来たらと考えています。
あと、このブログを書いているとマシュマロが食べたくなり急遽買いにいきました。
少しでもお客様の参考になればと考えております。