セキュリティ上の理由から、実行前にコードの整合性をチェックすることが攻撃者によるソフトウェアの改ざんを回避することが望ましいです。だから、私の質問は
Linuxで実行可能コードに署名して信頼できるソフトウェアのみを実行する方法は?
私はvan Doomet al。、、Linux用の署名済み実行可能ファイルの設計と実装、およびIBMの作業を読みました- [〜#〜] tlc [〜#〜] (Trusted Linux Client)by Safford&Zohar。 TLCはTPMコントローラーを使用していますが、これは素晴らしいことですが、この論文は2005年のものであり、現在の代替案を見つけることができませんでした。
別のオプションを知っていますか?
[〜#〜] update [〜#〜]:そして、他のOSについては? OpenSolaris? BSDファミリー?
DigSig カーネルモジュールは、bsign
というツールによって署名されたバイナリの検証を実装します。ただし、Linuxカーネルのバージョン2.6.21以降は何も行われていません。
これは古代の質問だと思いますが、たった今見つけました。
私はLinuxカーネル(バージョン2.4.3あたり)の署名付き実行可能ファイルのサポートを書いており、実行可能ファイルに署名し、execve(2)
時に署名をチェックし、署名検証情報をキャッシュするためのツールチェーン全体を用意しました(ファイルが書き込みまたはその他の方法で開かれたときに検証をクリアし、署名を任意のELFプログラムに埋め込むなど、すべてのプログラムの最初の実行時にいくつかのパフォーマンスペナルティが導入されました(カーネルが全体ファイルではなく、必要なページだけを要求します)が、システムが定常状態になると、うまく機能しました。
しかし、複雑さを正当化するには大きすぎるいくつかの問題に直面したため、追跡を停止することにしました。
署名付きライブラリのサポートはまだ構築していませんでした。署名付きライブラリでは、_ld.so
_ローダーとdlopen(3)
メカニズムも変更する必要があります。これは不可能ではありませんでしたが、インターフェースが複雑になりました。ローダーにカーネルに署名の検証を依頼する必要があるのでしょうか、それともユーザー空間で完全に計算を行う必要があるのでしょうか。検証のこの部分がユーザー空間で行われる場合、strace(2)
dプロセスからどのように保護しますか?そのようなシステムでは、strace(2)
を完全に禁止する必要がありますか?
独自のローダーを提供するプログラム について何をしますか?
ELFオブジェクトにコンパイルできない言語で書かれたプログラムは非常にたくさんあります。それぞれのインタープリターに対して、bash
、Perl
、python
、Java
、awk
、sed
などに言語固有の変更を提供する必要があります署名を検証することもできます。これらのプログラムのほとんどはフリーフォーマットのプレーンテキストであるため、ELFオブジェクトファイルへのデジタル署名の埋め込みを非常に簡単にする構造が欠けています。署名はどこに保存されますか?スクリプトで?拡張属性では?署名の外部データベースにありますか?
多くの通訳者は、彼らが何を許可するかについて広く開いています。 bash(1)
は、echo
と_/dev/tcp
_を使用して、リモートシステムと完全に独自に通信できます。攻撃者が行う必要のあること。署名されているかどうかにかかわらず、彼らがハッカーの制御下に置かれると、あなたはそれらを信頼できませんでした。
署名付き実行可能ファイルのサポートの主な動機は、システム提供の_/bin/ps
_、_/bin/ps
_、_/bin/kill
_などを置き換えるルートキットに由来します。はい、実行可能ファイルに署名することには他にも有用な理由があります。しかし、ルートキットは時間の経過とともに著しく印象的になり、多くのkernelハックを利用して管理者からアクティビティを隠しています。カーネルがハッキングされると、ゲーム全体が終了します。ルートキットが洗練された結果、私たちが使用されないようにすることを望んでいたツールは、ハッキングコミュニティで支持されなくなりました。
カーネルのモジュール読み込みインターフェースは広く開かれていました。プロセスにroot
特権が付与されると、チェックなしでカーネルモジュールを挿入するのは簡単でした。カーネルモジュールの別のベリファイアを作成することもできましたが、モジュールに関するカーネルのインフラストラクチャは非常に原始的でした。
GNU/Linux/FOSSモデルは実際に改ざんを助長します-ある種の。ユーザーとディストリビューターは、自分のニーズに合わせてソフトウェアを自由に変更(改ざん)できなければなりません。ソフトウェアを(ソースコードを変更せずに)カスタマイズして再コンパイルするだけでも、頻繁に行われますが、バイナリコード署名が壊れてしまいます。その結果、バイナリコード署名モデルは、GNU/Linux/FOSSにはあまり適していません。
代わりに、この種のソフトウェアは、ソースパッケージの署名や安全なハッシュの生成に依存しています。信頼性のある信頼できるパッケージ配布モデルと組み合わせると、これはバイナリコード署名と同じくらい安全になります(そうでない場合は、ソースコードの透過性に対して)。
これを見てください: http://linux-ima.sourceforge.net/
まだ署名はしていませんが、検証は可能です。
Solaris 10および11 OSの観点から質問に答えることができます。すべてのバイナリが署名されています。署名を確認するには、「elfsign」を使用します...
$ elfsign verify -v /usr/bin/bash
elfsign: verification of /usr/bin/bash passed.
format: rsa_sha1.
signer: O=Oracle Corporation, OU=Corporate Object Signing, OU=Solaris Signed Execution, CN=Solaris 11.
signed on: Fri Oct 04 17:06:13 2013.
Oracleは最近、Solaris 11の検証済みブートプロセスも追加しました。詳細については、- Solaris Verified Boot Introduction を参照してください。
OpenSolarisコードにはいくつかの製品グレードのフォークがあり、調査する価値のある3つはIllumos、SmartOS、およびOmniOSです。
Medusa DS9 を見てください。私はそれを長い(long)時間前に遊んだが、正しく覚えていれば、特定のバイナリを登録でき、カーネルでの変更は許可されなかったレベル。もちろん、マシンへのローカルアクセスで上書きすることはできますが、それほど簡単ではありませんでした。 constableと呼ばれるスマートデーモンがあり、マシン上で発生するすべてのことをチェックし、通常とは異なる何かが発生した場合、叫び始めます。
私は試したことはありませんが、以下をご覧ください。 http://blog.codenoise.com/signelf-digitally-signing-elf-binaries 。ソリューションはカーネルサポートを必要とせずに機能し、準備ができているように見えます。
署名者のコードは http://sourceforge.net/projects/signelf/ にあります。
「Linuxで信頼できるコードのみを実行する」という質問は解決しませんが、プログラムが改ざん/破損の可能性を検出する方法を作成することで、問題を部分的に解決します
セキュリティをチェーンとして考えるのが好きです。チェーンのリンクが弱いと、システム全体が危険にさらされる可能性があります。つまり、全体が「許可されていないユーザーがrootパスワードを取得するのを防ぐ」になります。
@DanMouldingによって提案されているように、ソフトウェアのソースも重要であり、将来的にはおそらく公式のOSアプリケーションストアが標準になるでしょう。 Playストア、AppleまたはMicrosoftストアについて考えてください。
秘密の悪意のあるコードのインストールと配布ははるかに油断のならない問題だと思います。結局のところ、不良コードをロードするには、まずシステムのどこかにインストールする必要があります。もちろん、通常はより多くのセキュリティ層が優れています。問題は、コストに見合う価値があるかどうかです。
私の意見では、答えは「依存する」です。 @sleblancで提案されている一連のセキュリティポリシーを採用することで、リスクを軽減できます。ファイルシステムを暗号化したり( https://en.wikipedia.org/wiki/Linux_Unified_Key_Setup )、バイナリに読み取り専用のファイルシステムを使用したり、メカニズムを使用してバイナリに署名および検証したりできます。
ただし、どのメカニズムを使用しても、攻撃者がルートアクセスを取得した後は何もできません。署名検証ツールは改ざんされたバージョンに置き換えるか、単に無効にすることができます。マシンが危険にさらされた後、ツールがユーザー空間またはカーネル空間で実行されるかどうかは問題ではありません(もちろん、後者はより安全です) )。
それで、Linuxカーネルが、ルートユーザーとオペレーティングシステムの間に署名検証モジュールと別のセキュリティレイヤーを埋め込めればいいのですが。
たとえば、これは最近のmacOSバージョンで採用されているアプローチです。一部のファイルは、rootアカウントによっても変更(および場合によっては読み取り)できず、ポリシーとカーネルモジュールにも制限があります(たとえば、システムにロードできるのは、署名済みまたは許可されたkextのみです)。 WindowsはAppLockerとほぼ同じアプローチを採用しました。
http://en.wikipedia.org/wiki/PKCS
そのPKCS7(S/MIME)記号を使用します。独自の証明書と秘密鍵のペアを生成し、証明書に自己署名してから、PKCS7を使用して秘密鍵と証明書でファイルに署名します。証明書を添付し、opensslコマンドを使用して実行時に自分自身を確認できます(man smimeまたは単にopenssl helpを実行します)。これは改ざん防止です。公開鍵が提供するファイルに含まれていても、その公開鍵のS/MIME署名は、配布しない秘密鍵でしか生成できないためです。したがって、ファイルが証明書によって署名されている場合、そのファイルは秘密鍵で誰かによって署名されている必要があります。秘密鍵は誰にも与えなかったので、それはあなたからのものである必要があります。
自己署名証明書を作成する方法は次のとおりです。
http://www.akadia.com/services/ssh_test_certificate.html
Opensslに自分の証明書を権限のルート(-CAfile)として信頼するように説得し、それをルートとして確認し、ファイルの証明書が自分のものであることを確認し(ハッシュ証明書)、ハッシュを確認する必要があります。ドキュメントには記載されていませんが、opensslの終了ステータスは、smime verifyを実行するときにチェックするサインの有効性を反映していることに注意してください。一致する場合は0、一致しない場合はゼロ以外です。
チェックがあなたのコードにある場合、彼らがあなたを打ち負かしたいのであれば、彼らはチェックを単に削除することができるので、これらすべては安全ではないことに注意してください。これを行う唯一の安全な方法は、OSにチェッカーをインストールしてバイナリをチェックし、署名されていない場合は実行を拒否することです。しかし、OSにはチェッカーがないため、Linuxを変更して削除/バイパスすることができます...これが本当に良いのは、人々があなたを迂回させないようにするだけでなく、破損したファイルを検出することです。
Linuxを取り巻く哲学、GNU et al。は、いじくり回しを中心に展開します。一方、一部のシステムは、プライバシーを損なう可能性があるソフトウェアの改ざんなどの脆弱性に対する保護に値するシステムのユーザーの整合性。
カーネルの実装は、カーネル自体の迅速な開発サイクルに対応できません。代わりに、ユーザー空間ツールを使用して、実行可能ファイルの署名の検証を実装することをお勧めします。実行可能ファイルをアーカイブまたはファイルシステムイメージに配置し、秘密キーを使用してイメージに署名します。その秘密鍵が開発マシン(プライベート)に残っている場合、サーバーがハッキングされても、攻撃者はシステムに騙して署名されていないイメージをマウントさせない限り、自分のイメージに署名してコードを注入することはできません。チェーンに沿ってさらに伸びます:
すべてを正しくすることは難しい努力です。別のアプローチでシステムを設計することで、すべてを回避する方がはるかに簡単です。