2013-04-12 12 views
5

スプーフィング(ルートとして)Unixソケット(ファイル・システム・ソケット)getsockopt()によって得ることができるピアクレデンシャル、オプションSO_PEERCREDに(互換)方法はありますか?UNIXソケット:getsockopt()をスプーフィングすることはできますか?SO_PEERCRED?

背景:
IはSO_PEERCREDを介してそれに接続するプロセスのUIDをチェックし(私は変更できない)サーバ・アプリケーションに接続する必要があります。 のアプリケーションに接続するには、情報を偽装したいのですが、もあります。
私は、サーバーが特定のピアUID/GIDを見ている非侵襲的な方法を探しています:質問を明確にするために

UPDATE

。 ソリューション(等LD_PRELOAD、システムコールインターセプト)カーネルを変更(またはカーネルモジュールの使用を取る)する必要を推奨またはサーバープロセスまたはその負荷を変化させる/どのような方法で処理を連結しています。

基本的には、特別な要件を必要とせずに任意のLinux(または一般的にはUNIX)サーバーで実行している場合、解決策が機能するはずです。サーバープロセスは既に実行されている可能性があります。

+1

もしあなたが 'root'ならば、' setuid'だけではないのですか?あなたは完全に制御された子プロセスからそれを行うことができますので、実際に特権を失うのを避けることができます。 – nneonneo

+0

私は確信していませんが、Linuxでは、 '/ proc//fdinfo/'に8進数のプレフィックスフラグがあります。 – alk

+1

サーバープロセスの開始を制御できますか?つまり、LD_PRELOADを使用して、報告された資格情報を変更するためにライブラリ関数/ syscallサンクを変更できますか? –

答えて

-1

いいえ。なぜなら、ピアのUIDとGIDを提供するメカニズムが、カーネルの内部でであり、カーネルを偽装できないからです!カーネルは、ピアのPIDを使用して、ピアの有効なクレデンシャルを推定します。これは片側がソケット上でconnectを実行したときに発生します。 copy_peercred()への電話番号はunix_stream_connect()からnet/unix/af_unix.cまでです。ピアが送信するデータを変更する方法や、ピアのPIDがそうでないことをカーネルに知らせるソケットはありません。これは、カーネルがピアのプロセスに関する内部知識を持たず、ピアが送信するIPパケットヘッダ内のデータだけを見ることができるAF_INETソケットとは異なります。

この効果を得るためにできる唯一のことは、ピアプロセスの実効UIDをrootまたは任意のUID/GIDに設定することです。そのためには、rootパスワードまたはsudo特権が必要です。

+1

しかし、あなたは*カーネルを偽装することができます - rootとして、モジュールをロードすることによって実行中のカーネルの動作を変更することができます。 –

+0

@ChrisStratton:あなたが書くモジュールは、Unixドメインソケットの動作を変更することはできません。 –

+0

あなたは**それを信じることに重大な間違いを犯しています。最も簡単なアプローチは、カーネルに入った直後にディスパッチする時点でシステムコールをリダイレクトするモジュールを作ることですが、Unixドメインソケット実装の内部を変更することも最終的にはオプションです。エクスポートされていないものは*保護*されていないことを覚えておいてください。ソースを開いてビルドの設定を知られている可能性が高いだけではありません。 –

3

あなたは正しい行にあります。ルートプロセスはこのようなことを盗む特権を持っていますが、SO_PEERCREDはプロセスにどのアイデンティティをピアに提示すべきかを指定するメカニズムやAPIを提供していません。あなたが行うことができます

2つのこと:あなたがconnect電話をかけるとき

  1. は一時的にルート(setreuid(desired,-1))をドロップします。プロセスがconnect(およびlistenの逆もあります)と呼ばれた時点で、ピアの資格情報でUnixドメイン接続がスタンプされます。 SO_PEERCREDは現時点でピアの資格情報を教えてくれません。その後、ルートを再開できます。

  2. さらに、別のAPIを使用してください。メッセージ・パッシングAPIは、プロセスがピアに提示するものを選択します。送信する認証情報を含むにstruct cmsgと電話をかけてください。カーネルは特権のないユーザーが指定した資格情報を無視し、相手側が実際の身元を確認するようにしますが、特権を持つプロセスはほかの人物のふりをすることができます。これは、あなたのニーズに適しています。なぜなら、根を落とし取り戻すことは危険な活動であり、この場合は不要です。コードサンプルを取得するには、Googleの "SCM_CREDENTIALS"(またはシステムの "man -K")を使用します。

+1

サーバーがSO_PASSCREDソケットオプションを設定せず、資格情報を読み取った場合、ソリューション2は機能しません。 SO_PEERCREDだけを使用すると、単純なワンショットPID認証に悩まされます。 SO_PEERCREDの例については、http://man7.org/tlpi/code/online/dist/sockets/scm_cred_recv.c.htmlを参照してください。いずれにしても、rootがSCM_CREDENTIALSを使用して権限を引き下げることは、「なりすまし」になることはほとんどありません。 –

+1

OK、それを "偽装"と呼んでください...また、いくつかの資格情報を送る場合は、もう一方の端にSO_PASSCREDを設定する必要はありません。彼らは 'recvmsg'出力にあなたのために到着すべきです。おそらくそれはOSに依存しているでしょうか?私はLinuxを使う傾向がありません。 SO_PASSCREDは、通常、資格情報を読み込みたいが、相手側は資格情報を書き込もうとしていないときに使用されます。カーネルに各メッセージでピアの資格情報を与えるように指示します(特にDGRAMソケットにはうってつけです)。 –

+1

「資格情報を受け取るためにSO_PASSCREDソケットオプションを設定する必要があります」という例を読んでください。オプションはSCM_CREDSと呼ばれるBSD/FreeBSDでも同じです。 –

関連する問題