13

起動後、Linux プログラムで root 権限を削除し、権限のないアカウントに切り替えたいと考えています。オンラインでさまざまな例を見つけましたが、具体的には私の要件に対して標準的なものはありません:

  1. これは永続的なドロップです
  2. (e)uid と (e)gid の両方を非ルートに切り替える必要があります
  3. Linux サポートのみ (カーネル > 2.6.32)
  4. 補助グループは必要ありません

私が見つけた最良のアプローチは次のとおりです。

uid_t new_uid = ...;
gid_t new_gid = ...;

gid_t rgid, egid, sgid;
if (setresgid(new_gid, new_gid, new_gid) < 0)
{
    perror("setresgid");
    exit(EXIT_FAILURE);
}
if (getresgid(&rgid, &egid, &sgid) < 0)
{
    perror("getresgid");
    exit(EXIT_FAILURE);
}
if (rgid != new_gid || egid != new_gid || sgid != new_gid)
{
    printf("unexpected gid");
    exit(EXIT_FAILURE);
}

if (setgroups(0, 0) != 0)
{
    perror("setgroups");
    exit(EXIT_FAILURE);
}

uid_t ruid, euid, suid;
if (setresuid(new_uid, new_uid, new_uid) < 0)
{
    perror("setresuid");
    exit(EXIT_FAILURE);
}
if (getresuid(&ruid, &euid, &suid) < 0)
{
    perror("getresuid");
    exit(EXIT_FAILURE);
}
if (ruid != new_uid || euid != new_uid || suid != new_uid)
{
    printf("unexpected uid");
    exit(EXIT_FAILURE);
}

これを exe にラップし、次のコマンドを使用して uid と gid が正しく表示されることを実証できます。

ps -eO user,uid,ruid,suid,group,gid,rgid,sgid

プログラムは、特権ポートにバインドしたり、ほとんどのルート所有ファイルを操作したりできないため、それで問題ありません。

また、プロセスに予期しない機能がないことを確認するcaptestプログラム (libcap-ng-utils に含まれています) も見つけました(7)

ただし、セキュリティが懸念事項であるため、必須ではないすべての特権を正しく削除したことをより確信したいと思います。どうすれば確信できますか?

ありがとう。

4

1 に答える 1

1

これを行うための「標準的な」方法は、DJBernstein によって「setuidgid」コードで実装されました。これは、もともと彼の QMail プログラムで使用され、現在は「daemontools」に含まれています。

GNU coreutils で使用される実際のコードは DJB の手順の説明に基づいており、そのコードはここで見ることができますhttps://github.com/wertarbyte/coreutils/blob/master/src/setuidgid.c

于 2012-09-12T11:23:20.823 に答える