2

I have a file in a subdirectory of /etc/ which I would like to copy, I can run this file as a regular user, however when I run

cp /etc/subdir/desired_file .

I am refused permission. However I can execute this file without superuser permissions. Is there a way for me to copy this file into another directory?

edit: without changing file permissions

Pale
  • 21
  • ls -l /etc/file gives you -rws--x--x 1 root root suid & user's executable bit enabled (lowercase s) - the bits rwsr-x---x are set. – Dipankar Nalui Apr 04 '18 at 09:18
  • Only chmod can change this. And root user has that permission. So normal user will not be able to do anything. read here https://unix.stackexchange.com/questions/79395/how-does-the-sticky-bit-work/79401#79401 – Dipankar Nalui Apr 04 '18 at 09:21
  • Do you have write permission in the target directory? – Kusalananda Apr 04 '18 at 09:26
  • can you post the output of 'll filename' command. – erTugRul Apr 04 '18 at 09:36
  • 1
    You might think that you could start executing the program and then use a utility to copy the process memory to a file. But I believe that when you're executing a read-restricted binary, memory-reading utilities are blocked as well. – Barmar Apr 04 '18 at 19:26

2 Answers2

1

cp src dst reads the contents of the src file and writes in into the new dst file it has created.

So it needs read permission to the file.

On Linux at least and on some file systems such as btrfs, it can replace the read()s + write()s with a ioctl (dest_fd, FICLONE, src_fd) to do a so called reflink copy where the data is initially not duplicated on disk, but even then it still needs to open the source file for reading onto src_fd.

If it was enough to copy a file to bypass read restrictions, then the permission system would be severely broken.

Now, instead of copying a file, you could make a new link to it with a different name:

After:

ln from/src to/dst

For which you only need search access to the from directory and search+write access to the to directory, with dst on the same filesystem as src. You end up with both src and dst, but note that they are the same file linked to two different directories (or the same directory with different names).

Now, if src is executable, and is a native executable format (as opposed to a script for instance, though you can't run a script without read permission as the interpreter does need to be able to read it), that means the system is allowed to map the contents of the executable into the memory of one of your processes, which kind of amounts to reading it on your behalf.

The system does take care not to allow bypassing the read restriction. For instance, at least on Linux, the process won't generate a core dump when receiving signals such as SIGQUIT (as sent upon Ctrl+\ ). It won't let you read /proc/<pid>/maps or /proc/<pid>/mem for that process:

$ 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

It will also not let you attach a debugger to it, even with kernel.yama.ptrace_scope = 0.

But the process itself can obviously read its own memory, so if you can convince it to dump it somewhere, you could recover some of the data in the file.

If the file is a dynamically linked ELF executable and it's not setuid/setgid... (secure-execution-mode not enabled), on GNU/Linux systems at least, you can convince the dynamic linker to inject arbitrary code into the executable with the $LD_PRELOAD mechanism, or tell it to use modified versions of the shared libraries it uses that have been hijacked to do that dumping by changing $LD_LIBRARY_PATH.

For instance with:

#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); }

(error handling left as an exercise to the reader)

Compiled with:

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

Running src as:

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

Would have it dump the sections of the file that are mapped into memory into the ./dst file.

If you have a readable copy of src and use:

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

And match the output against the output of objdump -h src-copy on the offsets, you'll see it's not identical as some sections are missing or have been modified by the dynamic linker. In my tests, they were:

 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

But the .text and .rodata sections at least are intact, which shows that it's futile to try to hide secrets in a non-readable dynamically linked ELF executable.

0

There could be two scenarios here:

  1. Either you lack read permission on desired_file. You might be having execute permission on the file but to view or copy the file, read permission is required.

  2. Or you lack write permissions on the destination directory.

Please go through https://www.tutorialspoint.com/unix/unix-file-permission.htm . It will help you know of unix permissions.

The owner can grant permissions using chmod command.

Nik
  • 33
  • 1
    Yes I lack read and write permissions, however given that I am capable of executing the program, is there any way to get the data of the executable and place that somewhere else. I.e. indirectly copy the program? – Pale Apr 04 '18 at 08:26
  • You can ask the owner to grant permission or impersonate the group or owner id to modify permissions.

    It is not possible to read a file's content with execute permission only.

    – Nik Apr 04 '18 at 08:31
  • You can run the below command to add the read permissions. But, this will require one time access to superuser --> chmod 755 /etc/subdir/desired_file – Nik Apr 04 '18 at 08:34
  • 1
    Yes I know about chmod, I should have made it clear in my question without gaining super user permissions. – Pale Apr 04 '18 at 08:46
  • 1
    If you're thinking about using ptrace() (eg: gdb, strace), forget it: if the "text" file is not readable you get an EPERM error. – A.B Apr 04 '18 at 12:19