VM 301
Kali Red
The attacking side: scans, proxies requests and runs bounded checks against lab targets only.
Stopped when recorded on 8 Nov 2026
The lab · VM 301 and VM 302
This is where I learn what an attack looks like from both sides. Kali Red runs a scoped test, Kali Blue looks for what that test left behind, and I decide what the evidence actually shows. Every test stays inside the isolated LAB_TEST network and on targets I set up for it.
The four walkthroughs below are labelled examples: the hostnames, addresses, accounts, timestamps and outputs are substituted to protect my lab, and nothing here is a live target. Real records are marked where they are used.
VM 301
The attacking side: scans, proxies requests and runs bounded checks against lab targets only.
Stopped when recorded on 8 Nov 2026
VM 302
The watching side: reads captures, host logs and the SIEM, and writes the analyst notes.
Stopped when recorded on 8 Nov 2026
That state comes from my inventory record and is separate from the exercises below, which are dated walkthroughs with example evidence.
Lab map · substituted names and addresses
VLAN 20 · LAB_TEST 192.0.2.0/24 (example)
Same VLAN: traffic between these never crosses Sophos.
VLAN 10 · SERVERS 198.51.100.0/24 (example)
Domain machines. Evidence flows to the SIEM; Kali Red does not.
Each walkthrough opens with a question I could have asked at the keyboard, then follows the test, the evidence, the obstacle, the fix or decision, and the retest. Pick a step, or press Play to walk through it.
Lab walkthroughExample evidence21 Oct 2026 · times in UTC
My first scan went to the file server on SERVERS. Nmap called 445 filtered: it sent SYNs and got nothing back, which can mean a firewall, a dead host or a lost reply.
nmap -Pn -sS -p 445 198.51.100.10PORT STATE SERVICE
445/tcp filtered microsoft-dsI captured on the Proxmox host, on the tap interface behind fs-01’s NIC. My first try used the wrong tap; on the right one the capture was still empty, so the SYNs never reached the server.
tcpdump -ni tap110i0 "tcp port 445 and host 192.0.2.31"0 packets captured
0 packets received by filterSophos had the answer: every SYN from Kali Red to SERVERS matched DROP_NEW_VLANS, the first rule in the order. The service was fine; my path was closed by design.
filter: src 192.0.2.31, dst 198.51.100.1019:02:14 Drop TCP 192.0.2.31:51544 → 198.51.100.10:445 Rule: DROP_NEW_VLANS
19:02:15 Drop TCP 192.0.2.31:51544 → 198.51.100.10:445 Rule: DROP_NEW_VLANSOpening SERVERS to the lab would have made the scan work and the lab worse. I left the rule alone and retested against trainbox, which sits on VLAN 20 with Kali Red.
On the same VLAN the traffic never crosses Sophos. Nmap now reported open, closed and filtered ports, each for a different reason.
nmap -Pn -sS -p 22,80,8080,9000 192.0.2.41PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
8080/tcp closed http-proxy
9000/tcp filtered cslistenerI read trainbox’s capture in Wireshark on Kali Blue. My first display filter kept only packets from Kali Red, so 8080 looked unanswered. Removing the source condition showed the RST: closed means the host is up and nothing listens.
display filter: tcp.port in {80 8080 9000}192.0.2.31 → .41 80 [SYN]
.41 → 192.0.2.31 80 [SYN, ACK]
192.0.2.31 → .41 80 [ACK]
192.0.2.31 → .41 8080 [SYN]
.41 → 192.0.2.31 8080 [RST, ACK]
192.0.2.31 → .41 9000 [SYN] (no reply: host firewall drops it)What I took from it: A dropped SYN, a reset and a handshake are three different answers. Before I call a service down, I check which one I got, where I captured it, and whether my filter could have hidden the reply.
Lab walkthroughExample evidence28 Oct 2026 · times in UTC
Signed in as test-a, I opened order 1042 through Burp Proxy. The request carries the order number in the path and the session in a cookie.
GET /api/orders/1042 HTTP/1.1
Host: shop.lab.example
Cookie: session=<test-a>HTTP/1.1 200 OK
{"id":1042,"owner":"test-a","items":2,"total":"18.40"}In Repeater I kept the request byte for byte and swapped only the cookie for test-b’s session. The server still returned test-a’s order: it checked that I was signed in, not that the order was mine.
GET /api/orders/1042 HTTP/1.1
Cookie: session=<test-b>HTTP/1.1 200 OK
{"id":1042,"owner":"test-a","items":2,"total":"18.40"}The access log shows which session read which record and when. It cannot show intent, and on its own it does not know the record belonged to someone else; the owner field had to be joined in.
grep "order=1042" access.log20:31:07 user=test-a GET /api/orders/1042 200 bytes=74
20:34:22 user=test-b GET /api/orders/1042 200 bytes=74Hiding the link in the interface would change nothing, because the request still works. The fix is a server-side check that the order’s owner is the signed-in user, before any data is read out.
The same replay now returns 404 with no order fields. The status alone would not have convinced me: a 200 with an error body or a 403 that still leaks a field are both possible, so I read the body too.
GET /api/orders/1042 HTTP/1.1
Cookie: session=<test-b>HTTP/1.1 404 Not Found
{"error":"not found"}What I took from it: An authorization bug lives in the server’s decision, not in the button. I test it by changing exactly one thing, the session, and I judge the result by the response body as well as the status code.
Lab walkthroughExample evidence4 Nov 2026 · times in UTC
From ws-02 I mapped a share on fs-01 as lab-tmp07 and typed a wrong password five times, well under the lockout threshold of 15.
Event 4625 is written on the computer where the logon was attempted, so I looked on fs-01, not ws-02. Five entries, logon type 3, sub status 0xC000006A: the account exists and the password was wrong.
Security log, filter: Event ID 462504/11/2026 20:41:12 4625 An account failed to log on
Account Name: lab-tmp07 Logon Type: 3
Workstation Name: WS-02 Source Address: 198.51.100.22
Sub Status: 0xC000006A (5 events, 20:41:12 to 20:41:40)My Wazuh search for 20:35 to 20:50 returned nothing. Event Viewer shows fs-01’s local clock, UTC+02:00 in this lab; the indexer stores UTC. I was searching two hours into the future.
data.win.system.eventID:4625 AND data.win.eventdata.targetUserName:lab-tmp07
range 2026-11-04 20:35 to 20:50 (UTC)0 hitsShifted to 18:35 to 18:50 UTC, the search found all five, and the frequency rule had raised one alert at 18:41:40.
same query, range 2026-11-04 18:35 to 18:50 (UTC)5 hits rule 60122 (logon failure) ×5
1 hit rule 60204 (multiple logon failures) 18:41:40In the CoPilot case replay for SOC-0151, I checked that source ws-02, account lab-tmp07, target fs-01, logon type 3 and the UTC time survived every hop. The triage agent gathered the five events and drafted the note; I read it against the events and closed the case as an expected lab exercise.
Example evidence · lab domain only
path: lab-tmp07 → Lab Users OUlab-tmp07 —MemberOf→ Helpdesk-Lab —ForceChangePassword→ (12 users in Lab Users)The graph suggested the throwaway account could reset other users’ passwords. That would matter far more than five failed logons.
Get-ADGroupMember -Identity "Helpdesk-Lab" | Select-Object -ExpandProperty SamAccountNamehelpdesk01
helpdesk02lab-tmp07 is not a member today. The BloodHound data was collected before I removed it, so the path was stale. I re-collect before trusting a path.
What I took from it: When a SIEM search is empty, I check the clock before the collector. Event Viewer shows local time and the indexer stores UTC, and that difference alone can hide every event.
ATT&CK mapping I added: T1110.001 Brute Force: Password GuessingMicrosoft: event 4625
Lab walkthroughExample evidence7 Nov 2026 · times in UTC
Version detection read the FTP banner and reported a release far older than anything I had installed.
nmap -sV -p 21 192.0.2.41PORT STATE SERVICE VERSION
21/tcp open ftp vsftpd 2.3.4Metasploit’s FTP version scanner returned the same banner, which proves only that the banner says so. The check for that version tests its precondition without running anything on the target; it came back negative.
use auxiliary/scanner/ftp/ftp_version
set RHOSTS 192.0.2.41
run[+] 192.0.2.41:21 - FTP Banner: '220 (vsFTPd 2.3.4)'
[*] check for this version: The target is not exploitable.On the network side Kali Blue saw two short FTP control sessions and nothing else. On the host, no new process, no new listener. Network contact happened; endpoint execution did not.
ss -ltnState Local Address:Port
LISTEN 0.0.0.0:21
LISTEN 0.0.0.0:22
LISTEN 0.0.0.0:80The installed package was a current build; the old string came from a ftpd_banner line in the training config. The lead was a decoy I had forgotten about.
dpkg -s vsftpd | grep Version
grep ftpd_banner /etc/vsftpd.confVersion: 3.0.5-0ubuntu3
ftpd_banner=(vsFTPd 2.3.4)I rolled trainbox back to its clean snapshot and checked the config hash against the baseline before the next exercise.
qm rollback 310 clean
qm listsnapshot 310`-> clean 2026-10-20 18:00:12 baseline for exercises
`-> current You are here!What I took from it: A banner is a claim made by the service about itself. I treat a version string as a lead, confirm it on the host, and keep a snapshot so a training target goes back to a known state after every test.
Every tool named on this page: what it takes in, what it produces, what that output can establish, and whether my records show the tool in use or it appears only in a walkthrough. The first four lead because security-testing roles ask for them: the OTARIS working-student listing for product security and testing names Nmap, Burp Suite, Metasploit and Wireshark.
| Tool | Role | Input | Evidence it produces | What it can establish | Shown as |
|---|---|---|---|---|---|
| Nmapwalkthrough 1, 4 | Service discovery | A scoped host and port list | Port states and version guesses | What answered, and how; not why a port is filtered | In a lab walkthrough |
| Burp Suitewalkthrough 2 | Web proxy and request replay | Browser traffic to a training app | Captured and replayed requests | How the server answers one changed variable | In a lab walkthrough |
| Metasploit Frameworkwalkthrough 4 | Banner scans and precondition checks | A disposable training VM | Banner text and check results | Whether a precondition holds; a banner proves only itself | In a lab walkthrough |
| Wiresharkwalkthrough 1 | Packet analysis | A capture file | Decoded TCP exchanges | SYN, RST or handshake, if the filter does not hide it | In a lab walkthrough |
| tcpdumpwalkthrough 1, 4 | Packet capture | One interface and a capture filter | pcap files and live counts | Whether packets reached that interface | In my records |
| PowerShellwalkthrough 3 | Directory cross-checks | Read-only AD queries | Current group membership | What is true now, against a stale graph | In a lab walkthrough |
| BloodHoundwalkthrough 3 | AD relationship graph | Collected lab-domain data | Paths between users, groups and rights | A hypothesis to verify, as of collection time | In a lab walkthrough |
| Windows Event Viewerwalkthrough 3 | Endpoint evidence | The Security log on the target | Event 4625 with logon type and sub status | Which logon failed, where, and why | In a lab walkthrough |
| Sophos logswalkthrough 1 | Firewall evidence | Log viewer filters | Allow and drop lines with the rule name | Which rule acted on a flow that crossed Sophos | In my records |
| Wazuhwalkthrough 3 | Detection and search | Agent events | Alerts and searchable events | What was collected and which rule matched | Reference architecture |
| SOCFortress CoPilotwalkthrough 3 | Cases and triage | Wazuh alerts | A case with its evidence and decision | That fields survived collection, and what was decided | Reference architecture |
| Splunk and Defender for Endpoint | Parallel evidence views | Selected endpoint data | SPL and KQL results | Whether a second view agrees | In my records |
| Proxmox snapshotswalkthrough 4 | Reset and verify | A disposable VM | A restored, known state | That the next test starts clean | In a lab walkthrough |
Where this connects: Wazuh and CoPilot are the SOCFortress stack (reference architecture); Splunk and Defender for Endpoint are the parallel views in Splunk and Defender side by side; the domain is described in Running Active Directory in my lab.
References: ATT&CK T1046 · ATT&CK T1110.001 · PortSwigger access control · Microsoft event 4625 · OTARIS listing
4 walkthroughs, all labelled examples. Which ones I have run, and with which tools, is kept with my records until I publish the evidence.