はじめに
こんにちは!オイシックス・ラ・大地(以後はORD)のSREセクションのインターンに参加しました、山岸涼です。
大学では、情報工学科に所属しておりプログラミングやコンピュータサイエンスなどを学んでいます。
課外活動では、サッカーサークルと学生プログラミングコミュニティに所属しながら大学生活を過ごしています。
これまでコミュニティや他社の就業型インターンで、チーム開発やハッカソンを経験してきました。その中で、Webサービスをどのように保守・運用していくのか興味を持ちました。インフラ周りの知識はなく、大学で少しネットワーク技術の知識を学んだ程度でAWSも触ったことがありませんが実践できる機会を経験したいと思い、応募しました。
本記事では、インターンで学んだことをまとめていきます!
インターンの概要
AWS WAFv2のマネージドルールを活用し、コーポレートサイトへの不正アクセス対策を行いました。コーポレートサイトとは、ORDの企業概要やサービスIRなどの情報を伝えるWebサイトです。
コーポレートサイト環境は、Amazon Elastic Kubernetes Service(EKS)上にWordPressを構築してWebサイトへの攻撃から保護するためにAWS WAFを活用しています。ORDで使用しているWAFは、2022年4月にWAFv1からWAFv2移行しましたが、基本的なルール設定のみを使用しておりました。
そこで本インターンでは、WAFv2でまだ活用できていない機能を検証してWebサイトへの攻撃対策を実施しました。
具体的にやったこと
インターンでは、コーポレートサイト環境を見立ててEC2、ALB、Route53、WAFv2の構成で検証しました。
- WordPress環境の構築
- WAFv2の基本設定を検証
- WAFv2のマネージドルールを検証
- レートベースのルールを検証
- Bot Controlを検証
WordPress環境の構築
インターンが始まってまず取り組んだのは、環境構築です。行った手順は次の通りです。
- Public subnetにEC2インスタンス(Amazon Linux 2, t2.micro)を作成
- EC2インスタンスへのSSH接続設定
- WordPressをインストール
- ALBを作成
- ALB経由でEC2インスタンスへのアクセス
- Route53でレコードを設定
- WordPressへブログをポスト
各環境の構築は、AWSのドキュメント*1に従って構築をしました。単にドキュメントのコマンドを入力するだけでなく、どういった設定をしているのか理解しながら作業を進めました。
作成したWordPressに対しては、ALB経由でHTTPS通信させたりRoute53へレコードを登録してアクセスできるようにしました。DNSの仕組みやロードバランサーの仕組みを理解しながら進めるのがとても勉強になりました。
このほかにも、Linuxの操作方法やEC2インスタンスにSSHするための秘密鍵・公開鍵を作成、データベースの設定、IT用語の学習などを行いました。振り返ると、ここが一番大変でした笑
WAFv2の基本設定を検証
WAFv2のマネージドルールを検証する前にまずは、簡単な設定でWAFの動作を確認するために特定のIPアドレスからのアクセス制限を行いました。
私が自宅からインターネットに接続しているグローバルIPアドレスをアクセス拒否の制限をかけるWAFv2のルールを作成しました。作成したWAFv2は、ALBと連携とさせてブラウザからアクセスしてみると403エラーと表示されアクセス制限が行えていることを確認しました!攻撃を行うユーザーのIPアドレスが分かれば、簡単に制限ができそうだと思いました。
WAFv2のマネージドルールを検証
ここからがインターンの本題です。
そもそもマネージドルールとは、あらかじめ定義されていて自動で管理されるAWS WAFのルールです。これを使うことにより、AWS上のWebアプリケーションを手軽にWAFで保護できるようになります。保護対象とするWebアプリケーションが動く仮想サーバーなどのリソースに対してWeb ACLにWAFを制御するためのルールを紐付けるという形を取ります。
コーポレートサイトで使用している環境は、前述したとおりWordPressを使用しているため、マネージドルールは次の3つを使用しました*2。
- AWS-AWSManagedRulesWordPressRuleSet:WordPressアプリケーション
- AWS-AWSManagedRulesPHPRuleSet:PHPアプリケーション
- AWS-AWSManagedRulesSQLiRuleSet:SQLデータベース
Web ACLに適用するルールグループから、「Add managed rule groups」を選択し、マネージドルールを追加しました。
これらのマネージドルールが動いているかを検証します。リクエスト時に特定の文字列が含まれていれば検知されます。それぞれの攻撃を想定したHTTPSアクセスを次に示します。
WordPressアプリケーション
curl "https://test-yamagishi.example.com/xmlrpc.php"
PHPアプリケーション
curl "https://test-yamagishi.example.com/?sample=fsockopen"
SQLデータベース
curl "https://test-yamagishi.example.com/user?type=user%27--"
実行結果は、次のように出力されマネージドルールが適用できていることを確認できました。
<html> <head><title>403 Forbidden</title></head> <body> <center><h1>403 Forbidden</h1></center> </body> </html>
AWSのマネジメントコンソールから、どういった理由でマネージドルールに引っ掛かっているかを確認し、ルール内容とAWSドキュメントの説明*3を捕捉情報として記載します。
まず、WordPressアプリケーションに対するアクセスは、WordPressExploitablePaths_URIPATH
と呼ばれるルールによってブロックされていました。
リクエストの URI パスに、脆弱性が簡単に悪用されることがわかっている xmlrpc.php などの WordPress ファイルがないかを検査します。
次にPHPアプリケーションに対するアクセスは、PHPHighRiskMethodsVariables_QUERYARGUMENTS
と呼ばれるルールによってブロックされていました。
すべてのクエリパラメータの値に、PHP スクリプトコードインジェクションの試行がないかを検査します。パターンの例には、fsockopen や $_GET スーパーグローバル変数などの関数があります。
最後にSQLデータベースに対するアクセスは、SQLi_QUERYARGUMENTS
と呼ばれるルールによってブロックされていました。
感度レベルを Low に設定した状態で組み込みの AWS WAF SQL インジェクション攻撃ルールステートメントを使用して、悪意のある SQL コードと一致するパターンがないかを確認するために、すべてのクエリパラメータの値を検査します。
AWSマネージドルールを使うことで簡単に不正アクセスの対策が行えそうだと分かりました!
レートベースのルールを検証
次にWAFv2のレートベースのルールを検証しました。レートベースのルールを設定すると、WAFv2が送信元IPアドレスのリクエスト数をカウントし、設定した閾値を超えるリクエスト数が確認された際に対象のIPアドレスを自動でブロックできます。
WAFとの連携後に、curlコマンドを実行します。 そして以下のように確認しました。
curl -I test-yamagishi.example.com/wp-admin/ HTTP/1.1 301 Moved Permanently Server: awselb/2.0 Date: Thu, 20 Oct 2022 11:52:31 GMT Content-Type: text/html Content-Length: 134 Connection: keep-alive Location: https://test-yamagishi.example.com:443/wp-admin/
次に対象のALBにApacheBench*4を使用してリクエストを400回送ります。 1回目の結果は以下となり、アクセスはブロックされませんでした。
ab -n 400 -c 1 test-yamagishi.example.com/wp-admin/ ..<省略>.. Complete requests: 400 Failed requests: 0 Non-2xx responses: 400
1回目後のすぐに、2回目のコマンド実行を行うと349回のリクエストが遮断されました。
ab -n 400 -c 1 test-yamagishi.example.com/wp-admin/ ..<省略>.. Complete requests: 400 Failed requests: 349 (Connect: 0, Receive: 0, Length: 349, Exceptions: 0) Non-2xx responses: 400
3回目は全てのアクセスがブロックされました!
ab -n 400 -c 1 test-yamagishi.example.com/wp-admin/ ..<省略>.. Complete requests: 400 Failed requests: 0 Non-2xx responses: 400
再度 curl コマンドを実行し、403エラーが返ってくることを確認しました。
curl -I test-yamagishi.sre.oisix.com/wp-admin/ HTTP/1.1 403 Forbidden Server: awselb/2.0 Date: Thu, 20 Oct 2022 12:02:28 GMT Content-Type: text/html Content-Length: 118 Connection: keep-alive
これで、何度もWebサイトへアクセスしてサーバーへ負荷をかけようとする悪意のあるユーザーの制限が出来そうです。
Bot Controlを検証
最後にWAFでBotによるアクセスを許可・拒否の制御を行う AWS WAF Bot Controlを検証しました。まずはWAFによる設定を行う前に検証で利用するBotからアクセスが可能なことを確認します。
本検証では、Botを想定してWPScan*5を活用しました。 WPScanとは、サイトのセキュリティをテストするために作成された、非営利目的の無料のブラックボックスWordPressセキュリティスキャナーです。今回は、Top 200 Most Common Password List 2021というサイトにあるパスワードを引用し、ブルートフォースアタックを試しました。
WPScanは、Docker版を使用しました。 パスワードリストファイル(pass.txt)を事前に作成し、DockerのVolumesを使って(-vコマンド)渡してあげることで使用頻度の高いパスワードから順番にログインできるかを確認します。
docker run -it --rm -v /Users/yamagishi_ryo/passwordlists:/passwordlists wpscanteam/wpscan --url https://test-yamagishi.example.com -e u --passwords /passwordlists/pass.txt
実行すると次のように出力されます。
_______________________________________________________________ __ _______ _____ \ \ / / __ \ / ____| \ \ /\ / /| |__) | (___ ___ __ _ _ __ ® \ \/ \/ / | ___/ \___ \ / __|/ _` | '_ \ \ /\ / | | ____) | (__| (_| | | | | \/ \/ |_| |_____/ \___|\__,_|_| |_| WordPress Security Scanner by the WPScan Team Version 3.8.22 Sponsored by Automattic - https://automattic.com/ @_WPScan_, @ethicalhack3r, @erwan_lr, @firefart _______________________________________________________________ [i] It seems like you have not updated the database for some time. ..<省略>.. [!] Valid Combinations Found: | Username: yamagishi_ryo, Password: XXXXXXXXXXXX
自身のパスワードがある場合、「ユーザー名とパスワード」が表示されます。パスワードが破られると同時に、ユーザー名まで知られてしまいました。
※パスワードリストファイル(pass.txt)に自身のパスワードがない場合、[i] No Valid Passwords Found.
と表示されます。
このブルートフォースアタックの対策としてBot Controlを設定します。
設定後に、再度WPScanを実行すると次のように出力されます。先程の実行結果と比べると、403エラーとなり見事ブルートフォースアタックに対してアクセス制限をする事ができました。
_______________________________________________________________ __ _______ _____ \ \ / / __ \ / ____| \ \ /\ / /| |__) | (___ ___ __ _ _ __ ® \ \/ \/ / | ___/ \___ \ / __|/ _` | '_ \ \ /\ / | | ____) | (__| (_| | | | | \/ \/ |_| |_____/ \___|\__,_|_| |_| WordPress Security Scanner by the WPScan Team Version 3.8.22 Sponsored by Automattic - https://automattic.com/ @_WPScan_, @ethicalhack3r, @erwan_lr, @firefart _______________________________________________________________ [i] It seems like you have not updated the database for some time. [?] Do you want to update now? [Y]es [N]o, default: [N]N Scan Aborted: The target is responding with a 403, this might be due to a WAF. Please re-try with --random-user-agent
検証結果より、簡単なパスワードですと容易に解読されてしまうことがわかりました。ここで行った設定の必要性が結びついたことを理解できました。
まとめ
AWS WAFv2のマネージドルールを活用して、セキュリティ対策を行いました。AWSの知識や操作、Linuxコマンドなど、様々なことを学ばせていただきました。 その中で不足しているなと感じた能力は、自己解決能力です。タスクに取り組む際に参考にするレファレンスを見つけるための検索力やエラーが発生した際、それらが意味する内容の理解力が不足していました。一人では難しいところを、メンターの井上さんにサポートをいただきながら、課題の解決に取り組むことが出来ました。 最初のタスクが完了した際のプルリクエストをマージしてもらえた時はとても嬉しかったです!
また、インド人のHiteshさんと英語で話す機会があり、ランチや2on1でお世話になりました。自分の英語力のなさを痛感したと同時に、初めて英語でコミュニケーションをとる機会を得ることができたので貴重な経験になりました。他の社員さんと英語で会話をしながら仕事をしている姿を見て自分もそうなりたいと思い、英語の勉強のモチベーションが上がりました! これからエンジニアで就職を考えている自分にとってとても素晴らしい経験をすることができたと思っております。 インターン後は、クラウドへの理解と基礎的なAWSの知識取得としてクラウドプラクティショナーの資格を取りたいと思います! 井上さんをはじめ、SREセクションの方々や他部署の社員の方にはオンラインMTGやランチ、ディナーでも話やすく面白い方ばかりで、この人たちのようなかっこいい人になりたい!と思う良いきっかけになりました! 短い間でしたが、大変お世話になりました。 本当にありがとうございました!
メンターからのコメント
山岸さんのメンターを担当しましたSREセクション井上です。 今回のインターンでは、コーポレートサイトに対するセキュリティ強化の一環でWAFv2の検証に取り組んでいただきました。
AWSやLinuxは、ほぼ初体験ということでしたがサクサクと検証を進めていただき思っていた以上の成果を出していただけました。インターン後半では、ほとんど手離れして分からない箇所を自力で調べながら進めていただきとても助かりました。検証で作成した構成は、AWSの代表的なサービスを使用しているのでまた触る機会があれば本インターンで学んだことを思い出していただけると嬉しいです!また、仕事以外にも社内Barへの参加や英語での2on1ランチなどイベントに足を運んで会社を知ろうとする姿勢がとても好印象でした。ORDの雰囲気を存分に楽しんでいただけたかと思います。また機会があればぜひ声をかけてください!
インターン先にORDのインターンを選んでいただきありがとうございました!