編集-1

編集-1

私はDebian Gnu / Linuxのさまざまな機能を試しています。

/bin/ping を現在の作業ディレクトリにコピーしました。もちろん、それは動作しませんでした。 setuid rootであることがわかりました。

その後、pingはpingに最小限の機能(ルートではない)を与え、sudo /sbin/setcap cap_net_raw=ep ./pingpingが期待どおりに機能しました。

その後、sudo /sbin/setcap -r ./ping能力をキャンセルします。これで期待どおりに動作しません。

今pingを動作させようとしていますcapsh

capsh権限がないため、rootとして実行してからroot権限を削除して、他のすべての権限を削除する必要があります。

secure-keep-caps文書化されていませんが、capsh機能マニュアルにあるこの機能も必要だと思います。からビット数を取得しました/usr/include/linux/securebits.h。出力に--printビットが正しいとマークされているため、正しいように見えます。

私は何時間もそれと私が今まで持っているものに触れてきました。

sudo /sbin/capsh --keep=1 --secbits=0x10 --caps="cap_net_raw+epi" == --secbits=0x10 --user=${USER} --print -- -c "./ping localhost"

ただし、その機能が存在しない場合に発生しますpingping: icmp open socket: Operation not permittedこれはまた、これが私たちが必要とするのに十分ではないことを--print示しています。Current: =p cap_net_raw+ie

sudo /sbin/capsh --caps="cap_net_raw+epi" --print -- -c "./ping localhost"機能をこれに設定するのCurrent: = cap_net_raw+eipは正しいですがroot

編集-1

今試してみましたsudo /sbin/capsh --keep=1 --secbits=0x11 --caps=cap_net_raw+epi --print -- -c "touch zz; ./ping -c1 localhost;"

これで以下が生成されます。

touch: cannot touch `zz': Permission denied
ping: icmp open socket: Operation not permitted

最初のエラーは予想されたが、secure-noroot: yes 2番目のエラーは予想されなかった。Current: = cap_net_raw+eip

編集2

==前に入れる--printと今表示されるので、以前のCurrent: = cap_net_raw+iエラーは説明されていますが、ルートから切り替えると電源が切れる理由は説明されていないので、このsecure-keep-caps問題を解決する必要があると思います。

編集3

私が見ることができる限り、execを呼び出すとvalid(e)とallowed(p)が失われます。これは当然のことですが、安全キャップをかぶせて紛失を防ぐ必要があると思います。私は何を逃したことがありませんか?

編集4

より多くの調査を行い、マニュアルをもう一度読みました。通常、ユーザーから切り替えると(または適用してルートを一般ユーザーにするとき)、機能が失われるようです。eこれは呼び出し時にオーバーライドできます。これは私が知っている限り不変です。prootsecure-norootsecure-keep-capsexec

私が知る限り、マニュアルどおりに動作しています。私が知っている限り、有用なことをする方法はありませんcapsh。私が知っている限り、関数を使用するには次のものが必要です。ファイル関数を使用または使用しない関数認識プログラムが必要ですexec。したがって、特権ラッパーはありません。

今私の質問は私が何を見逃していて、capsh私の目的は何ですか?

編集5

環境機能への回答を追加しました。継承された関数でも機能できますが、capsh便利に使用するには実行可能ファイルに設定する必要があります。私は周辺機能や継承された機能を許可せず、どのようにcapshが役に立つことができるか理解していません。


バージョン:

  • capshパッケージlibcap2-binバージョンから1:2.22-1.2
  • edit-3以前は最新バージョンを受け取り、capsh使いgit://git.debian.org/collab-maint/libcap2.git始めました。
  • uname -a Linux richard-laptop 3.2.0-4-amd64 #1 SMP Debian 3.2.65-1+deb7u2 x86_64 GNU/Linux ユーザースペースは32ビットです。

答え1

能力はプロセスの属性です。伝統的に3つのグループがあります。

  • 許可された機能():現在のプロセスで「アクティブ化」できる機能です。
  • 有効能力(金利):現在のプロセスで現在利用可能な機能です。
  • 遺伝能力(): 継承できるファイル機能です。

ルートとして実行されるプログラムは常に完全に受け入れられ、有効な機能を持っているので、より多くの機能を「追加」しても顕著な効果はありません。 (継承可能な機能セットは通常空です。)デフォルトでは、setcap cap_net_raw+ep pingこのプログラムを実行しているすべてのユーザーに対してこれらの機能を有効にします。

残念ながら、これらの関数は実行されたファイルにバインドされており、新しい子プロセスを実行した後も保持されません。 Linux 4.3 リリース環境能力これにより、子プロセスが機能を継承できます。 (あなたも見ることができますexecve() 中の関数変換存在する能力(7).)

機能を使用するときは、次のトラップに注意してください。

  • ユーザーをrootからroot以外のユーザーに変更すると、有効かつ許可された権限が消去されます(参照:ユーザーIDの変更が機能に与える影響存在する能力(7))。--keep=1オプションを使用すると、capshコレクションが消去されるのを防ぎます。
  • ユーザーまたはグループIDを変更すると、環境機能セットがクリアされます。回避策:環境機能の追加後ろにユーザーIDを変更しましたが、今後子プロセスを実行します。
  • 許可された機能セットと継承可能な機能セットの両方にすでに存在する場合にのみ、機能を環境機能セットに追加できます。

libcap 2.26以降、capshプログラムは次のオプションで環境機能を変更する機能を得ました--addamb犯罪)。オプションの順序が重要です。使用例:

sudo capsh --caps="cap_net_raw+eip cap_setpcap,cap_setuid,cap_setgid+ep" \
    --keep=1 --user=nobody --addamb=cap_net_raw -- \
    -c "./ping -c1 127.0.0.1"

ヒント:--printコマンドラインの任意の場所にこのオプションを追加して、capsh現在の機能を確認できます。

注:cap_setpcapは必須--addamb、オプションはcap_setuid,cap_setgid必須です--user

答え2

Lekensteinの答えは正確で完全に見えますが、環境機能セットが解決する問題を強調するために、別の観点から別の説明を提供しようとします。

次の実行時にsudo capsh --user=<some_user> --関数を再計算(および削除することもできます)する2つのシステムコールがあります。

  1. setuid:によるとman capabilities

SECBIT_KEEP_CAPS このフラグを設定すると、1 つ以上の 0 UID を持つスレッドが、すべての UID が 0 以外の値に切り替えられたときに機能を維持できます。このフラグが設定されていない場合、これらのUIDswitchはスレッドがすべての機能を失います。

つまり、上記のコマンドでは、システムコール時にSECBIT_KEEP_CAPSが設定されていることをcapsh確認する必要があります。setuidそれ以外の場合、すべての能力が失われます。それがまさにそのこと--keep=1です。これで、コマンドは次のようになります。sudo capsh --user=<some_user> --keep=1 --

  1. execve:このオプションを使用すると、--keep=1すべての機能セット(有効、許可、継承可能)が維持されます。まで...ただし、このexecveシステムコールを使用すると、execveより明確な方法で権限が再計算されます(root以外のユーザーの場合)。要するに、環境機能セットを追加する前に、スレッドが呼び出された後に集中するように「許可された」関数の場合は、次のことがexecveできます。

    • ファイルには「許可」セットの機能が必要です。。これはで行うことができますsetcap cap_net_raw+p /bin/bash。そうすると、スレッドの機能セット(境界セットを除く)がもはや効果がなくなるため、全体の練習が役に立たなくなります。
    • ファイルとスレッドの両方に「継承可能」セットに機能が必要です。。これは問題を解決すると思うかもしれませんが、これは許可されていないユーザーが呼び出すとスレッドの一意の権限が削除されることを示してsetcap cap_net_raw+iいます(現在これを監査する必要があります)。したがって、権限のないユーザーとしてこの条件を満たす方法はありません。execvesetuid

Linux 4.3で導入された環境機能を使用すると、setuid権限のないユーザーにスレッドが提供され、その後スレッドが提供されてもスレッドの機能を維持できますexecveファイル機能に頼る必要はありません。

答え3

最近、カーネルの呼び出し時間を改善するLekensteinの答えを少し調整しました。

sudo /usr/sbin/capsh --keep=1 --user=$USER \
  --inh=cap_net_raw --addamb=cap_net_raw -- \
  -c './ping -c1 localhost'

注:sudoersファイルによっては、環境が混乱する可能性があります(例:HOMEの変更)。 capshはuidを変更しますが、sudoの環境変更を元に戻すために何もしません。

だからどうしたの?一度見てください。

  • sudo /usr/sbin/capsh:有効な(これを実行できます)セットと許可された(有効なセットに追加できます)セットのすべての機能を持っていますが、他のセットには何もないルートから始めます。他のコレクションについては後で議論します。
  • --keep=1:セキュリティ(読み取り:レガシー)理由により、機能は通常、ルート - >ルートではなくIDスイッチから継承されません。このフラグはSECBIT_KEEP_CAPSこれを行う機能を有効にします。 exec時に自動的に消去される点は注目に値するが、これは良い考えです。
  • --user=$USER:UIDの変更ですべての機能が失われるわけではないので、ルートステータスを終了します。ありがたいことにSECBIT_KEEP_CAPS、私たちはルートと同じ権限を維持しており、私たちの機能をさらに混乱させます。
  • --inh=cap_net_raw:関数が継承可能でない場合は環境関数として設定できないため、ターゲット関数を継承可能なセットに追加します(次のトピックを参照)。
  • --addamb=cap_net_rawSECBIT_KEEP_CAPS:権限がないexecve(setuid / setgid / setcapなし)バイナリまだ私たちの能力の明確さは特権につながりません。 Linux 4.3には、権限のないバイナリを実行したときに有効で許可されたセットを再追加する環境セットが追加されました。完璧!
  • -- -c ...:すべての設定が完了したら、次のパラメータを使用してbashを実行します。機能セットが消去され(bashには権限がないため)、環境セットが再び追加されます。チャジャン!生のソケットを開くために必要な権限があります。

capshの特別な引数を使用して==これを確認できます。これは、コマンドラインの残りの部分を使用して独自に実行できるようにします。

sudo /usr/sbin/capsh --keep=1 --user=$USER \
  --inh=cap_net_raw --addamb=cap_net_raw == --print

Current: = cap_net_raw+eip

これは、cap_net_rawを有効(実行可能)、継承可能(子プロセスに転送可能)、許可(インポート許可)として処理することを意味します。その中に他の機能はありません。

機能と仕組みの詳細については、最良の方法は次のとおりです。Function(7) マニュアルページ。具体的にはタイトルTransformation of capabilities during execve()

答え4

このsetprivコマンドは.comよりも処理が簡単ですcapsh。質問のランタイム機能部分の代わりにこれを使用することを検討してください。部品に大きな影響はありませんsetcap

$ setpriv --help

Usage:
 setpriv [options] <program> [<argument>...]

Run a program with different privilege settings.

これでping、Fedora 32の権限を持たないユーザーとして、次のタスクを実行します。

$ cp /usr/bin/ping .
$ ./ping -c 1 ::1
PING ::1(::1) 56 data bytes
64 bytes from ::1: icmp_seq=1 ttl=64 time=0.030 ms

だから私は次を選択しましたtcptraceroute

$ tcptraceroute ::1
Running:
    traceroute -T -O info ::1 
You do not have enough privileges to use this traceroute method.
socket: Operation not permitted

そして

$ sudo setpriv --no-new-privs  --inh-caps '-all,+net_raw' --bounding-set '-all,+net_raw' tcptraceroute ::1
Running:
    traceroute -T -O info ::1 
traceroute to ::1 (::1), 30 hops max, 80 byte packets
 1  localhost (::1) <rst,ack>  0.041 ms  0.010 ms  0.007 ms

このコマンドには広範囲に昇格された権限がありません。

$ sudo setpriv --no-new-privs  --inh-caps '-all,+net_raw' --bounding-set '-all,+net_raw' touch /root/secret
touch: cannot touch '/root/secret': Permission denied

$ sudo setpriv --no-new-privs  --inh-caps '-all,+net_raw' --bounding-set '-all,+net_raw' sudo touch /root/secret
sudo: PERM_SUDOERS: setresuid(-1, 1, -1): Operation not permitted
sudo: no valid sudoers sources found, quitting
sudo: error initializing audit plugin sudoers_audit

$ sudo setpriv --no-new-privs  --inh-caps '-all,+net_raw' --bounding-set '-all,+net_raw' id
uid=0(root) gid=0(root) groups=0(root) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023

関連情報