Table of Contents

id

user@host ~ $ whoami
user
user@host ~ $ groups
wheel users android
user@host ~ $ groups john
android chromium
user@host ~ $ id
uid=1005(user) gid=100(users) grupy=100(users),10(wheel),968(android)
user@host ~ $ id john
uid=1234(john) gid=1001(chromium) grupy=1001(chromium),968(android)

su

user@host ~ $ su
Password:
root@host /home/user # exit
user@host ~ $ su john
Password:
[host /home/user]$ exit
exit
user@host ~ $ id
uid=1005(user) gid=100(users) groups=100(users),10(wheel),968(android)
user@host ~ $ newgrp android
user@host ~ $ id
uid=1005(user) gid=968(android) groups=968(android),10(wheel),100(users)
user@host ~ $ exit
exit
user@host ~ $ su john
Password:
[host /home/user]$ sg android -c 'ps -H -o user,group,cmd -t `tty`'
USER     GROUP    CMD
user     users    -bash
root     users      su john
john     chromium     bash
root     chromium       sg android -c ps -H -o user,group,cmd -t `tty`
john     android          ps -H -o user,group,cmd -t /dev/pts/11
[host /home/user]$ exit
exit
user@host ~ $
Notice that every time a command such as su, newgrp, … is started, it launches a new process (a shell by default).

who

user@host ~ $ who
user     tty2         2025-01-04 10:04 (:0)
user     pts/0        2025-01-04 10:04 (:0)
user     pts/1        2025-01-04 10:06 (:0)
user     pts/2        2025-01-04 12:25 (:0)
user     pts/4        2025-01-04 12:27 (:0)
user     tty3         2025-01-04 14:54
user     pts/6        2025-01-04 18:36 (:0)
jane     pts/5        2025-01-04 13:43
john     pts/3        2025-01-04 23:43
user@host ~ $ w
 23:46:14 up 13:45,  9 users,  load average: 0.97, 0.66, 0.53
USER     TTY        LOGIN@   IDLE   JCPU   PCPU WHAT
user     tty2      10:04   12:45m  0.00s  0.17s /usr/bin/startplasma-x11
user     pts/0     10:04    2:21   0.95s  0.72s /bin/bash
user     pts/1     10:06    2:04m  0.26s  0.06s alsamixer -c0
user     pts/2     12:25    0.00s  0.23s  0.23s /bin/bash
user     pts/4     12:27   54:13  10.42s 10.33s ssh root@10.0.0.7
user     tty3      14:54    8:52m  2:07    ?    xinit /etc/X11/xinit/xinitrc -- /etc/X11/xinit/xserverrc :1 -auth /tmp/serverauth.w8runSyQCb
user     pts/6     18:36    3:26m  0.21s   ?    /usr/bin/less
jane     pts/5     13:43    2:22   0.80s  0.52s top
john     pts/3     23:43    2:27   0.23s  0.01s /usr/lib/python-exec/python3.12/python
user@host ~ $ last -n 3 user
user     tty3                          Sat Jan  4 14:54   still logged in
user     pts/9                         Sat Jan  4 20:05 - 09:13 (5+13:08)
user     pts/1        :0               Thu Jan  2 10:05 - 10:21  (00:15)
wtmp begins Mon Dec 31 23:59:59 2024
user@host ~ $ last -n 7
john     pts/3                         Sat Jan  4 23:43   still logged in
user     tty3                          Sat Jan  4 14:54   still logged in
jane     pts/3                         Sat Jan  4 13:43   still logged in
user     pts/9                         Sat Jan  4 20:05 - 09:13 (2+13:08)
user     pts/1        :0               Thu Jan  2 10:05 - 10:21  (00:15)
user     pts/17       :0               Wed Jan  1 22:10 - 22:37  (00:26)
reboot   system boot  6.8.8            Wed Jan  1 22:08   still running
user     pts/16       :0               Wed Jan  1 12:10 - 12:37  (00:26)
wtmp begins Mon Dec 31 23:59:59 2024

umask

user@host ~ $ umask
0022
user@host ~ $ mkdir d_zero-two-two
user@host ~ $ touch f_zero-two-two
user@host ~ $ umask 027
user@host ~ $ mkdir d_zero-two-seven
user@host ~ $ touch f_zero-two-seven
user@host ~ $ umask 421
user@host ~ $ mkdir d_four-two-one
user@host ~ $ touch f_four-two-one
user@host ~ $ ls -ltr
drwxr-xr-x 2 user users  4096 Jan 04 00:01 d_zero-two-two
-rw-r--r-- 1 user users     0 Jan 04 00:02 f_zero-two-two
drwxr-x--- 2 user users  4096 Jan 04 00:03 d_zero-two-seven
-rw-r----- 1 user users     0 Jan 04 00:04 f_zero-two-seven
d-wxr-xrw- 2 user users  4096 Jan 04 00:05 d_four-two-one
--w-r--rw- 1 user users     0 Jan 04 00:06 f_four-two-one

chmod

user@host ~/perms $ ls -l butterflies.txt
-rw-r--r-- 1 user users 55 Jan 04 12:00 butterflies.txt
user@host ~/perms $ stat butterflies.txt
  File: butterflies.txt
  Size: 55              Blocks: 8          IO Block: 4096   regular file
Device: 254,3   Inode: 15466579    Links: 1
Access: (0644/-rw-r--r--)  Uid: ( 1005/    user)   Gid: (  100/   users)
Access: 2025-01-04 12:00:00.000000000 +0100
Modify: 2025-01-04 12:00:00.000000000 +0100
Change: 2025-01-04 12:00:00.000000000 +0100
 Birth: 2025-01-04 12:00:00.000000000 +0100
Permissions are shown in the symbolic notation as a part of the ls -l output, and both in the symbolic notation and in the octal notation in the output of the stat command.
The following three examples set the same permissions by use of different mode arguments provided to the chmod command:
user@host ~/perms $ stat butterflies.txt | sed -n '4p'
Access: (0644/-rw-r--r--)  Uid: ( 1005/    user)   Gid: (  100/   users)
user@host ~/perms $ chmod g+w butterflies.txt
user@host ~/perms $ stat butterflies.txt | sed -n '4p'
Access: (0664/-rw-rw-r--)  Uid: ( 1005/    user)   Gid: (  100/   users)
user@host ~/perms $ chmod ug+x butterflies.txt
user@host ~/perms $ stat butterflies.txt | sed -n '4p'
Access: (0774/-rwxrwxr--)  Uid: ( 1005/    user)   Gid: (  100/   users)
user@host ~/perms $ chmod o-r butterflies.txt
user@host ~/perms $ stat butterflies.txt | sed -n '4p'
Access: (0770/-rwxrwx---)  Uid: ( 1005/    user)   Gid: (  100/   users)
user@host ~/perms $ stat field.txt | sed -n '4p'
Access: (0644/-rw-r--r--)  Uid: ( 1005/    user)   Gid: (  100/   users)
user@host ~/perms $ chmod ug+x,g+w,o-r field.txt
user@host ~/perms $ stat field.txt | sed -n '4p'
Access: (0770/-rwxrwx---)  Uid: ( 1005/    user)   Gid: (  100/   users)
user@host ~/perms $ stat pause.txt | sed -n '4p'
Access: (0644/-rw-r--r--)  Uid: ( 1005/    user)   Gid: (  100/   users)
user@host ~/perms $ chmod 770 pause.txt
user@host ~/perms $ stat pause.txt | sed -n '4p'
Access: (0770/-rwxrwx---)  Uid: ( 1005/    user)   Gid: (  100/   users)
chmod allows omitting ugo in the symbolic notation, and in such case it performs each of the changes for user, group and others, unless the mask (umask) disables the mode bit in question:
user@host ~/perms $ chmod 0 rain.txt
user@host ~/perms $ stat rain.txt | sed -n '4p'
Access: (0000/----------)  Uid: ( 1005/    user)   Gid: (  100/   users)
user@host ~/perms $ umask
0022
user@host ~/perms $ chmod +rw rain.txt
user@host ~/perms $ stat rain.txt | sed -n '4p'
Access: (0644/-rw-r--r--)  Uid: ( 1005/    user)   Gid: (  100/   users)
Special permission bits in the symbolic notation are displayed as the letter s/S and t/T on the appropriate positions; capitalization indicates whether the execute permission veiled by the special permission is unset.
user@host ~/perms $ stat smell.txt | sed -n '4p'
Access: (0644/-rw-r--r--)  Uid: ( 1005/    user)   Gid: (  100/   users)
user@host ~/perms $ chmod g+s,o= smell.txt
user@host ~/perms $ stat smell.txt | sed -n '4p'
Access: (2640/-rw-r-S---)  Uid: ( 1005/    user)   Gid: (  100/   users)
user@host ~/perms $ chmod g+x smell.txt
user@host ~/perms $ stat smell.txt | sed -n '4p'
Access: (2650/-rw-r-s---)  Uid: ( 1005/    user)   Gid: (  100/   users)

ugo

user@host ~/perms $ chmod 077 butterflies.txt
user@host ~/perms $ chmod 707 field.txt
user@host ~/perms $ chmod 770 pause.txt
user@host ~/perms $ chgrp android field.txt
user@host ~/perms $ ls -l
total 24
----rwxrwx 1 user users     55 Jan 04 12:00 butterflies.txt
-rwx---rwx 1 user android   82 Jan 04 12:00 field.txt
-rwxrwx--- 1 user users     85 Jan 04 12:00 pause.txt
user@host ~/perms $ cat butterflies.txt
cat: butterflies.txt: Permission denied
user@host ~/perms $ su john
Password:
[host /home/user/perms]$ groups
android chromium
[host /home/user/perms]$ cat field.txt
cat: field.txt: Permission denied
[host /home/user/perms]$ cat pause.txt
cat: pause.txt: Permission denied
Notice that e.g., when the user john that belongs to the grup android accesses the file field.txt, only the permissions for the group are considered – the user cannot access the file even though "others" can.

dir_no_read

user@host ~ $ mkdir lights_off
user@host ~ $ chmod 333 lights_off
user@host ~ $ ls lights_off
ls: cannot open directory 'lights_off': Permission denied
user@host ~ $ fortune > lights_off/lego
user@host ~ $ cd lights_off
user@host ~/lights_off $ cat lego
You can be sure of succeding in your attacks if you only attack places which are undefended
user@host ~/lights_off $ ls -l .
ls: cannot open directory '.': Permission denied
user@host ~/lights_off $ ls -l ghost
ls: cannot access 'ghost': No such file or directory
user@host ~/lights_off $ ls -l lego
-rw-r--r-- 1 user users 92 Jan 04 12:00 lego

dir_create_remove

To create or remove entries (this includes any file type, e.g., ordinary files and directories) in a directory, it suffices to have execute and write access to the directory. The special "sticky bit" permission additionally forbids removing files by users that neither own the file to be removed nor the directory from which the file is to be removed.

user@host ~ $ chgrp android ffa
user@host ~ $ chmod g+w ffa
user@host ~ $ cd ffa
user@host ~/ffa $ touch user_file
user@host ~/ffa $ su john
Password:
[host /home/user/ffa]$ id
uid=1234(john) gid=1001(chromium) groups=1001(chromium),968(android)
[host /home/user/ffa]$ mkdir john_empty_dir john_dir
[host /home/user/ffa]$ touch john_file1 john_file2 john_file3 john_dir/file
[host /home/user/ffa]$ exit
exit
user@host ~/ffa $ su jane
Password:
jane@host /home/user/ffa $ touch jane_file
jane@host /home/user/ffa $ tree -pug
[drwxrwxr-x user     android ]  .
├── [-rw-r--r-- jane     android ]  jane_file
├── [drwxr-xr-x john     chromium]  john_dir
│   └── [-rw-r--r-- john     chromium]  file
├── [drwxr-xr-x john     chromium]  john_empty_dir
├── [-rw-r--r-- john     chromium]  john_file1
├── [-rw-r--r-- john     chromium]  john_file2
├── [-rw-r--r-- john     chromium]  john_file3
└── [-rw-r--r-- user     users   ]  user_file
3 directories, 6 files
jane@host /home/user/ffa $ rm -f user_file
jane@host /home/user/ffa $ rm -f john_file1
jane@host /home/user/ffa $ rm -rf john_empty_dir
jane@host /home/user/ffa $ rm -rf john_dir
rm: cannot remove 'john_dir/file': Permission denied
jane@host /home/user/ffa $ tree -pug
[drwxrwxr-x user     android ]  .
├── [-rw-r--r-- jane     android ]  jane_file
├── [drwxr-xr-x john     chromium]  john_dir
│   └── [-rw-r--r-- john     chromium]  file
├── [-rw-r--r-- john     chromium]  john_file2
└── [-rw-r--r-- john     chromium]  john_file3
2 directories, 4 files
jane@host /home/user/ffa $ exit
exit
user@host ~/ffa $ chmod o+t .
user@host ~/ffa $ su jane
Password:
jane@host /home/user/ffa $ rm -f jane_file
jane@host /home/user/ffa $ rm -f john_file2
rm: cannot remove 'john_file2': Operation not permitted
jane@host /home/user/ffa $ exit
exit
user@host ~/ffa $ rm -f john_file2
user@host ~/ffa $ chmod go=rx .
user@host ~/ffa $ su john
Password:
[host /home/user/ffa]$ tree -pug
[drwxr-xr-x user     android ]  .
├── [drwxr-xr-x john     chromium]  john_dir
│   └── [-rw-r--r-- john     chromium]  file
└── [-rw-r--r-- john     chromium]  john_file3
2 directories, 2 files
[host /home/user/ffa]$ rm john_file3
rm: cannot remove 'john_file3': Permission denied

write_only

user@host ~ $ touch incoming
user@host ~ $ chmod 422 incoming
user@host ~ $ cat incoming
user@host ~ $ echo "hello" >  incoming
-bash: incoming: Permission denied
user@host ~ $ su jane
Password:
jane@host /home/user $ cat incoming
cat: incoming: Permission denied
jane@host /home/user $ echo "hello" >  incoming
jane@host /home/user $ echo "user!" >> incoming
jane@host /home/user $ exit
exit
user@host ~ $ cat incoming
hello
user!

suid_sgid

Suid and sgid cause the executable to be run as a different user/group by changing the effective user/group identifier (euid/egid) to that of the file.

user@host ~ $ pygmentize prog.c
int main(int, char **a) {
  char *name;
  asprintf(&name, "%s.txt", a[0]);
  int file = creat(name, 0644);
  free(name);
  write(file, "Hello\n", 6);
  close(file);
  execlp("id", "id", 0);
  return 1;
}
user@host ~ $ gcc -w -ansi ./prog.c -o prog
user@host ~ $ su
Password:
root@host /home/user # cp prog prog-suid
root@host /home/user # cp prog prog-sgid
root@host /home/user # cp prog prog-none
root@host /home/user # chown daemon:man prog-*
root@host /home/user # chmod u+s prog-suid
root@host /home/user # chmod g+s prog-sgid
root@host /home/user # exit
user@host ~ $ stat prog-* | awk '/F/{f=$0}/)/{print f "\t" $0}'
  File: prog-none       Access: (0755/-rwxr-xr-x)  Uid: (    2/  daemon)   Gid: (   15/     man)
  File: prog-sgid       Access: (2755/-rwxr-sr-x)  Uid: (    2/  daemon)   Gid: (   15/     man)
  File: prog-suid       Access: (4755/-rwsr-xr-x)  Uid: (    2/  daemon)   Gid: (   15/     man)
user@host ~ $ chmod go+w .
user@host ~ $ ./prog-none
uid=1005(user) gid=100(users) groups=100(users),10(wheel),968(android)
user@host ~ $ ./prog-suid
uid=1005(user) gid=100(users) euid=2(daemon) groups=100(users),10(wheel),968(android)
user@host ~ $ ./prog-sgid
uid=1005(user) gid=100(users) egid=15(man) groups=15(man),10(wheel),100(users),968(android)
user@host ~ $ stat prog-*.txt | awk '/F/{f=$0}/)/{print f "\t" $0}'
  File: prog-none.txt   Access: (0644/-rw-r--r--)  Uid: ( 1005/    user)   Gid: (  100/   users)
  File: prog-sgid.txt   Access: (0644/-rw-r--r--)  Uid: ( 1005/    user)   Gid: (   15/     man)
  File: prog-suid.txt   Access: (0644/-rw-r--r--)  Uid: (    2/  daemon)   Gid: (  100/   users)
user@host ~ $ ls -ltr prog-*
-rwsr-xr-x 1 daemon man   15680 Jan 04 12:01 prog-suid
-rwxr-sr-x 1 daemon man   15680 Jan 04 12:02 prog-sgid
-rwxr-xr-x 1 daemon man   15680 Jan 04 12:03 prog-none
-rw-r--r-- 1 user   users     6 Jan 04 12:04 prog-none.txt
-rw-r--r-- 1 user   man       6 Jan 04 12:05 prog-sgid.txt
-rw-r--r-- 1 daemon users     6 Jan 04 12:06 prog-suid.txt

touch

user@host ~ $ stat essay.odt
  File: essay.odt
  Size: 73414           Blocks: 144        IO Block: 4096   regular file
Device: 254,3   Inode: 15466607    Links: 1
Access: (0644/-rw-r--r--)  Uid: ( 1005/    user)   Gid: (  100/   users)
Access: 2025-01-02 12:00:00.000000000 +0100
Modify: 2025-01-01 12:00:00.000000000 +0100
Change: 2025-01-02 12:00:00.000000000 +0100
 Birth: 2025-01-01 12:00:00.000000000 +0100
user@host ~ $ ls -l essay.odt
-rw-r--r-- 1 user users 73414 Jan  1 12:00 essay.odt
user@host ~ $ touch -d '2025-01-03 12:34' essay.odt
user@host ~ $ stat essay.odt
  File: essay.odt
  Size: 73414           Blocks: 144        IO Block: 4096   regular file
Device: 254,3   Inode: 15466607    Links: 1
Access: (0644/-rw-r--r--)  Uid: ( 1005/    user)   Gid: (  100/   users)
Access: 2025-01-03 12:34:00.000000000 +0100
Modify: 2025-01-03 12:34:00.000000000 +0100
Change: 2025-01-05 12:00:00.000000000 +0100
 Birth: 2025-01-01 12:00:00.000000000 +0100
user@host ~ $ ls -l essay.odt
-rw-r--r-- 1 user users 73414 Jan  3 12:34 essay.odt
user@host ~ $ touch -a -d 'yesterday 6pm' essay.odt
user@host ~ $ stat essay.odt
  File: essay.odt
  Size: 73414           Blocks: 144        IO Block: 4096   regular file
Device: 254,3   Inode: 15466607    Links: 1
Access: (0644/-rw-r--r--)  Uid: ( 1005/    user)   Gid: (  100/   users)
Access: 2025-01-04 18:00:00.000000000 +0100
Modify: 2025-01-03 12:34:00.000000000 +0100
Change: 2025-01-05 12:00:00.000000000 +0100
 Birth: 2025-01-01 12:00:00.000000000 +0100
user@host ~ $ ls -l essay.odt
-rw-r--r-- 1 user users 73414 Jan  3 12:34 essay.odt
user@host ~ $ date
Sun Jan  5 12:00:00 CET 2025
user@host ~ $ touch essay.odt
user@host ~ $ stat essay.odt
  File: essay.odt
  Size: 73414           Blocks: 144        IO Block: 4096   regular file
Device: 254,3   Inode: 15466607    Links: 1
Access: (0644/-rw-r--r--)  Uid: ( 1005/    user)   Gid: (  100/   users)
Access: 2025-01-05 12:00:00.000000000 +0100
Modify: 2025-01-05 12:00:00.000000000 +0100
Change: 2025-01-05 12:00:00.000000000 +0100
 Birth: 2025-01-01 12:00:00.000000000 +0100
user@host ~ $ ls -l essay.odt
-rw-r--r-- 1 user users 73414 Jan  5 12:01 essay.odt
Notice that the change date, which represents the date when metadata has been changed most recently, does get updated on each metadata change, which includes changing the file dates.