Step 249. Network Breach Analysis Simulation — Reconstructing the Incident Inside Packets

Step 249. Network Breach Analysis Simulation — Reconstructing the Incident Inside Packets

Level 3 — Real-World CTF & Advanced Offensive Skills | Difficulty ★★★★☆ | Estimated time: 3 hours

Prerequisites: Step 83~84 (Wireshark capture and filters), Step 245 (rebuilding an intrusion timeline), Step 173 (writing a pentest report). You know how to use tshark on the command line.

  • What you need: WSL Ubuntu (measured: Ubuntu 24.04, tshark 4.2.2, scapy 2.7.0 in a venv), a working folder, a Markdown editor.
  • ⚠️ All exercises in this chapter are for your own lab and legal platforms only. Applying them to unauthorized systems is a crime. Today’s pcap is a practice file you generate yourself.
  • Chapter type: today is a [hands-on] chapter. You play both attacker and analyst — you build a scenario pcap yourself, then analyze that file as if it were an unknown incident.

The comprehensive exam of the forensics track is handling a full breach. When an incident breaks, a real-world Incident Response (IR) team receives a bundle of evidence, finds the entry point, scopes the damage, builds a timeline, and writes a report. Today you experience that routine in miniature.

In the field, someone else produces the pcap. But for a first exercise, generating the attack packets yourself is better — when you analyze a file you built with the answers known, you can check exactly "what fingerprints get left behind" as you learn. Today you use the maker’s eye and the finder’s eye in the same day.


1. Learning Objectives

By the end of this chapter, you will be able to:

  • State the five phases of the IR process (preparation → detection → containment → recovery → lessons learned)
  • Generate a scenario pcap with scapy to create analysis practice material
  • Grasp the overall shape of an unfamiliar pcap first, using tshark statistics (io,phs, conv,tcp)
  • Find the three fingerprints — scanning, brute force, and data exfiltration — with filters
  • Reconstruct a timeline from evidence and write an IR report in the standard six-section structure

2. Background Knowledge — Today’s Tools and Concepts

Today’s Tools at a Glance

Category Details
Language/environment Python 3 (scapy venv) + WSL Linux shell
Today’s commands tshark -r, -Y display filters, -z io,phs, -z conv,tcp, -T fields
Concepts needed The 5 IR phases, scan fingerprints, brute-force fingerprints, exfiltration fingerprints, evidence preservation
Today’s deliverable incident.pcap (self-generated) + a timeline table + one IR report

2-1. The IR Process — Five Phases

Incident response follows a standardized process. Remember it as five phases.

① Preparation   — have tools and baselines ready in normal times
② Detection     — find anomalies and declare an incident
③ Containment   — stop the spread (suspend accounts, block networks)
④ Recovery      — return systems to normal
⑤ Lessons       — write the report and apply recurrence prevention

Today’s exercise covers ② Detection through ⑤ Lessons. Remember that the output of ① Preparation is "a baseline of the normal state" — anomalies are only visible against a reference.

2-2. Attackers Leave Fingerprints — Three Patterns

Most network breaches are a sequence of three scenes. Each scene leaves a different shape in the pcap.

The scan fingerprint: one source sends SYNs to many ports in a short time. It’s the shape of SYN going out and RST coming back from closed ports, in an unbroken series.

The brute-force fingerprint: authentication failure responses repeat against the same service. For FTP, 530 Login incorrect; for SSH, a pile of consecutive auth failures.

The exfiltration fingerprint: an abnormally large volume of bytes flowing from an internal host outward. In conversation statistics, the session where "outbound bytes" spikes is your suspect.

2-3. tshark — Wireshark’s Command-Line Face

tshark is the engine behind the Wireshark you worked with in the GUI in Step 83~84. On servers and in automated environments only the command line is available, so memorize these three usages.

  • tshark -r file -q -z io,phs — protocol hierarchy statistics: "what’s in this file"
  • tshark -r file -q -z conv,tcp — TCP conversation list: "who talked to whom, and how much"
  • tshark -r file -Y "filter" -T fields -e fieldname — extract specific fields from packets matching a condition

The iron rule of analysis is the overall shape first, then the details. Get the map from statistics, then zoom in with filters.

2-4. Evidence Preservation — Analysis Never Dirties the Original

In the field, you hash the original evidence first and analyze a copy. Build the habit in practice too — keep the original pcap read-only (tshark -r only reads), and accumulate analysis output in a separate working folder. Every claim in your report must point to evidence in that folder.


3. Follow Along

3-1. Building the Incident File — Generating a Scenario pcap with scapy

First, the attacker’s role. You synthesize the three scenes (scan → FTP brute force → file theft followed by exfiltration) into packets. Create make_incident_pcap.py in your working folder.

# Breach scenario pcap generator — scapy
# attacker 10.0.0.55 → victim server 10.0.0.10
from scapy.all import IP, TCP, Raw, wrpcap

BASE = 1757360000.0  # fixed reference time (epoch)
ATTACKER = "10.0.0.55"
SERVER = "10.0.0.10"
OPEN_PORTS = {21, 22}   # ports open on this server
pkts = []
t = BASE

def ts():
    global t
    t += 0.05
    return t

def syn(dport, sport):
    p = IP(src=ATTACKER, dst=SERVER) / TCP(sport=sport, dport=dport,
                                           flags="S", seq=1000)
    p.time = ts()
    pkts.append(p)
    flags = "SA" if dport in OPEN_PORTS else "RA"
    r = IP(src=SERVER, dst=ATTACKER) / TCP(sport=dport, dport=sport,
                                           flags=flags, seq=2000, ack=1001)
    r.time = ts()
    pkts.append(r)

def talk(src, dst, sport, dport, payload):
    p = IP(src=src, dst=dst) / TCP(sport=sport, dport=dport,
                                   flags="PA", seq=1, ack=1) / Raw(load=payload)
    p.time = ts()
    pkts.append(p)

# Scene 1: port scan — consecutive SYNs at 0.05-second intervals
for i, dport in enumerate(range(1, 41)):
    syn(dport, sport=40000 + i)

t += 30  # a pause while the attacker picks a target after the scan

# Scene 2: FTP brute force — 5 failures, then 1 success
for pw in ["123456", "password", "qwerty", "letmein", "admin", "backup01"]:
    talk(ATTACKER, SERVER, 50000, 21, b"USER admin\r\n")
    talk(SERVER, ATTACKER, 21, 50000, b"331 Password required\r\n")
    talk(ATTACKER, SERVER, 50000, 21, f"PASS {pw}\r\n".encode())
    if pw == "backup01":
        talk(SERVER, ATTACKER, 21, 50000, b"230 Login successful\r\n")
    else:
        talk(SERVER, ATTACKER, 21, 50000, b"530 Login incorrect\r\n")

t += 10

# Scene 3: list files → download a file → bulk transfer to the outside (203.0.113.77)
talk(ATTACKER, SERVER, 50000, 21, b"LIST\r\n")
talk(SERVER, ATTACKER, 21, 50000,
     b"150 Opening data\r\n-rw-r--r-- 1 admin admin 51200 payroll_2025Q3.xlsx\r\n226 Done\r\n")
talk(ATTACKER, SERVER, 50000, 21, b"RETR payroll_2025Q3.xlsx\r\n")
t += 5
for i in range(36):  # exfiltration: server → outside, 1400 bytes × 36
    talk(SERVER, "203.0.113.77", 443, 51000, b"X" * 1400)

wrpcap("incident.pcap", pkts)
print(f"created: incident.pcap, {len(pkts)} packets")

Input (measured 2026-09-09 on WSL, using the scapy 2.7.0 venv’s Python):

python3 make_incident_pcap.py

Output (measured 2026-09-09):

created: incident.pcap, 143 packets

How to read the output: 143 packets = 80 for the scan (SYN + response) + 27 for FTP + 36 for exfiltration. Because each packet got its timestamp stamped with p.time = ts(), this file is a "crime scene" that carries a clock. In the field, an IDS or a mirroring port produces files like this for you.

3-2. The First 30 Seconds — Grasping the Overall Shape

Now take off the attacker’s hat and become the analyst. Treat the file you just made as an unknown incident. The first command is protocol hierarchy statistics.

Input (measured 2026-09-09):

tshark -r incident.pcap -q -z io,phs

Output (measured 2026-09-09):

===================================================================
Protocol Hierarchy Statistics
Filter:

ip                                       frames:143 bytes:56651
  tcp                                    frames:143 bytes:56651
    ftp                                  frames:27 bytes:1611
      ftp.current-working-directory      frames:27 bytes:1611
    data                                 frames:36 bytes:51840
===================================================================

How to read the output: everything is TCP; within it, FTP is 27 frames, and 36 frames of unidentified data — but the bytes on the data side (51,840) are more than 30 times the FTP side (1,611). When you see the shape "a quiet control channel + a big data lump," that big lump is your next investigation target.

The second command is conversation statistics.

Input (measured 2026-09-09):

tshark -r incident.pcap -q -z conv,tcp | head -5

Output (measured 2026-09-09, first part only):

                                                           |       <-      | |       ->      | |     Total     |    Relative    |   Duration   |
                                                           | Frames  Bytes | | Frames  Bytes | | Frames  Bytes |      Start     |              |
10.0.0.10:443              <-> 203.0.113.77:51000               0 0 bytes        36 51 kB          36 51 kB        50.349995000         1.7500
10.0.0.55:50000            <-> 10.0.0.10:21                    13 865 bytes      14 746 bytes      27 1611 bytes    33.999996000        11.3000
10.0.0.55:40000            <-> 10.0.0.10:1                      1 40 bytes        1 40 bytes        2 80 bytes      0.000000000         0.0500

How to read the output: three things catch the eye. ① A session where 51 kB went in one direction only from the server (10.0.0.10) to the outside (203.0.113.77) — a conversation with 0 bytes received is not normal web use. ② The FTP conversation between 10.0.0.55 and the server. ③ One-packet conversations whose Relative Start marches from 0.00 seconds at 0.05-second intervals — that’s the trace of the scan (the list runs long, in port order 1, 2, 3…).

3-3. Confirming Scene 1 — Finding the Scan Fingerprint

Count, per source, the packets that send only a SYN with no ACK (= the first packet that opens a connection).

Input (measured 2026-09-09):

tshark -r incident.pcap -Y "tcp.flags.syn==1 && tcp.flags.ack==0" \
  -T fields -e ip.src -e ip.dst | sort | uniq -c | sort -rn

Output (measured 2026-09-09):

     40 10.0.0.55	10.0.0.10

How to read the output: one address initiated a connection to the same target 40 times. Normal users don’t behave like that — this is scan suspect #1. So what did the attacker find? Filter down to just the ports the server answered with SYN-ACK (= open).

Input (measured 2026-09-09):

tshark -r incident.pcap -Y "tcp.flags.syn==1 && tcp.flags.ack==1 && ip.src==10.0.0.10" \
  -T fields -e tcp.srcport

Output (measured 2026-09-09):

21
22

How to read the output: FTP (21) and SSH (22) were open. You already saw in the conversation statistics that the attacker’s next move went toward FTP — the scan results and the actual attack target connect up.

3-4. Confirming Scene 2 — Extracting the FTP Brute Force

Pull the commands, arguments, and response codes of the packets decoded as FTP, in time order.

Input (measured 2026-09-09):

tshark -r incident.pcap -Y ftp -T fields \
  -e frame.time_relative -e ip.src -e ftp.request.command \
  -e ftp.request.arg -e ftp.response.code

Output (measured 2026-09-09, first 12 lines and last 6 lines):

33.999996000	10.0.0.55	USER	admin
34.049996000	10.0.0.10			331
34.099996000	10.0.0.55	PASS	123456
34.149996000	10.0.0.10			530
34.199996000	10.0.0.55	USER	admin
34.249996000	10.0.0.10			331
34.299996000	10.0.0.55	PASS	password
34.349996000	10.0.0.10			530
...(same pattern repeats: qwerty, letmein, admin all fail with 530)...
34.999995000	10.0.0.55	USER	admin
35.049995000	10.0.0.10			331
35.099995000	10.0.0.55	PASS	backup01
35.149995000	10.0.0.10			230
45.199995000	10.0.0.55	LIST
45.249995000	10.0.0.10			150
45.299995000	10.0.0.55	RETR	payroll_2025Q3.xlsx

How to read the output: 530 five times, then a single 230 (login successful) — the textbook fingerprint of brute force. Right after succeeding, the attacker viewed the listing with LIST and downloaded payroll_2025Q3.xlsx with RETR. The initial intrusion vector is identified as "weak FTP password." Also note that FTP is a cleartext protocol, so the passwords are plainly visible — a lesson for the defense side.

3-5. Confirming Scene 3 — Measuring the Exfiltration Volume

The last suspect is the 51 kB that went outside. Count the packets and total bytes, and check when it happened.

Input (measured 2026-09-09):

tshark -r incident.pcap -Y "ip.dst==203.0.113.77" -T fields -e frame.len | \
  python3 -c "import sys; d=[int(x) for x in sys.stdin]; print(len(d), 'packets,', sum(d), 'bytes')"

Output (measured 2026-09-09):

36 packets, 51840 bytes

Also pull the absolute times of the first and last packets in the file.

Input (measured 2026-09-09):

tshark -r incident.pcap -T fields -e frame.time | head -1
tshark -r incident.pcap -T fields -e frame.time | tail -1

Output (measured 2026-09-09):

Sep  9, 2025 04:33:20.050000000 KST
Sep  9, 2025 04:34:12.149993000 KST

How to read the output: the downloaded file was 51,200 bytes per the listing, and the amount that went outside is 51,840 bytes — accounting for headers, the natural reading is that the stolen file was exfiltrated almost intact. The entire incident runs 52 seconds.

3-6. Reconstructing the Timeline — The Incident as a Single Table

Weave your findings so far in time order. This table is the backbone of the report.

| Time (relative) | Event | Evidence |
|-----------|------|------|
| 00.0 ~ 02.0s | 10.0.0.55 scans ports 1~40 | 40 SYNs; open ports 21·22 confirmed |
| 34.0 ~ 35.1s | FTP admin brute force; 6th attempt (backup01) succeeds | 530 ×5 → 230 |
| 45.2s | File listing viewed with LIST | payroll_2025Q3.xlsx found |
| 45.3s | payroll_2025Q3.xlsx downloaded | RETR command |
| 50.3 ~ 52.1s | Server→outside (203.0.113.77) 51,840-byte transfer | one-way conversation, 36 data frames |

How to read the output: placing "what the attacker did" and "what the server answered" on a single clock is the whole of a timeline. What you did with logs in Step 245, you simply did with packets today.

3-7. The IR Report — The Six-Section Structure

This is the standard structure of a real-world report. Fill this frame with your analysis results.

# Breach Analysis Report — incident.pcap
Date: ____ | Analyst: ____ | Evidence: incident.pcap (143 packets)

### 1. Summary
An external address broke into the server's FTP via brute force,
stole one payroll file, and exfiltrated it outside. Total elapsed
time: about 52 seconds. Immediate action required.

### 2. Timeline
(the table from 3-6)

### 3. Intrusion Path
Scan (ports 21·22 found) → FTP admin brute force (succeeded on 6th try) →
file theft (RETR) → external exfiltration (203.0.113.77)

### 4. Scope of Damage
- Account: FTP admin (password backup01 — exposed, must be retired)
- Host: 10.0.0.10
- Data: payroll_2025Q3.xlsx (51,200 bytes, exfiltration confirmed)

### 5. Containment Actions (proposed)
- Immediately change the admin FTP password or suspend the account
- Firewall-block 10.0.0.55 and 203.0.113.77
- Check server 10.0.0.10 for additional intrusion traces

### 6. Recurrence Prevention
- Retire the FTP (cleartext) service; migrate to SFTP
- Apply an account lockout policy on repeated login failures
- Add a detection rule for large outbound transfers

How to read the output: notice that Section 4’s damage scope is "listed out" — count without omission along the three axes of account, host, and data. Sections 5–6 come in pairs with the findings. The intrusion path was cleartext FTP, so the recurrence prevention is migrating to SFTP.


4. Missions & Exercises

Mission — Build a Variant Scenario and Write an Analysis Report

  1. Modify the generator from 3-1 to create a new incident: change the password list, move the success position (e.g., to the 9th attempt), adjust the exfiltration size
  2. Set the pcap you made aside (check only the filename), and re-analyze it in the analyst role only, following the command order of 3-2~3-5 — the rule is not to peek at the generation code
  3. Complete a timeline table in the 3-6 format
  4. Write a report in the 3-7 format, attaching tshark command output as evidence for every figure (packet counts, bytes, response code counts)
  5. Finally, compare the generation code against your analysis — grade how closely your analysis matched the actual incident

Exercises

Exercise 1. Write the five phases of the IR process in order, and explain which stretch of them today’s exercise covered.

Exercise 2. Explain why you run tshark -q -z io,phs and -z conv,tcp before any detailed filters.

Exercise 3. Give at least three grounds on which you judged "exfiltration" in today’s pcap.

Exercise 4. Explain what the fact that FTP is cleartext means for the attacker and for the defender, respectively.


5. Model Answers & Completion Criteria

Mission Model Answer

An example of a variant: if you moved the successful password to the 9th position, your analysis should show 530 eight times followed by 230 in the FTP extraction table, and your report’s Section 3 should say "succeeded on the 9th attempt." If you adjusted the exfiltration size, the one-way bytes in conv,tcp and the damaged data size in Section 4 change accordingly.

How to verify: ① Did you avoid looking at the generation code during analysis (an honesty self-check)? ② Does every row of the timeline have an evidence column? ③ Does every figure in the report match tshark output? ④ In the final comparison, if there was "a scene the analysis missed," that is exactly your improvement point for the next round — the same principle as Step 173’s missed-clue analysis.

Exercise Answers

Answer 1. Preparation → Detection → Containment → Recovery → Lessons. Today’s exercise covered the Detection stretch (finding anomalies and reconstructing the incident) and the Lessons stretch (writing the report); Containment and Recovery were only touched on as proposals in Sections 5–6. Preparation was experienced indirectly as "having the analysis tools (tshark, scapy) ready in advance."

Answer 2. With an unfamiliar pcap, starting from the details buries you in 143 packets (millions, in the field). Statistics are "the map" — you must first know which protocols exist and which conversations are large before you can decide where to aim your filters. The order of overall shape → detailed zoom determines your analysis time.

Answer 3. ① A one-way conversation with 0 bytes received (<- 0 bytes in conv,tcp). ② The outbound volume (51,840 bytes) almost exactly matches the size of the file stolen just before (51,200 bytes). ③ In time, the transfer (from 50.3s) follows immediately after the download (RETR, 45.3s). ④ The destination is an external address (203.0.113.77), not an internal range.

Answer 4. For the attacker, it’s a defenseless channel where simply capturing the packets reveals the passwords verbatim. For the defender, it has a double meaning: ① credentials are exposed to eavesdropping, and ② during incident analysis the exfiltrated contents become readable too. That’s why the first item of recurrence prevention is "retire cleartext protocols."

Completion Criteria Checklist

  • [ ] I can state the 5 IR phases in order
  • [ ] I can generate a scenario pcap with scapy
  • [ ] I can grasp the overall shape of an unfamiliar pcap with io,phs and conv,tcp
  • [ ] I can find the SYN scan fingerprint with a filter
  • [ ] I can explain the fingerprint of repeated auth failures (530) followed by success (230)
  • [ ] I can point out a one-way, high-volume session as an exfiltration candidate
  • [ ] Mission: I completed the timeline and the six-section report for my variant scenario

6. Common Pitfalls & Fixes

Wall 1. tshark shows a "Running as user root" warning

Symptom (measured 2026-09-09):

Running as user "root" and group "root". This could be dangerous.

Cause: this notice appears when you run tshark while logged into WSL as root.
Fix: it’s harmless for read-only analysis (-r), so you can proceed. If it bothers you, enter WSL as a regular user, or append 2>/dev/null to discard the warning to standard error — just remember that real error messages get hidden along with it.

Wall 2. You typed a filter and got completely empty results

Symptom: tshark -r incident.pcap -Y "ftp.request.command" outputs nothing.
Cause: usually a file path typo, or a typo in the filter field name.
Fix: first check with -z io,phs whether that protocol actually exists in the file. If today’s file had no FTP, there would be nothing to extract. Don’t go looking for an alley without a map.

Wall 3. Traffic you thought was FTP shows up as data in io,phs

Symptom (measured 2026-09-09): the exfiltration stretch is displayed only as data frames:36 bytes:51840.
Cause: tshark classifies TCP payloads it can’t decode as data. A formatless lump of bytes, like exfiltration traffic, ends up that way.
Fix: an oddly large data is itself a clue. Find which conversation it is with conv,tcp, and inspect the payload with a -Y "data" filter.

Wall 4. Absolute times appear in an unexpected timezone

Symptom: frame.time prints in a different timezone than expected (e.g., KST).
Cause: pcap timestamps are epoch (seconds based on UTC), and the display timezone follows the analyzing computer’s settings.
Fix: during analysis, view relationships with relative time (frame.time_relative); in the report, state absolute times together with the timezone. When combining times from multiple systems, timezones are a habitual source of evidence contamination.

Wall 5. You mix up "attacker behavior" and "normal administrator behavior"

Symptom: you can’t decide whether a successful FTP login is an attack or an administrator’s normal access.
Cause: there’s no baseline.
Fix: judge by the surrounding context — in today’s incident, the success was preceded by 5 failures and followed by a large outbound transfer. A single event may be ambiguous, but a sequence is unambiguous. In the field, preparing baselines of normal login times and frequencies in advance is the "Preparation" phase of IR.


7. Summary

Today’s Concepts

Concept One-line explanation
The 5 IR phases Preparation → Detection → Containment → Recovery → Lessons
Scan fingerprint Consecutive SYNs at short intervals from one source
Brute-force fingerprint Repeated auth failures (530) followed by a success (230)
Exfiltration fingerprint A one-way, high-volume session with 0 bytes received
Baseline A record of the normal state — anomalies show through comparison
Evidence preservation Original stays read-only; analysis happens on copies in a working folder

Today’s Commands & Tools

Command What it does
tshark -r file -q -z io,phs Protocol hierarchy statistics (the map)
tshark -r file -q -z conv,tcp Per-conversation TCP frames/bytes (suspect selection)
-Y "tcp.flags.syn==1 && tcp.flags.ack==0" Extract only connection-initiating (SYN) packets
-T fields -e fieldname Extract only the fields you want as a table
scapy wrpcap() Save synthesized packets to a pcap
frame.time / frame.time_relative Absolute time / time relative to the start of the capture

An Instinct More Important Than Commands

The order of analysis is always the same — get the map from statistics, zoom in with filters, weave it together with time. And one fact you learned by playing the attacker today: each scene of an attack has a different shape, and that’s why they can be told apart. Finally, the output of analysis is not "I figured it out" but a report — a third party following your commands exactly must reach the same conclusion. Remember that the six-section structure you wrote today is the same skeleton as a real-world IR team’s report.


Once every box is checked, Step 249 is complete. Click the checkbox in the sidebar to save your progress.