クラウドサービスを脆弱性診断する時のお作法

「とある診断員の備忘録」というタイトルのわりに、ブログを始めてから今まで脆弱性診断に関することを一切書いていなかったことに気づいたので、そろそろ脆弱性診断ネタを書こうかと思います。 今回はクラウドプラットフォームに対する脆弱性診断の小ネタです。

クラウドサービスを診断する時のお作法って?

私が脆弱性診断をやり始めた駆け出しの頃では、オンプレ環境の診断対象が多かったのですが、最近ではクラウドプラットフォームなどの利用が当たり前となったため、クラウド環境の診断対象と沢山エンカウントします。 クラウド環境に対して脆弱性診断を実施する場合には、実はいくつか抑えておくべきお作法があります。

1. クラウド事業者側に診断事前に申請が必要な場合がある

脆弱性診断の種類にもよりますが、ブラックボックステストでは疑似的な攻撃を実施して脆弱性の有無を判定するため、不正アクセスとして検知される可能性もあります。 そのためトラブル(※)を避けるためにも脆弱性診断を実施する場合には、「事前申請は必要ない」と明記でもされていない限りは、利用しているクラウドプラットフォーム環境の管理事業者(以下 クラウド事業者)側にちゃんと事前に脆弱性診断を実施して良いか確認をする必要があります。

ちなみに過去私が経験したものですと、事前の申請時には以下のような情報をクラウド事業者側から要求されるケースなどが良くありました。

※トラブルの一例
昔々、とある診断員はシステム担当者の方に、事業者側への事前連絡を再三お願いしていたのですが、何故だか連絡がされないまま診断がスタートしました。その後、診断による通信はめでたく不正アクセスとして検知され、診断途中にアクセス元IPが念願のブラックリスト入りを果たし、全ての通信がブロックされる事案となったそうです。ちなみにその時のブロックを解除してもらう手続きには結構期間が必要とのことであり、長い間診断が中断しましたとさ。めでたしめでたし。

2. 環境によっては脆弱性診断自体を実施できない場合がある

クラウド事業者側のポリシーで、環境などによってはそもそも脆弱性診断の実施を許可していないケースがあります。 私の経験ですと共有ホスティングのような、複数顧客で同じ環境を利用しているようなサービスの場合などでは、利用している他の顧客に影響がでるかもしれないため診断実施の許可をいただけなかったケースなどがありました。 また、後述しますがAWSなどでは、診断を実施可能な環境の条件が明確に指定されています。

上記二つのお作法の内容については、事業者側のポリシーによってマチマチです。 また、ポリシー自体が変更される場合もありますので、脆弱性診断を実施する際には、ご自身の利用しているプラットフォームの事業者にちゃんと確認をした方が良いと考えます。私も脆弱性診断を実施する際には、システム担当者の方に必ず上記のご確認をお願いしています。

有名どころではどうなの?

ここら辺の情報っていちいち確認するのが大変なので、メジャーなものはどこかにまとまっていてほしいなあーって正直結構前から思っていました。 折角の機会なので、脆弱性診断士の目の前に良く診断対象として登場する三大クラウドプラットフォーム(AWSMicrosoft Azure、GCP)の脆弱性診断に関するお作法についてちょっとまとめてみました。 (なお今回記載したものは2017/6/20時点の情報となります。)

AWS(Amazon Web Services)

AWSについては以下のサイトに脆弱性診断に関するポリシーが記載されています。

侵入テスト - AWS クラウドセキュリティ | AWS

上記に記載されているようにAWSでは診断事前に専用フォームからの申請が必要です。 具体的な申請の仕方についてはクラスメソッドさんの以下の記事に詳しく記載されています。

2017年版 AWSの侵入テストについて | Developers.IO

また、診断可能な対象については以下のように明確に定義されています。

なお、AWSについては手前味噌となりますが、ここら辺について過去に私がまとめたスライドがありますので宜しければご覧ください。

www.slideshare.net

Microsoft Azure

Microsoft Azureについては以下のサイトに脆弱性診断に関するポリシーが記載されています。

Microsoft Cloud Unified Penetration Testing Rules of Engagement

以前は診断事前の申請が必要だったのですが、割と最近にポリシー変更があったようです。

MICROSOFT AZURE PENETRATION TESTING NOTIFICATION
As of June 15, 2017, Microsoft no longer requires pre-approval to conduct a penetration test against Azure resources.

と記載があり、現時点では脆弱性診断の申請は不要となったようです。

GCP(Google Cloud Platform)

GCPについては以下の「ペネトレーション テスト」の項目にさらっとですが脆弱性診断に関するポリシーが記載されています。

Security and Compliance on the Google Cloud Platform  |  Google Cloud Platform

Google Cloud Platform のセキュリティを評価するためにペネトレーション テストを行う際に、Google へ連絡する必要はありません。ただし、Google Cloud Platform の利用規定ポリシーと利用規約を遵守し、テストの影響が他のお客様のアプリケーションに及ぶことなく、お客様のプロジェクトに限定されるようにする必要があります。脆弱性を発見した際は、脆弱性報奨金プログラムまでご報告ください。

上記のような記載があるため脆弱性診断の申請は不要です。

まとめ

メジャーなクラウドプラットフォームの脆弱性診断に関するお作法についてまとめてみました。 もし記載した内容などが誤っている場合にはご指摘いただければ幸いです!

AWS使って社内CTFやってみたよ

5/22に開催された第五回Security-JAWSにて登壇させていただきました!

Security-JAWS 【第5回】2017年5月22日(月) - Security-JAWS | Doorkeeper

タイトルそのままですが、某社内でAWSを使って社内CTFを開催した際のよもやま話をネタとしてお話しいたしました。 本当は当日投影したスライドとかをそのまま公開したかったのですが、イベント当日の写真とかについてはちょっと諸事情で公開できないので、今回はセッションの中でお話ししたAWSに絡む部分だけをまとめて、私のブログで公開しようかなと思います。

当日のセッションでもお話ししましたが、まずそもそもなんで社内CTFを開催したのかについては、

  • なんか社内でエンジニアの人に楽しんでもらえるようなイベントとかをやってみたかった
  • セキュリティに興味をもってもらうきっかけ作りとかには丁度いいのかなと思った
  • ぶっちゃけちょっと運営側にも興味があった

というようなもので、最初は適当な有志で集まってやってみようかという軽いノリではじめてみた感じです。 社内でやってみたら、思ったよりもウケが良く、数回開催するうちにちょっとづつ規模が大きくなってきて、前回は70人くらいの方に参加していただけるイベントを開催できました。

現在開催しているものは、スタンダードなJeopardy形式のCTFです。 CTFを全くやったことのない方でも参加しやすいように、「CTF for ビギナーズ」のスタイルを極限まで参考にさせていただき、午前中は講義(座学+ハンズオン)、午後からみんなでCTFをやるような一日コースの集合研修という感じで開催しています。現在はそういう感じですが、今後は常設CTFにしたりとか、他競技形式でのイベント開催なども、実現できるかはわかんないですが検討していきたいですね。

で、そんな中今までは、適当な機材をつかったオンプレの競技環境で開催していたのですが、段々規模が大きくなってきてめでたく予算もついたので、競技環境をクラウド化することになり、今回AWSを使って構築してみましたという感じです。という背景で、競技環境を構築する中でハマったことや、こんな感じでやりましたということなどをここで書かせていただきますw

AWSではイベント申請が必要

Security-JAWSのセッションでもお話ししましたが、弊社内CTFの一つの特徴として、競技用のクライント環境を運営側が全部用意しているという点があります。 これはまあ社内イベントならではの悩みなのかなと思うのですが、簡単に言えば社内だと諸事情によって競技用の端末を用意できない方とかもいらっしゃるので、そういう方でも気軽に参加していただくための運営側の配慮って感じですね。ちなみに「いやいや、俺は自前の環境でやりたいし」って方も勿論沢山いらっしゃるので、ご自分で用意できる方については持ち込みPCの利用もOKにしています。

で、まあイベント開催前に運営側で毎回このクライアントPCのキッティングをやっているんですけど、これがまあダルいし、結構大変なんですよね。という中、AWSにはAmazon WorkSpacesというDaaSがあります。

Amazon WorkSpaces (クラウド上の仮想デスクトップサービス) | AWS

これを見て「おお!クライント環境の用意はこれ使えば楽できるんじゃね!」ってそんな風に考えていた時期が俺にもありました。 結論から申しますと、実はその計画はとある理由によってお蔵入りとなってしまいますw

話は変わりますが、皆さんはAWSを使ってこういうイベントを開催する場合には専用の申請が必要だということをご存知でしょうか? 脆弱性診断を実施する際に申請する必要があるペネトレーションテスト申請は結構ご存知だと思うのですが、その解説ページに、「シミュレートされたその他のイベント」という項目の記載があります。

侵入テスト - AWS クラウドセキュリティ | AWS

上記には、どうやらこういったイベントをやるには、開催するイベントの内容などを事前にAWSに申請して許可をとらなければいけないルールがあることが記載されています。 私もAWSを利用して今回こういうイベントをやることになって初めてこのルールを知りました。

ペネトレーションテストの申請をされたことがある方は結構いらっしゃるのかなと思いますが、このセキュリティイベントに関する申請をされた方とかはあんまり多くいらっしゃらないのかなと思いましたので、ご参考までに今回どんな感じでやり取りをしたかについて簡単に書いてみました(まあ、そもそもこういったイベントを開催する人が、そこまで沢山いないだろというツッコミは置いておいてくださいw)。

まずはこんな感じで問い合わせをしてみたのですが…

f:id:tigerszk:20170526132431j:plain

ええー!?マジで!?WorkSpaces使えないの!?いきなり予想してなかった回答ををいただいたので、ちょっとビックリしました…。あとやり取りは英語じゃないとNGなようです。ちなみにAWS側から提出を要求された情報については以下のようなものでした。

原文そのまま 自分の理解
Account number(s): AWSのアカウント情報
Source IP(s) if applicable: イベント時にAWS環境に接続するアクセス元IP情報
Target IP(s) if applicable: イベント時に接続するAWS環境サーバのIP情報
Start Date: イベント開始日
End Date: イベント終了日
Regions involved in Event: イベントに関係するAWSリージョン
EC2 or RDS Instances involved, if applicable: イベントに関係するEC2またはRDSインスタンスの情報
Are you an Amazon Enterprise Customer?: Amazonの企業顧客かどうか
Software Used (if commercial): 使用するソフトウェア(商用の場合)
AWS products/Services to be used): 使用するAWS製品/サービス
Type of Simulated Event in detail: イベント内容の詳細
Dependent on the Simulated Event type, please confirm if target will be aware of the event?: イベント内容に応じて、対象(対象者?)がそのイベントを把握しているか確認してください。(※1)
Whom (email address) should the target party contact to verify this is indeed a Simulated Event?: これが本当にシミュレートされたイベントであるか確認するための連絡先情報
Please provide target domain name, if applicable: 対象ドメイン情報
Will your Event require AWS interaction? If so, please let us know in what capacity and why?: イベントでAWSとのやりとりが必要?もしそうならどんなことかと理由をお知らせください。

※1 こちらについてはイマイチ内容がわからなかったので内容について質問したのですが、特にAWS側からの回答はなく申請の許可がおりました。

ペネトレーションテスト申請と同じくらい結構色々情報を要求される感じでした。また、上記の内容については結構イベントの内容とか環境設計ができてる段階じゃないと、なかなか答えづらいんじゃないかなという印象を持ちました。ちょっとでもこの申請をされる方のご参考になれば幸いです。もしかしたら、イベント内容によっては設問が変わったりするのかもしれないですし、今後新しい設問が追加される可能性もあるので、これと全く同様というわけではない可能性はあります。

この回答に対して「ハイ喜んで~」と返信してしまうとまた地獄のクライアントPCキッティング大作戦が確定してしまうのがちょっと嫌だったのと、もしかしたら先方が何か勘違いしているのかもしれないし、ワンチャンあるかなと思ってちょっと食い下がってみたのですが…

f:id:tigerszk:20170526151332j:plain

f:id:tigerszk:20170526151350j:plain

というわけで、結局今回はWorkSpacesを使うことができませんでしたw 申請自体については、この後、設問に該当する情報を送ったら、次の日にあっさり許可がおりました。 もっと長い時間がかかるものなのかなと思ったのですが、思ったよりも早かったです。

結局どんな環境を構築したの?

上記のような理由により、今回WorkSpacesを使えなかったので、最終的には以下のようなシンプルな構成になっちゃいました。

f:id:tigerszk:20170526161618j:plain

社内イベントだし、そこまで大量アクセスが来ないだろうと想定し、問題サーバだけをELBを利用して冗長構成にした感じですね。今回やってみたかった取り組みの一つだったのですが、サーバで動作する問題については全部dockerを利用して作成しました。切っ掛けは以下の記事だったりします。

#cmdevio2016 (レポート: B-2) Trend Microのセキュリティコンテストの裏舞台でDockerとAnsibleを使った話 | Developers.IO

以前この記事を拝見して、「おー面白そう!自分もちょっとやってみたい!」と思っていたのと、検証目的でちょこちょこ触ってはいたのですが、サービス提供するようなシステムをdockerで構築した経験が無かったので、丁度良い機会だから今回勉強がてらやってみました。 ※ちなみに元記事の発表をされたトレンドマイクロの岩田さんより、今回の発表の後に、ご挨拶いただきめっちゃ嬉しかったです!ありがとうございました。

AWSであれば、ECR(Amazon EC2 Container Registry)を利用することで、速攻でプライベートレジストリ使ってdockerイメージを管理できるので非常に楽ちんです。 今回やってみた感想としては、docker使うとやっぱり本番へのデプロイがすごい楽だなという印象を持ちました。ローカルの開発環境で開発して、イメージが出来上がったらすぐに本番で稼働させられるのは魅力ですね。

今回作成したコンテナのタイプ的には大きく分けて以下の二種類に分かれます。

今回は全部で13個の問題コンテナを作成して、本番環境で動作させました。ちなみにdockerの管理にはECS(Amazon EC2 Container Service)を使ってみたかったのですが、諸事情によりというか単純に検証の時間が足りなくて断念し、本番時はローカル環境で動かしていたdocker-composeを利用して動作するコンテナを管理しました。

監視には折角AWS使っているので、CloudWatchを利用しようかなとも検討したのですが、やっぱり時間が無くて今回は多少慣れていたZabbixを採用しました。 今回はコンテナの監視もしてみようかなと思い、試験的ですが以下のzabbix-docker-monitoringを利用してDockerコンテナの監視もしてみました。

GitHub - monitoringartist/zabbix-docker-monitoring: Docker/Kubernetes/Mesos/Marathon/Chronos/LXC/LXD/Swarm container monitoring - Docker image, Zabbix template and C module

後は、各問題サーバのポート稼働状況やWebサービスについてはステータスコードの状況を監視したりっていう感じですね。競技中はslackにアラート通知を流すようにして、なんか問題があれば、問題があるdockerコンテナをイメージから再作成するような運用にしていました。ちなみに本番時は想定よりも問題サーバは全然安定稼働していて、特に障害対応することもなかったので一安心でした。

今回構築した環境では、時間的にできなかったことや、色々改善点もあるなあと思っているので、今後またちょこちょこいじっていこうかなと思っています。

ぶっちゃけ費用はおいくら?

Security-JAWSでも発表しましたが、AWSの利用料はこのぐらいでした。

f:id:tigerszk:20170526173139j:plain

WorkSpaces以外にも色々と検証したので、ただ開催するだけであればもっと安く上がるんじゃないかなと思います。

まとめ

というわけで、今回私がAWSを利用して社内CTFをやってみた所感をツラツラ書いてみました。もしAWSを使ってなにかこういうイベントをやろうと思っている方の参考に少しでもなれば幸いです。 開催したイベントも参加者の方には楽しんでいただけたみたいなので満足しています。まあただ、自分達でイベント運営やってみた感想としては、環境構築を通じて色々新しいことを勉強できたりするので個人的には非常に楽しかったりするのですが、楽しい以上にやはりそれなりに色々準備が大変だったので、運営側の方々の苦労を身をもって痛感しました。今後参加者としてITイベントに参加する時は、運営の方々にはより一層の敬意を払うべきだなと思った次第ですw

脆弱なWAF達で遊んでみた

最近、二つの脆弱なWAFが公開されました!

Vurp - Vulnerable Reverse Proxy: https://github.com/hasegawayosuke/vurp
ViddlerProxy: https://int21h.jp/tools/ViddlerProxy/

今回は巷(ごく一部かな?w)で話題のこの脆弱なWAF達で遊んでみたら非常に面白かったので、このブログでちょっとご紹介したいと思います。

脆弱なWAFとは?

そもそも、「脆弱なWAF」とは一体なんなのでしょうか?一般的なWAF(Web Application Firewall)は、Webサイトの脆弱性を悪用した攻撃から、Webサイトを保護するためのセキュリティ対策の一つです。 通常は守りたいWebサイトの通信経路上の前面に配置するような構成をとります。例えWebサイトに脆弱性が存在したとしても、前面のWAFにて攻撃をブロックできれば、Webサイトは攻撃を受けないため、導入することでセキュリティレベルの向上が期待できるわけです。

しかしながら、はせがわようすけさんが考案した脆弱なWAFについては上記とは全く真逆のコンセプトのもので、このWAFを経由してアクセスすることで、安全な作りのWebサイトであっても、脆弱なWebサイトに早変わりしてしまうというものになります。この時点で個人的には超面白い発想だなあと思いましたw ではこの脆弱なWAFを使うと、実際どんなことになるのか見てみましょう。

対象のWebサイトとして分かりやすいように適当なWordPressのサイトを用意してみました。

f:id:tigerszk:20170408150331j:plain:w700

適当なWordPressサイト

このWordpressの検索フォームに「"><script>alert("XSS")</script>」のようなスクリプトタグを入力した場合には、遷移後の画面ではXSSの対策のため入力値がHTMLエスケープされた状態にて出力されます。そのため当然スクリプトは動作しません。

f:id:tigerszk:20170408150721j:plain:w700

スクリプトタグを挿入した結果(そのままアクセスした場合)

f:id:tigerszk:20170408150727j:plain:w700

結果のソース(そのままアクセスした場合)

では、脆弱なWAFを経由した状態で、このサイトに同様の入力値を送信した場合にはどうなるでしょうか。

f:id:tigerszk:20170408151109j:plain:w700

スクリプトタグを挿入した結果(脆弱なWAFを経由した場合)

f:id:tigerszk:20170408151512j:plain:w700

結果のソース(脆弱なWAFを経由した場合)

なんと、先ほどは何も起こらなかったWebサイトにて、XSS脆弱性が発現し、alertが上がっています。 ソースを見ると先ほどはHTMLエスケープされていたはずの値が、入力されたスクリプトタグの値をそのまま出力されている状態になっていることが確認できます。

もうお分かりですよね?途中に挟まっている脆弱なWAFが、HTMLエスケープした値をわざわざHTMLエスケープ前の状態に変換してユーザ側に返しているのです。 これによって本来はちゃんとXSS対策されているサイトにもかかわらず、このWAFを経由することで、バンバンXSSが発現してしまう状態になってしまうわけです。

このように入力した値に応じて、いかにも脆弱性が存在するような挙動を返すことで、本来は安全なWebサイトなのにもかかわらず、ユーザからは脆弱性が存在するサイトに見えさせてしまうものが脆弱なWAFなわけです。 面白いですよね!

Vurpをためしてみた

ということで、はせがわようすけさんが公開されたVurpを早速試してみました。

VurpはNode.jsにて作成されているプログラムで、リバースプロキシとして動作をします。 実行にはNode.jsの実行環境といくつかモジュールのインストールが必要なようです。

CentOS 7では以下の手順で実行できました。

sudo yum install epel-release
sudo yum install nodejs npm
sudo npm install connect
sudo npm install http-proxy
sudo npm install set-cookie-parser
sudo npm install cookie
sudo npm install replacestream
sudo npm install commander
git clone https://github.com/hasegawayosuke/vurp
cd vurp/src/
sudo node main.js

readmeに詳しく記載されていますが、基本的には「config.js」というコンフィグファイルを編集して、Vurpを起動しているホストのURL、対象とするWebサイトのURL、脆弱性を発現する箇所の情報(URLやパラメータなど)を指定してあげる必要があります。
https://github.com/hasegawayosuke/vurp/blob/master/readme.md

コンフィグ設定後に指定したVurpを起動しているホストのURLにアクセスすれば利用できます。

現時点では以下の脆弱性に対応しているようです。

  • セキュリティのためのヘッダの削除
  • 任意ページへのクロスサイトスクリプティングの埋め込み
  • 推測可能なセッションIDへの振り替え
  • OSコマンドインジェクション

先ほどのようにパラメータを指定することで様々な箇所でXSSを実行できるのが面白いです。 XSS以外にも、OSコマンドインジェクションに対応されていたのに興味を持って、色々試していたのですが、入力したOSコマンドがVurpが動作しているホスト上で実行されるというものでした。 試している中で、「|sleep 10」とかを入力した場合でも速攻でレスポンスが返ってきたため、一瞬「アレ?」となったのですが、現時点ですと、挿入したOSコマンドの処理結果を含まずに、そのまますぐに対象サイトのレスポンスを返す仕様のようです。WAF側のプロセスを確認したらちゃんと挿入したOSコマンドは実行されていました。連続アクセスしたので沢山sleepコマンドが実行されていますw

f:id:tigerszk:20170408152446j:plain

Vurpが動作するホスト側でsleepコマンドが実行されている

ViddlerProxyをためしてみた

つづいてVurpにインスパイアされて、山崎圭吾さんが公開した「ViddlerProxy」も試してみました。 こちらについてはWindowsバイナリを配布されており、実行には.NET Framework 4.5が必要とのことです。 Vurpと同様にリバースプロキシとして動作をするようです。

現時点で、対応している脆弱性項目は以下のようです。

  • Cross Site Scripting (parameters, 501 error page, 404 error page)
  • SQL Injection (string, numeric)
  • OS Command Injection (with cmd.exe, with busybox-w32)
  • Path Traversal / Directory Traversal
  • Cross-Site Request Forgery (CSRF)
  • Use of Insufficiently Random Values (Simplify SessionId Cookie Values)
  • Cookie without HttpOnly Attribute
  • Cookie in HTTPS Session without Secure Attribute
  • HTTP TRACE/TRACK Method Enabled
  • HTTP PUT/DELETE Method Enabled
  • Clickjacking (X-Frame-Options Header Missing)
  • X-Content-Type-Options Header Missing
  • Strict-Transport-Security Header Missing
  • Information Exposure Through Directory Listing

こちらはVurpの脆弱性項目に追加して、さらにいくつか脆弱性項目に対応されているようですね。 そしてこのProxyはHTTPS通信にも対応しています。

ダウンロードしてきたzipファイルを解凍後にViddlerProxy.exeを実行すると以下のようなGUIが立ち上がります。

f:id:tigerszk:20170408175935j:plain

起動したViddlerProxy

後は、Parent Serverに対象とするWebサイトのURLとポート番号を入力してListensボタンを押すだけです。 hostsも自動的に書き換えてくれるらしく「http://viddler-vulnerable.example.jp」に自動的に遷移します。 非常にお手軽ですね!

脆弱性のパラメータなどに関する設定は「settings」タブで指定するようです。

このViddlerProxyはSQLインジェクションに対応しており、入力するSQL構文の内容による応答差分なども再現してくれています。 例えば以下のようなパラメータ値を送信すると以下のような応答結果になりました。

name=test' ⇒ 500 error
name=test' and ‘a’=‘a(構文が真となる場合) ⇒ 正常応答
name=test’ and ‘a’=‘b(構文が偽となる場合)⇒ ボディが空の200応答

パラメータ値の型(文字列型、数値型)も指定できるようです。

ディレクトリトラバーサルではフォルダの中に配置されている、「root」のディレクトリ以下のファイルを表示させる仕組みになっているみたいですね。Windows環境においても適切なファイルパスを渡せば「/etc/passwd」を表示させることも可能となっています。

OSコマンドインジェクションはViddlerProxyを実行しているWindowsホスト側でコマンドが実行され、コマンド実行結果もレスポンスに反映されるようですね。また、busyboxを利用することでWindows環境にて、Linuxコマンドも実行できるようにされているようです。以下のような感じでコマンドを実行できました。

cmd.exe経由の場合: oscmd=“;netstat -n;”
busybox経由の場合: oscmd=‘;uname -a;’

その他にも、強制的にPUT/DELETEメソッドを有効化させて、実際に使えてファイルを置いたり消したりすることなどができましたし、/icons/フォルダを指定するれば中身がちゃんと表示されるようになっていたり、色々な仕掛けが面白かったですw

まとめ

脆弱なWAF達と戯れて面白かったですw

脆弱性が存在するサイトを自分で実装とか構築することも色々勉強になると思いますが、とりあえずまずお手軽にWebアプリの脆弱性を体験するのであれば、非常にもってこいなツールなのではないでしょうか。あとは、脆弱性によってはHTTPヘッダインジェクションみたいにフレームワークミドルウェア側で対策されているため、脆弱性を作りこむのがちょっと面倒くさいものとかもあったりしますので、そういうのを再現する場合にはこのような形式の方が、お手軽なのかもしれないですね。また、疑似的に脆弱性を再現しているので、ハニーポットなどにも使えるのではないかなという印象を持ちました。

今後の機能追加などが楽しみです!

Apache Struts2の脆弱性(CVE-2017-5638)を検証してみた

Blogでもやろうかなと思いつつ、やるやる詐欺になっていたし、たまたま朝早く目が覚めたので思い切って始めることにしました。このBlogでは私が趣味でチョコチョコやっている脆弱性やスキャナの検証などについて書いていこうと思います。

さて、話題となっている以下Struts2脆弱性を昨日検証しました。

S2-045 - Apache Struts 2 Documentation - Apache Software Foundation

上記に記載がありますが、リモートから任意のコマンドが実行可能な脆弱性であり、影響範囲は Struts 2.3.5 - 2.3.31及び2.5 - 2.5.10だそうです。
また、既に複数サイトにてPoCが公開されているようです。

Struts脆弱性については定期的にみつかっているので、以前に試した検証用の環境などをすでにお持ちの方も多いと思われますが、dockerを利用すれば簡単に作成できます。
以下の記事にてdockerを利用したStruts2の検証環境の構築方法を解説されていますので、非常に参考になると思います。

Dockerを使って、Apache Struts2の脆弱性S2-037のやられ環境を手軽に作る - DARK MATTER

今回私もdocker環境を用いて検証してみました。

https://dist.apache.org/repos/dist/release/struts/2.3.31/

上記サイトよりstruts-2.3.31-apps.zipをダウンロードして以下のようなDokcerfileを作成しました。

FROM tomcat:7.0-jre8
ADD struts-2.3.31/apps/struts2-blank.war /usr/local/tomcat/webapps/
CMD ["catalina.sh", "run"]

docker環境でビルドして実行すればサクッと検証環境は出来上がります。

f:id:tigerszk:20170308062627j:plain

後はPoCを検証するだけの簡単なお仕事です。

以下では分かりやすくBurp Suiteを利用して攻撃のHTTPリクエストを送信しています。
PoCの中身を見ればすぐにわかりますが、内容としてはContent-Typeヘッダに細工したOGNLを指定してブン投げてるだけの非常にシンプルなものです。
あまりにもあっさり刺さったので、検証していてビックリしました。

攻撃が成功し、リモートからOSコマンドが実行されて、/etc/passwdの内容がレスポンス中に出力されています。

f:id:tigerszk:20170308061125j:plain
ちなみに本脆弱性が修正されているStruts 2.3.32 と 2.5.10.1はもう既にリリースされているようです。
https://dist.apache.org/repos/dist/release/struts/

同じくdocker環境を利用して修正版についても検証してみましたが、最新版の環境ではPoCの攻撃が刺さらないことを確認しました。Dokcerfile書き換えるだけなのでこういう時にもお手軽ですね。

後は、Struts脆弱性で大体話題になるのは1系への影響ですが、今回の脆弱性はOGNLを利用しているので、OGNLをサポートしていないStruts 1系には影響がないんじゃないかと推測しています。

そして、案の定早速攻撃が観測されているようですので、早急にアップデートなどの対策をされた方がよいでしょう。

Strutsは相変わらず定期的にポンポン割と影響度の高い脆弱性が報告されるので、サービスで利用されている場合はWAFなどを導入したほうが費用対効果的にも良い気がしますね。運用されている方もその方が多少気が楽になるのではないかなと思いました。

またこの記事を書いている途中に気づいたのですが、すでにpiyokangoさんが本件の詳細をまとめてくださってますね。

Struts2の脆弱性 CVE-2017-5638 (S2-045)についてまとめてみた - piyolog