August 1, 2026
The Complete Pentest Methodology: A Step by Step Practical Guide (Part 1)
2 in the cage, 1 is free.

By Abdelrhman mohamed
9 min read
Alright, let's get this party started.
This is a practical home lab , no fancy cloud , no pre chewed CTF flags waiting for you like a participation trophy. We're going to pressure test real world scenarios and the correct attacker mindset.
The fixed methodology steps for every machine are non negotiable: Information gathering → Enumeration → Vulnerability Assessment → Exploitation → Post-Exploitation → Privilege Escalation → Credential Dumping → Documentation → Persistence → Pivoting → Clearing Tracks.
What we're actually testing here: One machine sitting right next to us on the same network that we can actually touch… and two other machines living in a completely separate network behind it. The question is simple: how do we reach them when the only bridge is that dual-homed entry point? before we start (always take a note please).
Let's go.
Information Gathering*
Right now I'm sitting on a network with only one other machine visible.
First thing we do is run:
ip aip a
We grab the interface we're actually using (in this case "vboxnet0" with 192.168.56.1/24).
Then we fire up "netdiscover" to see who's living on the same network with us:
sudo netdiscover -i vboxnet0 -r 192.168.56.0/24sudo netdiscover -i vboxnet0 -r 192.168.56.0/24(netdiscover needs sudo because it works with the ARP protocol).
And just like that, the hosts start showing up.
Enumeration
What's the next step? Don't forget to take notes, okay?
Time to bring out my beloved, your beloved, everyone's beloved… Metasploit.
Fire it up.
Don't forget to create a workspace so you can always come back to your work later:
workspace -a "name of workspace"workspace -a "name of workspace"
Check the database status real quick with "db_status".
Then run "nmap" from inside "Metasploit":
db_nmap 192.168.56.104 -Pn -sV -Adb_nmap 192.168.56.104 -Pn -sV -A
Why? Because now every single piece of data gets stored inside the tool itself. It helps you way more, and we're done with the random scattered notes.
Even when you type:
servicesservices
You'll find all the results saved… and beautifully organized.
Alright, so now we have the open ports, the host itself, and even the banners all thanks to using -sV.
We also finished pretty fast because we only scanned the ports that speak TCP and completely ignored UDP. That's totally fine. If you want to check both, no problem at all just add -sU. It'll take a bit longer, but it's okay.
As for -Pn: I'm telling it not to ping so we don't waste time. You can also throw in -n to skip DNS resolution. All of this is just to save time.
And keep this in mind: when you're working inside a real company, your scan has to stay light. Don't make a lot of noise on the network traffic or slow down other people's work. Be careful. Stay stealthy. Go light.
Exploitation
Since we already have the version of every service and port, we can now search either on the internet or directly inside "Metasploit" to attack that service.
If a banner doesn't clearly show the version, there are plenty of modules inside "Metasploit" (especially in the auxiliary section) that can fingerprint the exact version much better than "nmap". Go look for them.
I searched using the search command with a filter like "type:exploit" to clean up the results as you can see. Read about these filters, they're extremely useful and keep you focused.
We actually found an FTP module, but that one is not friendly and needs a lot of attempts.
When I searched Google for the Samba version, it turned out it gives root access and is stronger and more recent.
So we're going to use that one to skip the privilege escalation part completely.
After setting the options and running it… , we got the shell.
We have root, but the shell is not interactive. It's not going to help at all and will become a real obstacle.
Post-Exploitation
shell upgrade Here we go, champ.
We upgraded the shell using this command, and now everything looks clean. Our shell is smooth and packed with features that will actually help us continue the work.
We now have "Meterpreter".
Of course the command I used is just a shortcut. You can also background the shell with Ctrl+Z, then search for the module:
post/multi/manage/shell_to_meterpreterpost/multi/manage/shell_to_meterpreterGive it the session number and it will handle the rest. But to save time and avoid the extra back and forth, we just use the short version:
sessions -u "session number"sessions -u "session number"If you don't know the session number, just type sessions.
(Did you notice something? Remember the module I mentioned post/multi/manage/shell_to_meterpreter? It starts with the word post… meaning post-exploitation.).
Of course, now we're in the Post-Exploitation Enumeration phase.
We need to pull every possible detail from the machine. And since we're already root, we don't need any higher privileges.
We'll use these modules:
post/linux/gather/enum_configs
post/linux/gather/enum_network
post/linux/gather/enum_systempost/linux/gather/enum_configs
post/linux/gather/enum_network
post/linux/gather/enum_systemYou don't really need more than these. They'll do the job. Just keep in mind they're Linux-only and they're just time-savers.
They will never replace proper manual enumeration.
How do we use them?
Simple. Background the session and load the module. It will only ask you for the session number (most post modules don't ask for anything else).
Or, without even leaving the session, just upload this script:
[https://github.com/rebootuser/LinEnum]
It does a nice local auto-enumeration. Go try it.
Credential Dumping
Of course, since we're root we can just read /etc/shadow.
But hold on a second… think with me.
We're already root, right? So why should we extract hashes and sit there cracking them?
We can simply change the users' passwords ourselves and save the headache.
Inside Meterpreter just type:
shellshell
You'll drop back into that useless non interactive shell.
Here's a clean little trick to get a more usable interactive shell:
/bin/bash -i/bin/bash -iNow you have an interactive shell. It's not perfect, but it gets the job done.
Then just run:
sudo passwd usernamesudo passwd username
And clean things up.
Don't come asking me "where did you get the username in the screenshot from?" We did the enumeration after the exploit, remember?
Oh right… and don't forget to take notes. Because we also have to cover hash cracking.
This is still a mandatory step. In real environments you might find an employee or admin using weak or repeated passwords, which violates security policy and you need to check that.
We open /etc/shadow and it dumps every user with their hash.
Focus on the important users (the ones that have /bin/bash in their line).
Copy the entire line from start to end. Cracking tools like "John the Ripper" or "Hashcat" know how to handle the full line , don't take the hash alone.
How do you know the hash type?
Linux puts the type right at the beginning between the dollar signs.
As you can see in the screenshot: $6$ = SHA-512.
A quick Google search will confirm it.
Now we run John the Ripper.
john --format=sha512crypt greenssh-hash --wordlist=/usr/share/wordlists/metasploit/unix_passwords.txtjohn --format=sha512crypt greenssh-hash --wordlist=/usr/share/wordlists/metasploit/unix_passwords.txt
If it's the first time, it will crack the password. Since I already ran it before, I just used:
john --format=sha512crypt greenssh-hash --showjohn --format=sha512crypt greenssh-hash --showResult:
greenssh:123456
Now we have the password. We can use it on the SSH or FTP services that showed up earlier.
And of course, during the post exploitation enumeration we already discovered every user and their groups. Since we're root, we can also add ourselves to whatever groups we want and make every user a "sudoer" if needed.
Persistence
This is where we lock in our presence, because there's a classic rule:
2 is 1 1 is none
You need more than one shell, and you need to be able to reach it at any time. Relying on a single shell or a single exploit means you're gambling on your access not guaranteeing it.
Since we already have the users' passwords, we can just SSH in normally.
But what if the user changes the password? Or the admin notices that you changed it?
Then what?
We need a permanent way in.
We start walking through /home (all the user directories) until we find one that has a .ssh folder.
Inside it we'll find the private key. Once we have that, we can connect anytime , even if the user changes the password a million times.
There are tons and tons of ways to establish persistence on Linux. We just showed the fastest, most common, and one of the cleanest methods.
Pivoting
Finally… the last stage.
After we fully owned the machine, took everything we needed, and did all the fun stuff, now it's time to build a bridge to the other machines.
Of course, during the post exploitation enumeration we already pulled network information and found another network interface with a slightly different subnet:
192.168.57.0/24
First we need to discover the other devices sitting on this internal network, so we run this simple bash loop:
for i in $(seq 254); do ping 192.168.57.$i -c1 -w1 & done | grep fromfor i in $(seq 254); do ping 192.168.57.$i -c1 -w1 & done | grep from
There are many ways to do this (port forwarding is one of them), but that method is very limited and will keep you restricted. It's useful, but there's a much better way:
SOCKS Proxy
So that all the traffic leaving my machine goes straight through the compromised host as if I'm sitting right next to the internal network.
How do we do it?
Simple.
Background the session, then tell "Metasploit" that any traffic for that subnet should go through this session:
route add network-range netmask session-idroute add network-range netmask session-id
Then load this module:
use auxiliary/server/socks_proxyuse auxiliary/server/socks_proxy
When you run it, it will stay running in the background by itself.
Pay attention to the options: it has a port, a local host, and the SOCKS version. Don't pick a port that conflicts with anything on your machine or the session. Keep it different.
Now go to your own machine and edit:
/etc/proxychains.conf/etc/proxychains.conf
Add the SOCKS line (usually something like socks4 127.0.0.1 1080 or whatever port you chose).
After that, from your own machine you can continue scanning normally just put **proxychains** in front of every command so it forces the traffic through the proxy instead of your local network interface:
proxychains nmap -A 192.168.57.2 -sV -Pn 2>/dev/nullproxychains nmap -A 192.168.57.2 -sV -Pn 2>/dev/null
We added 2> /dev/null at the end to silence any DNS errors so they don't spam the terminal and we can keep working cleanly.
And just like that… the internal network is now reachable.
So, that's the end of Part 1.
There are still a few things we haven't covered yet , like reporting, the rest of the devices (especially Windows), and privilege escalation.
But don't worry, we'll dive into all of that in Part 2, along with even cooler stuff, more interesting insights, and plenty of useful tips and hints.
By now, I think you've got a solid understanding of the methodology.
One thing I really recommend is taking lots of notes. I personally documented this entire lab in Obsidian using diagrams and mind maps.
I'll upload all of those with Part 2, along with every asset that might help you, on GitHub.
I really hope you found this article helpful, and thanks a lot for sticking with me until the end.