2

Ubuntu 12.04 (64 ビット) を使用して、Linux のアクセス許可に関するいくつかの実験を行っています。

以下のプログラムを作成しました。

#include<stdio.h>
#include <unistd.h>    
main(){   
    printf("euid=%4d uid=%4d egid=%4d gid=%4d\n", geteuid(), getuid(),getegid(),getgid());
    system("id");
}

そして、その実行可能ファイルを setuid/setgid ファイルとして設定します。

-rws--s--x 1 root  root   8638 Apr 28 02:00 pt*

特権のないユーザーから実行すると、次の出力が得られます。

euid=   0 uid=1001 egid=   0 gid=1001
uid=1001(test1) gid=1001(test1) euid=0(root) egid=0(root) groups=0(root),1001(test1)

system() syscall の使用後にルート権限が削除されることを期待します (これが、シェルコードが通常 system() の代わりに execv() を使用する理由です) が、そうではありません。

理由を説明していただけますか?

ありがとうございました。

4

2 に答える 2

1

system()特権を削除 (または追加、または変更) しません。そうすることは文書化されておらず、その実装または使用法について、そうであることを示唆するものはないはずです。なぜそうなると思ったのかわかりません。

「シェルコード」(悪意のあるエクスプロイト コード) が好まexecv()れるのは、次の 2 つの理由からだと思います。

  • system()の機能は、新しいプロセスをフォークし、指定されたコマンド ラインでシェルを生成し、それが終了するのを待つことです。シェルコードは、プロセスを fork してそれを待つ必要がなく、コマンド ラインを解析するために追加のシェルを導入する必要もありません。
  • execv(2)はシステムコールsystem(3)ですが、ライブラリ関数です。外部から導入されたコードは、それを呼び出すために、ライブラリ関数の実装が存在するアドレスを正しく推測する必要があります。しかし、システム コールを呼び出すには、syscall 番号と、カーネルにトラップする適切な魔法の (プラットフォーム固有の) マシン命令を呼び出すだけで済みます。
于 2013-04-28T02:45:53.083 に答える