👏

(悪用厳禁)OSコマンドインジェクション脆弱性を検証するPHPコード

2021/04/16に公開

概要

学習用としてOSコマンドインジェクション脆弱性を実際に動かして検証してみたいと思います。
実際にコードを試す場合は必ずローカルからしか接続できない環境で実行してください。

サンプルコード(Apache+PHP)

今回の検証はWindows10にWSL2でApache+PHPの環境を作成して実行しています。

検証環境:Ubuntu 20.04.2 LTS(WSL2) + Apache 2.4.41 + PHP 7.4.3

os_cmd_injection_test.php
/**
 * 【悪用厳禁】
 * 表題:OSコマンドインジェクションテスト(PHP)
 * 説明:OSコマンドインジェクション脆弱性を検証するためのPHPプログラムです。
 * 概要:フォームからサブミットされたコマンドを受け取りOSコマンドを実行して結果を表示する。
 */

// OSコマンド実行
$exec_cmd = "";
if ( isset($_POST['exec_cmd']) ) {
  $exec_cmd = $_POST['exec_cmd'];
  ob_start();
  passthru($exec_cmd);
  $cmd_result = ob_get_contents();
  ob_end_clean();
  $cmd_result = nl2br($cmd_result);
}

// 画面表示(HTML)
$html =<<<__EOL__
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<h1>OS Command Injection Test Program</h1>
<div>---- Input Command To Submit----</div>
<div>
<form method="post">
<input type="text" name="exec_cmd"></input><br />
<input type="submit" value="submit"></input>
</form>
</div>
<br />
<div>---- Exec OS Cmd ----</div>
<div>
$exec_cmd<br />
</div>
<div>---- OS Cmd Result ----</div>
<div>
$cmd_result
</div>
</body>
</html>
__EOL__;

header("Content-type: text/html; charset=UTF-8");
echo $html;

コマンドの実行結果が全て見えるようにpassthru()関数を利用しています。
passthru()はコマンド実行結果が標準出力に書き出されるためob_start()を使って標準出力をバッファして利用しています。OSコマンドはPOSTの有無で実行させます。

実行結果サンプル

実行コマンド:apache2 -v

実行結果:submit実行後

見事にOSコマンドの実行結果を表示させる事ができました。

PHPで外部プログラムが実行可能な主な関数

PHPは外部プログラムが実行できる関数が多数用意されていますのでpassthru()以外にも注意が必要です。

exec()
 コマンド結果の最後の行を返します。
system()
 成功時はコマンド出力の最後の行を返し、失敗時は false を返します。
passthru()
 一切干渉を受けずに直接コマンドから全てのデータを受けとる。
...

※他にもPHPの外部プログラムを実行する関数は存在するため要確認のこと

OSコマンドインジェクション対策

外部コマンドが実行できる関数を利用する際は、下記のような点に注意が必要です。
※あくまで個人的な私見です。
1.外部から渡された値を実行しない構造にする。
2.外部からコマンドを渡して実行させる場合は、指定されたコマンド以外が実行されないようにする
3.さらに「;」による連続コマンド 「>」によるファイル書き出しなど特殊記号を考慮する
 「;」「>」「<」「|」「&」「`」「(」「)」「$」「*」「?」「{」「}」「[」「]」「!」など。
4.別の脆弱性により不正なファイルアップロードが行われた場合にOSコマンドインジェクションが混入する可能性があるため「改ざん検知を検討する。
5.プログラムを実行するユーザー(WEBサーバの実行ユーザー)の権限を最低限にする

まとめ

OSコマンドインジェクション脆弱性はOSレベルの操作が可能となるため非常に危険な脆弱性です。Apacheが実行されているユーザー権限で可能な事がなんでもできてしまうためSSHでログインをされている事に等しいと言えます。
またコードに脆弱性を作り込まないように注意するだけではなく、他の脆弱性により不正なファイルアップロードが行われる事によりOSコマンドインジェクション脆弱性が混入されていく事に対する対策も検討していく必要があると考えます。
脆弱性は知らないでは済まされないため仕様通りに動くコードを作るだけではなく、セキュアなコードを書くための勉強も並行する必要性を感じます。

以上、OSコマンドインジェクション脆弱性を検証するPHPコードでした。あくまで学習用として悪用厳禁にてお願いします!!

GitHubで編集を提案

Discussion