Penetration testing
Step 172. ★ Capstone Scenario 1 — From Recon to Shell
Level 2 — Introduction to Security and Attack Skill Basics | Difficulty ★★★★☆ | Estimated time: 4 hours
Prerequisites: Steps 113~119 (recon, nmap, netcat, shells), Step 130 (time-attack mock penetration), and Step 164 (enumeration automation) completed.
- What you need: a Linux lab (WSL or Kali, with nmap, nc, and Python), a timer, and a text file for records. If you have a vulnerable VM (Metasploitable2 or a VulnHub Easy box), use it for the main lab.
- ⚠️ All exercises in this chapter are for your own lab and legal platforms only. Applying them to unauthorized systems is a crime.
- Character note: today is a [project] chapter. There is no new technique — the goal is connecting everything you’ve learned so far into one continuous flow.
Until now we’ve learned techniques one by one — nmap is nmap, a shell is a shell. But the real shape of competitions and penetration tests is different: you start with just an IP, and go alone until you get a shell. Today you perform that whole process against a timer. More important than technique is "not losing the flow" — the judgment to move to the next hypothesis when stuck, and the record of what you did and when. First, you internalize the entire flow with a mini chain that’s 100% reproducible inside your own computer; then you apply the same flow to a real lab machine.
1. Learning Objectives
By the end of this chapter, you will be able to:
- Perform the kill chain — recon → scan → enumerate → hypothesize → verify → shell — independently
- Read the difference in nmap output between a closed and an open service
- Prove with server logs that nmap’s version detection is an act of "talking to" the target
- Build the habit of falling back to the checklist when stuck
- Record the time and action of each stage as a timeline
2. Background Knowledge — Today’s Tools and Concepts
Today’s Tools at a Glance
| Category | Details |
|---|---|
| Language/environment | Linux shell (WSL/Kali), Python 3 (for the mini vulnerable service) |
| Today’s commands | nmap -sV, nc -v target port, tee, date |
| Concepts needed | kill chain, attack-hypothesis prioritization, the 30-minute rule, timeline records |
| Today’s artifact | a completed mini-chain record + (if you have a lab) an IP→shell timeline log |
2-1. The Kill Chain — Binding It into One Flow
The standard penetration flow looks like this.
Recon → what has the target left open — nmap
Enumeration → identify each service and its version — banners, -sV
Hypothesis → "if this service is this version, this attack will work"
Verification→ try the most promising hypothesis first
Shell → secure command execution → secure evidence (id output)
Record → the whole process's times, commands, and results as a timeline
Each stage was learned separately. Today’s task is the connections between them — the flow where scan results create enumeration questions, enumeration creates hypotheses, and hypotheses create the next commands.
2-2. Hypothesis Priorities and the 30-Minute Rule
If five ports are open, there are five hypotheses. You can’t verify them all at once, so you order them — the criteria are "is there a known vulnerability, is there no authentication, is it outdated?" And you need a rule for how long to cling to one: don’t get tied to a single hypothesis for more than 30 minutes. When 30 minutes pass, leave a memo and move to the next hypothesis. Getting trapped in a stuck spot is the biggest cause of failing a time attack.
2-3. When Stuck, Return to Recon — 90% Is a Missed Clue
When a penetration won’t move, most causes aren’t the exploit but something missed in recon. The fallback checklist:
□ Did you look at every port? (65535 with -p-)
□ Did you look at UDP? (-sU)
□ If it's web, did you scan paths? (gobuster/dirb)
□ Did you search vulnerabilities by service version? (searchsploit)
□ Is the banner lying? (connect directly and check)
In my experience, more than half of all problems unlock with these five questions.
2-4. Today’s Lab Structure — Two Stages
Stage 1 is the mini chain — against a "vulnerable service" you build yourself in your Linux lab, you run the whole flow from recon to command execution within 20 minutes. Even without an external target, the chain’s shape is the same. Stage 2 is the main lab — if you have a vulnerable VM, apply the same flow to the real machine and record the timeline. If you don’t, complete the stage-1 record and write the main-lab section as a plan.
3. Follow Along
3-1. Building the Mini "Vulnerable Service"
Let’s build the training target ourselves. It’s a small server that listens only on 127.0.0.1 and runs just four whitelisted safe commands — it merely imitates the "accepts commands without authentication" character of a real vulnerable service.
Input: minivuln.py:
# Training service for 127.0.0.1 only — runs only whitelisted safe commands
import socket, subprocess
ALLOWED = ["whoami", "id", "hostname", "uname"]
srv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
srv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
srv.bind(("127.0.0.1", 9000))
srv.listen(5)
srv.settimeout(120)
print("mini-vuln listening on 127.0.0.1:9000", flush=True)
while True: # accepts scanner probe connections too, then waits for the next
try:
conn, addr = srv.accept()
except socket.timeout:
break
conn.settimeout(3)
conn.sendall(b"MiniVulnService 1.0 readyn$ ")
try:
data = conn.recv(1024).decode(errors="ignore").strip()
except socket.timeout:
data = ""
print("received:", repr(data), flush=True) # server-side log — who asked what
cmd = data.split()[0] if data else ""
if cmd in ALLOWED:
out = subprocess.run(data.split(), capture_output=True, text=True).stdout
conn.sendall(out.encode())
else:
conn.sendall(b"command not allowedn")
conn.close()
srv.close()
How to read it: print("received:", ...) is today’s hidden protagonist — a log that makes who did what fully visible from the server’s side. This is attack practice and defender’s-eye practice at the same time.
3-2. Recon — Closed Doors and Open Doors
First, scan before starting the service.
Input (in your Linux lab):
nmap -p 9000 127.0.0.1
Output (measured 2026-09-09):
Starting Nmap 7.94SVN ( https://nmap.org ) at 2026-09-09 16:52 KST
Nmap scan report for localhost (127.0.0.1)
Host is up (0.000059s latency).
PORT STATE SERVICE
9000/tcp closed cslistener
Nmap done: 1 IP address (1 host up) scanned in 0.06 seconds
Now start the service and add version detection.
Input:
python3 minivuln.py > server.log 2>&1 &
sleep 1
nmap -p 9000 -sV 127.0.0.1
Output (measured 2026-09-09, key parts):
PORT STATE SERVICE VERSION
9000/tcp open cslistener?
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port9000-TCP:V=7.94SVN%I=7%D=9/9%...%r(NULL,1C,"MiniVulnServicex201.0x20readyn$x20")...
How to read it: closed changed to open. And when -sV doesn’t know the service, it shows the entire banner fingerprint — the phrase we planted, MiniVulnService 1.0 ready, read back as-is. The harvest of recon: port 9000, open, an unidentified service, banner captured.
3-3. The Scanner’s Footprints — Opening the Server Log
After the scan finishes, open the server-side log.
Input:
head -20 server.log
Output (measured 2026-09-09, partial excerpt):
mini-vuln listening on 127.0.0.1:9000
received: ''
received: 'GET / HTTP/1.0'
received: 'OPTIONS / HTTP/1.0'
received: 'OPTIONS / RTSP/1.0'
received: 'HELP'
received: 'GET /nice%20ports%2C/Tri%6Eity.txt%2ebak HTTP/1.0'
received: 'OPTIONS sip:nm SIP/2.0rnVia: SIP/2.0/TCP nm;branch=foo...'
How to read it: surprising, isn’t it? We ran a single scan, yet what the server received is dozens of different greetings — pretending to be HTTP, pretending to be RTSP, pretending to be SIP. nmap’s version detection doesn’t ask "who are you?" with one question; it tries talking in every known protocol and guesses the identity from what answer comes back. From the attacker’s perspective this is "recon is noisier than you think"; from the defender’s, "you can see scans just by reading logs" — a measured scene that teaches both.
Why do this: in an attack-technique chapter, gaining the defender’s eyes is not a bonus but the core. Only someone who knows how their attack lands in the other side’s logs can distinguish quiet recon from noisy recon.
3-4. Verification and Shell — Command Execution via nc
From recon, a hypothesis stands: "a service that accepts commands without authentication." Let’s verify it.
Input:
printf "idn" | nc -v -w 3 127.0.0.1 9000
printf "whoamin" | nc -v -w 3 127.0.0.1 9000
Output (measured 2026-09-09):
Connection to 127.0.0.1 9000 port [tcp/*] succeeded!
MiniVulnService 1.0 ready
$ uid=0(root) gid=0(root) groups=0(root)
Connection to 127.0.0.1 9000 port [tcp/*] succeeded!
MiniVulnService 1.0 ready
$ root
How to read it: the hypothesis was right — we executed id without authentication and received the result. This is the essence of a "shell": a channel where you put commands in remotely and get output back. It looks different from the bind/reverse shells of Steps 118~119, but the meaning is the same. And uid=0(root) — this server was running as root. In a real lab, this single line is the evidence of gaining the highest privilege.
Cleanup command (stop the server after the experiment):
pkill -f minivuln.py
3-5. Recording the Timeline — The Model Shape of a Mini Chain
Write what you just did as a timeline. Template:
16:52:00 recon starts — nmap -p 9000 127.0.0.1 → closed (confirmed service not running)
16:52:30 rescan — nmap -p 9000 -sV → open, banner "MiniVulnService 1.0" captured
16:53:00 hypothesis — likely a service accepting commands without authentication
16:53:30 verification — nc connect, run id → confirmed uid=0(root)
16:54:00 evidence saved — output stored to evidence/ via tee
16:54:30 done — server stopped, timeline complete (elapsed 2 min 30 s)
How to read it: each line is "time + what I did + result." This format becomes, as-is, the skeleton of Step 173’s review and report. The record is not a byproduct of the penetration — it’s half the deliverable.
3-6. Main Lab — Applying It to a Real Vulnerable VM
If you have a vulnerable VM, start the timer and apply the same flow.
0:00 full scan: nmap -p- -sV targetIP -oN scan_full.txt
→ capture all open ports and version list (this file is recon's backbone)
enumerate: identify the service on each port — path scanning too if web
hypothesize: search known vulnerabilities per version (searchsploit), prioritize
verify: most promising hypothesis first — apply the 30-minute rule
shell: the moment you get it, save id / whoami output as evidence
record: keep adding each stage's time to the timeline
If you don’t have a lab, fill each cell with "what command would I run if this were my lab" as a plan, and attach the 3-2~3-5 mini-chain measured records as evidence. Don’t fabricate output — marking plans as plans and measurements as measurements is this training’s honesty rule.
4. Missions & Exercises
Mission — From IP to Shell, with a Timeline
- Reproduce the mini chain (3-1~3-5) alone from start to finish and complete the timeline
- (If you have a lab) against one vulnerable VM, complete full scan → enumeration → hypothesis → shell, recording each stage’s time
- Add one line to the timeline: "the section where I spent the most time" and why
- Quote at least three lines of traces nmap left in the server log (server.log)
- (If you have no lab) write the main-lab plan, tagging every unmeasured part with
[to be replaced with measurement after lab run]
Exercises
Exercise 1. Using the 3-2 scan-output change as evidence, explain why attempting the exploit without recon is inefficient.
Exercise 2. As 3-3’s server log shows, version detection is noisy. Explain what this fact means to the attacker and to the defender, respectively.
Exercise 3. Explain why the 30-minute rule does not mean "give up."
Exercise 4. Connecting to Step 173’s review, explain why each timeline line must have the three elements "time + what I did + result."
Answers & completion criteria · expand/collapse
5. Model Answers & Completion Criteria
Mission Model Answer
A measured example of a completed timeline (2026-09-09 mini chain):
16:52 recon — confirmed closed, started the service, rescan gave open + banner
16:53 hypothesis formed — "an unauthenticated command-execution service"
16:53 verification succeeded — ran id via nc, confirmed uid=0(root)
16:54 evidence saved and done
Section where I spent the most time: on the first attempt, nmap -sV consumed the
server's single connection so the nc connection failed — fixing the server to a
repeating-accept structure took the longest.
That last sentence matters — the stuck spot and the breakthrough must be in the record for it to become learning. This sentence is reborn in the Step 173 report as "the sentence that lets readers dodge the same trap."
How to verify: ① does the timeline have every stage’s time? ② does the shell evidence include id or whoami output? ③ are there three or more server.log quotes? ④ are the stuck section and breakthrough recorded? ⑤ are unmeasured parts tagged? All being "yes" means complete.
Exercise Answers
Answer 1. In 3-2, the same port split into closed before the service started and open after — that is, recon alone tells you whether a door is even worth knocking on. An exploit without recon is like sticking a key into a closed door, and even if it’s open, without the version you can’t know which attack fits. Recon isn’t a stage that spends time — it’s the stage that saves it.
Answer 2. To the attacker it’s a warning: "your traces land in logs already at the recon stage" — dozens of protocol greetings all get recorded. To the defender it’s an opportunity: "read the logs and you can see scans" — a normal user doesn’t greet one port as SIP and RTSP. The same log teaches both sides different lessons.
Answer 3. The 30-minute rule doesn’t discard the hypothesis — it postpones it. While you leave a memo and verify other hypotheses, your view widens, and later you can come back with new clues. In a time attack, the enemy isn’t "the problem you can’t solve" but "the time you spent trapped on one problem."
Answer 4. Review is done from records, not from memory. With times you can analyze "where did I spend my time"; with actions and results you can reconstruct "what worked and what didn’t." A timeline with all three elements becomes, as-is, the first draft of the report’s attack-path section — today’s record is tomorrow’s document.
Completion Criteria Checklist
- [ ] I can say the kill chain’s six stages in order
- [ ] I measured the nmap output difference with the service on/off
- [ ] I can read the banner-fingerprint output
-sVleaves - [ ] I found and quoted the scanner’s traces in the server log
- [ ] I executed a command via nc and captured
idoutput - [ ] I completed the mini-chain timeline
- [ ] I can write the 30-minute rule and the fallback checklist in my own words
- [ ] (Lab) completed IP→shell, or (no lab) completed plan + tags
6. Common Pitfalls & Fixes
Wall 1. I get nc: connect to 127.0.0.1 port 9000 (tcp) failed: Connection refused
Symptom (measured 2026-09-09, connecting without the server):
nc: connect to 127.0.0.1 port 9000 (tcp) failed: Connection refused
Cause: there’s no listening service — exactly the closed state from 3-2.
Fix: start the server first (python3 minivuln.py &). In a real lab, this message is itself a recon result — "that port’s door is closed"; move to another port.
Wall 2. After scanning, the nc connection goes dead
Symptom: connecting with nc right after nmap -sV gets no response at all.
Cause (confirmed by 2026-09-09 measurement): if the server accepts only one connection, nmap’s version detection consumes that connection first.
Fix: build the server with a repeating-accept structure (while True: accept()) as in 3-1. It must accept the scanner’s probe connection and then wait for the next guest. This wall is itself evidence that "a scan talks to the target."
Wall 3. The full scan takes so long I give up
Symptom: nmap -p- is on its tenth minute.
Cause: an exhaustive survey of 65,535 ports is slow by nature — especially with default options.
Fix: split it into two stages — first a fast full sweep (-p- with minimum-speed options) to find only the open ports, then -sV on just those ports; that’s the field pattern. Running precision scans on every port from the start is the time thief.
Wall 4. I got the shell but can’t remember what I did
Symptom: you finished, but the timeline is empty.
Cause: you postponed recording to "later" — in the excited state it never gets written.
Fix: write one line immediately every time you run a command. The habit of leaving output in files with tee (Step 126) collects evidence automatically. A finish without records is half a finish — you’ll have nothing to use in Step 173.
Wall 5. Skipping the mini chain as a "toy"
Symptom: you omit 3-1~3-5, saying you’ll only do the real VM.
Cause: a misunderstanding of purpose — the mini chain is not the target but the practice range for the flow.
Fix: invest 20 minutes. When you get stuck in the real lab, the "baseline of normal behavior" you fall back to is the mini chain’s measured outputs. You need a baseline to see "what’s different."
7. Summary
Today’s Concepts
| Concept | One-line explanation |
|---|---|
| Kill chain | Recon→enumerate→hypothesize→verify→shell→record — the standard penetration flow |
| Attack hypothesis | "If this service is this version, then this attack" — the sentence before verification |
| 30-minute rule | Don’t get trapped on one hypothesis — postpone and move on |
| Fallback checklist | When stuck, return to recon — missed clues cause 90% |
| Timeline | A record of time+action+result — half the penetration’s deliverable |
| Scanner’s footprints | Version detection is dozens of greetings — it stays in the target’s logs |
Today’s Commands & Tools
| Tool | What it does |
|---|---|
nmap -p- targetIP |
Full-port survey (slow — stage 1 of the two-stage strategy) |
nmap -p port -sV targetIP |
Version detection — capturing banner fingerprints |
nc -v target port |
Talking to a service by hand |
pkill -f scriptname |
Cleaning up the experiment server |
tee file |
Sending output to screen and file at once — the evidence habit |
minivuln.py |
A training service for 127.0.0.1 only — the chain’s practice range |
An Instinct More Important Than Commands
Today you practiced not technique but flow. The chain where recon creates hypotheses, hypotheses create the next command, and everything remains as a record — once this chain sticks to your body, you’ll see what to do even when you meet an unfamiliar machine. And don’t forget the truth the server log showed: from the attack’s very first command, the target was watching. Knowing the difference between quiet recon and noisy recon, and knowing how your own actions land in logs — that’s half the skill, and the other half is records.
Once every box is checked, Step 172 is complete.
ONE STEP FURTHER
Finished this lesson?
Check the completion criteria, then mark your progress.