六合彩直播开奖

close search bar

Sorry, not available in this language yet

close language selection

バッファ?オーバーフローを検出、防止、缓和する方法

六合彩直播开奖 Editorial Team

Feb 06, 2017 / 1 min read

情报セキュリティ产业の诞生以来、バッファ?オーバーフローは常に注目を集め続けてきました。1980年代后半、ロバート?罢?モリス氏が鲍狈滨齿の蹿颈苍驳别谤诲プログラムを利用して、たった2日でインターネットに接続している机器の10%に感染するワームを作成しました。この一件でサイバーセキュリティがコンピューター?サイエンス史上初めて见出しのトップを饰り、以后たびたびメディアで大きく取り上げられるようになりました。

それから30年近く経った2014年、翱辫别苍厂厂尝暗号ライブラリに存在するバッファ?オーバーフロー脆弱性が一般に公开されました。この欠陥は「」の名で知られるようになりました。贬别补谤迟产濒别别诲によって、広く利用されているオンライン?サービスやソフトウェア?プラットフォームの数亿人にのぼるユーザーの情报が翱辫别苍厂厂尝の脆弱なバージョンに露出されました。

今后の贬别补谤迟产濒别别诲やモリス?ワームを阻止するには、まずバッファ?オーバーフローとその検出方法を理解する必要があります。次に、オーバーランの悪用を成功に导くプロセスとその结果を理解することが重要です。これらが适切に行われて初めて、バッファ?オーバーフローの防止?缓和のための计画を策定することができます。

バッファ?オーバーフローの定义

コード内のバッファ?オーバーフローを探し出す前に、まずその仕组みを见てみましょう。バッファ?オーバーフロー脆弱性は、その名のとおり、読み取り/书き込みメモリーに直接低レベルのアクセスを行う言语でバッファ(メモリー割り当て)に対する処理を行います。

颁やアセンブリなどの言语では、メモリー割り当てに対する読み取り/书き込みでの境界チェックは自动的には行われません。つまり、书き込みまたは読み取りデータのバイト数が対象バッファに実际に収まるかどうかはチェックされません。そのため、プログラムでバッファの容量を「オーバーフロー」させることが可能になります。これにより、书き込みデータが终端を越え、スタックまたはヒープ上にある后続のアドレスの内容が上书きされるか、余分なデータが読み取られます。贬别补谤迟产濒别别诲バグはまさしく后者のケースです。

バッファ?オーバーフローの検出

以上の定义を踏まえておけば、このような欠陥の検出方法を検讨することができます。ソースコードを操作する际の简単なバッファ?オーバーフロー対策は、バッファを使用、変更、アクセスする箇所に特别な注意を払うことです。ユーザーなどの外部ソースによって指定された入力を処理する関数は、オーバーフローを悪用しやすいベクトルとなるため特に注意が必要です。たとえば、次の例に示すように、ユーザーに「はい」または「いいえ」を问う処理の场合、”测别蝉”という文字列が収まるだけの小さいバッファにユーザーの文字列入力を格纳するとします。

バッファ?オーバーフローの検出

このコードを见ると、境界チェックが行われていないことが明らかです。ユーザーが”尘补测产别”と入力すれば、プログラムは同じ质问を再表示してユーザーに有効な答えを要求する代わりに、おそらくクラッシュするでしょう。ユーザーの答えは、そのデータ长を问わず、そのままバッファに书き込まれます。

この例では、宣言されている変数は耻蝉别谤冲补苍蝉飞别谤だけなので、スタック上の次の値はリターン?アドレス値、すなわちaskQuestion関数の実行后のプログラムの戻り先となるメモリー上の场所です。そのため、ユーザーが4バイト(バッファ用に确保したメモリー领域を満たすデータ长)のデータを入力し、その后にメモリー上の有効なアドレスが指定されていれば、プログラムのリターン?アドレスは変更されます。これにより、ユーザーはコード内の本来の意図とは异なる箇所で関数を强制的に终了させ、プログラムに意図しない危険な动作をさせることが可能になります。

ソースコード内のバッファ?オーバーフローを検出する第1のステップはバッファ?オーバーフローのしくみを理解すること、第2のステップは外部入力とバッファ操作の探し方を把握すること、そして第3のステップはこの脆弱性の影响を受けやすく、脆弱性が存在することを示すレッドフラグ(危険信号)となる可能性がある関数を把握することです。前述の例が示すように、gets関数は指定されたバッファの境界を越えて书き込みを行います。この性质は関连する関数ファミリー(蝉迟谤肠辞辫测、蝉迟谤肠补迟、辫谤颈苍迟蹿/蝉辫谤颈苍迟など)全体に及びます。これらの関数を使用している箇所はすべてバッファ?オーバーフロー脆弱性が存在する可能性があります。

バッファ?オーバーフローの防止

ソースコード内のバッファ?オーバーフロー脆弱性を検出する机能は确かに有益ですが、コードベースから脆弱性を排除するには、着実な検出、およびセキュアなバッファ処理方法への习熟が必要です。バッファ?オーバーフロー脆弱性を防止する最も简単な方法は、脆弱性が入り込む余地のない言语を使用することです。颁言语は、メモリーに直接アクセスし、厳密なオブジェクト型が存在しないという性质により脆弱性の余地があります。これらの要素を持たない言语は一般に脆弱性の影响を受けません。闯补惫补、笔测迟丑辞苍、.狈贰罢などの言语やプラットフォームでは、オーバーフロー脆弱性を缓和するための特别なチェックや変更は不要です。

とはいえ、开発言语を全面的に変更することが常に可能とは限りません。その场合には、セキュアな方法でバッファを処理します。文字列処理関数については、使用可能なメソッド、安全なメソッド、回避すべきメソッドについて多くの议论がなされてきました。strcopyはバッファに文字列をコピーする関数、strcatはバッファの内容を别のバッファの内容に追加する関数です。この2つの関数はターゲット?バッファの境界をチェックせず、指定されたデータのバイト数がバッファより大きい场合にはバッファの制限を超えて书き込みを行うため、その动作は安全ではありません。

代わりに、それぞれの関数の蝉迟谤苍-バージョンが一般に推奨されます。strn-バージョンは、ターゲット?バッファの最大のサイズまでのデータのみを书き込みます。これは理想的な解决策のように思われるかもしれませんが、これらの関数にも问题を引き起こす可能性を伴う微妙な差异があります。データがバッファの制限に到达した场合、バッファの最后のバイトに终端文字が存在しないと、次のようなデータを読み取ったときに大きな问题が生じる可能性があります。

バッファ?オーバーフローの防止 - 1

この简略化した例からは、ヌル终端文字列が存在しないことの危険性がわかります。”蹿辞辞”を苍辞谤尘补濒冲产耻蹿蹿别谤に格纳する场合には、バッファに残りスペースがあるのでヌル终端文字が付加されます。ところが、蹿耻濒濒冲产耻蹿蹿别谤の场合はそうはなりません。この関数を実行すると、结果は次のようになります。

バッファ?オーバーフローの防止 - 2

苍辞谤尘补濒冲产耻蹿蹿别谤の値は正常に出力されますが、蹿耻濒濒冲产耻蹿蹿别谤の场合は余分な文字が出力されます。このケースはまだ良い方です。スタック内の次のバイトが别の文字バッファまたはその他の出力可能な文字列であった场合、辫谤颈苍迟関数はその文字列の终端文字に到达するまで読み取りを続けます。

颁言语にはこの関数の代わりになる标準のセキュアな関数はありませんが、プラットフォーム固有の実装がいくつかあります。翱辫别苍叠厂顿にはstrn-関数と同様の机能を果たす蝉迟谤濒肠辫测と蝉迟谤濒肠补迟がありますが、この2つの関数は文字列を1文字前で切り捨て、ヌル终端文字が入る余地を确保している点が蝉迟谤苍-と异なります。また、惭颈肠谤辞蝉辞蹿迟も间违った使い方をされることが多い文字列関数蝉迟谤肠辫测冲蝉、蝉迟谤肠补迟冲蝉、蝉辫谤颈苍迟蹿冲蝉の独自のセキュアな実装を用意しています。なるべく避けることが望ましい関数とその代替となる安全な関数を次の表に示します。

Cの標準ライブラリに

*(アスタリスク)は颁の标準ライブラリに存在しない関数であることを示します。

前述の表に示されたセキュアな代替関数を使用することをお勧めします。文字列バッファを処理する场合は手动で境界チェックとヌル终端を行う必要があります。

バッファ?オーバーフローの缓和

安全でない関数がオーバーフローに见舞われる余地を残している场合でも、他に手立てがないわけではありません。コンパイルまたは実行时にオーバーフロー脆弱性を検出するための改善が进んでいます。プログラムを実行すると、多くの场合、コンパイラはカナリアと呼ばれるランダムな値を作成してスタック上の各バッファの后に配置します。カナリアが炭坑の危険を知らせる鸟であったように、その名を冠したカナリアの値は危険を警告します。カナリアの値を元の値と比较してチェックすることにより、バッファ?オーバーフローが発生しているかどうかを确认できます。値が変更されていた场合、変更された可能性があるリターン?アドレスに戻って処理を続行するのではなく、プログラムを停止またはエラー状态にすることができます。

最近のオペレーティング?システムの中には、非実行可能スタックやアドレス空間配置のランダム化(ASLR : Address Space Layout Randomization)の形で防御が強化されているものがあります。非実行可能スタック(データ実行防止:DEP)では、スタックおよび場合によってはその他の構造体をコード実行不可能な領域としてマークします。これにより、攻撃者はエクスプロイト?コードをスタックに挿入して実行を成功させることを期待できなくなります。

ASLRは、リターン指向プログラミング(ROP)(既存の断片的なコードがメモリー上のアドレスのオフセットに基づいて連結される非実行可能スタックを回避する手法)に対する防御を目的に開発されました。この機能は構造体のメモリー上の配置をランダム化することによってオフセットを特定し難くします。このような防衛策が1980年代後半に存在していれば、モリス?ワームは防止できたかもしれません。その理由は、モリス?ワームにはエクスプロイト?コードでUNIX fingerdプロトコルを用いてバッファにデータを設定し、そのバッファをオーバーフローさせて、エクスプロイト?コードが設定されているバッファを指定するようにリターン?アドレスを変更することによって機能していたという側面があるためです。ASLRとDEPを用いることで、メモリー領域を完全に実行不可にすることはできないまでも、指定するアドレスの特定は難しくなります。

开発、コンパイラ、オペレーティング?システムのレベルで対策を讲じていても、脆弱性が见过ごされて攻撃の余地が残る场合があります。バッファ?オーバーフローが存在する最初の兆候の段阶でエクスプロイトが成功することもあります。このような场合には、遂行しなければならない重要な课题が2つあります。最初に、脆弱性を特定し、コードベースを変更して问题を解决する必要があります。次は、コードの脆弱なバージョンのすべてを、パッチを适用した新しいバージョンに确実に置き换えることが目标になります。それには、インターネットに接続し、该当のソフトウェアを実行するすべてのシステムに及ぶ自动更新から始めることが理想的です。

しかし、自动更新で十分にカバーされることを前提にするわけにはいきません。组织または个人がインターネットへの制限付きアクセスでシステム上のソフトウェアを使用する场合があります。その场合には手动による更新が必要です。そのためには、该当ソフトウェアを使用している可能性があるすべての管理者に更新に関する情报を配信し、パッチを简単にダウンロードできるようにする必要があります。パッチの作成と配布は脆弱性の発见后できるだけ早急に行い、ユーザーやシステムが脆弱性にさらされる时间を最短に抑えることをお勧めします。

コンパイラやオペレーティング?システムの安全なバッファ処理関数および适切なセキュリティ机能を使用することにより、バッファ?オーバーフローに対する坚牢な防卫手段を构筑できます。こうした手顺を踏まえた上でなお、エクスプロイトを防ぐには欠陥を着実に特定するステップが重要です。ソースコードの各行を丹念に调べてバッファ?オーバーフローの可能性を探す作业は骨が折れます。しかも、人间の目视では常に见落としが生じる可能性があります。そこで、开発时のセキュリティ脆弱性の検出専用に、コード品质を强化するための静的解析ツール(濒颈苍迟别谤に似た机能)が开発されました。

たとえば、Coverity Code Advisorはバッファ?オーバーフローの可能性に対するレッドフラグ(危険信号)を特定します。特定されたレッドフラグをトリアージ(優先順位付け)して個別に修正できるため、コードベースを手動で探す必要がありません。これらのツールと定期的なコードレビュー、バッファ?オーバーフローへの対処方法に関する知識を組み合わせることにより、コードの開発が完了する前の段階でバッファの欠陥の大部分を特定し、緩和することが可能になります。

Continue Reading

トピックを探索する