シェルインジェクションについて話す

シェルインジェクションとは

シェルインジェクションはOSコマンドインジェクションとも呼ばれ、プログラムの脆弱性を利用して一連の悪意のある命令を作成し、標的プログラムに攻撃者のコマンドを実行させることを指します。シェルインジェクションはUnixシェルから名付けられていますが、プログラムがコマンドラインインターフェイスを呼び出すことを許可するシステムで実行されているほとんどのプログラムは、シェルインジェクション関連の脆弱性を誤って導入する可能性があります。シェルインジェクションの潜在的なリスクがあるインターフェイスには、Javajava.lang.Runtime.exec()および.NETのインターフェイスが含まれますSystem.Diagnostics.Process.Start()

SQLインジェクションなどの脆弱性と比較して、シェルインジェクションについて言及されることはめったにありませんが、プログラム外のリソースに直接接続できるため、通常、より深刻な影響があります。

この記事は、友人が書いたデモプログラムでシェルインジェクションの脆弱性が発見されたために書かれたものなので、最初は例としてプログラムを書き直しました。次のJavaコードでは、フロントエンドがDockerイメージ名をバックエンドサーバーに渡し、バックエンドサーバーがdocker pullコマンドを呼び出して対応するイメージファイルをプルします。

String imageName = (String) params.get("imageName");
String cmd = "docker pull " + imageName;
Process process = Runtime.getRuntime().exec(cmd);
// ...

フロントエンドから渡されるimageNameパラメータ値通常のイメージ名(たとえばnginx)の場合、docker pull nginxコマンドが実行されてnginxイメージがプルれます。また、フロントエンドから渡されたimageNameパラメータ値nginx; echo hacked、つまり悪意のある命令があるecho hacked場合、バックエンドプログラムはdocker pull nginx正常に実行されecho hacked後にコマンドを実行します。利便性を実証し、誤操作を回避するために、echoここでは直感的で無害なコマンドを使用しています。このコマンドをターミナルで直接実行した結果は次のとおりです。

# 示例中省略了执行结果与本文无关的一些输出信息
$ docker pull nginx; echo hacked
Status: Downloaded newer image for nginx:latest
docker.io/library/nginx:latest
hacked # <- 此处为执行恶意命令的结果

次に、DVWAのPHPプログラムを使用したシェルインジェクションのさまざまな方法を紹介します。

シェル注入法

以下は、クライアントからのパラメーターipをpingコマンドのパラメーターとして受け取り、操作の結果を出力するPHPプログラムです。

$target = $_REQUEST['ip'];
$cmd = shell_exec('ping -c 4 ' . $target);

echo "<pre>{
      
      $cmd}</pre>";

このセクションでは、上記の手順を通じていくつかのシェル注入方法を紹介します。例では、デモンストレーションとして直感的で無害な結果が得られるコマンドを使用します。

  • ; 継続指導

連続コマンドを使用する場合command1; command2command1コマンドが実行された後もcommand2コマンドは実行され続けます。例では、パラメータがユーザーによって入力される127.0.0.1; echo hackedと、プログラムは最初のping -c 4 127.0.0.1コマンドで実行され、実行はecho hackedコマンドを完了するために続行されます。ターミナルで実行されているこのコマンドの出力は次のとおりです。

$ ping -c 4 127.0.0.1; echo hacked
PING 127.0.0.1 (127.0.0.1): 56 data bytes
# ... ping的执行结果
4 packets transmitted, 4 packets received, 0.0% packet loss
hacked # <- echo hacked的执行结果
  • パイプライン |

command1 | command2パイプを使用することによりcommand1command2入力後の出力として実行を完了ます。たとえば、パラメータを入力する127.0.0.1 | grep lossと、プログラムはping -c 4 127.0.0.1コマンドをgrep loss入力コマンドとして出力しますこのコマンドgrep lossは、pingコマンドの出力で損失のある行を出力します。次に例を示します。

$ ping -c 4 127.0.0.1 | grep loss
4 packets transmitted, 4 packets received, 0.0% packet loss
  • & バックグラウンド実行

&コマンドの後に使用すると、コマンドがバックグラウンドで実行されます。ときに&他のコマンドが続いている(command1 & command2)、彼らはバックグラウンドで実行されるcommand1と、フォアグラウンドでcommand2たとえば、コマンドping -c 4 127.0.0.1 & echo hackedはバックグラウンドping -c 4 127.0.0.1で実行され、echo hackedコマンドを実行します。通常、このコマンドの結果は次のとおりです。

$ ping -c 4 127.0.0.1 & echo hacked
[1] 2333 # <- ping命令的进程号
hacked # <- echo hacked的执行结果
PING 127.0.0.1 (127.0.0.1): 56 data bytes
# ... ping的执行结果

注:pingコマンドにはネットワークI / Oが含まれるため、出力はコマンドの実行後ではechoなくpingコマンドのecho後になります。

  • &&||

&&そして、||類似し、使用の両方command1 && command2またはcommand1 || command22つの違いは&& command2、中間は実行が成功した後にcommand2のみcommand1実行され(終了コードは0)、|| command2中間は実行が失敗したcommand2後にのみcommand1実行される(終了コードはゼロ以外の値)ことです。

  • `command`$(command)

どちらのタイプのアクションもcommandコマンドを実行します。コマンドがcommand1 $(command2)時刻(command1 `command2`同じトークン)の場合command2command1パラメーターとして出力されます。ユーザー入力パラメータなどは$(echo hacked)pingのプログラム実行で最初echo hackedにコマンドを実行します。

いくつかのシェル噴射における上記方法に加えて、例えばリダイレクション(>、、 、なども、攻撃者によって使用されてもよいです。>><<<

シェル注入防御策

  • ユーザーが入力したコマンドを直接実行しないでください

プログラムでは、コマンドラインインターフェイスを介してコマンドを実行しないようにするか、ユーザーが入力したデータをシェルコマンドのパラメーターとして直接使用しないようにする必要があります。記事の冒頭にあるDockerコマンドと同様に、docker pullコマンドを直接使用する代わりに、Dockerが提供するAPIインターフェースを使用して対応するイメージをプルできます

  • ユーザーが入力したパラメーターを確認します

上記の例のpingプログラムのように、必要なパラメーターがIPv4アドレスであると仮定すると、パラメーターの形式を正規化によってチェックして、有効なIPv4アドレス文字列であるかどうかを確認できます。

$target = $_REQUEST['ip'];
if (!preg_match('/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/', $target)) {
    
    
  throw new Exception('Invalid ip');
}

$cmd = shell_exec('ping  -c 4 ' . $target);

echo "<pre>{
      
      $cmd}</pre>";
  • 一般的なシンボルをフィルタリングする

上記フィルタ含み|&;所望のパラメータは、特定のシンボルを含む場合、他の記号を、記号をエスケープすることができます。たとえば、echo hacked \&コマンドはバックグラウンドで実行されず、出力結果はhacked &です。

  • ブラックリストとホワイトリストのメカニズムを使用する

コマンドで許可されるパラメーターを制限するために、白黒リストを作成します。

  • 言語が提供するトランスコーディング方法を使用する

一部の言語は、phpのようなシェルパラメータをトランスコードするためのメソッドを提供しますが、escapeshellarg()安全であると完全に信頼することはできません。

  • 最小特権ユーザーを使用してプログラムを実行する

たとえば、Webアプリケーションでは、最低限必要な権限を持つユーザーがアプリケーションの実行に使用されます。この手段は実際の防御手段ではありません。攻撃された後の大きな影響を回避することを目的としており、シェルインジェクションの処理に使用されることに限定されません。

参照

おすすめ

転載: blog.csdn.net/ghosind/article/details/106198393