web-dev-qa-db-ja.com

ゼロ除算はセキュリティの脆弱性ですか?

ソフトウェアのバグと脆弱性は同じ概念と見なされることもありますが、それらの間には少なくとも1つの異なる側面が必要であり、最も顕著なのはexploitabilityです(後者にはプロパティがあります)。

私が興味を持っているのは、ゼロ除算のバグがソフトウェアの問題として報告される多くのケースを見た後でも、私はほとんど攻撃を思い付くことができない(DoS以外)除算を使用する-ゼロバグ。セキュリティの点ですべての種類のバグがシステムに同じ影響を与えるわけではありませんが、たとえばゼロによる除算のバグを使用して、DoSとは異なる何かを達成する攻撃方法はありますか?

81
Gwangmu Lee

問題は、ゼロによる除算を処理するために例外ハンドラーが呼び出されることです。一般に、攻撃者は例外ハンドラが通常のコードフローほど十分にテストされていないことを知っています。メインのロジックフローは適切で完全にテストされている可能性がありますが、例外ハンドラは、そのスコープ内のコード内のどこかで発生する割り込みによってトリガーできます。

int myFunction(int a, int b, SomeState state) {

    state(UNINITIALIZED);
    try {
        state.something(a/b);
        state(NORMAL);
    }
    catch () {
        state.something(b/a);
        state(INVERTED);
    }
    return retval;
}

この恐ろしい疑似コードは、欠陥が悪用される可能性がある1つの方法を示しています。初期化されていない状態が何らかの形で脆弱であるとしましょう。このルーチンが呼び出されると、状態は最初に初期化されていません。 bがゼロの場合、例外をキャッチして、他のロジックを実行しようとします。ただし、aとbの両方がゼロの場合、再度スローされ、状態は初期化されません。

ゼロによる除算自体は脆弱性ではなく、悪用される可能性があるのはその周りの悪いコードです。

105
John Deters

別の人為的だが実際の例に基づいて追加するには:

多くの(多くの)月前に、私の高校はNovell Netwareを実行していて、学生がdosプロンプトを直接実行できないように構成していました(たとえば、フロッピーディスクをフォーマットする必要がある場合に面倒でした)。ただし、X文字を超えるパスワードを入力した場合(つまり、しばらくキーを押し続けた場合)は、ネットウェアがクラッシュし、システムが... DOSプロンプトに戻ります。おそらくこれはバッファオーバーランでしたが、原則は同じです。メンテナンスモードに切り替えることで少なくとも予期しないクラッシュを処理するシステム(特に組み込みシステム)を扱っている場合、セキュリティ上の懸念があります。 。

50
Foon

他の答えが示唆しているように、それはシステム全体に完全に依存しています。それはコードだけでなく、プラットフォーム、言語、コンパイラーでもあります。

たとえばc ++では、整数のゼロによる除算は未定義の動作です。その特定の言語に関するルールの1つは、コンパイラーが未定義の動作が発生しないことを想定している場合であり、発生した場合は何でも実行できることです。

エラーメッセージを伴うクラッシュとクリーンアップ、エラーメッセージを伴わないクラッシュ、すべてを奇妙な状態にしておくこと、何も起こらなかったかのように続行しようとする最も恐ろしいことなどが含まれます。

現在、実際には、ほとんどの優れた最新のコンパイラーは、そのような何かにぶつかった場合にきれいにクラッシュしようとしますが、これにより、それが脆弱性であるとの仮定がなされている理由が明らかになります。別のコンパイラまたは別の設定でコードをビルドするだけで、コードを変更しない場合、プログラムが実行することは、完全なクラッシュからデータベースの消去に至る可能性があります。

19
Josiah

正しく構成されていないウェブサーバーと合わせて、PHP環境は、ゼロによる除算が発生した場合に内部パスのリーク)スクリプトへの物理パスを明らかにする可能性があります:

<?php
$denominator = $_GET['number'];
echo 1/$denominator;

Script.php?number = 0にアクセスすると、次のようになります。

警告:3行目の/var/www/html/script.phpのゼロ除算.

ワークショップや講義で、ソフトウェアのすべてのセキュリティ問題は本質的にバグであると私は時々言いますが、その逆は自動的には当てはまりません。

しかし、私は議論として悪用可能性に行くつもりはありません。あなたと私が悪用する方法を理解できないからといって、より巧妙な誰かがいつの日かしないという意味ではありません。 正式な証明を提供する必要があります。現在のプログラミング言語での正式な証明で頑張ってください。

だからあなたの質問に答えるために:ゼロによる除算couldは脆弱性またはその一部です。 通常例外が発生し、ソフトウェアが終了します。これ自体は攻撃者にとって重要な情報になる可能性があります(変数がゼロであることを知っています)。

ゼロによる除算aloneがセキュリティの脆弱性である可能性は低いですが、より大きなコンテキストでは、問題の一部である可能性があります。

したがって、ループを閉じるには、常にすべてのバグを真剣に扱う必要があります。確信が持てない場合(例:部門が制御していない変数を使用している場合)、セキュリティかどうかに関係なく、それをキャッチして処理する必要があります。 「ええ、それはバグですが、それがどのように悪用されるかはわかりません」は、セキュリティを意識した考え方ではありません。

13
Tom

ゼロによる除算は本質的にセキュリティの脆弱性ではありません。

ただし、アプリケーションサーバーをクラッシュさせ、ゼロで除算することでオフラインにできる場合、これはサービス拒否の脆弱性を構成する可能性があります。

10

最終的には、あなたの答えは個々のシステムに影響を与えることになると思います。システムは、0で除算しようとするとどう処理しますか?エレガントな場合、攻撃オプションは限られているか、存在しません。それがファンキーな何かをするなら、あなたはおそらく何かでそこに入ることができます。

基本的に、これからは標準的な攻撃が発生することはありません-とにかく私は承知しています-コンピュータは常にバグを適切に処理することができ、バグの不適切な処理は多くの脆弱性の原因です。

5
securityOrange

プログラムが信頼できるデータのみを受信し、悪意を持って作成されたデータが与えられた場合に動作要件を満たす必要がない場合、いくつかの動作要件がある場合に必要とされるよりもわずかに効率的なコードを生成できる可能性があります。すべてのデータについて満たす必要がありました。

一部のタスクには信頼できるデータの処理のみが含まれ、他のタスクには信頼できないソースからのデータの処理が含まれるため、C標準では、前者のタスクのみを目的とする実装で、後者を対象とするものや、前者の処理に役立つ可能性のある最適化を不必要に妨げる保証を提供する後者のタスクに適している。

残念ながら、標準は、実装が標準によって義務付けられたものを超えてどのような種類の動作保証を提供するかを示すことができる手段を提供していません。 C89が書かれたとき、著者は、「市場」が標準の作成者よりも、「どのような実装がどのような人気のある拡張機能」をサポートするかを決定するという標準の作成者よりも良い仕事をすることができると予想しました。要件、およびそのような態度は現在のコンパイラ市場に適合しなくなったとしても変わりません。

次のようなものが与えられた:

_if (x != 0) launch_nuclear_missiles();
... and then, possibly in another function
z=y/x;
_

一部の人々は、xがゼロ以外である場合に_launch_nuclear_missiles_のみを呼び出すものよりも、launch_nuclear_missiles()への無条件の呼び出しで「if」を置き換えるコンパイラを見るでしょう動作は、信頼できない入力を含まないタスクを処理する場合にのみ適切です。

使用しているコンパイラーが、当然ながら汎用コンパイラーが提供していた種類の弱い動作保証を守り、悪意を持って作成された入力が与えられた場合でも弱い動作制約を満たすプログラムの作成を容易にすることがわかっている場合、その場合、ゼロ除算はセキュリティ上の弱点をもたらすことはありません。信頼できない入力を含むタスクに適するように設計されていない積極的に最適化するコンパイラでは、「最適化」がもたらす可能性のある利点を打ち消すために十分な安全性チェックロジックを追加する必要があります。

5
supercat

しかし、例えば特権昇格のように、DoSとは異なる何かを達成するためにゼロ除算バグを使用する攻撃方法はありますか?

クイック検索 MITREのCVEデータベースでは、主にゼロによる除算がサービス拒否を引き起こすことを明らかにしますが、1つの特定のケース CVE-2005-0998 は他のことを許可します:

説明PHP-Nuke 7.6のWeb_Linksモジュールを使用すると、リモートの攻撃者が無効なshowパラメータを介して機密情報を取得できるため、ゼロによる除算がトリガーされますPHPエラーがサーバーの完全なパス名を漏らします。

これ自体は特権の昇格や特定の攻撃を許可しませんが、一般的に言えば、機密情報は他の攻撃の作成に役立ちます。言い換えれば、それ自体でゼロによる除算は単なる踏み石にすぎないのかもしれません。

4

これでどこから来たのかわかります。それ自体では、算術エラーを使用してデータ入力が必要なもの(コード実行など)を引き起こすためにどのように使用できるかを確認するのは困難です。

ただし、言語によっては、フロー制御の問題を引き起こしたり、スレッドを選択的にクラッシュさせたりする可能性があります。これは、他の問題を複雑にしたり、本当に(不幸な)場合に、搾取可能な何かを倍増します。データエントリとバグは必ずしも同じである必要はありません。

これは少し不自然ですが、たとえば、リンクリストに既にあるオブジェクトをヘッドにコピーを追加して移動し、それが見つかるまで反復してコピーを削除するとします。これをスレッド内で行い、何らかの理由で(たとえば、誰かがstats printステートメントを反復ループに入れて間違っている場合)、同じ要素の2つのコピーがあるリストを不良状態のままにする可能性があります。これが片付けられたら:ダブルフリー...

この新しい要素のコンテンツを制御でき、statの結果をゼロで除算し、それでもコンテンツを十分に制御できる場合、これは十分に悪用される可能性があります。

可能性は低いですが、可能です。

3
ANone

質問は「サービス拒否がセキュリティの脆弱性と見なされるのはなぜですか?」とより適切に表現されている可能性があります。 Linuxをx86プロセッサで実行しているときに、プロセッサが整数を0で除算した場合(または、符号付き整数の最小値を-1で除算した場合、supercat)、プログラムはSIGFPEシグナルを受信します。 Windowsでは、これは不正な操作です。 C/C++標準では未定義の動作と見なされているため、コードを見ただけでは何が起こるかを確実に知ることはできません。

通常、これは、すべてではないが多くのサービス拒否の脆弱性と同様に、「クラッシュ」を引き起こします。次に、プログラムが異常終了した場合に利用できる可能性のいくつかを示します。

  • これにより、別のプログラムが最初のリソースと同じリソース(ポートなど)を使用して、同じプログラムのふりをすることができます。
  • クラッシュすると、悪用される可能性のあるプログラムによって使用されるクリーンアップ操作が回避される可能性があります。
  • プログラムの終了コードが、子プロセスのPIDのシグナル状態をチェックしていない別のプログラムで使用されている場合、プログラムがエラーコードを返したと考えられます。たとえば、私のLinuxマシンでは、次の2つのプログラムはどちらも_$?_(前のコマンドの戻りコードを表すためにシェルスクリプトで使用される変数)を_136_に設定します。int main(int argc, char** argv) { return 1 / (argc - 1); }およびint main() { return 136; }
  • クラッシュすると、コアダンプなどのセキュリティキー、パスワード、コカコーラのレシピなどの保護されたメモリが含まれる可能性があります。

さらに、最適化のために、コンパイラーは除数が0になることはないと想定し、考慮していないコードを最適化する可能性があります。これは、ゼロ除算の動作が未定義(または同等)であるCやC++などのコンパイル済み言語にのみ適用されます。 clangまたはgccの他のいくつかの回答の例を使用してそれを行う最適化されたコードを生成することはできませんでしたが、それらまたは他のコンパイラが過去または将来にそうすることを妨げるものは何もありません。

2
Erroneous

ここにいくつかの非常に具体的な答えがあります。 (未処理の)ゼロによる除算は主に機能上の問題であることに同意しますが、それはセキュリティの問題として悪用できないことを意味するものではありません。実際、バグに適用したときに「機能」と「セキュリティ」の分類を利用できるバグは非常に多くあり、あまり意味がないようです。

ここでは、範囲外と見なすものについて何も議論せずに、セキュリティ問題(DOS)のカテゴリを却下します。最も明白なシナリオは、エラーが発生するとプログラムのインスタンスが停止することです。しかし、もっと微妙な影響があります-大量のデータがファイルシステムに書き込まれる場合(コアダンプなど)、ファイルシステムがいっぱいになることにより、2番目のタイプのDOSへの道が開かれます。

Jefreyは、PHPアプリケーションの開示について言及していますが、エラーメッセージ、ログ、およびコアダンプは、どの言語で書かれたプログラムからもアクセスできないはずの情報を抽出しようとする人々に、豊富な選択の根拠を提供します。

プログラムの早期終了が何らかの応答につながる場合、攻撃者は選択した時点で特定のプログラムをトリガーする手段を持っています。攻撃者は、システムの動作をある程度制御して、攻撃/特権の昇格を容易にすることができます。

制御システムが手動であっても、セキュリティ動作があまり明確に定義されておらず、パスフレーズ、パスワード、秘密鍵などの資産が機能しているシステムの移行状態がまだあります。

1
symcbean

これが違いを生む可能性のある例の例です。

それは100%考案されたものですが、特定の例が見つかるまで、多くのクラスのエクスプロイトが理論的な「考案された」例によって識別されます。

擬似コードです。

try:
   get the average cpu usage per logged in user
   if this average is too high, tell the person logging on that we're busy.
   get login credentials
   verify login credentials
   if credentials are invalid, tell them to go away
   restrict access for this session to the correct access for this user
if there is an exception:
   do nothing

let the user in

この場合、ログインしているユーザーごとの平均CPUは、「合計CPU /ログインしているユーザーの数」として計算される可能性があります。ログインしているユーザーがいない場合、「0で除算」され、「if例外がある」という条項があります。これには、アクセスの制限が含まれます。新しいセッションには、最後にログインしたユーザーと一致するアクセス、または無制限のアクセスが含まれる場合があります。

この例はすべてのコードを一緒に示していますが、メインコードはしばしば何かを呼び出し、それは別の何かを呼び出し、相互作用する2つの側面(この場合、0による除算、および例外が無視されるという事実)は部分的に実行される可能性があります遠く離れているコードの。

多くの人が述べたように、ゼロによる除算(それ自体)はセキュリティバグではなく、実際にはまったくバグではありません。私の知る限り、ほとんどの(おそらくすべて!)プログラミング言語は、ゼロによる除算が発生したときに何が起こるかについての情報を明確に文書化しています。例外のあるほとんどすべての言語にはゼロによる除算の例外があると思います(機械的な計算機が無限ループに陥るのを見てきました)。

1
AMADANON Inc.