WindowsからLinuxカーネルを作成する方法は?

オーバーヘッド保護の開発における実務経験


私たちは、課せられたセキュリティ機能の実装、つまりソフトウェアシステムへの埋め込みに関する特定の問題に焦点を当てた一連の実用的な記事を公開し始めています。 例としてLinuxカーネルを使用して、その機能を変更、拡張、補完するために使用される方法とツールを検討します。



最初の記事では、主要な埋め込み方法の簡単な概要を紹介します。 さらに、技術的な詳細に注意しながら、個々の埋め込み方法を詳しく見ていきます。





セキュリティアプローチ



一般に受け入れられている慣行に従って、機密性、完全性、アクセシビリティのカテゴリを含むモデルが標準情報セキュリティモデルとして使用されます。 同時に、保護されたシステムは、このモデルを実装する機能が割り当てられているシステムを意味すると理解されています。 このようなシステムの基本要素であるオペレーティングシステム(OS)のコアは、情報セキュリティを確保するプロセスで重要な役割を果たしているため、セキュリティの向上という問題が主要な役割を担っています。



セキュリティ機能を構築するには、組み込みツールと手持ち現金の2つのアプローチがあります。 組み込みツールの特徴は、保護されたシステムに最初に存在することです。一方、課された資金は、運用中、運用前に保護されたシステムに導入されます。



各アプローチには、適用性の限界を決定する独自の長所と短所があります。 多くの場合、1つのアプローチの長所は別のアプローチの脆弱性です。 したがって、組み込みのセキュリティ機能の利点には、保護されたシステムの信頼性を検証する必要がないことが含まれます。 これはオーバーレイの欠点でもあります-保護対象が本物であると判断する方法は? 一方、保護されたシステムへの組み込みセキュリティツールの統合には、オペレーティングシステムコンポーネントのサプライヤーとセキュリティツール自体の選択に制限が伴います。 この問題は、システムの認証が重要な役割を果たしているロシア市場で特に深刻であり、内蔵の保護機器が規制当局によって定義された要件を常に満たすわけではありません(ロシアのFSTECの要件を参照)。



ソフトウェアシステムへの埋め込みの目標と目的



他のソフトウェアシステムと同様に、オペレーティングシステムの中核は、共通のコンピューティングシステムを形成する相互接続されたソフトウェアモジュール(コンポーネント)のセットです。 OSカーネル、特にLinuxカーネルに課せられた保護ツールの実装は、それをそのサブシステムのオペレーティングメカニズムに統合する必要があることを意味します。 同時に、埋め込みとは、追加の(サードパーティの)プログラム要素を導入するプロセスとして理解され、一方ではシステム自体の機能が維持され、他方では機能が拡張または変更されるように実行されます。



埋め込みといえば、次の実用的な問題を考慮します。 与えられた(基本的な)アルゴリズムに従って機能するソフトウェアシステムのターゲットコンポーネントがあるとします。 この基本アルゴリズムに特定の変更を加えることができるように、このコンポーネントの動作を変更する必要があります。



したがって、埋め込みの主な目的は、ソフトウェアシステムのコンポーネントの機能を制御、変更、および拡張する能力を得ることです。一方、埋め込みの主な目的は、操作性を維持しながら既存のソフトウェアシステムで実装を保証することです。 埋め込みが正常に完了することは、その構成に新しいコンポーネントが存在する状態でソフトウェアシステムの機能を維持することを特徴としています。

最新のソフトウェアシステムの中心部分であるOSカーネルは、アプリケーションとハードウェアレベルでデータを処理するデバイスとの間の仲介役として機能します。 同時に、その主なタスクは効果的なリソース管理です。



カーネルへのLinuxの埋め込みについて



そのアーキテクチャにより、Linuxカーネルは、動作中に必要に応じてロードされるモジュールを介して機能を拡張できるモノリシックカーネルです。 この機能により、Linuxカーネルは、実際にはカーネルの一部であるさまざまな機能をオーバーライド/補完できる拡張機能を開発できます。 実際にサブシステムの順序を変更します。



ソフトウェアシステムのコンポーネントを、対応する機器で実行されるさまざまな種類のアプリケーションおよびシステムプログラムと見なすと、これらのプログラムのセクションの実行中に埋め込みを制御し、制御をインターセプトする機能を取得することができます。 この場合、このような状況を処理するプログラムコードはインターセプターコード、またはより簡単にフック(英語、フック)と呼ばれます。 傍受(制御)および埋め込み自体という用語は類似していると見なされ、これが別に指定されていない場合は、同じことを意味するために使用されます。 ただし、両者の既存の違いに留意する必要があります。埋め込みとは一般的な意味での実装プロセスであり、傍受はむしろ特定の方法論的手法を示します。



動的埋め込み方法の特徴は、予想される変更を有効にするためにターゲットシステムを再起動する必要がないことです。 原則として、傍受のオブジェクトは関数であり、1つまたは別のアルゴリズムを実装するカーネルコードの要素です。 まれに、例外ハンドラー、特にシステムコールマネージャーなどのシステムメカニズムで埋め込みが発生します。



カーネル関数のインターセプトは、さまざまなメカニズムを再定義/補完するための基本的な方法です。 Linuxカーネルは、アーキテクチャに依存する小さな部分を除き、ほぼ完全にCで記述されているという事実に基づいて、ほとんどのカーネルコンポーネントに埋め込むには、対応する機能をインターセプトするのに十分であると言えます。



例外処理は、多くのシステムメカニズムの機能の根底にあります。 その結果、Linuxカーネル例外ハンドラーをインターセプトすると、システムの制御の度合いを高めることができ、システムコールマネージャーをインターセプトすると、Linuxカーネルサービスへのアプリケーションソフトウェア要求を規制することができます。



従来の埋め込み方法は、 パッチング (英語、 パッチング )に基づいています。これは、コードまたはデータに変更を加えて、目的のアルゴリズムの動作を目的の方法で変更できるようにする手法です。 技術的には、パッチの結果、RAMのセルの内容が変更されます。 ただし、コードの変更は、データの変更とは対照的に、主にコードとデータの基本的な違いに関連する独自の特性を持っています。

パッチ技術を使用した傍受の実装には、資格だけでなく、コア自体だけでなく、使用されているハードウェアプラットフォームの機能の動作原理を理解する必要があります。 コードを変更するときは、マルチプロセッサシステムの場合、埋め込みの正確性に特別な注意を払う価値があります。これは、変更の結果として一貫性が侵害されるべきではないためです。 さらに、カーネルコードを変更から保護するためのメカニズムをバイパスする必要性、およびエクスポートされていない非表示の文字を検索および使用する機能を考慮する必要があります。 ほとんどの場合、何らかの方法でパッチを適用することで埋め込みの問題を解決できます。



パッチの短所は、ターゲットシステムのコンポーネントの整合性に対する必要な違反と考えることができます。 コードの変更は簡単に検出できますが、これは一部のコンテキストでは基本的な制限事項です。 この種の制限の例は、特に、Windows OSのカーネル保護メカニズム- カーネルパッチ保護 (PatchGuardとして知られています)です。 その機能の1つは、OSカーネルの主要コンポーネントの整合性制御の実装です。これにより、コード変更に基づいたほとんどの標準的な埋め込み方法が無効になります。 同時に、オーバーレイをインストールするためにこのツールを無効にすることは極端なオプションです。 組み込みセキュリティ機能に重複する機能がない場合、システムの全体的なセキュリティは明らかに低下します。



ターゲットコンポーネントの整合性を維持しながら埋め込みを実装するには、この種の制限のないメソッドを使用する必要があります。 原則として、これらのメソッドの一部は、プラットフォームのハードウェア機能(ハードウェアブレークポイントなど)を使用しますが、少なくともセットインターセプトの数に制限がある場合、原則としてユニバーサルにすることはできません。 一方で、さまざまな種類の仮想関数や他の動的に置き換えられたポインターを使用する可能性は常に残っており、特定の制限内でシステムの動作を再定義できます。 特に後者は、仮想ファイルシステム( VFS )のフレームワーク内で実行される操作を傍受するために一般的です。仮想メソッドテーブルがオブジェクトの操作に使用される場合、コードを変更せずに置換を実行できます。 ただし、このアプローチには多くの制限もあり、その主な理由は、提供されないものを制御する方法がないことです。



おわりに



したがって、OSのカーネルに埋め込むには、特定のタスクに関連した使用が多かれ少なかれ適切なメソッドがあります。 パッチ適用は基本的な埋め込み方法であり、整合性(コード)の維持に制限がない場合に適用できます。 それ以外の場合、状況に応じて、アーキテクチャ固有のソリューション(ハードウェアブレークポイントの使用など)、仮想関数のオーバーロード、およびその他の方法が適用される場合があります。



何らかの方法で、カーネルへの埋め込みの実装により、コンポーネントの操作のロジックを変更できると同時に、この目的のためのメサニズムを埋め込むことでセキュリティの度合いを高めることができます。



次の記事では、最も一般的な埋め込み方法の1つであるカーネル関数をインターセプトする方法について詳しく説明します。



All Articles