グループメンバーシップとsetuid / setgidプロセス


10

プロセスデエスカレート経由権限setuid()setgid()UID / GID彼らはセットのグループメンバーシップを継承していないようです。

特権ポートを開くためにrootとして実行する必要があるサーバープロセスがあります。その後、特定の非特権uid / gid 1にエスカレートします-たとえば、ユーザーfoo(UID 73)のuid / gid 。ユーザーfooはグループのメンバーですbar

> cat /etc/group | grep bar
bar:x:54:foo

したがって、としてログインするとfoo/test.txt次の特性を持つファイルを読み取ることができます。

> ls -l /test.txt
-rw-r----- 1 root bar 10 Mar  8 16:22 /test.txt

ただし、std=gnu99ルートを実行すると、次のCプログラム(コンパイル)が表示されます。

#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>

int main (void) {
    setgid(73);
    setuid(73);
    int fd = open("/test.txt", O_RDONLY);
    fprintf(stderr,"%d\n", fd);
    return 0;
}   

常にアクセス許可が拒否されたことを報告ます。これは非ログインプロセスに関係していると思いますが、許可が機能すると想定されている方法をハムストリングのように扱います。


1.これはサーバーのSOPであることが多く、Apacheを使用して誰かが報告したため、これを回避する方法があるはずだと思います。Apacheはオーディオグルー​​プに追加されており、サウンドシステムを使用できるようです。もちろん、これはおそらく元のプロセスではなくフォークで起こりますが、実際には私のコンテキストでは同じです(それはsetuid呼び出しの後にフォークされた子プロセスです)。


setuid()/ setgid()呼び出しを切り替えます。
フォンブランド2014年

@vonbrand ROTFL私はそこでフェイスパームに参加していると思いました-同じ結果なので、質問を編集して赤いニシンを排除します。
goldilocks 2014年

1
setgid(54)代わりにを使用した場合setgid(73)(のように/etc/groups、グループにbarはgid 54があります)、それは機能しますか?
lgeorget 2014年

@lgeorget確かに、それは目的を無効にします。プロセスには他の理由で独自のGIDが必要です。同様に、これらのファイルには、それらが持っているアクセス許可が必要です。そのため、複数のグループのメンバーシップが必要です。たとえば、2人のユーザーがこれを行う必要がある場合はどうでしょうか。あなたがそれをsetuid()した後、あなたは再びできないことに注意してください...しかし、うーん...私はあなたと一緒にできると思いますseteuid()...
goldilocks

1
私の質問は、他のどこかに隠された微妙な問題がないことを確認することでした。:-)
lgeorget 2014年

回答:


14

問題は、ということですsetuidし、setgid あなたのプロセスにそれが必要とするすべての認証情報を与えるのに十分ではありません。プロセスの承認は、

  • そのUID
  • そのGID
  • その補足グループ
  • その機能。

詳細については、man 7 credentialsを参照してください。したがって、あなたの場合、問題はUIDとGIDを正しく設定しているが、プロセスの補足グループを設定していないことです。また、グループにbarはGID 54があり、73はないため、プロセスが属するグループとして認識されません。

やったほうがいい

#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <grp.h>

int main (void) {
    gid_t supplementary_groups[] = {54};

    setgroups(1, supplementary_groups);
    setgid(73);
    setuid(73);
    int fd = open("/test.txt", O_RDONLY);
    fprintf(stderr,"%d\n", fd);
    return 0;
}  

1
これは興味深い質問であり、実際に多くの人々に役立つ可能性があるため、より多くの賛成票を投じる価値があります。:-)
lgeorget 2014年

だから私はシリアルポートで同様の問題を抱えていました。私はこれをdialoutグループに実装しましたが、最初はうまくいきました。
tl8 2017

0

OK、ネットを少し巡りました。最初はAPUEがすべての答えを保持すると思っていましたが、間違っていました。そして、私のコピー(旧版)が動作しているので... UnixとLinuxの管理ハンドブックの第5章は有望に見えますが、それはわかりません(最初の2つのエディションのコピーだけでも動作しています)。

私が見つけた小さなリソース(「デーモンライティングUNIX」のグーグル)はすべて、ttyから分離する方法などの重要なステップについて話します。しかし、UID / GIDについては何もしません。不思議なことに、http: //tldp.orgにある広範なHOWTOコレクションでさえ詳細を持っているようには見えません。唯一の例外は、Jason ShortのLinuxデーモンを作ろう-パートIです。SUID / SGIDとそのすべての混乱がどのように機能するかについての詳細は、Chen、Wagner、DeanのSUIDがわかりやすくなっています(USENIX 2002の論文)。ただし、LinuxにはFSUIDという追加のUIDがあります(詳しくは、WolterのUnix非互換性ノート:UID設定関数を参照してください)。

プロセスをデーモン化することは、心の弱い人には絶対にありません。一般的なセキュリティの考慮事項は、D。WheelerのLinuxおよびUnix向け安全なプログラミングHOWTO-安全なソフトウェアの作成に記載されています。Systemdは、そのほとんどを単純化することを約束します(したがって、セキュリティ上の問題につながるミスの余地を減らします)。デーモンのマニュアルを参照してください。


1
問題はデーモン化についてではありません。SUIDビット(プロセスに実行可能ファイルの所有者のアクセス許可を与える)とを混同しましたsetuid()。これにより、プロセスがUIDを任意に変更できるようになります。SUIDは通常、権限の昇格(非特権->特権)を許可することを目的としてsetuid()いますが、反対のことしかできません。
goldilocks 2014年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.