Table of Contents
- Linux System Enumeration:
- General OS Information
- User Information
- Network Information
- Process Information
- Service Configuration
- Sensitive Files
- Scheduled Tasks
- General OS Information
- User Information
- Network Information
- Process Information
- Service Configuration
- Sensitive Files
- Scheduled Tasks
- Website Root
- Configuration Files
- Logs
- Web Applications
- MySQL/MariaDB
- PostgreSQL
- MongoDB
- Find SUID/SGID Files
- Find Configuration Files
- Find Password Files
-
Linux System Enumeration
- Windows System Enumeration
- Web Server Enumeration
- Database Enumeration
- File system Enumeration
Linux System Enumeration:
# General OS Information
/etc/os-release
/proc/version
uname -a
#system architechture
uname -m
# User Information
/etc/passwd
/etc/shadow
/home/
~/.bash_history
# Network Information
/etc/hosts
/etc/resolv.conf
/sbin/ifconfig
/sbin/route
# Process Information
/proc/self
ps -ef
top -n 1
# Service Configuration
/etc/init.d/
/etc/systemd/system/
/etc/nginx/sites-enabled/ # Default name - default|.conf
/etc/apache2/sites-enabled/
# Sensitive Files
/var/log/
/root/
/home/user/.ssh/
# Scheduled Tasks
/etc/cron.*
/var/spool/cron/crontabs/
Windows System Enumeration:
# General OS Information
systeminfo
ver
# User Information
net users
net user [username]
# Network Information
ipconfig /all
route print
arp -a
# Process Information
tasklist
net start
# Service Configuration
sc qc [servicename]
sc queryex type= service state= all
# Sensitive Files
dir C:\ /s /b | findstr /i "passwords.xml"
dir C:\Users\ /s /b | findstr /i "credentials"
# Scheduled Tasks
schtasks /query /fo LIST /v
Web Server Enumeration:
# Website Root
/var/www/
/var/www/websitenamehere
/var/www/websitenamehere/app/orappname.py
# Configuration Files
/etc/nginx/nginx.conf
/etc/apache2/apache2.conf
/etc/httpd/conf/httpd.conf
# Logs
/var/log/nginx/access.log
/var/log/nginx/error.log
/var/log/apache2/access.log
/var/log/apache2/error.log
# Web Applications
/var/www/html/wp-config.php # WordPress
/var/www/html/configuration.php # Joomla
/var/www/html/sites/default/settings.php # Drupal
Database Enumeration (Linux):
sql #mysql #mariadb #dbeneumeration
# MySQL/MariaDB
/etc/mysql/my.cnf
/var/log/mysql/error.log
~/.mysql_history
# PostgreSQL
/etc/postgresql/[version]/main/postgresql.conf
/var/log/postgresql/
~/.psql_history
# MongoDB
/etc/mongod.conf
/var/log/mongodb/mongod.log
General Filesystem Enumeration (Linux):
enumeration #find #privesc #linux
# Find SUID/SGID Files
find / -perm -4000 2>/dev/null
find / -perm -2000 2>/dev/null
# Find Configuration Files
find / -name *.conf 2>/dev/null
# Find Password Files
find / -name *.pwd 2>/dev/null
# Find Writable Directories for All Users
find / -writable -type d 2>/dev/null
Automating Privilege escalation artifacts
#!/usr/bin/env bash
# <mark></mark><mark></mark><mark></mark><mark></mark><mark></mark><mark></mark><mark></mark><mark></mark><mark></mark><mark></mark><mark></mark><mark></mark><mark></mark><mark></mark><mark></mark><mark></mark><mark></mark><mark></mark><mark></mark>=
# privesc-helper.sh
#
# Local Linux enumeration helper for privilege escalation triage.
# - Runs read-only enumeration commands
# - Saves outputs to a timestamped directory
# - Extracts SUID/SGID binaries and prints likely GTFOBins links
#
# Usage:
# chmod +x privesc-helper.sh
# ./privesc-helper.sh # quick-ish (no full / find)
# ./privesc-helper.sh --full # includes heavy filesystem finds under /
# ./privesc-helper.sh --outdir /tmp/x # custom output dir
# ./privesc-helper.sh --no-color
#
# Notes:
# - Some commands may be missing depending on distro/busybox constraints.
# - GTFOBins links are generated heuristically (may not exist for every binary).
# <mark></mark><mark></mark><mark></mark><mark></mark><mark></mark><mark></mark><mark></mark><mark></mark><mark></mark><mark></mark><mark></mark><mark></mark><mark></mark><mark></mark><mark></mark><mark></mark><mark></mark><mark></mark><mark></mark>=
set -Eeuo pipefail
VERSION="1.0.0"
# ----------------------------- defaults --------------------------------------
MODE="quick" # quick | full
OUTDIR_BASE="./privesc-output"
NO_COLOR="0"
# ----------------------------- helpers ---------------------------------------
ts() { date -u +"%Y-%m-%dT%H:%M:%SZ"; }
if [[ "${NO_COLOR}" == "0" ]] && [[ -t 1 ]]; then
RED=$'\e[31m'; GRN=$'\e[32m'; YLW=$'\e[33m'; BLU=$'\e[34m'; MAG=$'\e[35m'; CYN=$'\e[36m'; DIM=$'\e[2m'; RST=$'\e[0m'
else
RED=""; GRN=""; YLW=""; BLU=""; MAG=""; CYN=""; DIM=""; RST=""
fi
log() { echo "${CYN}[*]${RST} $*"; }
good() { echo "${GRN}[+]${RST} $*"; }
warn() { echo "${YLW}[!]${RST} $*"; }
err() { echo "${RED}[-]${RST} $*" >&2; }
have() { command -v "$1" >/dev/null 2>&1; }
safe_run() {
# safe_run "label" cmd...
local label="$1"; shift
{
echo "### $label"
echo "Timestamp: $(ts)"
echo "Command: $*"
echo
"$@"
} >> "${LOGFILE}" 2>&1 || {
echo >> "${LOGFILE}"
echo "[command failed] $label" >> "${LOGFILE}"
echo >> "${LOGFILE}"
return 0
}
}
write_file() {
# write_file path "content"
local path="$1"; shift
printf "%s" "$*" > "$path"
}
# ----------------------------- args ------------------------------------------
usage() {
cat <<'USAGE'
privesc-helper.sh - Linux local enumeration helper
Options:
--full Include heavy filesystem searches under /
--quick Default (no heavy filesystem searches)
--outdir DIR Base output directory (default: ./privesc-output)
--no-color Disable ANSI colors
-h, --help Show help
Examples:
./privesc-helper.sh
./privesc-helper.sh --full --outdir /tmp/privesc
USAGE
}
while [[ $# -gt 0 ]]; do
case "$1" in
--full) MODE="full"; shift ;;
--quick) MODE="quick"; shift ;;
--outdir) OUTDIR_BASE="${2:-}"; shift 2 ;;
--no-color) NO_COLOR="1"; shift ;;
-h|--help) usage; exit 0 ;;
*) err "Unknown argument: $1"; usage; exit 2 ;;
esac
done
# Recompute colors if --no-color was passed after init
if [[ "${NO_COLOR}" == "1" ]]; then
RED=""; GRN=""; YLW=""; BLU=""; MAG=""; CYN=""; DIM=""; RST=""
fi
# ----------------------------- setup -----------------------------------------
RUN_ID="$(date -u +'%Y%m%d_%H%M%S')"
OUTDIR="${OUTDIR_BASE%/}/run_${RUN_ID}"
mkdir -p "${OUTDIR}"
LOGFILE="${OUTDIR}/report.txt"
SUMMARY="${OUTDIR}/summary.txt"
JSONLIKE="${OUTDIR}/facts.txt"
touch "${LOGFILE}" "${SUMMARY}" "${JSONLIKE}"
good "Output directory: ${OUTDIR}"
log "Mode: ${MODE}"
log "Writing main log: ${LOGFILE}"
# ----------------------------- header ----------------------------------------
{
echo "# privesc-helper.sh"
echo "Version: ${VERSION}"
echo "Timestamp: $(ts)"
echo "User: $(id 2>/dev/null || true)"
echo "Hostname: $(hostname 2>/dev/null || true)"
echo "PWD: $(pwd)"
echo
} >> "${LOGFILE}"
# ----------------------------- section: general OS ---------------------------
log "Collecting general OS info..."
# /etc/os-release and /proc/version if readable
[[ -r /etc/os-release ]] && safe_run "OS Release (/etc/os-release)" cat /etc/os-release
[[ -r /proc/version ]] && safe_run "Kernel Version (/proc/version)" cat /proc/version
safe_run "uname -a" uname -a
safe_run "uname -m" uname -m
if have lsb_release; then
safe_run "lsb_release -a" lsb_release -a
fi
# ----------------------------- section: user info ----------------------------
log "Collecting user info..."
[[ -r /etc/passwd ]] && safe_run "/etc/passwd" cat /etc/passwd
# /etc/shadow often unreadable; record perms + try read if possible
safe_run "shadow perms" ls -l /etc/shadow || true
[[ -r /etc/shadow ]] && safe_run "/etc/shadow (readable!)" cat /etc/shadow
safe_run "whoami" whoami
safe_run "id" id
safe_run "groups" groups || true
safe_run "env" env | sort
# Home directories listing
safe_run "list /home" ls -la /home || true
safe_run "list ~" bash -lc 'ls -la ~' || true
# bash history if present/readable
if [[ -n "${HOME:-}" ]] && [[ -r "${HOME}/.bash_history" ]]; then
safe_run "~/.bash_history" bash -lc 'tail -n 200 ~/.bash_history'
fi
# Sudo/priv context
if have sudo; then
safe_run "sudo -n -l (non-interactive)" sudo -n -l
fi
# ----------------------------- section: network ------------------------------
log "Collecting network info..."
[[ -r /etc/hosts ]] && safe_run "/etc/hosts" cat /etc/hosts
[[ -r /etc/resolv.conf ]] && safe_run "/etc/resolv.conf" cat /etc/resolv.conf
# Prefer modern tools, fallback to legacy if present
if have ip; then
safe_run "ip a" ip a
safe_run "ip r" ip r
else
have ifconfig && safe_run "ifconfig -a" ifconfig -a
have route && safe_run "route -n" route -n
fi
have arp && safe_run "arp -a" arp -a
if have ss; then
safe_run "ss -lntup" ss -lntup
elif have netstat; then
safe_run "netstat -lntup" netstat -lntup
fi
# ----------------------------- section: processes ----------------------------
log "Collecting process info..."
safe_run "ps -ef" ps -ef
if have top; then
safe_run "top -n 1 (batch)" top -n 1 -b
fi
# /proc/self minimal inspection
safe_run "/proc/self (ls -la)" ls -la /proc/self || true
# ----------------------------- section: services/config ----------------------
log "Collecting service configuration hints..."
safe_run "list /etc/init.d" ls -la /etc/init.d || true
safe_run "list /etc/systemd/system" ls -la /etc/systemd/system || true
# nginx/apache enabled sites if exist
safe_run "list /etc/nginx/sites-enabled" ls -la /etc/nginx/sites-enabled || true
safe_run "list /etc/apache2/sites-enabled" ls -la /etc/apache2/sites-enabled || true
# ----------------------------- section: sensitive locations -------------------
log "Collecting sensitive file locations (lightweight listing)..."
safe_run "list /var/log (top level)" ls -la /var/log || true
safe_run "list /root" ls -la /root || true
# SSH keys for current user + common paths
if [[ -n "${HOME:-}" ]]; then
safe_run "list ~/.ssh" bash -lc 'ls -la ~/.ssh' || true
safe_run "grep -R \"PRIVATE KEY\" in ~/.ssh (names only)" bash -lc 'grep -RIl --binary-files=without-match "PRIVATE KEY" ~/.ssh 2>/dev/null' || true
fi
# ----------------------------- section: scheduled tasks -----------------------
log "Collecting scheduled task info..."
safe_run "list /etc/cron.*" bash -lc 'ls -la /etc/cron.* 2>/dev/null || true'
safe_run "list /var/spool/cron/crontabs" ls -la /var/spool/cron/crontabs || true
have crontab && safe_run "crontab -l" crontab -l
# ----------------------------- section: DB/web/server config ------------------
log "Collecting web/db config hints..."
# Web server config common
[[ -r /etc/nginx/nginx.conf ]] && safe_run "/etc/nginx/nginx.conf" cat /etc/nginx/nginx.conf
[[ -r /etc/apache2/apache2.conf ]] && safe_run "/etc/apache2/apache2.conf" cat /etc/apache2/apache2.conf
[[ -r /etc/httpd/conf/httpd.conf ]] && safe_run "/etc/httpd/conf/httpd.conf" cat /etc/httpd/conf/httpd.conf
# Web logs paths commonly exist; just list + tail if readable
for f in \
/var/log/nginx/access.log /var/log/nginx/error.log \
/var/log/apache2/access.log /var/log/apache2/error.log
do
if [[ -e "$f" ]]; then
safe_run "log perms: $f" ls -l "$f"
[[ -r "$f" ]] && safe_run "tail $f" bash -lc "tail -n 200 '$f'"
fi
done
# CMS configs (just check existence + perms; do not dump huge files unless readable)
for f in \
/var/www/html/wp-config.php \
/var/www/html/configuration.php \
/var/www/html/sites/default/settings.php
do
[[ -e "$f" ]] && safe_run "webapp config (perms): $f" ls -l "$f"
[[ -r "$f" ]] && safe_run "webapp config (head): $f" bash -lc "head -n 120 '$f'"
done
# DB configs from your list
[[ -r /etc/mysql/my.cnf ]] && safe_run "/etc/mysql/my.cnf" cat /etc/mysql/my.cnf
[[ -e /var/log/mysql/error.log ]] && safe_run "mysql error log perms" ls -l /var/log/mysql/error.log || true
[[ -r /var/log/mysql/error.log ]] && safe_run "tail mysql error log" bash -lc "tail -n 200 /var/log/mysql/error.log" || true
[[ -n "${HOME:-}" && -r "${HOME}/.mysql_history" ]] && safe_run "~/.mysql_history (tail)" bash -lc 'tail -n 200 ~/.mysql_history' || true
# PostgreSQL versioned path - enumerate dirs
if [[ -d /etc/postgresql ]]; then
safe_run "list /etc/postgresql" ls -la /etc/postgresql
# dump conf if present
while IFS= read -r conf; do
[[ -r "$conf" ]] && safe_run "postgresql.conf: $conf" cat "$conf"
done < <(find /etc/postgresql -maxdepth 4 -type f -name postgresql.conf 2>/dev/null || true)
fi
[[ -d /var/log/postgresql ]] && safe_run "list /var/log/postgresql" ls -la /var/log/postgresql || true
[[ -n "${HOME:-}" && -r "${HOME}/.psql_history" ]] && safe_run "~/.psql_history (tail)" bash -lc 'tail -n 200 ~/.psql_history' || true
[[ -r /etc/mongod.conf ]] && safe_run "/etc/mongod.conf" cat /etc/mongod.conf
[[ -e /var/log/mongodb/mongod.log ]] && safe_run "mongodb log perms" ls -l /var/log/mongodb/mongod.log || true
[[ -r /var/log/mongodb/mongod.log ]] && safe_run "tail mongodb log" bash -lc 'tail -n 200 /var/log/mongodb/mongod.log' || true
# ----------------------------- filesystem enumeration -------------------------
log "Filesystem enumeration..."
SUID_FILE="${OUTDIR}/suid_sgid.txt"
GTFO_FILE="${OUTDIR}/gtfobins_links.txt"
CONF_FIND="${OUTDIR}/found_confs.txt"
PWD_FIND="${OUTDIR}/found_pwds.txt"
WRITABLE_FIND="${OUTDIR}/world_writable_dirs.txt"
touch "${SUID_FILE}" "${GTFO_FILE}" "${CONF_FIND}" "${PWD_FIND}" "${WRITABLE_FIND}"
# Quick mode: keep it smaller (common dirs), Full mode: search /
if [[ "${MODE}" == "full" ]]; then
warn "Full mode enabled: running finds under / (can be slow/noisy)."
FIND_ROOTS=(/)
# SUID/SGID
log "Finding SUID/SGID files..."
{
echo "### SUID (-4000)"
find / -perm -4000 -type f 2>/dev/null || true
echo
echo "### SGID (-2000)"
find / -perm -2000 -type f 2>/dev/null || true
} > "${SUID_FILE}"
# .conf
log "Finding *.conf files..."
find / -type f -name "*.conf" 2>/dev/null > "${CONF_FIND}" || true
# *.pwd
log "Finding *.pwd files..."
find / -type f -name "*.pwd" 2>/dev/null > "${PWD_FIND}" || true
# Writable dirs
log "Finding writable directories (current user writable) ..."
find / -writable -type d 2>/dev/null > "${WRITABLE_FIND}" || true
else
# Quick mode roots: typical “interesting” areas; avoids full disk scan
FIND_ROOTS=(/etc /opt /srv /var/www /var/backups /home)
log "Quick mode: limiting find scope to: ${FIND_ROOTS[*]}"
log "Finding SUID/SGID files (quick scope)..."
{
echo "### SUID (-4000)"
find "${FIND_ROOTS[@]}" -perm -4000 -type f 2>/dev/null || true
echo
echo "### SGID (-2000)"
find "${FIND_ROOTS[@]}" -perm -2000 -type f 2>/dev/null || true
} > "${SUID_FILE}"
log "Finding *.conf files (quick scope)..."
find "${FIND_ROOTS[@]}" -type f -name "*.conf" 2>/dev/null > "${CONF_FIND}" || true
log "Finding *.pwd files (quick scope)..."
find "${FIND_ROOTS[@]}" -type f -name "*.pwd" 2>/dev/null > "${PWD_FIND}" || true
log "Finding writable directories (quick scope)..."
find "${FIND_ROOTS[@]}" -writable -type d 2>/dev/null > "${WRITABLE_FIND}" || true
fi
# ----------------------------- GTFOBins link mapping --------------------------
log "Generating GTFOBins link candidates from SUID/SGID results..."
# Heuristic: for each path, take basename and produce GTFOBins URL.
# This catches common privesc vectors (SUID/SGID + known escape sequences).
# Some pages won’t exist; this is still useful as a fast “look here first” list.
{
echo "# GTFOBins link candidates (heuristic)"
echo "# Timestamp: $(ts)"
echo "# Source: $(basename "${SUID_FILE}")"
echo
# Extract file paths from SUID file (skip header lines)
awk '
$0 ~ /^\/.*/ { print $0 }
' "${SUID_FILE}" | while IFS= read -r p; do
bn="$(basename "$p")"
# basic LoLBIN family heuristics:
# - if bn has dots/spaces, normalize minimally for URL
url_bn="${bn// /%20}"
printf "%-60s %s\n" "$p" "https://gtfobins.github.io/gtfobins/${url_bn}/"
done
echo
echo "# Also check (if present) built-in docs/manpages for these binaries:"
echo "# man <bin> | less"
echo "# <bin> --help"
} > "${GTFO_FILE}"
# ----------------------------- summary ---------------------------------------
log "Writing summary..."
# Basic facts extraction for fast eyeballing
KERNEL="$(uname -r 2>/dev/null || true)"
ARCH="$(uname -m 2>/dev/null || true)"
ME="$(id -un 2>/dev/null || true)"
SUID_COUNT="$(awk '$0 ~ /^\/.*/ {c++} END{print c+0}' "${SUID_FILE}")"
{
echo "Timestamp: $(ts)"
echo "Mode: ${MODE}"
echo "User: ${ME}"
echo "Kernel: ${KERNEL}"
echo "Arch: ${ARCH}"
echo "Output: ${OUTDIR}"
echo
echo "Artifacts:"
echo " - report: ${LOGFILE}"
echo " - suid/sgid list: ${SUID_FILE} (count: ${SUID_COUNT})"
echo " - gtfobins links: ${GTFO_FILE}"
echo " - conf files: ${CONF_FIND}"
echo " - *.pwd files: ${PWD_FIND}"
echo " - writable dirs: ${WRITABLE_FIND}"
echo
echo "Next manual steps (high-signal):"
echo " 1) Review sudo rules: sudo -l"
echo " 2) Inspect SUID/SGID + GTFOBins links"
echo " 3) Check cron/systemd overrides and writable service files"
echo " 4) Search for creds in configs/logs (carefully):"
echo " grep -RIn \"pass\\|token\\|secret\\|key\" /etc /var/www 2>/dev/null"
} | tee "${SUMMARY}" >/dev/null
# Append pointers into main report
{
echo
echo "<mark></mark><mark></mark><mark></mark><mark></mark><mark></mark> Summary <mark></mark><mark></mark><mark></mark><mark></mark><mark></mark>"
cat "${SUMMARY}"
echo
echo "<mark></mark><mark></mark><mark></mark><mark></mark><mark></mark> SUID/SGID <mark></mark><mark></mark><mark></mark><mark></mark>=="
sed -n '1,220p' "${SUID_FILE}" || true
echo
echo "<mark></mark><mark></mark><mark></mark><mark></mark><mark></mark> GTFOBins <mark></mark><mark></mark><mark></mark><mark></mark>==="
sed -n '1,220p' "${GTFO_FILE}" || true
echo
} >> "${LOGFILE}"
good "Done."
good "Open: ${SUMMARY}"
good "Open: ${LOGFILE}"
# Clear history/traces of script for stealth KeKW