[レポート]Security-JAWS DAYS ~Day2~ に参加しました。一部writeupあり。 #secjaws #secjaws30 #jawsug #secjawsdays

8/26-27の2日間にわたり大規模かつオフライン&オンラインのハイブリッドで開催された Security-JAWS DAYS のDay2で開催されたCTFに参加してきました。本記事はそのレポート兼writeupです。
2023.08.29

こんにちは、AWS事業本部@福岡オフィスのべこみん(@beco_minn)です。

先日、Security-JAWS DAYS~Day2~というイベントに参加してきました。

なんとそのイベントではAWSベースのCTFが行われるというではありませんか!!!楽しそう!!ということで、今回はそのイベント参加レポ&ちょっとしたwriteupです。

もちろんDay2もあればDay1もあります。

Day1の様子については下記をご覧ください。YouTubeでアーカイブも公開されています。

イベント概要

今回のイベントはAWS寄りのCTFということで、webやcryptoなどのジャンル分けはされておらず、問題は以下の難易度別に分かれていました。

  • Trivia
    • 13問
    • 各10pt
  • Warmup
    • 6問
    • 各50pt
  • Easy
    • 4問
    • 各100pt
  • Medium
    • 5問
    • 各200pt
  • Hard
    • 2問
    • 各300pt

TriviaやWarmupに一部例外はありますが、FLAGの形式は SJWAS{****} です。

本記事のwriteupでは私が実際に時間内で解けた問題のみについて書いています。

writeup

Trivia

Triviaはその名の通りトリビア、雑学的な知識です。

問題としては、ググれば分かるOSINT(Open Source Intelligence)系の問題がほとんどでした。AWSを普段から触っている方なら半分以上はググらなくても回答出来る問題ですね。

回答は下の方に隠しておくので、この記事を読んでいる皆さんもチャレンジしてみてください。

Trivia1

Security-JAWS#01の開催年月日はいつでしょうか? (yyyymmdd形式でご回答ください)

Trivia2

AWS WAFv2がリリースされたのは何年何月? (yyyymm形式でご回答ください)

Trivia3

AWS Acount IDは何桁? (x桁の数字の部分のみをご回答ください。)

Trivia4

このIAMユーザー(シークレットキー+アクセスキー)が所属するAWSアカウントIDは何?

※ すみません、この問題は他の情報を失念しました。もっと詳細な情報が渡されていて、AWS CLIは使わず回答出来たはず。

Trivia5

IAM Policyで一番強い権限のAWSマネージドポリシー名は?

Trivia6

AWS Security HubのAWS基礎セキュリティのベストプラクティス v1.0.0でチェックされるパスワードポリシーの最小桁数はいくつ? (x桁の数字の部分のみをご回答ください。)

Trivia7

AWS Config Rulesのrestricted-sshでNONCONPLIANTとなるCIDR は?

Trivia8

AWS WAFのfreeのManaged Rule GroupsにおいてもっともWCUの高いルールのWCU値はいくつか?

Trivia9

Amazon GuardDutyの追加で設定できる保護プランは、S3 Protection・EKS Protection・RDS Protection・Lambda Protectionと後何? (xxxxxxx Protectionのxxxxxxxの部分をご回答ください)

Trivia10

FIPS 準拠に関する国家安全保障局の CNSSP 15 と、2 層の CNSA 暗号化に関する保存データ機能パッケージ (DAR CP) バージョン 5.0 ガイダンスを満たすように設計されたS3のセキュリティ機能の名称は?

Trivia11

Route53にてドメイン登録をする際に、ドメインのチェックを行う必要がありますが、チェック可能なドメイン長は最大で何文字? (x文字の数字の部分のみをご回答ください。)

Trivia12

クラウドホスト型決済アプリケーションにおける暗号化オペレーションの簡素化を支援するAWSのマネージドサービスは?

Trivia13

以下のCloudTrailログを読み取り、作成されたユーザー名を回答してください。

 {
    "eventVersion": "1.08",
    "userIdentity": {
        "type": "AssumedRole",
        "principalId": "AROXXXXXXXXXXXXXXXXX:test-user",
        "arn": "arn:aws:sts::123456789012:assumed-role/test-user/test-user",
        "accountId": "123456789012",
        "accessKeyId": "ASIA44JPO63AVLDDIY5N",
        "sessionContext": {
            "sessionIssuer": {
                "type": "Role",
                "principalId": "AROXXXXXXXXXXXXXXXXX",
                "arn": "arn:aws:iam::123456789012:role/test-user",
                "accountId": "123456789012",
                "userName": "test-user"
            },
            "webIdFederationData": {},
            "attributes": {
                "creationDate": "2022-10-15T21:38:24Z",
                "mfaAuthenticated": "true"
            }
        }
    },
    "eventTime": "2022-10-15T22:05:16Z",
    "eventSource": "iam.amazonaws.com",
    "eventName": "CreateUser",
    "awsRegion": "us-east-1",
    "sourceIPAddress": "AWS Internal",
    "userAgent": "AWS Internal",
    "requestParameters": {
        "userName": "KRJXVVAWC13R",
        "tags": []
    },
    "responseElements": {
        "user": {
            "path": "/",
            "userName": "KRJXVVAWC13R",
            "userId": "AIDAXXXXXXXXXXXXXXXXX",
            "arn": "arn:aws:iam::123456789012:user/KRJXVVAWC13R",
            "createDate": "Oct 15, 2022 10:05:16 PM"
        }
    },
    "requestID": "5eda3a85-64ed-4c5f-8d0a-9497e05f99bd",
    "eventID": "5586ec9d-4e9d-431b-ad8e-e33a6c8ecb94",
    "readOnly": false,
    "eventType": "AwsApiCall",
    "managementEvent": true,
    "recipientAccountId": "123456789012",
    "eventCategory": "Management",
    "sessionCredentialFromConsole": "true"
}

答え

←の矢印をクリックすると回答が表示されます

Trivia1

→ 20160517

Trivia2

→ 201911

Trivia3

→ 12

Trivia4

→ 946546793415

Trivia5

→ AdministratorAccess

Trivia6

→ 8

Trivia7

→ 0.0.0.0/0

Trivia8

→ 700

Trivia9

→ Malware

Trivia10

→ DSSE-KMS

Trivia11

→ 255

Trivia12

→ AWS Payment Cryptography

Trivia13

→ KRJXVVAWC13R

Warmup

ここからは私が実際に考えた流れを元にwriteupを書いていきます。

AWS CLI practice

このAWSユーザー(シークレットキー+アクセスキー)が所属するAWSアカウントIDは何?

上図のダウンロードボタンをクリックするとアクセスキーとシークレットキーだけが書かれたCSVがダウンロード出来ます。Warmupでは以降も同様の問題が続きました。

今回のCTFはAWS CLIを使う問題が多かったので、チュートリアルのようなこの問題が用意されていることに作問者さんの優しさを感じました。

これは簡単ですね。皆さんも普段見知らぬアクセスキーがあればまず最初に叩くCLIコマンドがありますよね?

そうです、 aws sts get-caller-identity です。

実行結果はこんな感じ

$ aws sts get-caller-identity --profile ctf-0

{
    "UserId": "AIDA5YYUV3PDXROBLRDKF",
    "Account": "946546793415",
    "Arn": "arn:aws:iam::946546793415:user/ctf_challenge_0"
}

答えは 946546793415 ですね。

Run Function

アクセスキーを調べてFLAGを入手せよ!

CTFでは問題文に意味が無く、問題のタイトルにヒントが隠されていることがあります。

Run Functionとのことなので、Lambda Functionを実行すれば良いのかな?と推測します。

しかし、何のFunctionを叩けるのか分からないので、まずは入手したアクセスキーからユーザーにはどんな権限が付けられているのかを確認します。

以降の問題でも同じ作業を行いますが、私は「aws cli 権限確認」とググって出てきたブログをチートシート代わりに下記CLIコマンドを実行しました。普段AWS CLIコマンドを確認する時は真っ先に公式ドキュメントを見に行きますが、こういう時にチートシート代わりになる記事は本当にありがたいです。

まずは aws sts get-caller-identity --profile ctf-6 でユーザー名を取得します。

その後、ユーザーにどんな権限がアタッチされているのかを確認します。

まずは管理ポリシーから確認します。

aws iam list-attached-user-policies \
    --user-name ctf_challenge_6 \
    --query 'AttachedPolicies[].PolicyArn' \
    --profile ctf-6

しかし管理ポリシーは何もアタッチされていないようです。次はインラインポリシーを確認します。

aws iam list-user-policies \
    --user-name ctf_challenge_6 \
    --profile ctf-6

このコマンドを実行すると、ユーザー ctf_challenge_6 に runlambda というインラインポリシーがアタッチされていることが分かりました。

下記コマンドでポリシードキュメントを確認します。

aws iam get-user-policy \
    --user-name ctf_challenge_6 \
    --policy-name runlambda \
    --query 'PolicyDocument' \
    --profile ctf-6

ポリシードキュメントを確認すると、どうやらこのユーザーは run_me という名前のLambda Functionに対して実行権限を持っているようです。

invokeコマンドで実行します。

aws lambda invoke \
    --function-name run_me \
    --profile ctf-6 response.json

実行すると、こんな実行結果が返ってきました。

{"statusCode": 200, "body": "\"Look at the log!\""}

はい、ログを見ます。でもCLIでLambdaの実行ログってどうやって見るんだ。。?

ググったらこの記事が見つかったのでやってみます。

aws lambda invoke \
    --function-name run_me out \
    --log-type Tail \
    --query 'LogResult'
    --output text \
    --profile ctf-6 | base64 -d

すると、 SJAWS{You_was_able_to_arrive_@t_the_lambda_function.-well_done!} というフラグを取得出来ました。

Find data 1

この問題は数少ないマネジメントコンソールを使って解く問題でした。

CSVファイルをダウンロードすると、中にはサインイン用URLとアカウント名、パスワードが記載されていました。

「FLAGはバケツに突っ込んである」とのことなので、普通にS3バケットを見に行くと FLAG といういかにもなファイルが置いてありました。

中を確認するとFLAGがそのまま書いてありました。

SJAWS{mazuha-kote-sh1rabe_yokumitukemasitane!}

Find data 2

Find dataはシリーズもので、全部で3問あるようです。

2も1と同じ問題文ですね。

今回はCSVの中身がアクセスキーなのでCLIで作業します。

まずは aws sts get-caller-identity を叩きます。

$ aws sts get-caller-identity --profile ctf-3
{
    "UserId": "AIDAQZ2IU22WKS2WQP2P2",
    "Account": "055450064556",
    "Arn": "arn:aws:iam::055450064556:user/ctf_challenge_3"
}

その後ユーザーの権限情報を確認しようとしたのですが、IAMの権限付与されておらず権限を確認することが出来ませんでした。

仕方ないのでS3のコマンドを叩くことにしました。

まずはlsコマンドから

$ aws s3 ls --profile ctf-3
2023-08-13 23:13:07 backup-37szjp8pny7xx01
2023-08-26 22:43:13 camouflagedrop-wxhqft4lqf-assets-wxhqft4lqf-assets
2023-08-26 22:39:22 camouflagedrop-wxhqft4lqf-web-wxhqft4lqf-static
2023-08-22 20:16:14 cdk-hnb659fds-assets-055450064556-ap-northeast-1
2023-08-25 03:05:46 file-storage-afeffefespntbaiw7o5
2023-08-06 21:55:59 himituno-bucket1
2023-08-06 21:58:33 himituno-bucket2
2023-08-06 23:08:46 himituno-bucket3
2023-08-27 02:41:30 my-backup-file-ulxmhiw3jroec7sclynr06fkvhqssf
2023-08-22 20:56:47 s3misssignurl-t6j4qj4r-assets-t6j4qj4r-assets-bucket
2023-08-22 20:52:31 s3misssignurl-t6j4qj4r-web-t6j4qj4r-static-host-bucket
2023-08-24 04:24:09 totemo-kawaii-neko-no-namae-ha-lise-desu
2023-08-27 01:18:59 ulxmhiw3jroec7sclynr06fkvhqssf

さっきのFind data 1のバケットが himituno-bucket1 だったので、 himituno-bucket2 に当たりを付けて調査を進めます。

$aws s3 ls s3://himituno-bucket2 --profile ctf-3
                PRE SECRET

どうやらSECRETというprefixが付いているようです。lsコマンドに--recursiveオプションを付けてサブディレクトリのオブジェクトを全て確認します。

$ aws s3 ls himituno-bucket2 --recursive --profile ctf-3
2023-08-06 22:03:43      62896 SECRET/1/flag.jpg
2023-08-06 22:03:43      62896 SECRET/10/flag.jpg
2023-08-06 22:03:44      62896 SECRET/100/flag.jpg
2023-08-06 22:03:44      62896 SECRET/1000/flag.jpg
2023-08-06 22:03:45      62896 SECRET/101/flag.jpg
2023-08-06 22:03:45      62896 SECRET/102/flag.jpg
2023-08-06 22:03:45      62896 SECRET/103/flag.jpg
2023-08-06 22:03:46      62896 SECRET/104/flag.jpg
2023-08-06 22:03:46      62896 SECRET/105/flag.jpg
2023-08-06 22:03:46      62896 SECRET/106/flag.jpg
2023-08-06 22:03:47      62896 SECRET/107/flag.jpg
2023-08-06 22:03:47      62896 SECRET/108/flag.jpg
2023-08-06 22:03:47      62896 SECRET/109/flag.jpg
2023-08-06 22:03:48      62896 SECRET/11/flag.jpg
2023-08-06 22:03:48      62896 SECRET/110/flag.jpg
2023-08-06 22:03:48      62896 SECRET/111/flag.jpg
2023-08-06 22:03:48      62896 SECRET/112/flag.jpg
〜中略〜
2023-08-06 ??:??:??      62896 SECRET/998/flag.jpg
2023-08-06 ??:??:??      62896 SECRET/999/flag.jpg
2023-08-06 ??:??:??      62896 SECRET/99/flag.jpg
2023-08-06 ??:??:??      62896 SECRET/9/flag.jpg

。。。。。。。。。。

なんと1~1000までのディレクトリの配下に、それぞれ flag.jpeg というjpegファイルがありました。。。

試しにいくつか開いてみるとこんな画像が。

。。。。。。

全て同じファイル名だけど、どこかに当たりファイルがあるはず。じゃあ画像ファイルのハッシュ値を付き合わせれば良いのでは?と思ってChatGPTくんにスクリプトを書いてもらったのですが、私のプロンプト力が足りなかったのか検知出来ず。。。

そこで私は「実はこの中に当たりファイルなんて無いのでは?」と疑心暗鬼になり、ハズレの画像に対して解析ツールを使って色々と無駄なことをやってました。

ここで一旦この問題は諦めました。

別の問題を終え、改めて最初から手順をなぞることに。

さっきの s3 ls --recursiveの結果をVSCode上で改めて確認してみると、1つだけファイルサイズが異なるものがあることに気付きました。(拡張子、ファイル名、ファイルサイズの順に検索をかけて気付きました)

444のflag.jpgを開くとこんな画像が。

ということでクリアです。FLAGは SJAWS{ta@1hen-yoku_mitukemashita!}

ちなみに自分はこのFind data 2に一番時間を掛けてしまいました。。。

Show IAM policy

このユーザーにアタッチされているポリシーを確認してみよう!Policyドキュメントを注意深くみたらFLAGが隠れているかも。

ポリシーを調べれば良いだけみたいです。余裕ですね。

今まで同様、下記を実行します。

  • aws sts get-caller-identity
  • ユーザーにアタッチされている管理ポリシーの確認
  • ユーザーにアタッチされているインラインポリシーの確認

しかしポリシーは付いていないようです。

他のポリシー。。グループポリシーかなぁと思ってユーザーがグループに所属しているかどうか確認します。

$ aws iam list-groups-for-user \
    --user-name ctf_challenge_5 \
    --query 'Groups[].GroupName' \
    --profile ctf-5

[
    "ctf5"
]

してました。次にこのグループにアタッチされているポリシーを確認します。

まずは管理ポリシーから。

$aws iam list-attached-group-policies \
    --group-name ctf5 \
    --query 'AttachedPolicies[].PolicyArn' \
    --profile ctf-5

何も出ません。

次はインラインポリシーを確認します。

$aws iam list-group-policies \
    --group-name ctf5 \
    --profile ctf-5

{
    "PolicyNames": [
        "selfcheck"
    ]
}

ありました!selfcheckというインラインポリシーが付いているようです。

このポリシードキュメントを確認します。

$aws iam get-group-policy \
    --group-name ctf5 \
    --policy-name selfcheck \
    --query 'PolicyDocument' \
    --profile ctf-5

{
    "Version": "2012-10-17",
    "Statement": {
        "Sid": "U0pBV1N7RG9feW91LWZpbmRfdGhlX0B0dGFjaGVkX3AwbDFjeT99",
        "Effect": "Allow",
        "Action": [
            "iam:Get*",
            "iam:List*"
        ],
        "Resource": [
            "arn:aws:iam::055450064556:group/ctf5",
            "arn:aws:iam::055450064556:user/ctf_challenge_5"
        ]
    }
}

普段からAWSのポリシーに触れている人ならSIDに違和感を覚えますよね。

恐らく何かしらでエンコードされてるんだろうなと思ったので、SIDの U0pBV1N7RG9feW91LWZpbmRfdGhlX0B0dGFjaGVkX3AwbDFjeT99 を下記サイトでデコードしました。

すると出てきました。Base64でエンコードされていたみたいです。

SJAWS{Do_you-find_the_@ttached_p0l1cy?}

Where is the password?

「AWSのとあるサービスからパスワードを取得してください!ヒント:AWSで安全にパスワード管理をしたい時に利用するサービスと言えば?」 パスワードがFLAGとなっています。

この問題もサービス問題で、Find data 1同様にマネジメントコンソールで解くタイプの問題でした。

WarmupというよりTriviaな問題ですね。

サインイン後、問題文から推測してAWS Secrets Managerを見に行くと、FLAGが置いてありました。

Easy

Find data 3

最後のFind data 3です。問題文自体は今までと同じ。

念の為Find data 2と同じくIAMポリシーを確認しようとしましたが、権限が無く何も分かりませんでした。

なのでまたs3 lsコマンドを実行します。

$ aws s3 ls --profile ctf-4
2023-08-13 23:13:07 backup-37szjp8pny7xx01
2023-08-26 22:43:13 camouflagedrop-wxhqft4lqf-assets-wxhqft4lqf-assets
2023-08-26 22:39:22 camouflagedrop-wxhqft4lqf-web-wxhqft4lqf-static
2023-08-22 20:16:14 cdk-hnb659fds-assets-055450064556-ap-northeast-1
2023-08-25 03:05:46 file-storage-afeffefespntbaiw7o5
2023-08-06 21:55:59 himituno-bucket1
2023-08-06 21:58:33 himituno-bucket2
2023-08-06 23:08:46 himituno-bucket3
2023-08-27 02:41:30 my-backup-file-ulxmhiw3jroec7sclynr06fkvhqssf
2023-08-22 20:56:47 s3misssignurl-t6j4qj4r-assets-t6j4qj4r-assets-bucket
2023-08-22 20:52:31 s3misssignurl-t6j4qj4r-web-t6j4qj4r-static-host-bucket
2023-08-24 04:24:09 totemo-kawaii-neko-no-namae-ha-lise-desu
2023-08-27 01:18:59 ulxmhiw3jroec7sclynr06fkvhqssf

さっきと同じですね。恐らくhimituno-bucket3を見るのでしょう。

バケットの中を確認すると、readme.txtというファイルが置かれていました。readme.txtには下記だけ書かれていました。

It was pointed out that placing sensitive data on S3 is not recommended, so I removed it.

削除した?センシティブなデータを削除した。。じゃあどこかに移したのかな?と思ってAWS Secrets ManagerとSSM Parameter Storeを見ようとしましたが権限がありません。

もしかして。。と思ってhimituno-bucket3がバージョニング有効化されているかを確認しました。

$ aws s3api list-object-versions --profile ctf-4 \
--bucket himituno-bucket3
{
    "Versions": [
        {
            "ETag": "\"c9f27b84582adb55f13c221fcb6a98c2\"",
            "Size": 34,
            "StorageClass": "STANDARD",
            "Key": "SECRET_DATA",
            "VersionId": "MO4Xz6sB8DONDjCid6ideiRgfdyywcSv",
            "IsLatest": false,
            "LastModified": "2023-08-06T14:09:57+00:00",
            "Owner": {
                "DisplayName": "metal.preacher.667+secjawsctf02",
                "ID": "fc0f5cd79b017dfe728d64cc204668f1627550263b144a54ae6c2074446d2f59"
            }
        },
        {
            "ETag": "\"5a60a9f41ca16805b78555e750446f4f\"",
            "Size": 89,
            "StorageClass": "STANDARD",
            "Key": "readme.txt",
            "VersionId": "C5Liv01TTxQDidoi3Uhs2NJuBkFCPCQI",
            "IsLatest": true,
            "LastModified": "2023-08-06T14:11:05+00:00",
            "Owner": {
                "DisplayName": "metal.preacher.667+secjawsctf02",
                "ID": "fc0f5cd79b017dfe728d64cc204668f1627550263b144a54ae6c2074446d2f59"
            }
        }
    ],
    "DeleteMarkers": [
        {
            "Owner": {
                "DisplayName": "metal.preacher.667+secjawsctf02",
                "ID": "fc0f5cd79b017dfe728d64cc204668f1627550263b144a54ae6c2074446d2f59"
            },
            "Key": "SECRET_DATA",
            "VersionId": "RNzJqEkR36thowt.ug5SxaGYT18yckYP",
            "IsLatest": true,
            "LastModified": "2023-08-06T14:10:21+00:00"
        }
    ]
}

バージョニングされていて、SECRET_DATA といういかにもなデータの削除マーカーとバージョン情報がありますね。

この結果を見て aws s3api delete-object を使って削除マーカーを削除しようとしましたが、権限がありませんでした。

調べてみると、version-idが分かっていれば aws s3api get-object で削除前のファイルを取得出来るようです。

$aws s3api get-object \
    --bucket himituno-bucket3 \
    --key SECRET_DATA \
    --profile ctf-4 \
    --version-id MO4Xz6sB8DONDjCid6ideiRgfdyywcSv SECRET_DATA

SECRET_DATAの中には下記のフラグが入っていました。

SJAWS{Versi0ning_ni_kizukim@sita?}

Get Provision

EC2 上で動く Web アプリケーションからインスタンスのプロビジョニングのデータを入手せよ! http://gpweb.scjdaysctf2023.net/

問題文は上記です。(現在上記URLのサーバーは停止しています)

開くと下図のような画面が表示されていました。

どうやらURLを入力するとURL先の情報を教えてくれるプロキシサービスのようです。ご丁寧に「本サービスにしようれているクラウドサービス(Amazon EC2, ...)」と書いてくれています。

プロビジョニングのデータって何を取れば良いんだ?と思い、とりあえずインスタンスメタデータからinstance-idを取得出来るかどうかを確認してみました。

http://169.254.169.254/latest/meta-data/instance-id

出来ました。

次に「プロビジョニングのデータ」について考えます。ユーザーが自由に設定出来る文字列ということでユーザーデータじゃないか?と思い調べてたところ、メタデータ同様リンクローカルアドレスからユーザーデータも取得出来るようです。

ということで取得してみます。

http://169.254.169.254/latest/user-data

取れました。FLAGは SJAWS{Get_1nst@nce_U2er_dat@!} ですね。

まとめ

CTFで使うのは攻撃的なスキルですが、「どういう攻撃手段があるか」を知ることで「そういう攻撃を受けない、受けても被害を最小限にするにはどうすれば良いか」という防御的な視点を学ぶことが出来ます。

今回のCTFでの私の順位は約100人中32位と全く満足出来ない結果でしたが、全ての問題を通してとても勉強になる最高のイベントでした。足掛かりは分かったものの、そこからどうして良いか分からないという問題がいくつかあったので、そこを克服出来るように情報セキュリティの勉強を続けます。

このような素敵なイベントを開催していただいて、Security-JAWSの運営の方々、作問者の方々には非常に感謝しています。またこのような機会があれば是非参加させていただきます。

このCTFは本当に特別なイベントだと思いますが、これに似たイベントとして AWS Security Jam というAWS公式のイベントが年に数回あります。Security Jamは厳密はCTFではないですし、利用するのはCLIではなくマネジメントコンソールですが、AWSのセキュリティに興味ある方は是非参加してみてください。

本記事がどなたかのお役に立てれば幸いです。

以上、べこみんでした。