feat: upgrade 5 skills with full content for v1.1.0

Replaced stub SKILL.md files with complete implementations:
- analyzing-linux-audit-logs-for-intrusion (257 lines, full auditd workflow)
- analyzing-windows-amcache-artifacts (237 lines, AmcacheParser + timeline)
- detecting-oauth-token-theft (266 lines, Azure AD token protection)
- implementing-devsecops-security-scanning (372 lines, full CI/CD pipeline)
- implementing-privileged-session-monitoring (323 lines, PAM session audit)

Also bumps index.json to version 1.1.0.
This commit is contained in:
mukul975
2026-03-21 12:36:58 +01:00
parent d77aaf8b28
commit e2c3836c30
6 changed files with 859 additions and 279 deletions
+1 -1
View File
File diff suppressed because one or more lines are too long
@@ -1,13 +1,16 @@
---
name: analyzing-linux-audit-logs-for-intrusion
description: >
Parse and analyze Linux auditd logs to detect intrusion indicators
including unauthorized file access, privilege escalation, syscall
anomalies, and suspicious process execution using ausearch and Python.
Uses the Linux Audit framework (auditd) with ausearch and aureport utilities
to detect intrusion attempts, unauthorized access, privilege escalation, and
suspicious system activity. Covers audit rule configuration, log querying,
timeline reconstruction, and integration with SIEM platforms. Activates for
requests involving auditd analysis, Linux audit log investigation, ausearch
queries, aureport summaries, or host-based intrusion detection on Linux.
domain: cybersecurity
subdomain: log-analysis
tags: [auditd, linux-forensics, syscall-monitoring, intrusion-detection]
version: "1.0"
subdomain: incident-response
tags: [auditd, ausearch, aureport, linux-security, intrusion-detection, HIDS, forensics]
version: 1.0.0
author: mahipal
license: Apache-2.0
---
@@ -141,6 +144,9 @@ ausearch -k exec_from_tmp -ts this-week
# Search for SSH key modifications
ausearch -k ssh_key_tampering -ts this-month
# Search for a specific event by audit event ID
ausearch -a 12345
# Search events in a specific time range
ausearch -ts 03/15/2026 08:00:00 -te 03/15/2026 18:00:00
@@ -156,20 +162,29 @@ Use `aureport` to produce aggregate summaries for triage:
# Summary of all authentication events
aureport -au -ts this-week --summary
# Report of all failed events
# Report of all failed events (login, access, etc.)
aureport --failed --summary -ts today
# Report of executable runs
aureport -x --summary -ts today
# Report of all anomaly events
# Report of all anomaly events (segfaults, promiscuous mode, etc.)
aureport --anomaly -ts this-week
# Report of file access events
aureport -f --summary -ts today
# Report of all events by key (maps to custom rule keys)
# Report of all events by key (maps to your custom rule keys)
aureport -k --summary -ts this-month
# Report of all system calls
aureport -s --summary -ts today
# Report of events grouped by user
aureport -u --summary -ts this-week
# Detailed time-based event report for timeline building
aureport -ts 03/15/2026 08:00:00 -te 03/15/2026 18:00:00 --summary
```
### Step 5: Reconstruct the Attack Timeline
@@ -177,55 +192,66 @@ aureport -k --summary -ts this-month
Combine ausearch queries to build a chronological narrative:
```bash
# Identify the initial access timestamp
# Step 5a: Identify the initial access timestamp
ausearch -m USER_LOGIN -ua 0 --success yes -ts this-week -i | head -50
# Trace what the attacker did after gaining access
ausearch -ua <UID> -ts "03/15/2026 14:00:00" -te "03/15/2026 18:00:00" -i | aureport -f -i
# Step 5b: Trace what the attacker did after gaining access
# Get all events from the compromised account within the incident window
ausearch -ua <UID> -ts "03/15/2026 14:00:00" -te "03/15/2026 18:00:00" -i \
| aureport -f -i
# Extract all commands executed during the incident window
# Step 5c: Extract all commands executed during the incident window
ausearch -m EXECVE -ts "03/15/2026 14:00:00" -te "03/15/2026 18:00:00" -i
# Check for persistence mechanisms installed
# Step 5d: Check for persistence mechanisms installed
ausearch -k cron_persistence -ts "03/15/2026 14:00:00" -i
ausearch -k ssh_key_tampering -ts "03/15/2026 14:00:00" -i
# Step 5e: Check for lateral movement (outbound connections)
ausearch -k network_connection -ts "03/15/2026 14:00:00" -i
```
### Step 6: Forward Audit Logs to SIEM
Configure `audisp-remote` or `auditbeat` to ship logs to a central SIEM:
Configure `audisp-remote` or `auditbeat` to ship logs to a central SIEM for correlation:
```bash
# Using audisp-remote plugin (/etc/audit/plugins.d/au-remote.conf)
# Option A: Using audisp-remote plugin
# Edit /etc/audit/plugins.d/au-remote.conf
active = yes
direction = out
path = /sbin/audisp-remote
type = always
# Remote target (/etc/audit/audisp-remote.conf)
# Configure remote target in /etc/audit/audisp-remote.conf
remote_server = siem.internal.corp
port = 6514
transport = tcp
# Option B: Using Elastic Auditbeat
# Install auditbeat and configure /etc/auditbeat/auditbeat.yml
# Auditbeat reads directly from the kernel audit framework
```
## Key Concepts
| Term | Definition |
|------|------------|
| **auditd** | Linux Audit daemon that receives kernel audit events and writes to `/var/log/audit/audit.log` |
| **auditctl** | CLI to control the audit system: add/remove rules, check status, set backlog size |
| **ausearch** | Query tool for searching audit logs by message type, user, file, key, or time range |
| **aureport** | Reporting tool that generates aggregate summaries for triage and compliance |
| **audit rule key (-k)** | User-defined label on audit rules for fast filtering with ausearch and aureport |
| **augenrules** | Merges `/etc/audit/rules.d/` files into `audit.rules` and loads into the kernel |
| **auditd** | The Linux Audit daemon that receives audit events from the kernel and writes them to `/var/log/audit/audit.log` |
| **auditctl** | Command-line utility to control the audit system: add/remove rules, check status, set backlog size |
| **ausearch** | Query tool that searches audit logs by message type, user, file, key, time range, or event ID |
| **aureport** | Reporting tool that generates aggregate summaries of audit events for triage and compliance |
| **audit rule key (-k)** | A user-defined label attached to an audit rule, enabling fast filtering of related events with ausearch and aureport |
| **syscall auditing** | Kernel-level monitoring of system calls (execve, open, connect, ptrace) that captures process and file activity |
| **augenrules** | Utility that merges all files in `/etc/audit/rules.d/` into `/etc/audit/audit.rules` and loads them into the kernel |
## Verification
- [ ] auditd is running and rules are loaded (`auditctl -l` returns expected rule count)
- [ ] No audit backlog overflow (`auditctl -s` shows lost: 0)
- [ ] ausearch returns events for each custom key
- [ ] No audit backlog overflow (`auditctl -s` shows `backlog: 0` or low value, lost: 0)
- [ ] ausearch returns events for each custom key (`ausearch -k <key> -ts today` returns results)
- [ ] aureport generates non-empty summaries for authentication, executable, and file events
- [ ] Timeline reconstruction produces a coherent chronological sequence
- [ ] Critical file watches trigger alerts on test modifications
- [ ] Logs are forwarding to central SIEM
- [ ] Audit rules persist across reboot (rules in `/etc/audit/rules.d/`)
- [ ] Timeline reconstruction produces a coherent chronological sequence of attacker actions
- [ ] Critical file watches trigger alerts on test modifications (`touch /etc/shadow` generates an event)
- [ ] Logs are forwarding to central SIEM (verify with a test event and confirm receipt)
- [ ] Audit rules persist across reboot (rules in `/etc/audit/rules.d/`, not only via `auditctl`)
@@ -1,81 +1,237 @@
---
name: analyzing-windows-amcache-artifacts
description: >
Parse and analyze Windows Amcache.hve registry hive to extract program
execution evidence, file metadata, SHA-1 hashes, and device connection
history for digital forensics and incident response investigations.
Parses and analyzes the Windows Amcache.hve registry hive to extract evidence
of program execution, application installation, and driver loading for digital
forensics investigations. Uses Eric Zimmerman's AmcacheParser and Timeline
Explorer for artifact extraction, SHA-1 hash correlation with threat intel,
and timeline reconstruction. Activates for requests involving Amcache forensics,
program execution evidence, Windows artifact analysis, or application compatibility
cache investigation.
domain: cybersecurity
subdomain: digital-forensics
tags: [amcache, windows-forensics, registry-analysis, execution-artifacts]
version: "1.0"
tags: [amcache, windows-forensics, program-execution, AmcacheParser, eric-zimmerman, timeline-analysis, DFIR]
version: 1.0.0
author: mahipal
license: Apache-2.0
---
# Analyzing Windows Amcache Artifacts
Extract execution evidence from Amcache.hve including application paths,
SHA-1 hashes, timestamps, and publisher metadata for DFIR investigations.
## When to Use
- When investigating security incidents that require analyzing windows amcache artifacts
- When building detection rules or threat hunting queries for this domain
- When SOC analysts need structured procedures for this analysis type
- When validating security monitoring coverage for related attack techniques
- Determining which programs have existed or executed on a Windows system during incident response
- Correlating SHA-1 hashes from Amcache against known malware databases (VirusTotal, CIRCL, MISP)
- Building an application installation and execution timeline for forensic investigations
- Identifying deleted executables that leave traces in Amcache even after file removal
- Investigating insider threats by documenting which portable or unauthorized applications were present
- Analyzing driver loading history to detect rootkits or malicious kernel modules
**Do not use** as sole proof of program execution. Amcache proves file existence and metadata registration, but ShimCache (AppCompatCache) and Prefetch provide stronger execution evidence. Use all three artifacts together for conclusive analysis.
## Prerequisites
- Familiarity with digital forensics concepts and tools
- Access to a test or lab environment for safe execution
- Python 3.8+ with required dependencies installed
- Appropriate authorization for any testing activities
- A forensic image or live triage copy of `C:\Windows\appcompat\Programs\Amcache.hve` (and associated `.LOG1`, `.LOG2` transaction logs)
- Eric Zimmerman's AmcacheParser (`AmcacheParser.exe`) downloaded from https://ericzimmerman.github.io/
- Eric Zimmerman's Timeline Explorer for viewing parsed CSV output
- Optionally: Registry Explorer for manual hive inspection
- A SHA-1 whitelist of known-good executables (e.g., NSRL hashset) for filtering
- .NET 6+ runtime installed (required by current EZ tools)
- Write access to an output directory for CSV results
## Example Output
## Workflow
```text
$ AmcacheParser.exe -f "C:\Evidence\Amcache.hve" --csv /analysis/amcache_output
### Step 1: Acquire the Amcache.hve File
AmcacheParser v1.5.1 - Amcache.hve Parser
============================================
Input: C:\Evidence\Amcache.hve (12.4 MB)
Last Write Time: 2024-01-18 23:59:45 UTC
Extract the Amcache hive from a forensic image or live system:
[+] Parsing File entries... Found: 4,567
[+] Parsing Program entries... Found: 234
[+] Parsing Driver entries... Found: 189
[+] Parsing Device Container entries Found: 45
[+] Parsing Shortcut entries... Found: 312
```powershell
# From a live system (requires elevated privileges and raw copy tool)
# Amcache.hve is locked by the system; use a raw disk copy tool
# Option A: FTK Imager - mount image and navigate to:
# C:\Windows\appcompat\Programs\Amcache.hve
# Also collect: Amcache.hve.LOG1, Amcache.hve.LOG2
--- Unassociated File Entries (No Known Publisher) ---
SHA-1 | Path | Name | Size | First Run (UTC) | Publisher
--------------------|-----------------------------------------------|-------------------|-----------|-----------------------|----------
a1b2c3d4e5f6a7b8...| C:\ProgramData\Updates\ | update_client.exe | 1,258,496 | 2024-01-15 14:36:30 | (none)
b2c3d4e5f6a7b8c9...| C:\Windows\Temp\ | mimikatz.exe | 1,250,816 | 2024-01-16 02:30:15 | (none)
c3d4e5f6a7b8c9d0...| C:\Windows\Temp\ | procdump64.exe | 421,376 | 2024-01-16 02:28:00 | Sysinternals
d4e5f6a7b8c9d0e1...| C:\ProgramData\svc\ | updater.exe | 345,088 | 2024-01-15 14:37:00 | (none)
e5f6a7b8c9d0e1f2...| C:\Users\jsmith\AppData\Local\Temp\ | psexec.exe | 834,936 | 2024-01-16 02:40:00 | Sysinternals
f6a7b8c9d0e1f2a3...| C:\Users\jsmith\Downloads\ | netscan.exe | 512,000 | 2024-01-15 15:10:22 | (none)
# Option B: Using KAPE for automated triage collection
kape.exe --tsource C: --tdest D:\Evidence\%m --target Amcache
--- Program Entries (Recently Installed) ---
Name | Version | Publisher | Install Date | Source
------------------------|---------------|------------------------|-----------------|--------
PuTTY | 0.80 | Simon Tatham | 2024-01-14 | MSI
WinSCP | 6.1.2 | Martin Prikryl | 2024-01-14 | MSI
7-Zip | 23.01 | Igor Pavlov | 2024-01-15 | MSI
(Unknown) | (Unknown) | (none) | 2024-01-15 | Manual
--- Driver Entries (Suspicious) ---
Name | SHA-1 | Signer | Install Date
------------------------|---------------------|-----------------------|-------------
WinDivert64.sys | 1a2b3c4d5e6f... | (self-signed) | 2024-01-15
npf.sys | 2b3c4d5e6f7a... | Nmap Project | 2024-01-15
Summary:
Total execution artifacts: 4,567
Unsigned/suspicious entries: 6
Recently installed programs: 4 (2 suspicious)
Suspicious drivers: 2
CSV exported to: /analysis/amcache_output/
# Option C: From a mounted forensic image (E: = mounted image)
copy "E:\Windows\appcompat\Programs\Amcache.hve" D:\Evidence\
copy "E:\Windows\appcompat\Programs\Amcache.hve.LOG1" D:\Evidence\
copy "E:\Windows\appcompat\Programs\Amcache.hve.LOG2" D:\Evidence\
```
Always collect the transaction log files (`.LOG1`, `.LOG2`) alongside the hive. AmcacheParser replays uncommitted transactions from these logs to recover the most complete data.
### Step 2: Parse Amcache with AmcacheParser
Run AmcacheParser against the acquired hive:
```powershell
# Basic parsing with CSV output
AmcacheParser.exe -f "D:\Evidence\Amcache.hve" --csv "D:\Evidence\Output"
# Parse with a SHA-1 whitelist to exclude known-good entries (NSRL)
AmcacheParser.exe -f "D:\Evidence\Amcache.hve" -w "D:\Whitelists\nsrl_sha1.txt" --csv "D:\Evidence\Output"
# Parse with a SHA-1 inclusion list (only show matches against known-bad hashes)
AmcacheParser.exe -f "D:\Evidence\Amcache.hve" -b "D:\IOCs\malware_sha1.txt" --csv "D:\Evidence\Output"
# Include deleted entries with high-precision timestamps
AmcacheParser.exe -f "D:\Evidence\Amcache.hve" --csv "D:\Evidence\Output" -i --mp
```
AmcacheParser produces multiple CSV files in the output directory:
| Output File | Contents |
|-------------|----------|
| `Amcache_AssociatedFileEntries.csv` | File entries with SHA-1 hashes, paths, sizes, and timestamps |
| `Amcache_UnassociatedFileEntries.csv` | Orphaned file entries from older Amcache format |
| `Amcache_ProgramEntries.csv` | Installed program metadata (name, publisher, version, install date) |
| `Amcache_DeviceContainers.csv` | USB and device connection history |
| `Amcache_DevicePnps.csv` | Plug-and-Play device driver information |
| `Amcache_DriverBinaries.csv` | Loaded driver binaries with paths and hashes |
### Step 3: Analyze File Entries for Suspicious Programs
Open the `AssociatedFileEntries.csv` in Timeline Explorer and examine key columns:
```
Key columns to review:
- ProgramId : Links file to its parent program entry
- SHA1 : Hash for threat intel lookups
- FullPath : Original file location on disk
- FileSize : Size of the executable
- FileKeyLastWriteTimestamp : When the Amcache entry was last updated
- Name : File name
- Publisher : Code signing publisher (blank = unsigned)
- BinProductVersion : Version string from the PE header
- LinkDate : PE compilation timestamp (useful for detecting timestomping)
```
Filter for suspicious indicators:
```
# In Timeline Explorer, apply these filters:
# 1. Find unsigned executables (potentially malicious)
Publisher column = (empty)
# 2. Find executables from suspicious paths
FullPath contains: \temp\, \appdata\, \downloads\, \public\, \programdata\
# 3. Find executables with recent timestamps during incident window
FileKeyLastWriteTimestamp between: 2026-03-15 00:00:00 and 2026-03-16 00:00:00
# 4. Find executables with suspicious compilation dates (timestomping)
LinkDate year < 2015 AND FileKeyLastWriteTimestamp year = 2026
```
### Step 4: Correlate SHA-1 Hashes with Threat Intelligence
Extract SHA-1 hashes and check against malware databases:
```powershell
# Extract unique SHA-1 hashes from the parsed output
# Using PowerShell to extract the SHA1 column
Import-Csv "D:\Evidence\Output\Amcache_AssociatedFileEntries.csv" |
Select-Object -ExpandProperty SHA1 -Unique |
Where-Object { $_ -ne "" } |
Out-File "D:\Evidence\Output\extracted_hashes.txt"
# Check hashes against VirusTotal using vt-cli
foreach ($hash in Get-Content "D:\Evidence\Output\extracted_hashes.txt") {
vt file $hash --format json | Select-Object -Property meaningful_name, last_analysis_stats
}
# Check hashes against CIRCL hashlookup
foreach ($hash in Get-Content "D:\Evidence\Output\extracted_hashes.txt") {
Invoke-RestMethod -Uri "https://hashlookup.circl.lu/lookup/sha1/$hash"
}
# Cross-reference with NSRL to identify known-good vs. unknown
# Unknown hashes that are not in NSRL warrant closer investigation
```
### Step 5: Analyze Program Entries for Unauthorized Installations
Review the `ProgramEntries.csv` for software the attacker may have installed:
```
Key columns in ProgramEntries:
- ProgramName : Display name of installed application
- ProgramVersion : Version string
- Publisher : Software publisher
- InstallDate : When the program was installed
- Source : Installation source (msi, exe, etc.)
- UninstallKey : Registry uninstall path
- PathsList : Installation directories
```
Look for:
- Remote access tools (AnyDesk, TeamViewer, ngrok, Chisel)
- Hacking tools (Mimikatz, PsExec, Cobalt Strike)
- Tunneling utilities (plink, socat, WireGuard)
- Programs installed during the incident window
- Programs installed to non-standard locations
### Step 6: Analyze Driver Binaries for Rootkit Evidence
Review the `DriverBinaries.csv` for suspicious loaded drivers:
```
Key columns in DriverBinaries:
- DriverName : Name of the driver
- DriverInBox : Whether it shipped with Windows (false = third-party)
- DriverSigned : Whether the driver has a valid signature
- DriverTimeStamp : Compilation timestamp
- Product : Product associated with the driver
- ProductVersion : Driver version
- SHA1 : Hash of the driver binary
```
Filter for `DriverInBox = false` and `DriverSigned = false` to find unsigned third-party drivers that may be rootkits or vulnerable drivers used in BYOVD (Bring Your Own Vulnerable Driver) attacks.
### Step 7: Build a Timeline from Amcache Data
Combine Amcache data with other artifacts for a comprehensive timeline:
```powershell
# Merge Amcache CSV with other EZ Tools output using Timeline Explorer
# Load the following CSVs into Timeline Explorer:
# - Amcache_AssociatedFileEntries.csv (file evidence)
# - Amcache_ProgramEntries.csv (install evidence)
# - Prefetch output from PECmd.exe (execution evidence)
# - ShimCache output from AppCompatCacheParser.exe (execution evidence)
# Sort all entries by timestamp to reconstruct the attack sequence
# Timeline Explorer supports multi-file loading and column-based sorting
# Export the combined timeline
# File > Save to CSV > combined_timeline.csv
```
## Key Concepts
| Term | Definition |
|------|------------|
| **Amcache.hve** | A Windows registry hive at `C:\Windows\appcompat\Programs\Amcache.hve` that stores metadata about applications, files, and drivers for application compatibility purposes |
| **Associated File Entry** | An Amcache record linked to a specific program installation, containing file path, size, hash, and timestamps |
| **Unassociated File Entry** | An orphaned Amcache record from an older format that is not linked to a program entry; common on Windows 7/8 systems |
| **Program Entry** | Amcache record containing installation metadata: program name, version, publisher, install date, and uninstall key |
| **SHA-1 Hash** | Cryptographic hash stored in Amcache for each registered file, enabling malware identification through threat intelligence lookups |
| **LinkDate** | The PE compilation timestamp embedded in the executable header; discrepancy with file system timestamps may indicate timestomping |
| **Transaction Logs** | `.LOG1` and `.LOG2` files containing uncommitted registry transactions that AmcacheParser replays for complete data recovery |
| **NSRL (National Software Reference Library)** | NIST-maintained database of SHA-1 hashes for known commercial software, used as a whitelist to filter benign entries |
## Verification
- [ ] Amcache.hve and transaction logs (LOG1, LOG2) were collected from the forensic image
- [ ] AmcacheParser produced all expected CSV output files without errors
- [ ] SHA-1 hashes were extracted and checked against VirusTotal or CIRCL hashlookup
- [ ] Unsigned executables in suspicious paths have been flagged for further analysis
- [ ] Program entries show all software installations within the incident window
- [ ] Driver binaries have been checked for unsigned or out-of-box entries
- [ ] LinkDate vs. FileKeyLastWriteTimestamp comparison has been performed to detect timestomping
- [ ] Amcache findings are correlated with Prefetch and ShimCache for execution confirmation
- [ ] Final timeline integrates Amcache data with other forensic artifacts
+158 -63
View File
@@ -1,13 +1,17 @@
---
name: detecting-oauth-token-theft
description: >
Detect OAuth access token theft and misuse by analyzing sign-in logs for
impossible travel, new device patterns, token replay from unusual IPs,
and anomalous scope requests via Microsoft Graph and Okta APIs.
Detects and responds to OAuth token theft and replay attacks in cloud
environments, focusing on Microsoft Entra ID (Azure AD) token protection,
conditional access policies, and sign-in anomaly detection. Covers access
token theft, refresh token replay, Primary Refresh Token (PRT) abuse, and
pass-the-cookie attacks. Activates for requests involving OAuth token theft
detection, token replay prevention, Azure AD conditional access token
protection, or cloud identity attack investigation.
domain: cybersecurity
subdomain: identity-security
tags: [oauth, token-theft, identity-attacks, impossible-travel]
version: "1.0"
subdomain: cloud-security
tags: [oauth, token-theft, azure-ad, entra-id, conditional-access, token-replay, identity-security, PRT]
version: 1.0.0
author: mahipal
license: Apache-2.0
---
@@ -30,21 +34,31 @@ license: Apache-2.0
- Microsoft Entra ID P2 license (required for Identity Protection risk detections and conditional access)
- Global Administrator or Security Administrator role in the Entra admin center
- Microsoft Defender for Cloud Apps (MDCA) license for session anomaly detection
- Access to Entra ID Sign-in Logs and Audit Logs (Diagnostic Settings to Log Analytics or Sentinel)
- Access to Entra ID Sign-in Logs and Audit Logs (requires Diagnostic Settings configured to Log Analytics or Sentinel)
- Familiarity with OAuth 2.0 authorization flows (authorization code, device code, client credentials)
- Microsoft Sentinel or equivalent SIEM ingesting Entra ID sign-in and audit logs
## Workflow
### Step 1: Understand the Token Theft Attack Surface
Key token types and theft vectors:
Identify which token types are at risk and how they are stolen:
| Token Type | Lifetime | Theft Vector | Impact |
|---|---|---|---|
| Access Token | 60-90 min | Memory dump, proxy interception | API access for token lifetime |
| Refresh Token | Up to 90 days | Browser cookie theft, malware | Persistent access |
| Primary Refresh Token | Session-based | Mimikatz, AADInternals | Full SSO to all M365/Azure apps |
| Session Cookie | Varies | XSS, AitM proxy | Full session hijacking |
```
Token Type | Lifetime | Theft Vector | Impact
----------------------|-------------|----------------------------------|------------------
Access Token | 60-90 min | Memory dump, proxy interception | API access for token lifetime
Refresh Token | Up to 90 days| Browser cookie theft, malware | Persistent access, new access tokens
Primary Refresh Token | Session-based| Mimikatz, AADInternals, malware | Full SSO to all M365/Azure apps
Session Cookie | Varies | XSS, browser exploit, AitM proxy | Full session hijacking
Device Code Token | 15 min auth | Phishing (device code flow abuse)| Attacker gets refresh token via social engineering
```
Common attack techniques:
- **AitM Phishing (Adversary-in-the-Middle)**: Attacker proxies the legitimate login page via tools like Evilginx2, capturing session cookies and tokens after the user completes MFA
- **Device Code Phishing**: Attacker generates a device code, sends it to the victim via email/Teams, victim authenticates, attacker receives the token
- **PRT Extraction**: Attacker with local admin on a device extracts the Primary Refresh Token using Mimikatz (`sekurlsa::cloudap`) or AADInternals
- **Browser Cookie Theft**: Malware or infostealer exfiltrates browser cookies containing session tokens
### Step 2: Configure Entra ID Sign-in Risk Detection
@@ -54,118 +68,199 @@ Enable Identity Protection to flag anomalous token usage:
Entra Admin Center > Protection > Identity Protection > Risk Detections
Key risk detections for token theft:
- Anomalous Token : Unusual token characteristics
- Token Issuer Anomaly : Token from unusual issuer
- Unfamiliar Sign-in : New location for user
- Impossible Travel : Geographically impossible sign-ins
- Malicious IP Address : Known malicious source
- Anomalous Token : Token has unusual characteristics (claim anomalies)
- Token Issuer Anomaly : Token issued by an unusual token issuer
- Unfamiliar Sign-in : Sign-in from a location not seen before for the user
- Impossible Travel : Sign-ins from geographically distant locations in impossible time
- Malicious IP Address : Sign-in from a known malicious IP
- Suspicious Browser : Sign-in from a suspicious or attacker-controlled browser
```
Configure risk-based conditional access:
```
Policy: "Block High-Risk Sign-ins"
Users: All users (exclude break-glass accounts)
Conditions: Sign-in Risk = High
Grant: Block access
Entra Admin Center > Protection > Conditional Access > New Policy
Policy: "Require MFA for Medium-Risk"
Conditions: Sign-in Risk = Medium
Grant: Require MFA + password change
Policy Name: "Block High-Risk Sign-ins - Token Theft Protection"
Assignments:
Users: All users (exclude break-glass accounts)
Cloud Apps: All cloud apps
Conditions:
Sign-in Risk: High
Grant:
Block access
Policy Name: "Require MFA for Medium-Risk Sign-ins"
Assignments:
Users: All users
Cloud Apps: All cloud apps
Conditions:
Sign-in Risk: Medium
Grant:
Require multifactor authentication
Require password change
```
### Step 3: Enable Token Protection
### Step 3: Enable Token Protection (Preview)
Bind sign-in session tokens to device TPM:
Configure Token Protection to bind sign-in session tokens to the device:
```
Entra Admin Center > Protection > Conditional Access > New Policy
Policy: "Enforce Token Protection"
Users: Pilot group (expand after validation)
Cloud Apps: Office 365 Exchange Online, SharePoint Online
Conditions: Device Platforms = Windows
Session: Require token protection for sign-in sessions
Grant: Require compliant or Hybrid Azure AD joined device
Policy Name: "Enforce Token Protection for Desktop Sessions"
Assignments:
Users: All users (start with a pilot group)
Cloud Apps: Office 365 Exchange Online, Office 365 SharePoint Online
Conditions:
Device Platforms: Windows
Session:
Require token protection for sign-in sessions (Preview): Enabled
Grant:
Require device to be marked as compliant
OR Require Hybrid Azure AD joined device
```
Token Protection ensures that access tokens are cryptographically bound to the device's Trusted Platform Module (TPM). If an attacker steals a token and replays it from a different device, the token is rejected because the proof-of-possession key does not match.
### Step 4: Detect Token Replay in Sign-in Logs
KQL queries for Microsoft Sentinel or Log Analytics:
Query Entra sign-in logs for indicators of token theft:
```kusto
// Detect anomalous token usage
// KQL query for Microsoft Sentinel or Log Analytics
// Detect sign-ins where the token was issued in one location and used in another
SigninLogs
| where TimeGenerated > ago(7d)
| where RiskDetail contains "token" or RiskEventTypes_V2 has "anomalousToken"
| project TimeGenerated, UserPrincipalName, IPAddress, Location,
RiskDetail, RiskLevelDuringSignIn, AppDisplayName
RiskDetail, RiskLevelDuringSignIn, AppDisplayName,
DeviceDetail, ClientAppUsed, TokenIssuerType
| sort by TimeGenerated desc
// Detect impossible travel with token reuse
SigninLogs
| where TimeGenerated > ago(7d)
| where ResultType == 0
| where ResultType == 0 // Successful sign-ins only
| summarize Locations=make_set(Location), IPs=make_set(IPAddress),
Count=count() by UserPrincipalName, bin(TimeGenerated, 1h)
| where array_length(Locations) > 1
| sort by TimeGenerated desc
// Detect device code flow abuse (phishing)
// Detect device code flow abuse (often used in phishing)
SigninLogs
| where TimeGenerated > ago(7d)
| where AuthenticationProtocol == "deviceCode"
| project TimeGenerated, UserPrincipalName, IPAddress, Location, AppDisplayName
| project TimeGenerated, UserPrincipalName, IPAddress, Location,
AppDisplayName, DeviceDetail, ResultType
| sort by TimeGenerated desc
// Detect token replay: same token used from multiple IPs
AADNonInteractiveUserSignInLogs
| where TimeGenerated > ago(7d)
| where ResultType == 0
| summarize IPs=make_set(IPAddress), IPCount=dcount(IPAddress)
by UserPrincipalName, CorrelationId
| where IPCount > 1
| sort by IPCount desc
```
### Step 5: Investigate and Respond
### Step 5: Investigate and Respond to Token Theft
When a token theft event is detected, follow this response procedure:
```powershell
# Revoke all refresh tokens for compromised user
# Step 5a: Revoke all refresh tokens for the compromised user
# Microsoft Graph PowerShell
Connect-MgGraph -Scopes "User.ReadWrite.All"
Revoke-MgUserSignInSession -UserId "user@contoso.com"
# Force password reset
# Step 5b: Force password reset
Update-MgUser -UserId "user@contoso.com" -PasswordProfile @{
ForceChangePasswordNextSignIn = $true
}
# Review and revoke malicious OAuth app consent grants
Get-MgUserOauth2PermissionGrant -UserId "user@contoso.com"
# Step 5c: Review and revoke OAuth app consent grants
# Check for malicious app consent (common post-compromise persistence)
Get-MgUserOauth2PermissionGrant -UserId "user@contoso.com" |
Select-Object ClientId, ConsentType, Scope
# Remove suspicious OAuth grants
Remove-MgOauth2PermissionGrant -OAuth2PermissionGrantId "<grant-id>"
# Check for mail forwarding rules (common post-compromise action)
# Step 5d: Review enterprise app registrations for rogue apps
Get-MgServicePrincipal -Filter "displayName eq 'Suspicious App'" |
Select-Object AppId, DisplayName, SignInAudience
# Step 5e: Check for mail forwarding rules (common post-compromise action)
Get-MgUserMailFolderRule -UserId "user@contoso.com" -MailFolderId "Inbox" |
Where-Object { $_.Actions.ForwardTo -ne $null }
Where-Object { $_.Actions.ForwardTo -ne $null -or $_.Actions.RedirectTo -ne $null }
```
### Step 6: Enable Continuous Access Evaluation (CAE)
### Step 6: Implement Continuous Access Evaluation (CAE)
Enable CAE to revoke tokens in near-real-time when conditions change:
```
Entra Admin Center > Protection > Conditional Access > Continuous Access Evaluation
Settings:
Strictly enforce location policies: Enabled
CAE triggers near-real-time token revocation when:
- User account disabled/deleted
- Password changed/reset
- Admin explicitly revokes tokens
- Identity Protection detects elevated risk
CAE ensures that when you revoke a user's session or change their
risk level, the enforcement happens within minutes rather than waiting
for the access token to naturally expire (60-90 minutes).
Critical events that trigger immediate token revocation with CAE:
- User account disabled or deleted
- Password changed or reset
- MFA enabled for the user
- Admin explicitly revokes refresh tokens
- Azure AD Identity Protection detects elevated user risk
- Network location change violates conditional access policy
```
### Step 7: Configure Defender for Cloud Apps Session Policies
Set up real-time session monitoring to detect and block suspicious token usage:
```
Microsoft Defender for Cloud Apps > Policies > Session Policies
Policy: "Block download from unmanaged device with stolen token"
Session Control Type: Monitor and block activities
Activity Source: App = Office 365, SharePoint Online
Activity Filter: Device tag does not equal "Compliant"
Activity Type: Download
Action: Block
Policy: "Alert on mass file download (exfiltration via stolen token)"
Session Control Type: Monitor only
Activity Source: App = Office 365
Activity Filter: Repeated activity > 10 downloads in 5 minutes
Action: Alert administrators
```
## Key Concepts
| Term | Definition |
|------|------------|
| **Primary Refresh Token (PRT)** | Long-lived device-bound token providing SSO to all Azure AD apps |
| **Token Protection** | Conditional access feature binding tokens to device TPM |
| **Continuous Access Evaluation** | Near-real-time policy enforcement on token revocation |
| **AitM (Adversary-in-the-Middle)** | Phishing that proxies auth flow to capture session cookies post-MFA |
| **Device Code Flow** | OAuth grant for input-constrained devices; abused in phishing campaigns |
| **Primary Refresh Token (PRT)** | A long-lived token issued to a registered device that provides SSO to all Azure AD-integrated applications, cryptographically bound to the device's TPM |
| **Token Protection** | Entra ID conditional access feature that binds sign-in session tokens to the device, preventing replay from other devices |
| **Continuous Access Evaluation (CAE)** | Protocol that enables near-real-time enforcement of security policies by allowing resource providers to subscribe to Entra ID critical events |
| **AitM (Adversary-in-the-Middle)** | Phishing technique where an attacker proxies the legitimate authentication flow to capture session cookies after the victim completes MFA |
| **Device Code Flow** | OAuth 2.0 authorization grant for input-constrained devices; abused by attackers who send device codes to victims via phishing |
| **Proof of Possession (PoP)** | Cryptographic mechanism where a token includes a claim tied to a device key, ensuring the token can only be used by the device that obtained it |
| **Refresh Token** | Long-lived OAuth token (up to 90 days) used to obtain new access tokens without re-authentication; primary target for persistent access |
## Verification
- [ ] Identity Protection risk detections generating alerts for anomalous tokens
- [ ] Identity Protection risk detections are enabled and generating alerts for anomalous token activity
- [ ] Conditional access policies block high-risk sign-ins and require MFA for medium-risk
- [ ] Token Protection confirmed working (test from unregistered device fails)
- [ ] KQL queries return results against synthetic anomaly events
- [ ] CAE enabled and verified (revoke session, confirm access blocked within minutes)
- [ ] Incident response runbook includes token revocation and OAuth consent review
- [ ] Token Protection policy is applied to pilot group and confirmed working (test from unregistered device fails)
- [ ] KQL queries in Sentinel return results when tested against synthetic token anomaly events
- [ ] Continuous Access Evaluation is enabled and verified (revoke session, confirm access blocked within minutes)
- [ ] Defender for Cloud Apps session policies are active and monitoring download activity
- [ ] Device code flow is restricted via conditional access (block or require compliant device)
- [ ] Incident response runbook includes token revocation, password reset, and OAuth consent review steps
- [ ] Mail forwarding rules and OAuth app grants are audited for compromised accounts
@@ -1,13 +1,17 @@
---
name: implementing-devsecops-security-scanning
description: >
Integrate security scanning into CI/CD pipelines using tools like Semgrep,
Trivy, and Gitleaks. Covers SAST, SCA, container scanning, and secret
detection with structured JSON output for pipeline gates.
Integrates Static Application Security Testing (SAST), Dynamic Application
Security Testing (DAST), and Software Composition Analysis (SCA) into CI/CD
pipelines using open-source tools. Covers Semgrep for SAST, Trivy for SCA
and container scanning, OWASP ZAP for DAST, and Gitleaks for secrets
detection. Activates for requests involving DevSecOps pipeline setup,
automated security scanning in CI/CD, SAST/DAST/SCA integration, or
shift-left security implementation.
domain: cybersecurity
subdomain: application-security
tags: [devsecops, sast, sca, container-security, ci-cd]
version: "1.0"
tags: [devsecops, SAST, DAST, SCA, semgrep, trivy, owasp-zap, gitleaks, CI-CD, shift-left]
version: 1.0.0
author: mahipal
license: Apache-2.0
---
@@ -17,26 +21,32 @@ license: Apache-2.0
## When to Use
- Setting up automated security scanning in a new or existing CI/CD pipeline
- Shifting security left by catching vulnerabilities before production
- Meeting compliance requirements (SOC 2, PCI-DSS, ISO 27001) mandating automated security testing
- Integrating SAST, DAST, and SCA for comprehensive application security coverage
- Establishing security gates that block deployments with critical/high vulnerabilities
- Shifting security left by catching vulnerabilities before code reaches production
- Meeting compliance requirements (SOC 2, PCI-DSS, ISO 27001) that mandate automated security testing
- Integrating SAST, DAST, and SCA together to achieve comprehensive application security coverage
- Establishing security gates that block deployments containing critical or high-severity vulnerabilities
**Do not use** as a replacement for manual penetration testing. Automated scanning catches common patterns but cannot replace human-driven assessments for business logic flaws.
**Do not use** as a replacement for manual penetration testing. Automated scanning catches common vulnerability patterns but cannot replace human-driven security assessments for business logic flaws and complex attack chains.
## Prerequisites
- CI/CD platform: GitHub Actions, GitLab CI, Jenkins, or Azure DevOps
- Container runtime (Docker) for running scanning tools
- A staging environment URL for DAST scanning
- Tool requirements: Semgrep (free), Trivy (free), OWASP ZAP (free), Gitleaks (free)
- A staging environment URL for DAST scanning (DAST cannot test static code)
- Repository access with permissions to modify CI/CD workflow files
- Tool-specific requirements:
- Semgrep: free for open-source rulesets (`p/security-audit`, `p/owasp-top-ten`)
- Trivy: free, no account required
- OWASP ZAP: free, Docker image available
- Gitleaks: free, no account required
## Workflow
### Step 1: Add Secrets Detection with Gitleaks
Secrets detection runs first because leaked credentials are the highest-priority finding. Add to `.github/workflows/security.yml`:
```yaml
# .github/workflows/security.yml
name: DevSecOps Security Pipeline
on:
push:
@@ -51,15 +61,39 @@ jobs:
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
fetch-depth: 0 # Full history for scanning all commits
- name: Run Gitleaks
uses: gitleaks/gitleaks-action@v2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
```
Configure `.gitleaks.toml` in the repository root for custom rules and allowlists:
```toml
[extend]
useDefault = true
[allowlist]
description = "Global allowlist"
paths = [
'''\.gitleaks\.toml''',
'''test/fixtures/.*''',
'''docs/examples/.*'''
]
[[rules]]
id = "custom-internal-api-key"
description = "Internal API key pattern"
regex = '''INTERNAL_KEY_[A-Za-z0-9]{32}'''
tags = ["internal", "api-key"]
```
### Step 2: Add SAST Scanning with Semgrep
Semgrep performs static code analysis to find security vulnerabilities, bugs, and code patterns:
```yaml
sast-scan:
name: SAST (Semgrep)
@@ -68,22 +102,59 @@ jobs:
image: semgrep/semgrep
steps:
- uses: actions/checkout@v4
- name: Run Semgrep SAST scan
run: |
semgrep scan \
--config p/security-audit \
--config p/owasp-top-ten \
--config p/secrets \
--severity ERROR \
--error \
--json --output semgrep-results.json .
- uses: actions/upload-artifact@v4
--json \
--output semgrep-results.json \
.
- name: Upload SAST results
if: always()
uses: actions/upload-artifact@v4
with:
name: semgrep-results
path: semgrep-results.json
```
### Step 3: Add SCA and Container Scanning with Trivy
For custom rules, create `.semgrep/custom-rules.yml`:
```yaml
rules:
- id: no-exec-user-input
patterns:
- pattern: exec($INPUT)
- pattern-not: exec("...")
message: >
User input passed to exec(). This is a command injection vulnerability.
severity: ERROR
languages: [python]
metadata:
cwe: "CWE-78: OS Command Injection"
owasp: "A03:2021 - Injection"
- id: no-raw-sql-queries
patterns:
- pattern: cursor.execute(f"...")
- pattern: cursor.execute("..." + ...)
message: >
SQL query built with string concatenation or f-strings. Use parameterized queries.
severity: ERROR
languages: [python]
metadata:
cwe: "CWE-89: SQL Injection"
owasp: "A03:2021 - Injection"
```
### Step 3: Add SCA Scanning with Trivy
Trivy scans dependencies, container images, IaC files, and generates SBOM:
```yaml
sca-scan:
@@ -91,7 +162,8 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Trivy filesystem scan (dependencies)
- name: Run Trivy filesystem scan (dependencies)
uses: aquasecurity/trivy-action@0.28.0
with:
scan-type: 'fs'
@@ -100,66 +172,156 @@ jobs:
exit-code: '1'
format: 'json'
output: 'trivy-fs-results.json'
- name: Build and scan container image
run: |
docker build -t app:${{ github.sha }} .
- uses: aquasecurity/trivy-action@0.28.0
- name: Run Trivy IaC scan (Terraform, CloudFormation)
uses: aquasecurity/trivy-action@0.28.0
with:
scan-type: 'config'
scan-ref: '.'
severity: 'CRITICAL,HIGH'
exit-code: '1'
format: 'json'
output: 'trivy-iac-results.json'
- name: Upload SCA results
if: always()
uses: actions/upload-artifact@v4
with:
name: trivy-results
path: trivy-*.json
container-scan:
name: Container Image Scan (Trivy)
runs-on: ubuntu-latest
needs: [sast-scan] # Build image only after SAST passes
steps:
- uses: actions/checkout@v4
- name: Build Docker image
run: docker build -t app:${{ github.sha }} .
- name: Scan container image
uses: aquasecurity/trivy-action@0.28.0
with:
image-ref: 'app:${{ github.sha }}'
severity: 'CRITICAL,HIGH'
exit-code: '1'
format: 'json'
output: 'trivy-image-results.json'
- name: Generate SBOM
uses: aquasecurity/trivy-action@0.28.0
with:
image-ref: 'app:${{ github.sha }}'
format: 'cyclonedx'
output: 'sbom.json'
- name: Upload SBOM
uses: actions/upload-artifact@v4
with:
name: sbom
path: sbom.json
```
### Step 4: Add DAST Scanning with OWASP ZAP
DAST runs against a deployed staging environment. It is slower than SAST/SCA and should run asynchronously or on a schedule:
```yaml
dast-scan:
name: DAST (OWASP ZAP)
runs-on: ubuntu-latest
needs: [deploy-staging]
needs: [deploy-staging] # Must run after app is deployed to staging
steps:
- uses: actions/checkout@v4
- name: ZAP Baseline Scan
- name: Run ZAP Baseline Scan (fast, suitable for CI)
uses: zaproxy/action-baseline@v0.14.0
with:
target: ${{ vars.STAGING_URL }}
rules_file_name: '.zap/rules.tsv'
cmd_options: '-a -j'
# For nightly full scans, use action-full-scan instead:
# - name: Run ZAP Full Scan (comprehensive, 30-60 min)
# uses: zaproxy/action-full-scan@v0.12.0
# with:
# target: ${{ vars.STAGING_URL }}
```
Configure `.zap/rules.tsv` alert thresholds:
Create `.zap/rules.tsv` to configure alert thresholds:
```tsv
10010 IGNORE (Cookie No HttpOnly Flag - acceptable for non-sensitive cookies)
10011 IGNORE (Cookie Without Secure Flag - staging uses HTTP)
90033 WARN (Loosely Scoped Cookie)
10038 FAIL (Content Security Policy Header Not Set)
40012 FAIL (Cross Site Scripting - Reflected)
40014 FAIL (Cross Site Scripting - Persistent)
40018 FAIL (SQL Injection)
90019 FAIL (Server Side Code Injection)
10038 FAIL (Content Security Policy Header Not Set)
90020 FAIL (Remote OS Command Injection)
```
### Step 5: Enforce Security Gates
### Step 5: Aggregate Results and Enforce Security Gates
Create a summary job that aggregates all scan results and enforces pass/fail gates:
```yaml
security-gate:
name: Security Gate
runs-on: ubuntu-latest
needs: [secrets-scan, sast-scan, sca-scan]
needs: [secrets-scan, sast-scan, sca-scan, container-scan]
if: always()
steps:
- name: Check scan results
run: |
echo "Checking security scan results..."
# Fail the pipeline if any upstream job failed
if [[ "${{ needs.secrets-scan.result }}" == "failure" ]]; then
echo "BLOCKED: Secrets detected"; exit 1
echo "BLOCKED: Secrets detected in repository"
exit 1
fi
if [[ "${{ needs.sast-scan.result }}" == "failure" ]]; then
echo "BLOCKED: SAST critical/high findings"; exit 1
echo "BLOCKED: SAST found critical/high vulnerabilities"
exit 1
fi
if [[ "${{ needs.sca-scan.result }}" == "failure" ]]; then
echo "BLOCKED: Vulnerable dependencies"; exit 1
echo "BLOCKED: SCA found critical/high vulnerable dependencies"
exit 1
fi
if [[ "${{ needs.container-scan.result }}" == "failure" ]]; then
echo "BLOCKED: Container image has critical/high vulnerabilities"
exit 1
fi
echo "All security gates passed"
```
### Step 6: Configure Pre-commit Hooks
### Step 6: Configure Branch Protection Rules
Enforce the security pipeline as a required status check:
```
GitHub Repository > Settings > Branches > Branch Protection Rules
Branch name pattern: main
Require status checks to pass before merging: Enabled
Required status checks:
- Secrets Detection (Gitleaks)
- SAST (Semgrep)
- SCA & Container Scan (Trivy)
- Security Gate
Require branches to be up to date before merging: Enabled
```
### Step 7: Set Up Developer Feedback Loop
Configure pre-commit hooks so developers catch issues before pushing:
```yaml
# .pre-commit-config.yaml
@@ -168,36 +330,43 @@ repos:
rev: v8.22.1
hooks:
- id: gitleaks
- repo: https://github.com/semgrep/semgrep
rev: v1.102.0
hooks:
- id: semgrep
args: ['--config', 'p/security-audit', '--error']
args: ['--config', 'p/security-audit', '--config', 'p/owasp-top-ten', '--error']
```
Install and activate pre-commit:
```bash
pip install pre-commit
pre-commit install
pre-commit run --all-files
pre-commit run --all-files # Test against existing codebase
```
## Key Concepts
| Term | Definition |
|------|------------|
| **SAST** | Static Application Security Testing - analyzes source code without execution |
| **DAST** | Dynamic Application Security Testing - tests running applications |
| **SCA** | Software Composition Analysis - scans dependencies for known vulnerabilities |
| **SBOM** | Software Bill of Materials - inventory of all components |
| **Shift Left** | Moving security testing earlier in the SDLC |
| **Security Gate** | CI/CD checkpoint blocking deployment on scan failures |
| **SAST (Static Application Security Testing)** | Analyzes source code without executing it to find security vulnerabilities; runs fast, catches issues early, but cannot find runtime flaws |
| **DAST (Dynamic Application Security Testing)** | Tests a running application by sending requests and analyzing responses; finds runtime issues but requires a deployed environment |
| **SCA (Software Composition Analysis)** | Scans project dependencies against vulnerability databases (NVD, GitHub Advisory) to find known-vulnerable libraries |
| **SBOM (Software Bill of Materials)** | Machine-readable inventory of all components and dependencies in an application, used for vulnerability tracking and compliance |
| **Shift Left** | Security practice of moving security testing earlier in the SDLC, from post-deployment to pre-commit and CI stages |
| **Security Gate** | A CI/CD pipeline checkpoint that blocks deployment if security scan results exceed defined severity thresholds |
| **Pre-commit Hook** | Local Git hook that runs security checks before code is committed, providing the fastest developer feedback loop |
## Verification
- [ ] Gitleaks blocks commits containing hardcoded secrets
- [ ] Semgrep runs on every PR and reports findings
- [ ] Trivy detects known-vulnerable dependencies
- [ ] OWASP ZAP baseline scan runs against staging URL
- [ ] Security gate blocks merges when critical/high findings exist
- [ ] Branch protection rules enforce required status checks
- [ ] Pre-commit hooks catch issues locally before push
- [ ] Gitleaks blocks commits and PRs containing hardcoded secrets (test with a dummy API key)
- [ ] Semgrep scan runs on every PR and reports findings as annotations or comments
- [ ] Trivy filesystem scan detects a known-vulnerable dependency (test by adding a vulnerable package)
- [ ] Trivy container scan runs successfully against the built Docker image
- [ ] SBOM is generated and stored as a build artifact in CycloneDX or SPDX format
- [ ] OWASP ZAP baseline scan runs against the staging URL without crashing
- [ ] Security gate job blocks merges to main when any scan finds critical/high severity issues
- [ ] Branch protection rules enforce required status checks before merge
- [ ] Pre-commit hooks catch secrets and SAST findings locally before push
- [ ] Developer documentation explains how to interpret scan results and fix common findings
@@ -1,13 +1,17 @@
---
name: implementing-privileged-session-monitoring
description: >
Monitor and audit privileged user sessions including SSH, RDP, and
database access. Tracks session metadata, records commands, detects
anomalous activity, and enforces session policies for PAM compliance.
Implements privileged session monitoring and recording using Privileged Access
Management (PAM) solutions, focusing on CyberArk Privileged Session Manager
(PSM) and open-source alternatives. Covers session recording configuration,
keystroke logging, real-time monitoring, risk-based session analysis, and
compliance audit trail generation. Activates for requests involving privileged
session recording, PAM session monitoring, CyberArk PSM configuration,
administrator activity monitoring, or compliance session auditing.
domain: cybersecurity
subdomain: identity-access-management
tags: [pam, session-monitoring, privileged-access, audit-logging]
version: "1.0"
tags: [PAM, CyberArk, PSM, privileged-session, session-recording, session-monitoring, compliance]
version: 1.0.0
author: mahipal
license: Apache-2.0
---
@@ -16,174 +20,304 @@ license: Apache-2.0
## When to Use
- Deploying session recording for all privileged access to critical servers and databases
- Meeting compliance requirements (PCI-DSS 10.2, SOX, HIPAA, ISO 27001) mandating privileged activity monitoring
- Investigating incidents where an administrator may have performed unauthorized actions
- Implementing real-time alerting for high-risk commands during privileged sessions
- Deploying or configuring session recording for all privileged access to critical servers and databases
- Meeting compliance requirements (PCI-DSS 10.2, SOX, HIPAA, ISO 27001) that mandate privileged activity monitoring
- Investigating an incident where an administrator or third-party vendor may have performed unauthorized actions
- Implementing real-time alerting for high-risk commands executed during privileged sessions
- Establishing a forensic audit trail of all administrative actions on production infrastructure
**Do not use** for monitoring standard user sessions; use EDR/UBA for general user behavior monitoring.
**Do not use** for monitoring standard user sessions or endpoint activity; use EDR/UBA solutions for general user behavior monitoring. Privileged session monitoring focuses specifically on elevated-access sessions.
## Prerequisites
- CyberArk PAM or Privilege Cloud with Digital Vault, or open-source alternative (Teleport)
- PSM (Privileged Session Manager) or PSMP installed on hardened jump server
- Network architecture routing all privileged access through the PSM proxy
- Sufficient storage for recordings (estimate: 50-250 KB/min for RDP, 5-20 KB/min for SSH)
- CyberArk PAM Self-Hosted or Privilege Cloud deployment with Digital Vault configured
- CyberArk Privileged Session Manager (PSM) or PSM for SSH (PSMP) installed on a hardened Windows/Linux jump server
- Network architecture where all privileged access is routed through the PSM proxy (no direct RDP/SSH to targets)
- PVWA (Password Vault Web Access) deployed and accessible for session review
- Active Directory integration for authenticating PAM users
- Sufficient storage for session recordings (estimate: 50-250 KB per minute for RDP, 5-20 KB per minute for SSH)
- Alternatively for open-source: Teleport, Apache Guacamole with session recording, or `script`/`ttyrec` for Linux
## Workflow
### Step 1: Route All Privileged Access Through PSM
### Step 1: Architecture — Route All Privileged Access Through PSM
Ensure no direct privileged access bypasses the recording proxy:
```
Architecture:
Admin User --> PVWA (Web Portal) --> PSM (Jump Server) --> Target Server
Architecture Overview:
Admin User ──> PVWA (Web Portal) ──> PSM (Jump Server) ──> Target Server
│ │ │
│ Credentials never │ Session is │
│ exposed to admin │ recorded and │
│ │ stored in Vault │
└── MFA + AD Auth ──────────────────> │ │
└── RDP/SSH proxy ──>│
Network Controls:
- DENY direct RDP (3389) / SSH (22) to targets from user networks
- ALLOW RDP/SSH to targets ONLY from PSM server IPs
- ALLOW PVWA access (443) from admin user networks
- Firewall: DENY direct RDP (3389) and SSH (22) to target servers from user networks
- Firewall: ALLOW RDP/SSH to target servers ONLY from PSM server IPs
- Firewall: ALLOW PVWA access (443) from admin user networks
- PSM server: Hardened, no internet access, local admin access restricted
```
### Step 2: Configure PSM Connection Components
Define how PSM connects to target systems. In the PVWA administration console:
```
PVWA > Administration > Connection Components
PVWA > Administration > Configuration > Connection Components
For Windows RDP:
For Windows RDP targets:
Connection Component: PSM-RDP
Record Sessions: Yes
Recording Format: AVI (video) + Keystrokes (text)
Record Windows Titles: Yes
Protocol: RDP
Client Application: mstsc.exe
Recording Settings:
Record Sessions: Yes
Recording Format: AVI (video) + Keystrokes (text)
Record Windows Titles: Yes
For Linux SSH:
For Linux SSH targets:
Connection Component: PSM-SSH
Record Sessions: Yes
Record Unix Commands: Yes
Protocol: SSH
Client Application: PSM-SecureCRT or PSM-Putty
Recording Settings:
Record Sessions: Yes
Recording Format: AVI + Text commands
Record Unix Commands: Yes
For Database targets (SQL Server Management Studio):
Connection Component: PSM-SSMS
Protocol: Custom
Client Application: SSMS.exe
Recording Settings:
Record Sessions: Yes
Record SQL Queries: Yes (via keystroke logging)
```
### Step 3: Configure Session Recording Policies
```
PVWA > Platform Management > Session Management
Define recording rules based on risk level and compliance requirements:
```
PVWA > Administration > Platform Management > [Platform] > Session Management
Session Recording Settings:
Enable Session Recording: Yes
Keystroke Logging: Enable Transcript + Window Events
Storage: Vault (encrypted, tamper-proof)
Recording Type: Record and Save (not just Monitor)
Retention periods (per compliance):
PCI-DSS: 1 year available, 3 months accessible
SOX: 7 years
HIPAA: 6 years
Keystroke Logging:
Enable Transcript: Yes
Enable Window Events: Yes
Per-Safe policies:
Production-Servers-Admin: Record all, real-time monitoring
Third-Party-Vendor-Access: Record all, dual authorization required
Storage:
Recordings Storage Location: Vault (encrypted, tamper-proof)
Retention Period: 90 days (adjust per compliance requirement)
PCI-DSS: Retain for 1 year, available for 3 months
SOX: Retain for 7 years
HIPAA: Retain for 6 years
Compression:
Enable Recording Compression: Yes
Compression Level: Medium (balance storage vs. quality)
```
### Step 4: Enable Real-Time Monitoring and Alerting
Configure CyberArk Privileged Threat Analytics (PTA):
For granular control, configure per-safe recording policies:
```
Safe: Production-Servers-Admin
Record all sessions: Yes
Safe: Development-Servers
Record all sessions: No (optional for non-production)
Safe: Third-Party-Vendor-Access
Record all sessions: Yes
Enable real-time monitoring: Yes
Require dual authorization: Yes
```
### Step 4: Enable Real-Time Session Monitoring
Configure live session monitoring for SOC analysts:
```
PVWA > Monitoring > Privileged Session Monitoring
Live Monitoring Dashboard:
- Active Sessions: Shows all current privileged sessions in real-time
- Session Details: User, target, duration, risk score
- Actions Available:
- Watch: View the session in real-time (read-only)
- Suspend: Temporarily freeze the session
- Terminate: Immediately end the session
Configure monitoring alerts in CyberArk Privileged Threat Analytics (PTA):
PTA > Configuration > Security Events
Rule: High-Risk Command Detected
Trigger patterns:
Trigger: Unix command matches pattern
Patterns:
- rm -rf /
- chmod 777
- useradd / passwd root
- wget http* | sh / curl * | bash
- iptables -F
- useradd
- passwd root
- dd if=/dev/
- wget http* | sh
- curl * | bash
- nc -e /bin/sh
- python -c 'import socket,subprocess'
Action: Alert SOC + Flag session as high-risk
Rule: Credential Access Attempt
Trigger:
Trigger: Windows process matches
Patterns:
- mimikatz.exe
- procdump.exe targeting lsass
- ntdsutil.exe
- secretsdump
Action: Terminate session + Alert SOC + Lock account
Rule: Unusual Session Duration
Trigger: Session > 4 hours
Trigger: Session duration exceeds 4 hours
Action: Alert SOC for review
```
### Step 5: Configure Session Review Workflow
Set up the post-session review process for auditors:
```
PVWA > Recordings > Search and Review
Review features:
- Video playback with timeline scrubbing
- Keystroke transcript alongside video
- Window title log for application tracking
- Risk events highlighted on timeline
Search Filters:
- Date range
- Target server
- User who initiated the session
- Safe name
- Session risk score (from PTA)
- Session duration
Review Workflow:
1. Auditor opens recorded session in PVWA HTML5 player
2. Video playback with timeline scrubbing
3. Keystroke transcript displayed alongside video
4. Window title log shows which applications were opened
5. Risk events are highlighted on the timeline with markers
6. Auditor marks session as: Reviewed-OK, Reviewed-Suspicious, or Requires-Investigation
Fast-Forward Features:
- Jump to keystrokes (skip idle time)
- Jump to risk events (flagged by PTA)
- Text search within keystroke transcript
- Auditor can mark: Reviewed-OK, Suspicious, Requires-Investigation
- Filter by window title changes
```
### Step 6: Open-Source Alternative - Teleport
### Step 6: Open-Source Alternative Teleport for Session Recording
For environments without CyberArk, Teleport provides session recording for SSH, RDP, and Kubernetes:
```yaml
# /etc/teleport.yaml
# /etc/teleport.yaml - Session recording configuration
teleport:
nodename: teleport-proxy.corp.internal
data_dir: /var/lib/teleport
auth_service:
enabled: yes
session_recording: "node-sync"
session_recording: "node-sync" # Record at the node level, sync to auth server
# Session recording storage (S3 for production)
audit_sessions_uri: "s3://teleport-session-recordings/sessions?region=us-east-1"
# Enhanced session recording (captures commands even in nested shells)
enhanced_recording:
enabled: true
command_events: true
network_events: true
disk_events: true
ssh_service:
enabled: yes
enhanced_recording:
enabled: true
proxy_service:
enabled: yes
web_listen_addr: 0.0.0.0:443
```
Query recorded sessions with `tsh`:
```bash
# List recorded sessions
tsh recordings ls --from=2026-03-15
tsh recordings ls --from=2026-03-15 --to=2026-03-19
# Play back a session
# Play back a specific session
tsh play <session-id>
# Export session events for SIEM
# Export session events as JSON (for SIEM ingestion)
tsh recordings export <session-id> --format=json > session_events.json
# Search for sessions containing specific commands
tsh recordings ls --query='command == "rm -rf"'
```
### Step 7: Forward Session Metadata to SIEM
```
CyberArk PTA > SIEM Integration
Protocol: TCP + TLS (Syslog CEF)
Destination: siem.corp.internal:6514
Send session events and alerts to the SIEM for correlation with other security data:
Events forwarded:
- Session start/stop with user, target, duration
- High-risk command alerts
```
CyberArk PTA Integration:
SIEM Connector: Syslog (CEF format) or REST API
Target: Splunk, Microsoft Sentinel, QRadar, or Elastic
Events Forwarded:
- Session start/stop with user, target, and duration
- High-risk command detection alerts
- Session termination events
- Dual-authorization approvals/denials
- Failed connection attempts
- Dual-authorization requests and approvals/denials
Syslog Configuration (PTA):
PTA > Configuration > SIEM Integration
Protocol: TCP + TLS
Destination: siem.corp.internal:6514
Format: CEF (Common Event Format)
Example CEF Event:
CEF:0|CyberArk|PTA|12.6|HighRiskCommand|High Risk Command Detected|8|
src=10.1.5.42 suser=admin1 dhost=prod-db-01 cs1=rm -rf /var/log
cs2=PSM-SSH cs3=Production-Servers-Admin
```
## Key Concepts
| Term | Definition |
|------|------------|
| **PSM** | Privileged Session Manager - proxy recording all sessions in video and text |
| **PSMP** | PSM for SSH Proxy - Linux-based proxy for SSH, SCP, SFTP sessions |
| **PTA** | Privileged Threat Analytics - behavioral analytics and risk scoring for sessions |
| **Dual Authorization** | Two authorized users must approve before a privileged session is established |
| **Session Isolation** | All admin access proxied through PAM; no direct connections to targets |
| **Keystroke Transcript** | Searchable text log of all keystrokes during a recorded session |
| **PSM (Privileged Session Manager)** | CyberArk component that acts as a proxy/jump server, recording all privileged sessions in video and text format |
| **PSMP (PSM for SSH Proxy)** | Linux-based PSM proxy specifically for SSH, SCP, and SFTP sessions |
| **Connection Component** | CyberArk configuration that defines how PSM launches client applications (RDP, SSH, SSMS) to connect to target systems |
| **Privileged Threat Analytics (PTA)** | CyberArk module that applies behavioral analytics and risk scoring to recorded sessions to detect anomalous activity |
| **Dual Authorization** | Security control requiring two authorized users to approve a privileged session before it is established |
| **Session Isolation** | Architecture principle where administrators never directly connect to targets; all access is proxied through the PAM system |
| **Keystroke Transcript** | Text log of all keystrokes typed during a recorded session, searchable for audit and forensic purposes |
| **Vaulting** | Storing privileged credentials in an encrypted digital vault so they are never exposed to the end user |
## Verification
- [ ] All privileged access routes through PSM (direct RDP/SSH blocked by firewall)
- [ ] Session recordings stored encrypted with tamper protection
- [ ] Keystroke transcripts captured and searchable for SSH and RDP
- [ ] PTA rules trigger alerts for high-risk commands (test with benign trigger)
- [ ] All privileged access to production targets routes through PSM (direct RDP/SSH is blocked by firewall)
- [ ] Session recordings are being stored in the Vault with encryption and tamper protection
- [ ] Keystroke transcripts are captured and searchable for SSH and RDP sessions
- [ ] PTA rules trigger alerts for high-risk commands (test with a benign trigger pattern)
- [ ] Real-time monitoring dashboard shows active sessions with correct metadata
- [ ] Recordings play back in PVWA HTML5 player with timeline and transcript
- [ ] Retention policies match compliance requirements
- [ ] Dual authorization enforced for vendor and high-risk access
- [ ] Session metadata and alerts forwarding to SIEM
- [ ] Session recordings play back correctly in PVWA HTML5 player with timeline and transcript
- [ ] Storage estimates are validated and retention policies match compliance requirements
- [ ] Dual authorization is enforced for vendor and high-risk target access
- [ ] Session metadata and alerts are forwarding to SIEM and correlating correctly
- [ ] Auditors can search, review, and annotate sessions through the PVWA interface
- [ ] Terminated sessions leave a complete recording up to the point of termination