最近 CTF に興味を持ちまして、その取っ掛かりとして今回タイトルに記載した本を購入しました。CTF って何って方は以下の URL から CTF の概要が確認できますので、ぜひご参照ください。
CTF(Capture The Flag)とは?概要から基本ルール、メリットデメリットまで徹底解説
今回は現在の職であるアプリケーションエンジニアと近しい「Web 問題」から読みました。各章ごとに学んだことと、感想について書きます。
○ Web 問題とは
Web 問題とは、ブラックボックス、すなわちソースコードが参照できない状態でユーザーが入力を与え、そこから得られた出力をもとに脆弱性を探し、FLAGを獲得する問題のことです。Web アプリケーションの構成を知ることが FLAG 獲得への1歩となります。Webサーバーには Apache や nginx が使われているのか、言語は PHP や Perl が使われているのか、DBMS には SQL Server や Mongo DB が使われているのかなどを知ることで、攻撃の手法を効率的に絞り込みます。パスの末尾や HTTP ヘッダの情報(サーバーのバージョン情報など)、エラーメッセージ、Web フレームワーク固有のページへの強制リダイレクト、画面上には出ない hidden 要素やコメントの部分が参考になるそうです。調査ツールとして Burp や Fiddler が挙げられていました。他にもヒントがありそうな個所として、ブラウザから閲覧されることを想定していない robots.txt や /admin、.git などがねらいとのことで、このような情報を集めるための、Nikto と呼ばれるツールがあるそうです。何らかの方法で、データベースファイルを入手することができたら、SQL インジェクションをせずとも、SQLite を使用して、データベースの中身を参照することができます。
○ 任意コード実行系の脆弱性について
任意実行系とは、ShellShock や OS コマンドインジェクションを利用して、任意のコードを実行できるようにする、または、シェルを奪った上で解く問題のことです。シェルを奪えば Web 問題はほぼ終わったようなもので、ファイルアップロードの容量に制限がかかっている場合でも、nc 等のコマンドを利用し、バックドアを作成すれば制限を超えた容量を持つファイルをアップロードすることが可能になります。シェルを奪った後は、基本的にフィルタを回避して FLAG を探すコードを実行するだけです。フィルタ回避の方針としては、ステートメントにエンコード・デコードを利用して、適切な命令を送ったり、既に存在するファイルに対して、URLを直接指定したりするなど、様々なアプローチがあるとのことです。
○ 各種脆弱性の利用
各種脆弱性の詳細について記載されていました。
OSコマンドインジェクション : ユーザーの入力をそのまま OS コマンドとして発行してしまう脆弱性で、ネットワーク関連 ( ping や tracert ) のコマンドや sendmail コマンド、Perl の Open コマンドを使用していそうなところで利用できることがあるそうです。DB に OS 系のコマンドが格納されていて、それを読みだして実行するなど、一捻りされた問題が多いようです。
Perl の open コマンド : ファイルの読み書き等のモードが指定されていないかつ、先頭か末尾に|が付いている場合はコマンドを実行するという仕様があるそうです。先頭に|が付いている場合は、ファイルハンドルからの出力をコマンドに渡し、末尾に|が付いている場合は、コマンドからの出力をファイルハンドルに渡します。そのため、 末尾に|を付け、ls コマンドを実行した場合、ファイルの一覧を表示することができてしまいます。
PHP の require 関数 : PHP の require 関数 には URL を直接読み込ませることができるため、スクリプトを格納した URL を読み込ませ、実行させることができてしまうそうです。
アップローダーの制限 : ファイルヘッダを見て、ファイルの制限をかけている場合は、ファイルヘッダのバイナリを変更し、png 形式などに見せかけることで制限を回避できるそうです。
ファイルの権限 : アップローダーからファイルをアップロードし、アップロードファイルの実行権限に制限がかかっていない場合は、そのファイルのパスをそのまま URL などで指定することで、実行できる可能性があります。そのため、FLAG を検索するスクリプトをアップロードし、実行することで問題をクリアできるかもしれません。
また、脆弱性の種類ではありませんが、インジェクションが成功していても何も表示されない場合や、エラーすら出ない場合のアプローチとして Web サーバー側で使われていそうな nc コマンドや ping コマンドを利用し、自分宛てに通信させる方法、sleep コマンドを利用して処理の時間差で確かめる方法を紹介していました。
○ シェルを取った後の手法
シェルを取った後でもインジェクションできる文字数が制限されている場合や、権限の問題で FLAG が記載されているファイルを参照できない可能性があり、その場合は、別のアプローチが必要です。
FLAG がありそうな場所を探してみる
FLAG が置かれていそうな以下の場所探してみましょう。
・ルートディレクトリ
・var/www/
・var/log/
・home/ 以下の読めるディレクトリ
・Web アプリケーションのソースコード (コメントアウトされている、または、使用されていない変数に格納されていることがあるとのこと)
権限で参照できない場合
自分の権限を確認して、自分の権限レベルで実行できることをリストアップし、その中からできることを順次実行していきましょう。sudo や cron を確認したり、欲しい権限で動いているプロセスを確認したり、setuid が付いている実行ファイルを確認することも有用です。または、チームで挑んでいて、バイナリ解析が得意な人がいれば、その人に頼るのもありとのことです。
○ まとめ
主に Web 問題についての概要と、解き方のアプローチ、各種脆弱性について説明している印象を受けました。初心者である私としては、言葉だけではイメージしにくいところもあるので、例題などを少し交えながらの説明が欲しいところでした。そのため、初心者にはあまり向いていないかもしれません。ただ、実践的な解き方については述べられていたので、実際に問題を解く際に見るべき点などは学べたと思います。
次回は学んだアプローチ手法を活かして、実際に問題集の Web 問題に挑戦してみたいと思います。