こんにちは!作者のActiveTKです。
今回はヌルバイト攻撃について話していこうと思います。
※情報量が少ない為、https://qiita.com/tabo_purify/items/d7a67709f54865df891e
と似た内容になっています。すみません。
1. ヌルバイトとは
ヌルバイト(ヌル文字)は、ほとんどの言語で「\0」が割り当てられています。
URLエンコードすると、「%00」になります。
C言語では文字列の終端を示すために使われます。
なので、3文字を入れるchar配列を作る際は、
char test[] = {'a', 'b', 'c', '\0'};
と宣言します。
printfという文字列を表示する関数は、最初のヌルバイトまでを表示します。
strlenという文字列の長さを取得する関数は、最初のヌルバイトまでの長さを表示します。
他にも、1文字ずつ実行する時に
for( int n = 0; test[n] != '\0'; n++ ) {
// 処理
}
と最後のヌルバイトまでを実行される事が多いです。
2. 攻撃が成立する理由
実は、PHP自体がC言語で出来ているらしく、
プログラミング言語としてのPHPは、CやPerl, Javaなどのプログラミング言語に強く影響を受けており、これらの言語に近く学習しやすい文法を有する。 組み込み関数についてもこれらの言語から直接輸入されたものも多く、関数名を変えずにそのまま取り込んだことで標準関数の命名規則が一貫していないといった問題も有している。
PHP (プログラミング言語) – Wikipedia
結論としてPHPとヌルバイトの相性が悪いみたいです。
3. 攻撃の併用
この脆弱性は、「ディレクトリ・トラバーサル攻撃」と併用されやすいです。
ディレクトリ・トラバーサル攻撃では、アップロードするファイル名に「../../hogehoge」のような文字列を設定する事により、非公開ディレクトリに書き込んだり他のファイルを上書きしたりする事が出来ます。
ですが、保存先を「./{ファイル名}.txt」などとして、強制的に拡張子を「.txt」にされている事が多いです。
こんな時に悪用されてしまうのがヌルバイト攻撃です。
ファイル名の最後にヌルバイトを付ける事で、「.txt」の部分を無視させる事が出来てしまいます。
そうすれば、自由な拡張子のファイルをアップロード出来ます。
.phpなどのファイルをアップロードされれば、system関数などでサーバーを乗っ取られ兼ねます。
4. 実際は。。
現在はかなり対策されており、成立は難しいみたいです。
ですが、PHPのバージョンを最新版にしたり、ホワイトリスト方式で不正な文字列を排除するようにしましょう。
PHP 5.3.4以降では文字列にヌルバイトが入っていると、requireやfile_get_contentsで警告が出るようになりました。
PHP 5.3.3以前だと「file.php?filename=../../大事なファイル%00」にアクセスするだけで大事なファイルの中身を見る事が出来てしまったという事です。
以下、このサイト(スターサーバー)のPHPのバージョン設定ページです。(2021/04/01時点)
非推奨ですが、未だにPHP 5.3.3以前に設定可能です。
