質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
OS

OS(オペレーティングシステム)は、システムソフトウェアの一種であり、一般的に、ハードウェアを直接的に管理・操作する最も中心的な機能を有するソフトウェアがオペレーティングシステムとして呼ばれます。

セキュリティー

このタグは、コンピューターシステムの安全性やデータの機密性に関連したトピックの為に使われます。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

シェル

シェル(shell)はUnix や Linux 系のOSで使用されるコマンドインタプリタを指します。

Q&A

解決済

2回答

4716閲覧

【PHP】シェル経由について教えてください

退会済みユーザー

退会済みユーザー

総合スコア0

OS

OS(オペレーティングシステム)は、システムソフトウェアの一種であり、一般的に、ハードウェアを直接的に管理・操作する最も中心的な機能を有するソフトウェアがオペレーティングシステムとして呼ばれます。

セキュリティー

このタグは、コンピューターシステムの安全性やデータの機密性に関連したトピックの為に使われます。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

シェル

シェル(shell)はUnix や Linux 系のOSで使用されるコマンドインタプリタを指します。

0グッド

0クリップ

投稿2016/05/02 07:59

PHPとシェルについて教えてください。

最近、OSコマンドインジェクションによる情報漏えいが多発しているので、理解しようと思い、調べております。
シェルやPHPについて知識が乏しい素人です。
ワードの誤用や質問の意図が分かり難いなどあるかと思いますが、回答いただけると幸いです。

シェルに関しては、こちらのページで確認し、シェルはカネールとの間に入って色々と作業をしているとの認識でおります。

■シェルとサーバの関係は?

シェルの役割については、何となく理解しました。
PHPに関しても、サーバー上にあるZned Engineによって処理していると理解しております。
引用ですが、PHP側に関しては、下記のようなイメージで理解しております。

イメージ説明

引用:独習PHP 第2版
※第2版からの引用ですが、2016年4月9日に新しい第3版が出ています。

上図を参考に私の方でシェルとカーネルを追加しました。

イメージ説明

【質問1】
シェルを実行する関数の利用を避けることで、OSコマンドインジェクションの対策になると「IPAの記事」に書いてあるので、Zend Engineとシェルがやり取りをしているのかと考えましたが、私の認識(上図)であっていますか?

※私が作成した図はこちらの「Cacoo」から編集も可能ですので、文章等で回答しにくい場合は、編集していただけると幸いです。

■使用する関数がシェル経由か調べるには?

先ほどの「IPAの記事」にはPHPの場合、exec(), passthru(), proc_open(), shell_exec(), system()をなるべく使わないとの記述があります。
この関数は、シェル経由するため使わない方がよいとのことかと存じます。

【質問2】
PHPマニュアルを見てもシェル経由する関数かどうか記載がありません。
どのようにすれば、シェル経由する関数なのか確認することができますか?

【質問3】
そもそも、なぜシェル経由する必要があるのでしょうか?
調べた感じでは、シェル経由する関数とシェル経由しない関数の2種類があるのかと思います。
シェル経由する関数はカネールの機能を利用しないと実現できないために、シェル経由しているということでしょうか?

ご存知の方いれば、教えてください。
よろしくお願いいたしますm(__)m

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

質問1や2は他の人がいい感じの回答をつけると思うので、質問3だけ。。。

そもそも、なぜシェル経由する必要があるのでしょうか?
調べた感じでは、シェル経由する関数とシェル経由しない関数の2種類があるのかと思います。
シェル経由する関数はカネールの機能を利用しないと実現できないために、シェル経由しているということでしょうか?

これは誰かから聞いたとかどこかで見たとかではない、わたしの予想というか勘というかそういうレベルのふわっとした妄言なのですが、、、(つまりソースはない)

Linux でプログラムを実行するとき、最終的に次の関数が実行されます。

int execve(const char *filename, char *const argv[], char *const envp[]);

つまり、次のものが必要とされます。

  • 実行ファイル名
  • コマンド引数の配列
  • 環境変数の配列

一方、PHP のような言語から外部コマンドを実行したい場合、次のようなものを指定すると思います。

  • コマンドライン文字列(実行ファイル名+複数のコマンド引数をスペースで連結したもの)

とりあえず環境変数は無視しまして・・・

前述の通り、最終的に必要なのは「実行ファイル名」と「コマンド引数の配列」なので、「コマンドライン文字列」をバラバラに分割する必要がありますが、それを行っているのがいわゆる「シェル」です。

なので、「コマンドライン文字列」を指定してコマンドを実行する場合は、大抵の場合シェルを経由します。

例えば、nodejs の child_process モジュールなどを見てみると、シェルを経由する child_process.exec は「コマンドライン文字列」を指定するのに大して、シェルを経由しない child_process.spawn では「実行ファイル名」と「コマンド引数の配列」を指定するようになっています。

PHP でもシェルを経由しない pcntl_exec は「実行ファイル名」と「コマンド引数の配列」を指定します。

つまり、「コマンドライン文字列」を指定して外部プログラムを実行できるようにするためには、シェルを経由する必要があります。

もちろん、「コマンドライン文字列」をプログラミング言語の方でバラバラに分割するようにすればシェルを経由せずに実行することも可能です。例えば Ruby などでは、一部のメタ文字を含んでいない場合は、Ruby の側で「コマンドライン文字列」を「実行ファイル名」と「コマンド引数の配列」に分割することでシェルを経由せずに実行します。

メタ文字を含まない、ということは、スペースで分割するだけで簡単にコマンドライン文字列をバラすことができるので、そのような実装になっているのだと思います(メタ文字を含む場合、シェルと同等のパーサが必要になりますし、リダイレクトやパイプなどのシェル特有の機能が出てきてしまいます)。

なお、これらの事情は Linux などの *nix 系 OS の事情であって、Windows では異なります。

Windows の場合、外部プログラムを実行するときの API は「実行ファイル名」と「コマンドライン引数(コマンド引数をスペースで繋げた文字列)」を指定します。

それどころか lpApplicationName は省略可能なので、「コマンドライン文字列(実行ファイル名+コマンド引数をスペースで繋げた文字列)」だけでも可能です。

つまり、Windows の場合はシェルを経由させなくても「コマンドライン文字列」を指定して外部プログラムを実行することが容易です。

そのため、PHP の proc_open には Windows にだけ bypass_shell というシェルを経由いないオプションがあります。

投稿2016/05/02 09:07

ngyuki

総合スコア4514

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2016/05/02 09:58 編集

いつも回答ありがとうございます。 詳しい解説と参考サイトありがとうございます^^ 私の乏しい知識では、一部理解できないところもあるので、調べながら理解したいと思います。 回答ありがとうございましたm(__)m
退会済みユーザー

退会済みユーザー

2016/05/12 07:41 編集

Linux?コマンドライン?という状態だったので、下記の本を読んだら何となく理解できるようになりました^^ + UNIXの絵本(株式会社アンク) + まんがでわかるLinux シス管系女子 (日経BPパソコンベストムック) PHPで外部コマンドを実行するときに書くコードは、必要な情報を連結して記述(メタ文字を含む)しており、この情報をバラバラにして解釈できるようにするためにシェルを経由している、または経由する必要があるということなんですね。 逆にシェルを経由しないものは、上述した必要な情報をバラバラに記述(メタ文字を含まない)して実行しているんですね。 語弊があるかもしれませんが、要はメタ文字を含む場合はシェルを経由しないと解釈できないので、シェルを経由し、メタ文字を含まないときはシェルを経由しないということなんですね。 ただ、Windowsだけは特殊でメタ文字を含んでもシェルを経由しないで実行できるんですね。 今も基本的なことは理解できていないので、誤解しているところもあると思いますが、何となく理解できた気がします^^ わかりやすい回答ありがとうございましたm(__)m
guest

0

ベストアンサー

【質問1】 基本的には、ほとんどの関数はシェルを経由しません(Zend Engineから直接カーネルを呼び出します)。質問2とも重なりますが、シェル経由となるのは他のプログラムを呼び出す機能のうち、さらに一部だけです。

【質問2】PHPのマニュアルでプログラム実行関数としてまとめてあります。あと、バッククオート演算子も仲間に入ります。

【質問3】PHPから外部のプログラムを実行する際に、シェルを介することで「パイプ」や「リダイレクト」などのような出力制御ができるようになったり、「シェルスクリプト」が実行できるようになったりします。逆に言えばこれらを使わずにプログラムを実行するときにはシェル経由の意味はあまりありませんし、ましてや外部プログラムを実行しない時にはまったく関係しません。

投稿2016/05/02 08:37

maisumakun

総合スコア145183

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2016/05/02 09:52

いつも回答ありがとうございます。 ・ググるとシェルがカーネルを覆うような関係図になっていたので、全てシェル経由するのかと勘違いしておりました。Zend Engineから直接カーネルを呼ぶこともあるんですね。シェル経由しない関数というのは、文字通りの意味なんですね。 ・PHPマニュアルにまとめてあるのに気づきませんでした(^^;) これらの関数を利用するとき、利用されているときは、OSコマンドインジェクションの可能性があるので、対策する必要があるということですね。 ・シェルについて知識が乏しく「パイプ」や「リダイレクト」について知りませんでした。このような機能を使うときにシェル経由するということなんですね。シェルについてもっと調べてみたいと思います。 回答ありがとうございましたm(__)m
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問