Playbook: VPN Abuse / Unauthorized VPN Access
ID: PB-41
Severity: High | Category: Initial Access / Persistence
MITRE ATT&CK: T1133 (External Remote Services), T1078 (Valid Accounts)
Trigger: SIEM alert (VPN login from unusual location), impossible travel, brute force on VPN portal, compromised VPN credentials on dark web
⚠️ WARNING: VPN access provides direct internal network access. A compromised VPN session is equivalent to an attacker sitting on your LAN.
VPN Threat Landscape
graph TD
VPN["🔒 VPN Threats"] --> CredTheft["Credential Theft"]
VPN --> Vuln["VPN Vulnerability"]
VPN --> Split["Split Tunneling Abuse"]
VPN --> Session["Session Hijacking"]
CredTheft --> Phish["Phishing for VPN creds"]
CredTheft --> Dark["Credentials on dark web"]
CredTheft --> Brute["Brute force / spray"]
Vuln --> CVE["CVE exploitation\nPulse Secure, FortiGate"]
Vuln --> ZeroDay["Zero-day in VPN appliance"]
Split --> Exfil["Data exfil via split tunnel"]
Split --> Pivot["Pivot to internal network"]
style VPN fill:#ff6600,color:#fff
style CVE fill:#cc0000,color:#fff
style ZeroDay fill:#cc0000,color:#fff
VPN Attack Chain
graph LR
A["1️⃣ Credential Theft\nPhishing/Dark web"] --> B["2️⃣ VPN Auth\nValid credentials"]
B --> C["3️⃣ Internal Access\nNetwork recon"]
C --> D["4️⃣ Lateral Movement\nRDP/SMB/WMI"]
D --> E["5️⃣ Persistence\nBackdoor account"]
E --> F["6️⃣ Exfiltration\nData theft"]
style A fill:#ffcc00,color:#000
style B fill:#ff9900,color:#fff
style D fill:#ff4444,color:#fff
style F fill:#660000,color:#fff
Decision Flow
graph TD
Alert["🚨 Suspicious VPN Activity"] --> Type{"Alert type?"}
Type -->|"Unusual location"| Geo["Check GeoIP\nProxy/VPN/Tor?"]
Type -->|"Impossible travel"| Travel["Compare with last login\nPhysically possible?"]
Type -->|"Brute force"| BF["Check failed attempts\nSource IP reputation"]
Type -->|"After hours access"| Hours["Check user schedule\nOn-call roster?"]
Geo --> Legit{"Legitimate travel?"}
Travel --> Legit
BF --> Threshold{"Threshold exceeded?"}
Hours --> Legit
Legit -->|"No — Suspicious"| Verify["📞 Call user to verify"]
Legit -->|"Yes — Expected"| Log["Log & monitor"]
Threshold -->|"Yes > 10 failures"| Block["🔴 Block source IP"]
Verify --> Confirmed{"User confirms?"}
Confirmed -->|"No — Not them"| Contain["🔴 CONTAIN\nRevoke VPN session"]
Confirmed -->|"Yes — Legitimate"| Close["Close alert"]
style Alert fill:#ff6600,color:#fff
style Contain fill:#cc0000,color:#fff
Investigation Process
sequenceDiagram
participant SIEM
participant SOC as SOC Analyst
participant VPN as VPN Admin
participant User
participant IR as IR Team
SIEM->>SOC: 🚨 VPN anomaly detected
SOC->>VPN: Pull session logs (IP, duration, bandwidth)
SOC->>SOC: GeoIP check + impossible travel calc
SOC->>User: 📞 Phone call verification
User->>SOC: "That wasn't me!"
SOC->>VPN: Terminate active session immediately
SOC->>IR: Escalate — compromised VPN credentials
IR->>VPN: Reset user credentials + revoke MFA token
IR->>SOC: Hunt for lateral movement during session
VPN Session Risk Scoring
graph TD
Score["Risk Score Calculation"] --> Geo{"GeoIP unusual?"}
Geo -->|Yes| G["+ 30 points"]
Geo -->|No| G0["+ 0"]
Score --> Time{"Outside business hours?"}
Time -->|Yes| T["+ 20 points"]
Time -->|No| T0["+ 0"]
Score --> Duration{"Session > 8 hours?"}
Duration -->|Yes| D["+ 15 points"]
Duration -->|No| D0["+ 0"]
Score --> BW{"High bandwidth?"}
BW -->|Yes| B["+ 25 points"]
BW -->|No| B0["+ 0"]
Score --> MFA{"MFA bypassed?"}
MFA -->|Yes| M["+ 50 points 🔴"]
MFA -->|No| M0["+ 0"]
G --> Total["Total Score"]
T --> Total
D --> Total
B --> Total
M --> Total
style Score fill:#333,color:#fff
style M fill:#cc0000,color:#fff
Response Timeline
gantt
title VPN Abuse Response Timeline
dateFormat HH:mm
axisFormat %H:%M
section Detection
SIEM alert :a1, 00:00, 5min
GeoIP + travel analysis :a2, after a1, 10min
section Verification
Contact user :a3, after a2, 15min
Confirm unauthorized :a4, after a3, 5min
section Containment
Kill VPN session :a5, after a4, 2min
Reset credentials :a6, after a5, 10min
section Investigation
Session activity audit :a7, after a6, 60min
Lateral movement hunt :a8, after a7, 120min
section Recovery
New credentials :a9, after a8, 30min
VPN Appliance Vulnerability Check
graph TD
subgraph "Critical VPN CVEs to Monitor"
CVE1["CVE-2024-21762\nFortiOS RCE"]
CVE2["CVE-2023-46805\nIvanti Connect Secure"]
CVE3["CVE-2021-22893\nPulse Secure RCE"]
CVE4["CVE-2020-5902\nF5 BIG-IP"]
CVE5["CVE-2023-20269\nCisco ASA/FTD"]
end
style CVE1 fill:#cc0000,color:#fff
style CVE2 fill:#cc0000,color:#fff
style CVE3 fill:#cc0000,color:#fff
| # |
Action |
Owner |
| 1 |
Identify suspicious VPN session (user, IP, duration) |
SOC T1 |
| 2 |
GeoIP + impossible travel analysis |
SOC T1 |
| 3 |
Contact user via phone for verification |
SOC T1 |
| 4 |
If unauthorized — kill VPN session immediately |
VPN Admin |
| 5 |
Reset user password and revoke MFA token |
IAM Team |
| 6 |
Check for activity during unauthorized session |
SOC T2 |
2. Investigation Checklist
VPN Session Analysis
Network Activity During Session
Credential Investigation
3. Containment
| Scope |
Action |
Details |
| VPN Session |
Terminate immediately |
Kill active session |
| Credentials |
Reset password + MFA |
New token enrollment |
| Source IP |
Block at perimeter |
Firewall rule |
| Internal access |
Review and revoke |
File shares, RDP |
4. Eradication & Recovery
- Force password reset for affected account
- Re-enroll MFA (new device/token)
- Review all systems accessed during unauthorized session
- Check for persistence (new accounts, scheduled tasks, backdoors)
- Patch VPN appliance if vulnerability exploited
5. Post-Incident
Lessons Learned
| Question |
Answer |
| How were VPN credentials compromised? |
[Phishing/dark web/reuse] |
| Was MFA enabled and enforced? |
[Yes/No] |
| Did anomaly detection trigger promptly? |
[Time to detect] |
| Was split tunneling policy appropriate? |
[Review] |
6. Detection Rules (Sigma)
title: VPN Login from Unusual Country
logsource:
product: vpn
detection:
selection:
action: 'login_success'
filter:
src_country|contains:
- 'TH'
- 'US'
- 'SG'
condition: selection and not filter
level: high
References