概要
以前、「LFI(ローカルファイルインクルード)」と「ディレクトリトラバーサル」の違いが分からなくなったことがあったので、その時に調べたものを共有したいと思います。
phpのソースコードを実際に見ながら、何が違うのかを見てみましょう。
本記事は教育目的で書かれています。許可を得ていない対象へのハッキングは犯罪です。
参考
ソースコードは主に以下のサイトから引用しています。
用語解説
LFI(ローカルファイルインクルード):ローカルファイルインクルードはWebアプリにおける脆弱性で、本来閲覧権限のないサーバー内のファイルを読み込んだり、実行したりすることが可能です。
ディレクトリトラバーサル:ディレクトリトラバーサルはWebアプリにおける脆弱性で、本来閲覧権限のないサーバー内のファイルを閲覧することが可能です。
LFIについて
LFIの脆弱性があるソースコードの例を見てみましょう。
<?php
$file = $_GET['file'];
if(isset($file))
{
include("pages/$file");
}
else
{
include("index.php");
}
?>
このコードは、GETリクエストの"file"パラメータにある値(ファイルのパス)を読み込むというシンプルなものです。
一番大事なのは、include()関数です。
この関数は外部ファイル(phpファイル)を読み込み、実行します。
さらに、絶対パスだけではなく相対パスも引数として渡すことが可能です。
つまり上のソースコードの例においては、このようにエクスプロイトすることが出来ます。
#通常のリクエスト
http://example.com/script?file=index.php
#LFI用のリクエスト
http://example.com/script?file=../../../../var/www/html/upload/exploit.php
include()が相対パスも受け入れ可能なので、"../../../../var/www/html/upload/exploit.php"をきちんを処理してくれます。
ちなみにLFIは、状況によってはRCE(リモートコード実行)が可能になる場合があります。少し今回のスコープから外れるので、詳しくは話しませんが是非調べてみることをお勧めします。
ディレクトリトラバーサル
ディレクトリトラバーサルの脆弱性があるソースコードの例を見てみましょう。
<?php
$file = $_GET['file'];
file_get_contents('directory/' . $file);
?>
このコードも先程と同じように、GETリクエストの"file"パラメータにある値(ファイルのパス)を読み込むというシンプルなものです。
今回一番大事なのは、file_get_contents()関数です。
この関数は、ファイルを文字列として読み込みます。相対パスも引数として渡すことが可能です。
つまり上のソースコードの例においては、このようにエクスプロイトすることが出来ます。
#通常のリクエスト
http://example.com/script?file=index.php
#ディレクトリトラバーサル用のリクエスト
http://example.com/script?file=../../../../../../etc/passwd
file_get_contents()が相対パスも受け入れ可能なので、"../../../../../../etc/passwd"をきちんを処理してくれます。
気づいた方も多いかもしれませんが、LFIとディレクトリトラバーサルは基本的に同じようにエクスプロイトします。
2つの違い
この2つの脆弱性は、ファイルを実行できるのか、それとも文字列として見ることができるだけなのかの違いです。
LFIはファイルを実行できるのに対して、ディレクトリトラバーサルは閲覧のみ可能ということです。端的に言えば、関数の違いということになります。
一般的には、LFIの方が重大な脆弱性であると考えられています。RCEに繋がる可能性がそもそもありますからね。
最後に
今回は、LFIとディレクトリトラバーサルの違いを簡単に説明しました。
この記事が皆さんのお役に立てれば嬉しいです。最後まで読んでくださってありがとうございました。
質問がある方は是非コメントしてください😃