実行権限はあるがコピー権限はないファイルをどのようにコピーしますか?

実行権限はあるがコピー権限はないファイルをどのようにコピーしますか?

/etc/のサブディレクトリにコピーしたいファイルがありますが、通常のユーザーとしてそのファイルを実行できますが、実行すると

cp /etc/subdir/desired_file .

許可が拒否されました。ただし、スーパーユーザー権限なしでファイルを実行できます。このファイルを別のディレクトリにコピーする方法はありますか?

編集:ファイル権限を変更しないでください

ベストアンサー1

cp src dstファイルの内容を読み取り、生成された新しいファイルsrc に書き込みます。dst

したがって、ファイルに対する読み取り権限が必要です。

少なくともLinuxbtrfsread()いくつかのwrite()ファイルシステム(例:ioctl (dest_fd, FICLONE, src_fd)リンクの配信コピーsrc_fdデータが最初にディスクにコピーされなかった場合でも。

ファイルをコピーするだけで読み取り制限を迂回することができれば、権限システムが深刻に破損します。

これで、ファイルをコピーする代わりに、別の名前でファイルへの新しいリンクを作成できます。

後ろに:

ln from/src to/dst

これを行うには、fromディレクトリへの検索アクセス権とディレクトリへの検索+書き込みアクセス権のみが必要です。toで終わるdstsrc、2つの異なるディレクトリ(または異なる名前を持つ同じディレクトリ)へのリンクsrcdst同じファイルの。

もしsrcそうなら実行可能ファイルこれはデフォルトの実行可能形式です(たとえば、スクリプトとは対照的に、インタプリタが読み取り可能である必要があるため、読み取り権限なしでスクリプトを実行することはできませんが)。つまり、システムがオブジェクトをマッピングできることを意味します。実行可能ファイルは、次のいずれかのメモリに保存されます。あなたのこれはあなたに代わって読むのと同じです。

システムは読み取り制限バイパスを許可しないように注意してください。たとえば、少なくともLinuxでは、プロセスがSIGQUIT(Ctrl+から送信\ )などの信号を受信したときにコアダンプを生成しません。プロセスを読み取っ/proc/<pid>/mapsたり実行したりできません。/proc/<pid>/mem

$ cp /usr/bin/sleep .
$ chmod 111 sleep
$ ./sleep inf &
[1] 86474
$ cat /proc/$!/maps
cat: /proc/86474/maps: Permission denied
$ cat /proc/$!/mem
cat: /proc/86474/mem: Permission denied

またkernel.yama.ptrace_scope = 0

しかし、プロセス自体は明らかに自分のメモリを読み取ることができるので、プロセスがどこかにメモリを捨てるように説得できれば回復することができます。一部ファイルのデータ。

ファイルが動的にリンクされたELF実行可能ファイルで、setuid / setgidではない場合...(安全実行モードが有効になっていない)少なくともGNU / Linuxシステムでは、動的リンカーが実行可能ファイルにランダムなコードを挿入するように説得できます。 。$LD_PRELOADまたは、変更を転送するためにハイジャックされた共有ライブラリの変更されたバージョンを使用するように指示します$LD_LIBRARY_PATH

たとえば、

#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>

static void init(void) __attribute__((constructor));
static void init(void)
{
  FILE *maps, *dst;
  char exe[4096], path[4096];
  char *start, *end;
  off_t offset;
  int n;

  n = readlink("/proc/self/exe", exe, sizeof(exe));
  exe[n] = '\0';
  dst = fopen(getenv("DST"), "w");
  maps = fopen("/proc/self/maps", "r");

  while((n = fscanf(maps, "%p-%p%*s%lx%*s%*s%*[ ]%[^\n ]\n", &start, &end, &offset, path)) != EOF) {
    if (n == 4 && !strcmp(path, exe)) {
      printf("Dumping [%p - %p] from %s at offset %#lx\n", start, end, path, offset);
      fseek(dst, offset, SEEK_SET);
      fwrite(start, end - start, 1, dst);
    }
  }
  exit(0);
}

(エラー処理は読者の練習問題として残しておきます.)

次にコンパイル:

gcc -fPIC -shared -o hack.so that-file.c

次に実行するsrc

DST=./dst LD_PRELOAD=./hack.so ./src
truncate -r src dst

ファイルのメモリマップされた部分が./dstファイルにダンプされます。

次の読み取り可能なコピーがあり、次のものをsrc使用する場合:

cmp -l src-copy dst | perl -pe 's/\d+/sprintf"%#x",$&-1/e'

objdump -h src-copy出力をオフセットの出力と一致させると、一部が欠落しているか動的リンカーによって変更されたため、同じではないことがわかります。私のテストでは、次のようになります。

 20 .init_array   00000008  0000000000009bb0  0000000000009bb0  00008bb0  2**3
                  CONTENTS, ALLOC, LOAD, DATA
 21 .fini_array   00000008  0000000000009bb8  0000000000009bb8  00008bb8  2**3
                  CONTENTS, ALLOC, LOAD, DATA
 22 .data.rel.ro  000000b8  0000000000009bc0  0000000000009bc0  00008bc0  2**5
                  CONTENTS, ALLOC, LOAD, DATA
 23 .dynamic      000001f0  0000000000009c78  0000000000009c78  00008c78  2**3
                  CONTENTS, ALLOC, LOAD, DATA
 24 .got          00000190  0000000000009e68  0000000000009e68  00008e68  2**3
                  CONTENTS, ALLOC, LOAD, DATA
 26 .bss          000001b8  000000000000a080  000000000000a080  00009080  2**5
                  ALLOC

ただし、部分は少なくとも完全であり、これは、読み取れない動的にリンクされたELF実行可能ファイルに秘密を隠そうとする試みが無益であることを示しています.text.rodata

おすすめ記事