Skip to main content
COSMICBYTEZLABS
NewsSecurityHOWTOsToolsStudyTraining
ProjectsChecklistsAI RankingsNewsletterStatusTagsAbout
Subscribe

Press Enter to search or Esc to close

News
Security
HOWTOs
Tools
Study
Training
Projects
Checklists
AI Rankings
Newsletter
Status
Tags
About
RSS Feed
Reading List
Subscribe

Stay in the Loop

Get the latest security alerts, tutorials, and tech insights delivered to your inbox.

Subscribe NowFree forever. No spam.
COSMICBYTEZLABS

Your trusted source for IT intelligence, cybersecurity insights, and hands-on technical guides.

429+ Articles
114+ Guides

CONTENT

  • Latest News
  • Security Alerts
  • HOWTOs
  • Projects
  • Exam Prep

RESOURCES

  • Search
  • Browse Tags
  • Newsletter Archive
  • Reading List
  • RSS Feed

COMPANY

  • About Us
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CosmicBytez Labs. All rights reserved.

System Status: Operational
  1. Home
  2. HOWTOs
  3. SentinelOne Forensics Rollback and Remediation
SentinelOne Forensics Rollback and Remediation
HOWTOAdvanced

SentinelOne Forensics Rollback and Remediation

This document provides comprehensive procedures for forensic evidence collection, ransomware rollback, and threat remediation using SentinelOne Complete...

Dylan H.

Security Operations

February 11, 2026
39 min read

SCENARIO

This document provides comprehensive procedures for forensic evidence collection, ransomware rollback, and threat remediation using SentinelOne Complete SKU capabilities. These procedures are critical for MSP security operations teams conducting incident response, preserving evidence for legal proceedings, recovering from ransomware attacks, and ensuring complete threat eradication.

Use this documentation when:

  • Conducting forensic investigations requiring evidence preservation
  • Responding to ransomware incidents requiring file recovery
  • Performing comprehensive threat remediation across endpoints
  • Building incident response playbooks for your SOC team
  • Training analysts on SentinelOne Complete capabilities
  • Preparing evidence packages for legal or compliance requirements

SKU Requirement: SentinelOne Singularity Complete is required for most features documented here. Control SKU lacks Deep Visibility, Remote Shell, File Fetch, and 1-Click Rollback capabilities.

MITRE ATT&CK Framework References:

  • Evidence Collection: Supports investigation of all ATT&CK tactics
  • Rollback: Mitigates T1486 (Data Encrypted for Impact)
  • Remediation: Addresses T1059 (Command and Scripting Interpreter), T1053 (Scheduled Task/Job), T1547 (Boot or Logon Autostart Execution)

REQUIREMENTS & ASSUMPTIONS

Prerequisites

Console Access:

  • SentinelOne Management Console with Admin or SOC role
  • API token with appropriate permissions for automation scripts
  • Access to Deep Visibility, Remote Shell, and forensic features

Endpoint Requirements:

  • SentinelOne agent version 21.5+ (recommended: latest GA release)
  • Agent online and communicating with console
  • Volume Shadow Copy Service (VSS) enabled for rollback capability
  • Sufficient disk space for VSS snapshots (minimum 10% free space recommended)

Infrastructure:

  • Secure storage location for forensic evidence
  • Chain of custody documentation templates
  • Incident ticketing system integration
  • SIEM integration for log correlation (optional)

Assumed Knowledge

  • Basic incident response procedures
  • SentinelOne console navigation
  • PowerShell scripting fundamentals
  • Understanding of Windows/Linux file systems
  • MITRE ATT&CK framework familiarity

SECTION 1: FORENSIC EVIDENCE COLLECTION

1.1 Threat Storyline Analysis and Timeline Reconstruction

The Storyline feature automatically correlates all related events into a coherent attack narrative, essential for forensic analysis.

Accessing Storyline:

  1. Navigate to Sentinels > Threats
  2. Click on the threat to investigate
  3. Select the Storyline tab
  4. Review the visual attack chain

Storyline Components:

Timeline View Elements:
├── Process Tree: Parent-child process relationships
├── File Operations: Created, modified, deleted, renamed files
├── Registry Changes: Keys and values modified
├── Network Connections: Outbound communications with IPs/domains
├── DNS Queries: Domain resolution attempts
├── Login Events: User authentication activities
├── Cross-Process Events: Code injection, memory manipulation
└── Module Loads: DLLs and drivers loaded

Timeline Reconstruction Process:

  1. Identify Initial Access Point (MITRE T1566, T1189, T1078)

    • Review the earliest event in the Storyline
    • Note the triggering application (browser, email client, document)
    • Document the user context and timestamp
  2. Map Execution Chain (MITRE T1059, T1204)

    • Trace process spawning relationships
    • Document command-line arguments (often contain IOCs)
    • Identify interpreter abuse (PowerShell, cmd, wscript, mshta)
  3. Document Persistence Mechanisms (MITRE T1547, T1053, T1543)

    • Registry Run keys
    • Scheduled tasks
    • Services created or modified
    • Startup folder items
  4. Capture Network IOCs (MITRE T1071, T1041)

    • C2 server IP addresses and domains
    • Ports and protocols used
    • Data exfiltration destinations
    • DNS queries for DGA domains

Deep Visibility Query for Timeline:

-- Reconstruct timeline for specific endpoint
EndpointName = "WORKSTATION-001" AND
CreatedAt >= "2026-01-07T00:00:00Z" AND
CreatedAt <= "2026-01-08T23:59:59Z"
| sort by CreatedAt asc

Export Storyline for Documentation:

  1. In Storyline view, click Export
  2. Select format: JSON (for analysis) or PDF (for reports)
  3. Include all related events
  4. Save to secure forensic evidence storage

1.2 Artifact Collection from Deep Visibility

Deep Visibility provides comprehensive endpoint telemetry for forensic artifact collection.

Key Forensic Queries:

-- All process executions on compromised endpoint
EventType = "Process Creation" AND
EndpointName = "WORKSTATION-001" AND
CreatedAt >= "2026-01-07T00:00:00Z"
| columns ProcessName, ProcessCmd, ParentProcessName, User, CreatedAt, SHA256
 
-- File operations during incident window
EventType IN ("File Creation", "File Modification", "File Deletion") AND
EndpointName = "WORKSTATION-001" AND
CreatedAt >= "2026-01-07T12:00:00Z" AND
CreatedAt <= "2026-01-07T14:00:00Z"
| columns FilePath, EventType, ProcessName, CreatedAt
 
-- Network connections to external IPs
EventType = "IP Connect" AND
EndpointName = "WORKSTATION-001" AND
DstIP NOT STARTSWITH "10." AND
DstIP NOT STARTSWITH "192.168." AND
DstIP NOT STARTSWITH "172."
| columns SrcProcName, DstIP, DstPort, CreatedAt
 
-- Registry modifications (persistence indicators)
EventType IN ("Registry Key Create", "Registry Value Create", "Registry Value Modified") AND
EndpointName = "WORKSTATION-001" AND
(RegistryPath CONTAINS "Run" OR
 RegistryPath CONTAINS "Services" OR
 RegistryPath CONTAINS "Winlogon")
| columns RegistryPath, RegistryValue, ProcessName, CreatedAt
 
-- DNS queries for threat intelligence
EventType = "DNS" AND
EndpointName = "WORKSTATION-001" AND
CreatedAt >= "2026-01-07T00:00:00Z"
| columns DNSRequest, SrcProcName, CreatedAt

Exporting Deep Visibility Data:

  1. Run the query in Deep Visibility console
  2. Click Export button
  3. Select format:
    • CSV: For spreadsheet analysis
    • JSON: For programmatic processing
    • STIX: For threat intelligence platforms
  4. Download and store in evidence repository

Evidence Preservation Best Practice:

  • Hash all exported files immediately (SHA256)
  • Document export timestamp and analyst name
  • Store in write-once media or evidence management system
  • Maintain chain of custody log

1.3 Memory Dump Collection

Memory forensics captures volatile data including encryption keys, credentials, and malware that only exists in RAM.

Initiating Memory Dump via Console:

  1. Navigate to Sentinels > Endpoints
  2. Select the target endpoint
  3. Click Actions > Fetch Files
  4. Select Full Memory Dump
  5. Wait for collection (can take 10-30 minutes depending on RAM size)
  6. Download password-protected ZIP when ready

Memory Dump via Remote Shell:

# Connect to endpoint via Remote Shell
# Navigate to Sentinels > [Endpoint] > Actions > Remote Shell
 
# Option 1: Use Windows built-in (requires admin)
# Creates minidump of specific process
$processId = (Get-Process -Name "suspicious_process").Id
rundll32.exe C:\Windows\System32\comsvcs.dll, MiniDump $processId C:\Temp\memory.dmp full
 
# Option 2: Full memory dump using winpmem (if deployed)
# Deploy winpmem to endpoint first via File Fetch upload
C:\Tools\winpmem_mini_x64.exe C:\Temp\full_memory.raw
 
# Option 3: Using procdump (Sysinternals)
procdump.exe -ma lsass.exe C:\Temp\lsass.dmp

Memory Dump Analysis Tools:

  • Volatility 3: Open-source memory forensics framework
  • Rekall: Advanced memory analysis
  • WinDbg: Microsoft debugging tools

MITRE ATT&CK Relevance:

  • T1003 (OS Credential Dumping): Recover cached credentials
  • T1055 (Process Injection): Identify injected code
  • T1620 (Reflective Code Loading): Find fileless malware

1.4 Disk Image Collection

For severe incidents or legal requirements, full disk imaging preserves all evidence.

Remote Disk Imaging Considerations:

SentinelOne does not perform full disk imaging natively. Use these approaches:

Option 1: Targeted File Collection via File Fetch

Critical Windows Artifacts:
  System Files:
    - C:\Windows\System32\config\SAM
    - C:\Windows\System32\config\SYSTEM
    - C:\Windows\System32\config\SOFTWARE
    - C:\Windows\System32\config\SECURITY
    - C:\$MFT (Master File Table)
    - C:\$LogFile (NTFS journal)
    - C:\$UsnJrnl:$J (USN Journal)
 
  Event Logs:
    - C:\Windows\System32\winevt\Logs\Security.evtx
    - C:\Windows\System32\winevt\Logs\System.evtx
    - C:\Windows\System32\winevt\Logs\Application.evtx
    - C:\Windows\System32\winevt\Logs\PowerShell*.evtx
    - C:\Windows\System32\winevt\Logs\Microsoft-Windows-Sysmon*.evtx
 
  User Artifacts:
    - C:\Users\*\NTUSER.DAT
    - C:\Users\*\AppData\Local\Microsoft\Windows\UsrClass.dat
    - C:\Users\*\AppData\Roaming\Microsoft\Windows\Recent\*
    - C:\Users\*\AppData\Local\Microsoft\Windows\WebCache\*
 
  Execution Artifacts:
    - C:\Windows\Prefetch\*.pf
    - C:\Windows\AppCompat\Programs\Amcache.hve
    - C:\Windows\AppCompat\Programs\RecentFileCache.bcf

Option 2: Remote Imaging via Remote Shell

# Using FTK Imager CLI (if deployed)
ftkimager.exe \\.\PhysicalDrive0 C:\Evidence\disk_image --e01 --compress 6
 
# Using dd for Windows
dd.exe if=\\.\PhysicalDrive0 of=C:\Evidence\disk.raw bs=64K
 
# Targeted logical collection
robocopy C:\Users C:\Evidence\Users /E /COPYALL /LOG:C:\Evidence\users_copy.log

Option 3: Physical Collection For legal proceedings requiring full disk images:

  1. Network quarantine the endpoint via SentinelOne
  2. Dispatch technician with write-blocker
  3. Create forensic image using FTK Imager or dd
  4. Maintain chain of custody documentation

1.5 Evidence Preservation and Chain of Custody

Proper evidence handling ensures admissibility in legal proceedings.

Chain of Custody Documentation:

# Evidence Chain of Custody Form
 
## Case Information
- Case ID: INC-2026-0108-001
- Case Title: Ransomware Incident - ACME Corp
- Lead Investigator: [Name]
- Date Opened: 2026-01-08
 
## Evidence Item
- Evidence ID: EVD-001
- Description: Memory dump from WORKSTATION-001
- Collection Method: SentinelOne File Fetch
- Collection Date/Time: 2026-01-08 14:32:00 UTC
- Collected By: [Analyst Name]
- Original Location: WORKSTATION-001 (192.168.1.50)
- File Hash (SHA256): [hash value]
- File Size: 16,384 MB
 
## Chain of Custody Log
| Date/Time | Released By | Received By | Purpose | Location |
|-----------|-------------|-------------|---------|----------|
| 2026-01-08 14:35 | SentinelOne | J. Smith | Collection | S1 Console |
| 2026-01-08 14:40 | J. Smith | Evidence Server | Storage | \\evidence\cases\ |
| 2026-01-08 16:00 | Evidence Server | M. Jones | Analysis | Forensic WS |
 
## Integrity Verification
- [ ] Hash verified on receipt
- [ ] Stored in tamper-evident container
- [ ] Access logged and monitored

Evidence Storage Requirements:

  1. Immediate Actions:

    • Calculate SHA256 hash upon collection
    • Document collection method and timestamp
    • Store on write-protected or WORM storage
  2. Storage Location:

    • Encrypted network share with access logging
    • Cloud evidence management platform (e.g., Axon Evidence)
    • Air-gapped forensic workstation for analysis
  3. Retention Policy:

    • Minimum 7 years for compliance (varies by regulation)
    • Legal hold may extend indefinitely
    • Document destruction when retention expires

1.6 Exporting Threat Data for Legal/Compliance

Generate Comprehensive Threat Report:

  1. Navigate to Threats > [Select Threat]
  2. Click Export > Full Report
  3. Include:
    • Threat details and classification
    • Complete Storyline with timestamps
    • All IOCs (hashes, IPs, domains)
    • Remediation actions taken
    • Analyst notes

API Export for SIEM/Legal:

# Export threat data via API
$threatId = "1234567890"
$headers = @{
    "Authorization" = "ApiToken $apiToken"
    "Content-Type" = "application/json"
}
 
# Get threat details
$threat = Invoke-RestMethod -Uri "$consoleUrl/web/api/v2.1/threats/$threatId" -Headers $headers
 
# Get timeline events
$timeline = Invoke-RestMethod -Uri "$consoleUrl/web/api/v2.1/threats/$threatId/timeline" -Headers $headers
 
# Export to JSON for legal
$evidencePackage = @{
    exportDate = (Get-Date -Format "yyyy-MM-ddTHH:mm:ssZ")
    exportedBy = $env:USERNAME
    threatDetails = $threat.data
    timeline = $timeline.data
}
 
$evidencePackage | ConvertTo-Json -Depth 20 | Out-File "C:\Evidence\Threat-$threatId-Export.json"
 
# Calculate hash for integrity
$hash = Get-FileHash "C:\Evidence\Threat-$threatId-Export.json" -Algorithm SHA256
"SHA256: $($hash.Hash)" | Out-File "C:\Evidence\Threat-$threatId-Export.json.sha256"

SECTION 2: ROLLBACK CAPABILITIES (Complete SKU)

2.1 How Ransomware Rollback Works

SentinelOne's 1-Click Rollback leverages Windows Volume Shadow Copy Service (VSS) to restore files encrypted or modified by ransomware.

Technical Architecture:

Rollback Process Flow:
┌─────────────────────────────────────────────────────────────────┐
│                     Normal Operations                            │
│  [Files] ──write──> [VSS Snapshot] ──monitor──> [S1 Agent]      │
└─────────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────────┐
│                   Ransomware Attack                              │
│  [Ransomware] ──encrypt──> [Files] ──detect──> [S1 Behavioral AI]│
│                                                                  │
│  Detection Triggers:                                             │
│  • Mass file modifications                                       │
│  • Encryption entropy changes                                    │
│  • Known ransomware behaviors                                    │
│  • File extension changes (.encrypted, .locked)                  │
└─────────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────────┐
│                   Automatic Response                             │
│  1. Kill ransomware process                                      │
│  2. Quarantine malicious files                                   │
│  3. Block persistence mechanisms                                 │
│  4. Initiate rollback from VSS snapshots                        │
│  5. Restore files to pre-encryption state                       │
└─────────────────────────────────────────────────────────────────┘

VSS Integration Details:

  • SentinelOne monitors VSS snapshots continuously
  • Agent tracks file modifications with associated snapshots
  • Rollback queries VSS for pre-modification versions
  • Files restored to exact state before malicious changes
  • Works independently of Windows System Restore

MITRE ATT&CK Mitigation:

  • T1486 (Data Encrypted for Impact): Primary mitigation
  • T1485 (Data Destruction): Partial mitigation via VSS
  • T1490 (Inhibit System Recovery): Detection of VSS deletion attempts

2.2 Prerequisites and Requirements

Endpoint Requirements:

RequirementDetailsVerification Command
OS SupportWindows 7 SP1+, Server 2008 R2+[System.Environment]::OSVersion
VSS EnabledVolume Shadow Copy service runningGet-Service -Name VSS
VSS SpaceMinimum 10% disk space for shadowsvssadmin list shadowstorage
Agent Version21.5+ recommendedCheck console or SentinelCtl.exe version
Policy SettingRollback enabled in site policyConsole: Settings > Policy

Verification Script:

# Run on endpoint to verify rollback readiness
Write-Host "=== SentinelOne Rollback Readiness Check ===" -ForegroundColor Cyan
 
# Check VSS Service
$vss = Get-Service -Name VSS
Write-Host "`n[VSS Service]" -ForegroundColor Yellow
Write-Host "  Status: $($vss.Status)"
Write-Host "  StartType: $($vss.StartType)"
 
# Check Shadow Storage
Write-Host "`n[Shadow Storage]" -ForegroundColor Yellow
$shadowStorage = vssadmin list shadowstorage 2>&1
if ($shadowStorage -match "No shadow copies") {
    Write-Host "  WARNING: No shadow storage configured" -ForegroundColor Red
} else {
    $shadowStorage | ForEach-Object { Write-Host "  $_" }
}
 
# Check Available Shadows
Write-Host "`n[Shadow Copies]" -ForegroundColor Yellow
$shadows = vssadmin list shadows 2>&1
if ($shadows -match "No shadow copies") {
    Write-Host "  WARNING: No shadow copies available" -ForegroundColor Red
} else {
    $shadowCount = ($shadows | Select-String "Shadow Copy ID").Count
    Write-Host "  Available shadow copies: $shadowCount"
}
 
# Check Disk Space
Write-Host "`n[Disk Space]" -ForegroundColor Yellow
Get-WmiObject Win32_LogicalDisk -Filter "DriveType=3" | ForEach-Object {
    $freePercent = [math]::Round(($_.FreeSpace / $_.Size) * 100, 2)
    $status = if ($freePercent -lt 10) { "[LOW]" } else { "[OK]" }
    Write-Host "  $($_.DeviceID) - Free: $freePercent% $status"
}
 
# Check SentinelOne Agent
Write-Host "`n[SentinelOne Agent]" -ForegroundColor Yellow
$s1Service = Get-Service -Name "SentinelAgent" -ErrorAction SilentlyContinue
if ($s1Service) {
    Write-Host "  Agent Status: $($s1Service.Status)"
} else {
    Write-Host "  WARNING: SentinelOne agent not found" -ForegroundColor Red
}

Policy Configuration:

  1. Navigate to Settings > Policy > [Site Policy]
  2. Under Agent Settings > Remediation:
    • Enable Rollback toggle
    • Configure Automatic Rollback for ransomware threats
  3. Under Protection > Ransomware:
    • Enable Behavioral AI - Ransomware
    • Set action to Kill & Quarantine

2.3 Initiating Manual Rollback

Via Console:

  1. Navigate to Threats
  2. Select the ransomware threat
  3. Verify threat is mitigated (killed/quarantined)
  4. Click Actions > Rollback
  5. Confirm the rollback action
  6. Monitor progress in threat details

Via API:

# Initiate rollback via API
$threatId = "1234567890"
$headers = @{
    "Authorization" = "ApiToken $apiToken"
    "Content-Type" = "application/json"
}
 
$rollbackBody = @{
    data = @{
        ids = @($threatId)
    }
} | ConvertTo-Json
 
$result = Invoke-RestMethod `
    -Uri "$consoleUrl/web/api/v2.1/threats/actions/rollback" `
    -Method POST `
    -Headers $headers `
    -Body $rollbackBody
 
if ($result.data.affected -gt 0) {
    Write-Host "[SUCCESS] Rollback initiated for threat $threatId" -ForegroundColor Green
} else {
    Write-Host "[FAILED] Rollback could not be initiated" -ForegroundColor Red
}

Rollback Status Monitoring:

# Monitor rollback progress
$threatId = "1234567890"
 
do {
    $threat = Invoke-RestMethod `
        -Uri "$consoleUrl/web/api/v2.1/threats/$threatId" `
        -Headers $headers
 
    $rollbackStatus = $threat.data.threatInfo.rollbackStatus
 
    Write-Host "Rollback Status: $rollbackStatus - $(Get-Date -Format 'HH:mm:ss')"
 
    if ($rollbackStatus -eq "completed") {
        Write-Host "[SUCCESS] Rollback completed successfully" -ForegroundColor Green
        break
    } elseif ($rollbackStatus -eq "failed") {
        Write-Host "[FAILED] Rollback failed - check threat details" -ForegroundColor Red
        break
    }
 
    Start-Sleep -Seconds 30
} while ($true)

2.4 Automatic Rollback Configuration

Enable Automatic Rollback:

  1. Navigate to Settings > Policy > [Site Policy]
  2. Select Remediation section
  3. Configure:
Automatic Rollback Settings:
  Enabled: Yes
  Trigger Conditions:
    - Ransomware detected by Behavioral AI
    - Threat classified as ransomware
    - Automatic mitigation successful
 
  Rollback Scope:
    - All files modified by threat process
    - Files modified by child processes
    - Registry changes associated with threat

Policy JSON (via API):

{
  "data": {
    "policy": {
      "agentSettings": {
        "remediation": {
          "rollback": {
            "enabled": true,
            "automaticRollback": true,
            "rollbackOnRansomware": true
          }
        }
      }
    }
  }
}

2.5 Rollback Limitations and Considerations

What Rollback CAN Restore:

  • Files encrypted by detected ransomware
  • Files deleted by malware
  • Registry changes made by threat
  • Files modified in the attack chain

What Rollback CANNOT Restore:

LimitationExplanationWorkaround
Deleted VSS SnapshotsSome ransomware deletes shadow copies before encryptingEnable VSS protection; detect T1490 with STAR rules
Network SharesVSS only covers local volumesUse backup solution for network storage
Cloud-Synced FilesOneDrive/Dropbox may sync encrypted filesUse cloud provider's version history
Pre-Existing DamageOnly restores from point of snapshotRegular backup strategy
Undetected ThreatsMust be detected by S1 to trigger rollbackEnable all detection engines
macOS/LinuxVSS is Windows-only technologyUse platform-specific backup tools
Large Time GapsLong-running encryption may exceed snapshot retentionIncrease VSS storage allocation

STAR Rule for VSS Deletion Detection:

-- Detect attempts to delete shadow copies (T1490)
EventType = "Process Creation" AND
(ProcessCmd CONTAINS "vssadmin delete shadows" OR
 ProcessCmd CONTAINS "wmic shadowcopy delete" OR
 ProcessCmd CONTAINS "bcdedit /set" AND ProcessCmd CONTAINS "recoveryenabled no" OR
 ProcessCmd CONTAINS "wbadmin delete catalog")

2.6 Testing Rollback Procedures

Safe Testing Methodology:

  1. Create Test Environment:

    • Isolated VM or test endpoint
    • Known-good baseline snapshot
    • Test files in designated folder
  2. Simulate Ransomware Behavior (Safe):

# SAFE SIMULATION - Only modifies test files
# Run in isolated test environment only
 
$testFolder = "C:\RollbackTest"
New-Item -Path $testFolder -ItemType Directory -Force
 
# Create test files
1..10 | ForEach-Object {
    $content = "Original content for file $_"
    $content | Out-File "$testFolder\TestFile$_.txt"
}
 
Write-Host "Test files created. Verify in SentinelOne console before proceeding."
Read-Host "Press Enter to simulate file modification (simulated encryption)"
 
# Simulate encryption (actually just modifies files)
Get-ChildItem "$testFolder\*.txt" | ForEach-Object {
    $encrypted = "ENCRYPTED: " + (Get-Content $_.FullName)
    $encrypted | Out-File $_.FullName
    Rename-Item $_.FullName "$($_.FullName).locked"
}
 
Write-Host "Files 'encrypted'. Initiate rollback from SentinelOne console."
  1. Verify Rollback:
    • Initiate rollback from console
    • Verify files restored to original content
    • Document results

Rollback Test Checklist:

  • VSS enabled and functional
  • Test files created with known content
  • Simulated modification detected by SentinelOne
  • Manual rollback initiated successfully
  • Files restored to original state
  • Automatic rollback tested (if configured)
  • Results documented for compliance

SECTION 3: REMEDIATION ACTIONS

3.1 Kill Process Remediation

Terminates malicious processes immediately.

Via Console:

  1. Navigate to threat or endpoint
  2. Click Actions > Kill
  3. Confirm termination

Via API:

# Kill threat processes
$threatId = "1234567890"
 
$killBody = @{
    data = @{
        ids = @($threatId)
    }
} | ConvertTo-Json
 
$result = Invoke-RestMethod `
    -Uri "$consoleUrl/web/api/v2.1/threats/actions/kill" `
    -Method POST `
    -Headers $headers `
    -Body $killBody
 
Write-Host "Kill action affected $($result.data.affected) threat(s)"

MITRE ATT&CK: Disrupts active execution (T1059, T1106)


3.2 Quarantine File Remediation

Moves malicious files to encrypted quarantine storage.

Via Console:

  1. Navigate to threat
  2. Click Actions > Quarantine
  3. File moved to C:\ProgramData\Sentinel\Quarantine\

Via API:

# Quarantine threat
$threatId = "1234567890"
 
$quarantineBody = @{
    data = @{
        ids = @($threatId)
    }
} | ConvertTo-Json
 
$result = Invoke-RestMethod `
    -Uri "$consoleUrl/web/api/v2.1/threats/actions/quarantine" `
    -Method POST `
    -Headers $headers `
    -Body $quarantineBody
 
Write-Host "Quarantine action affected $($result.data.affected) threat(s)"

Quarantine Management:

# List quarantined items
$quarantined = Invoke-RestMethod `
    -Uri "$consoleUrl/web/api/v2.1/threats?mitigationStatuses=quarantined" `
    -Headers $headers
 
$quarantined.data | Select-Object `
    @{N="ThreatName";E={$_.threatInfo.threatName}},
    @{N="Computer";E={$_.agentRealtimeInfo.computerName}},
    @{N="QuarantinedAt";E={$_.threatInfo.mitigatedAt}} |
    Format-Table -AutoSize
 
# Restore from quarantine (false positive)
$unquarantineBody = @{
    data = @{
        ids = @($threatId)
    }
} | ConvertTo-Json
 
Invoke-RestMethod `
    -Uri "$consoleUrl/web/api/v2.1/threats/actions/un-quarantine" `
    -Method POST `
    -Headers $headers `
    -Body $unquarantineBody

3.3 Remediate & Kill Actions

Combined action that kills processes AND removes persistence mechanisms.

Full Remediation Includes:

  • Kill all threat processes
  • Quarantine malicious files
  • Remove registry persistence
  • Delete scheduled tasks
  • Remove services
  • Clean startup items

Via Console:

  1. Navigate to threat
  2. Click Actions > Remediate & Kill
  3. All associated artifacts cleaned

Via API:

# Full remediation
$threatId = "1234567890"
 
$remediateBody = @{
    data = @{
        ids = @($threatId)
    }
} | ConvertTo-Json
 
$result = Invoke-RestMethod `
    -Uri "$consoleUrl/web/api/v2.1/threats/actions/remediate" `
    -Method POST `
    -Headers $headers `
    -Body $remediateBody
 
Write-Host "Remediation affected $($result.data.affected) threat(s)"

3.4 Network Quarantine (Isolation)

Isolates endpoint from network while maintaining SentinelOne console communication.

When to Use:

  • Active ransomware spreading laterally
  • Data exfiltration in progress
  • Compromised endpoint pending investigation
  • Preventing C2 communication

Via Console:

  1. Navigate to Sentinels > Endpoints
  2. Select endpoint
  3. Click Actions > Network Quarantine
  4. Confirm isolation

Via API:

# Network quarantine endpoint
$agentId = "1234567890123456789"
 
$isolateBody = @{
    data = @{
        ids = @($agentId)
    }
} | ConvertTo-Json
 
# Isolate
$result = Invoke-RestMethod `
    -Uri "$consoleUrl/web/api/v2.1/agents/actions/disconnect" `
    -Method POST `
    -Headers $headers `
    -Body $isolateBody
 
Write-Host "Isolated $($result.data.affected) endpoint(s)"
 
# Reconnect after investigation
$reconnectResult = Invoke-RestMethod `
    -Uri "$consoleUrl/web/api/v2.1/agents/actions/connect" `
    -Method POST `
    -Headers $headers `
    -Body $isolateBody
 
Write-Host "Reconnected $($reconnectResult.data.affected) endpoint(s)"

Network Quarantine Behavior:

  • All network traffic blocked except SentinelOne management
  • User sees no network connectivity
  • Remote Shell still accessible for investigation
  • DNS queries blocked
  • Persists across reboots until released

3.5 Custom Remediation Scripts via Remote Shell

For complex remediation requiring custom actions.

Common Remediation Commands:

# === PERSISTENCE REMOVAL ===
 
# Remove malicious Run key
Remove-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Run" -Name "MaliciousEntry" -Force
 
# Remove malicious scheduled task
Unregister-ScheduledTask -TaskName "MalwareTask" -Confirm:$false
 
# Remove malicious service
Stop-Service -Name "MaliciousService" -Force -ErrorAction SilentlyContinue
sc.exe delete "MaliciousService"
 
# Remove startup folder items
Remove-Item "C:\Users\*\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup\malware.lnk" -Force
 
# === FILE CLEANUP ===
 
# Remove specific malware files
Remove-Item "C:\Users\Public\malware.exe" -Force
Remove-Item "C:\ProgramData\MalwareFolder" -Recurse -Force
 
# Remove files by pattern
Get-ChildItem -Path C:\ -Recurse -Include "*.encrypted" -ErrorAction SilentlyContinue | Remove-Item -Force
 
# === PROCESS TERMINATION ===
 
# Kill process by name
Stop-Process -Name "malicious_process" -Force
 
# Kill process by PID
Stop-Process -Id 1234 -Force
 
# Kill processes running from temp
Get-Process | Where-Object {$_.Path -like "*\Temp\*"} | Stop-Process -Force
 
# === NETWORK CLEANUP ===
 
# Remove malicious hosts file entries
$hostsFile = "C:\Windows\System32\drivers\etc\hosts"
$content = Get-Content $hostsFile | Where-Object {$_ -notmatch "malicious-domain.com"}
$content | Set-Content $hostsFile
 
# Reset DNS cache
Clear-DnsClientCache
 
# Block malicious IP via firewall
New-NetFirewallRule -DisplayName "Block Malicious IP" -Direction Outbound -RemoteAddress "192.0.2.100" -Action Block
 
# === CREDENTIAL HYGIENE ===
 
# Force password change on next logon (run as admin)
net user username /logonpasswordchg:yes
 
# Clear credential cache
cmdkey /list | ForEach-Object {
    if ($_ -match "Target: (.+)") {
        cmdkey /delete:$matches[1]
    }
}

3.6 Bulk Remediation Across Endpoints

For incidents affecting multiple endpoints.

Bulk Threat Remediation Script:

<#
.SYNOPSIS
    Bulk remediation script for SentinelOne threats
.DESCRIPTION
    Performs bulk remediation actions across multiple threats/endpoints
.PARAMETER Action
    Remediation action: Kill, Quarantine, Remediate, Rollback
.PARAMETER ThreatFilter
    Filter criteria for threats to remediate
#>
 
param(
    [Parameter(Mandatory=$true)]
    [ValidateSet('Kill','Quarantine','Remediate','Rollback')]
    [string]$Action,
 
    [Parameter(Mandatory=$false)]
    [string]$Classification = "ransomware",
 
    [Parameter(Mandatory=$false)]
    [int]$DaysBack = 1,
 
    [Parameter(Mandatory=$true)]
    [string]$ApiToken,
 
    [Parameter(Mandatory=$true)]
    [string]$ConsoleUrl
)
 
$headers = @{
    "Authorization" = "ApiToken $ApiToken"
    "Content-Type" = "application/json"
}
 
# Build filter
$dateFilter = (Get-Date).AddDays(-$DaysBack).ToString("yyyy-MM-ddT00:00:00Z")
$endpoint = "/web/api/v2.1/threats?resolved=false&classifications=$Classification&createdAt__gte=$dateFilter"
 
Write-Host "=== SentinelOne Bulk Remediation ===" -ForegroundColor Cyan
Write-Host "Action: $Action"
Write-Host "Classification: $Classification"
Write-Host "Date Filter: Last $DaysBack day(s)"
 
# Get matching threats
$threats = Invoke-RestMethod -Uri "$ConsoleUrl$endpoint" -Headers $headers
$threatCount = $threats.pagination.totalItems
 
Write-Host "`nFound $threatCount threat(s) matching criteria" -ForegroundColor Yellow
 
if ($threatCount -eq 0) {
    Write-Host "No threats to process. Exiting." -ForegroundColor Green
    exit 0
}
 
# Display threats for confirmation
$threats.data | ForEach-Object {
    Write-Host "  - $($_.id): $($_.threatInfo.threatName) on $($_.agentRealtimeInfo.computerName)"
}
 
$confirm = Read-Host "`nProceed with $Action on $threatCount threat(s)? (yes/no)"
if ($confirm -ne "yes") {
    Write-Host "Operation cancelled." -ForegroundColor Yellow
    exit 0
}
 
# Perform remediation
$threatIds = $threats.data | Select-Object -ExpandProperty id
 
$actionBody = @{
    data = @{
        ids = $threatIds
    }
} | ConvertTo-Json
 
$actionEndpoint = switch ($Action) {
    'Kill'       { "/web/api/v2.1/threats/actions/kill" }
    'Quarantine' { "/web/api/v2.1/threats/actions/quarantine" }
    'Remediate'  { "/web/api/v2.1/threats/actions/remediate" }
    'Rollback'   { "/web/api/v2.1/threats/actions/rollback" }
}
 
try {
    $result = Invoke-RestMethod `
        -Uri "$ConsoleUrl$actionEndpoint" `
        -Method POST `
        -Headers $headers `
        -Body $actionBody
 
    Write-Host "`n[SUCCESS] $Action completed on $($result.data.affected) threat(s)" -ForegroundColor Green
}
catch {
    Write-Host "`n[ERROR] $Action failed: $($_.Exception.Message)" -ForegroundColor Red
}
 
# Log results
$logEntry = @{
    Timestamp = Get-Date -Format "yyyy-MM-ddTHH:mm:ssZ"
    Action = $Action
    ThreatCount = $threatCount
    ThreatIds = $threatIds
    Result = if ($result) { "Success" } else { "Failed" }
} | ConvertTo-Json
 
$logPath = "C:\BIN\LOGS\S1-BulkRemediation-$(Get-Date -Format 'yyyyMMdd-HHmmss').json"
$logEntry | Out-File $logPath
Write-Host "Log saved to: $logPath"

SECTION 4: INCIDENT RESPONSE WORKFLOWS

4.1 Initial Triage Procedures

Triage Decision Tree:

                    ┌─────────────────┐
                    │  Alert Received │
                    └────────┬────────┘
                             │
                    ┌────────▼────────┐
                    │ Check Confidence│
                    │     Level       │
                    └────────┬────────┘
                             │
            ┌────────────────┼────────────────┐
            │                │                │
     ┌──────▼──────┐  ┌──────▼──────┐  ┌──────▼──────┐
     │    HIGH     │  │   MEDIUM    │  │     LOW     │
     │  Immediate  │  │   Review    │  │   Monitor   │
     │   Action    │  │  Required   │  │    Only     │
     └──────┬──────┘  └──────┬──────┘  └──────┬──────┘
            │                │                │
     ┌──────▼──────┐  ┌──────▼──────┐  ┌──────▼──────┐
     │ • Isolate   │  │ • Analyze   │  │ • Log event │
     │ • Preserve  │  │   Storyline │  │ • Schedule  │
     │ • Escalate  │  │ • Check VT  │  │   review    │
     └─────────────┘  │ • Decide    │  └─────────────┘
                      └─────────────┘

Initial Triage Script:

<#
.SYNOPSIS
    Initial threat triage script for SentinelOne alerts
#>
 
param(
    [Parameter(Mandatory=$true)]
    [string]$ThreatId,
    [string]$ApiToken,
    [string]$ConsoleUrl
)
 
$headers = @{
    "Authorization" = "ApiToken $ApiToken"
    "Content-Type" = "application/json"
}
 
Write-Host "=== THREAT TRIAGE: $ThreatId ===" -ForegroundColor Cyan
 
# Get threat details
$threat = (Invoke-RestMethod -Uri "$ConsoleUrl/web/api/v2.1/threats/$ThreatId" -Headers $headers).data
 
# Display summary
Write-Host "`n[THREAT SUMMARY]" -ForegroundColor Yellow
Write-Host "  Name: $($threat.threatInfo.threatName)"
Write-Host "  Classification: $($threat.threatInfo.classification)"
Write-Host "  Confidence: $($threat.threatInfo.confidenceLevel)"
Write-Host "  Engine: $($threat.threatInfo.detectionEngines -join ', ')"
Write-Host "  Status: $($threat.threatInfo.mitigationStatus)"
 
Write-Host "`n[ENDPOINT]" -ForegroundColor Yellow
Write-Host "  Computer: $($threat.agentRealtimeInfo.computerName)"
Write-Host "  User: $($threat.threatInfo.processUser)"
Write-Host "  OS: $($threat.agentRealtimeInfo.osName)"
Write-Host "  Agent: $($threat.agentRealtimeInfo.agentVersion)"
 
Write-Host "`n[FILE DETAILS]" -ForegroundColor Yellow
Write-Host "  Path: $($threat.threatInfo.filePath)"
Write-Host "  SHA256: $($threat.threatInfo.sha256)"
Write-Host "  SHA1: $($threat.threatInfo.sha1)"
Write-Host "  MD5: $($threat.threatInfo.md5)"
 
# VirusTotal lookup
Write-Host "`n[THREAT INTELLIGENCE]" -ForegroundColor Yellow
$vtUrl = "https://www.virustotal.com/gui/file/$($threat.threatInfo.sha256)"
Write-Host "  VirusTotal: $vtUrl"
 
# Triage recommendation
Write-Host "`n[TRIAGE RECOMMENDATION]" -ForegroundColor Magenta
$confidence = $threat.threatInfo.confidenceLevel
$classification = $threat.threatInfo.classification
 
if ($confidence -eq "high" -and $classification -in @("ransomware", "trojan", "malware")) {
    Write-Host "  CRITICAL - Immediate isolation and remediation required" -ForegroundColor Red
    Write-Host "  Recommended Actions:"
    Write-Host "    1. Network quarantine endpoint"
    Write-Host "    2. Full remediation (Kill + Quarantine)"
    Write-Host "    3. Check for lateral movement"
    Write-Host "    4. Collect forensic evidence"
} elseif ($confidence -eq "medium") {
    Write-Host "  ELEVATED - Investigation required" -ForegroundColor Yellow
    Write-Host "  Recommended Actions:"
    Write-Host "    1. Review Storyline for context"
    Write-Host "    2. Check VirusTotal results"
    Write-Host "    3. Determine if legitimate software"
} else {
    Write-Host "  LOW - Monitor and review" -ForegroundColor Green
    Write-Host "  Recommended Actions:"
    Write-Host "    1. Document for trending analysis"
    Write-Host "    2. Schedule periodic review"
}
 
# Output for ticket system
$triageReport = @{
    ThreatId = $ThreatId
    TriageTime = Get-Date -Format "yyyy-MM-ddTHH:mm:ssZ"
    Analyst = $env:USERNAME
    Confidence = $confidence
    Classification = $classification
    Endpoint = $threat.agentRealtimeInfo.computerName
    Recommendation = if ($confidence -eq "high") { "CRITICAL" } elseif ($confidence -eq "medium") { "ELEVATED" } else { "LOW" }
}
 
$triageReport | ConvertTo-Json | Out-File "C:\BIN\LOGS\Triage-$ThreatId.json"
Write-Host "`nTriage report saved to: C:\BIN\LOGS\Triage-$ThreatId.json"

4.2 Containment Strategies

Containment Matrix:

Threat TypePrimary ContainmentSecondary ContainmentNotes
Ransomware (Active)Network QuarantineKill + RollbackSpeed critical
Ransomware (Detected)Kill + QuarantineRollbackVerify no spread
Trojan/RATNetwork QuarantineFull RemediationPrevent C2
CryptominerKill ProcessBlock Pool IPsLower priority
Lateral MovementNetwork Quarantine AllCredential ResetScope critical
Data ExfiltrationNetwork QuarantineForensic CollectionPreserve evidence

Containment Automation Script:

function Invoke-ThreatContainment {
    param(
        [string]$ThreatId,
        [ValidateSet('Ransomware','Trojan','Cryptominer','DataExfil','LateralMovement')]
        [string]$ThreatType,
        [string]$ApiToken,
        [string]$ConsoleUrl
    )
 
    $headers = @{
        "Authorization" = "ApiToken $ApiToken"
        "Content-Type" = "application/json"
    }
 
    # Get threat details
    $threat = (Invoke-RestMethod -Uri "$ConsoleUrl/web/api/v2.1/threats/$ThreatId" -Headers $headers).data
    $agentId = $threat.agentRealtimeInfo.agentId
 
    Write-Host "Containing $ThreatType threat on $($threat.agentRealtimeInfo.computerName)" -ForegroundColor Cyan
 
    switch ($ThreatType) {
        'Ransomware' {
            # Immediate network isolation
            Write-Host "  [1/4] Network quarantine..." -ForegroundColor Yellow
            $isolateBody = @{data=@{ids=@($agentId)}} | ConvertTo-Json
            Invoke-RestMethod -Uri "$ConsoleUrl/web/api/v2.1/agents/actions/disconnect" -Method POST -Headers $headers -Body $isolateBody
 
            # Kill processes
            Write-Host "  [2/4] Killing threat processes..." -ForegroundColor Yellow
            $killBody = @{data=@{ids=@($ThreatId)}} | ConvertTo-Json
            Invoke-RestMethod -Uri "$ConsoleUrl/web/api/v2.1/threats/actions/kill" -Method POST -Headers $headers -Body $killBody
 
            # Quarantine files
            Write-Host "  [3/4] Quarantining malicious files..." -ForegroundColor Yellow
            $quarantineBody = @{data=@{ids=@($ThreatId)}} | ConvertTo-Json
            Invoke-RestMethod -Uri "$ConsoleUrl/web/api/v2.1/threats/actions/quarantine" -Method POST -Headers $headers -Body $quarantineBody
 
            # Initiate rollback
            Write-Host "  [4/4] Initiating rollback..." -ForegroundColor Yellow
            $rollbackBody = @{data=@{ids=@($ThreatId)}} | ConvertTo-Json
            Invoke-RestMethod -Uri "$ConsoleUrl/web/api/v2.1/threats/actions/rollback" -Method POST -Headers $headers -Body $rollbackBody
 
            Write-Host "[CONTAINED] Ransomware containment complete" -ForegroundColor Green
        }
 
        'Trojan' {
            Write-Host "  [1/3] Network quarantine..." -ForegroundColor Yellow
            $isolateBody = @{data=@{ids=@($agentId)}} | ConvertTo-Json
            Invoke-RestMethod -Uri "$ConsoleUrl/web/api/v2.1/agents/actions/disconnect" -Method POST -Headers $headers -Body $isolateBody
 
            Write-Host "  [2/3] Full remediation..." -ForegroundColor Yellow
            $remediateBody = @{data=@{ids=@($ThreatId)}} | ConvertTo-Json
            Invoke-RestMethod -Uri "$ConsoleUrl/web/api/v2.1/threats/actions/remediate" -Method POST -Headers $headers -Body $remediateBody
 
            Write-Host "  [3/3] Endpoint remains isolated pending investigation" -ForegroundColor Yellow
            Write-Host "[CONTAINED] Trojan containment complete - manual review required" -ForegroundColor Green
        }
 
        'Cryptominer' {
            Write-Host "  [1/2] Killing miner processes..." -ForegroundColor Yellow
            $killBody = @{data=@{ids=@($ThreatId)}} | ConvertTo-Json
            Invoke-RestMethod -Uri "$ConsoleUrl/web/api/v2.1/threats/actions/kill" -Method POST -Headers $headers -Body $killBody
 
            Write-Host "  [2/2] Quarantining miner files..." -ForegroundColor Yellow
            $quarantineBody = @{data=@{ids=@($ThreatId)}} | ConvertTo-Json
            Invoke-RestMethod -Uri "$ConsoleUrl/web/api/v2.1/threats/actions/quarantine" -Method POST -Headers $headers -Body $quarantineBody
 
            Write-Host "[CONTAINED] Cryptominer stopped - no isolation required" -ForegroundColor Green
        }
 
        default {
            Write-Host "  Performing standard containment..." -ForegroundColor Yellow
            $remediateBody = @{data=@{ids=@($ThreatId)}} | ConvertTo-Json
            Invoke-RestMethod -Uri "$ConsoleUrl/web/api/v2.1/threats/actions/remediate" -Method POST -Headers $headers -Body $remediateBody
            Write-Host "[CONTAINED] Standard containment complete" -ForegroundColor Green
        }
    }
}

4.3 Eradication Steps

Comprehensive Eradication Checklist:

## Eradication Checklist
 
### Phase 1: Primary Threat Removal
- [ ] All malicious processes terminated
- [ ] Malicious files quarantined
- [ ] Registry persistence removed
- [ ] Scheduled tasks deleted
- [ ] Malicious services removed
- [ ] Startup items cleaned
 
### Phase 2: Secondary Cleanup
- [ ] Temp folders cleaned
- [ ] Browser cache cleared
- [ ] Downloaded malware removed
- [ ] Dropped payloads deleted
- [ ] Config files removed
 
### Phase 3: System Verification
- [ ] Full system scan completed
- [ ] Deep Visibility query shows no IOCs
- [ ] No suspicious processes running
- [ ] No unusual network connections
- [ ] Event logs reviewed
 
### Phase 4: Credential Hygiene
- [ ] Local admin password changed
- [ ] Domain credentials reset (if compromised)
- [ ] Service account passwords rotated
- [ ] Cached credentials cleared
- [ ] MFA verified/enabled

Automated Eradication Script:

function Invoke-ThreatEradication {
    param(
        [string]$ThreatId,
        [string]$ApiToken,
        [string]$ConsoleUrl
    )
 
    $headers = @{
        "Authorization" = "ApiToken $ApiToken"
        "Content-Type" = "application/json"
    }
 
    Write-Host "=== THREAT ERADICATION: $ThreatId ===" -ForegroundColor Cyan
 
    # Get threat details
    $threat = (Invoke-RestMethod -Uri "$ConsoleUrl/web/api/v2.1/threats/$ThreatId" -Headers $headers).data
 
    # Phase 1: Primary removal
    Write-Host "`n[Phase 1] Primary Threat Removal" -ForegroundColor Yellow
    $remediateBody = @{data=@{ids=@($ThreatId)}} | ConvertTo-Json
    $result = Invoke-RestMethod -Uri "$ConsoleUrl/web/api/v2.1/threats/actions/remediate" -Method POST -Headers $headers -Body $remediateBody
    Write-Host "  Remediation action completed: $($result.data.affected) threat(s)"
 
    # Phase 2: Verify via Deep Visibility
    Write-Host "`n[Phase 2] Verification Query" -ForegroundColor Yellow
    $sha256 = $threat.threatInfo.sha256
    $endpoint = $threat.agentRealtimeInfo.computerName
 
    Write-Host "  Query Deep Visibility for residual IOCs:"
    Write-Host "  EndpointName = `"$endpoint`" AND SHA256 = `"$sha256`""
 
    # Phase 3: Mark resolved
    Write-Host "`n[Phase 3] Resolution" -ForegroundColor Yellow
    $resolveBody = @{
        data = @{
            threatIds = @($ThreatId)
            resolution = "confirmed_threat"
            analystNote = "Eradication completed $(Get-Date -Format 'yyyy-MM-dd HH:mm'). Remediation actions: Kill, Quarantine, Remove persistence. Verified via Deep Visibility."
        }
    } | ConvertTo-Json
 
    Invoke-RestMethod -Uri "$ConsoleUrl/web/api/v2.1/threats/mark-as-resolved" -Method POST -Headers $headers -Body $resolveBody
    Write-Host "  Threat marked as resolved"
 
    Write-Host "`n[ERADICATION COMPLETE]" -ForegroundColor Green
}

4.4 Recovery Procedures

Recovery Workflow:

Recovery Process:
┌─────────────────────────────────────────────────────────────────┐
│ 1. VERIFY ERADICATION                                           │
│    • Deep Visibility confirms no active IOCs                    │
│    • Full scan shows clean                                      │
│    • No suspicious processes or connections                     │
└─────────────────────────────────┬───────────────────────────────┘
                                  │
┌─────────────────────────────────▼───────────────────────────────┐
│ 2. RESTORE NETWORK ACCESS                                       │
│    • Remove network quarantine                                  │
│    • Verify connectivity                                        │
│    • Test critical application access                           │
└─────────────────────────────────┬───────────────────────────────┘
                                  │
┌─────────────────────────────────▼───────────────────────────────┐
│ 3. RESTORE DATA (if needed)                                     │
│    • Rollback completed files verified                          │
│    • Restore from backup if rollback incomplete                 │
│    • Verify data integrity                                      │
└─────────────────────────────────┬───────────────────────────────┘
                                  │
┌─────────────────────────────────▼───────────────────────────────┐
│ 4. USER COMMUNICATION                                           │
│    • Notify user of restoration                                 │
│    • Provide security awareness guidance                        │
│    • Document any remaining actions                             │
└─────────────────────────────────┬───────────────────────────────┘
                                  │
┌─────────────────────────────────▼───────────────────────────────┐
│ 5. MONITORING                                                   │
│    • Enable enhanced monitoring for 7 days                      │
│    • Create watchlist for endpoint                              │
│    • Schedule follow-up verification                            │
└─────────────────────────────────────────────────────────────────┘

Recovery Script:

function Invoke-EndpointRecovery {
    param(
        [string]$AgentId,
        [string]$ThreatId,
        [string]$ApiToken,
        [string]$ConsoleUrl
    )
 
    $headers = @{
        "Authorization" = "ApiToken $ApiToken"
        "Content-Type" = "application/json"
    }
 
    Write-Host "=== ENDPOINT RECOVERY ===" -ForegroundColor Cyan
 
    # Step 1: Verify clean state
    Write-Host "`n[Step 1] Verifying endpoint clean state..." -ForegroundColor Yellow
    $agent = (Invoke-RestMethod -Uri "$ConsoleUrl/web/api/v2.1/agents?ids=$AgentId" -Headers $headers).data[0]
 
    if ($agent.infected) {
        Write-Host "  WARNING: Endpoint still shows infected status" -ForegroundColor Red
        Write-Host "  Please complete eradication before recovery"
        return
    }
    Write-Host "  Endpoint shows clean" -ForegroundColor Green
 
    # Step 2: Remove network quarantine
    Write-Host "`n[Step 2] Removing network quarantine..." -ForegroundColor Yellow
    if ($agent.networkStatus -eq "disconnected") {
        $connectBody = @{data=@{ids=@($AgentId)}} | ConvertTo-Json
        Invoke-RestMethod -Uri "$ConsoleUrl/web/api/v2.1/agents/actions/connect" -Method POST -Headers $headers -Body $connectBody
        Write-Host "  Network access restored" -ForegroundColor Green
    } else {
        Write-Host "  Endpoint already connected" -ForegroundColor Green
    }
 
    # Step 3: Verify rollback status
    Write-Host "`n[Step 3] Checking rollback status..." -ForegroundColor Yellow
    if ($ThreatId) {
        $threat = (Invoke-RestMethod -Uri "$ConsoleUrl/web/api/v2.1/threats/$ThreatId" -Headers $headers).data
        $rollbackStatus = $threat.threatInfo.rollbackStatus
        Write-Host "  Rollback status: $rollbackStatus"
 
        if ($rollbackStatus -eq "completed") {
            Write-Host "  Files restored successfully" -ForegroundColor Green
        } elseif ($rollbackStatus -eq "failed") {
            Write-Host "  Rollback failed - manual restoration required" -ForegroundColor Red
        }
    }
 
    # Step 4: Generate recovery report
    Write-Host "`n[Step 4] Generating recovery report..." -ForegroundColor Yellow
    $recoveryReport = @{
        RecoveryDate = Get-Date -Format "yyyy-MM-ddTHH:mm:ssZ"
        Analyst = $env:USERNAME
        AgentId = $AgentId
        Endpoint = $agent.computerName
        ThreatId = $ThreatId
        NetworkRestored = $true
        RollbackStatus = $rollbackStatus
        VerificationStatus = "Clean"
    }
 
    $reportPath = "C:\BIN\LOGS\Recovery-$AgentId-$(Get-Date -Format 'yyyyMMdd').json"
    $recoveryReport | ConvertTo-Json | Out-File $reportPath
    Write-Host "  Report saved: $reportPath"
 
    Write-Host "`n[RECOVERY COMPLETE]" -ForegroundColor Green
    Write-Host "Recommended: Monitor endpoint for 7 days"
}

4.5 Post-Incident Analysis

Lessons Learned Template:

# Post-Incident Analysis Report
 
## Incident Summary
- **Incident ID:** INC-2026-0108-001
- **Date/Time Detected:** 2026-01-08 14:32 UTC
- **Date/Time Resolved:** 2026-01-08 16:45 UTC
- **Total Duration:** 2 hours 13 minutes
- **Affected Systems:** 1 endpoint (WORKSTATION-001)
- **Affected Users:** 1 (john.doe)
- **Data Impact:** None (rollback successful)
 
## Attack Summary
- **Initial Access:** Phishing email with malicious attachment
- **Execution:** User opened Word document, enabled macros
- **Persistence:** Scheduled task created
- **Impact:** Ransomware encryption attempt (blocked)
 
## Timeline
| Time (UTC) | Event |
|------------|-------|
| 14:30 | Phishing email received |
| 14:32 | User opened attachment |
| 14:32 | Macro executed PowerShell |
| 14:33 | SentinelOne detected ransomware behavior |
| 14:33 | Automatic kill and quarantine |
| 14:35 | SOC notified via alert |
| 14:40 | Analyst initiated network quarantine |
| 14:45 | Rollback initiated |
| 14:50 | Rollback completed |
| 15:30 | Investigation completed |
| 16:00 | Network quarantine removed |
| 16:30 | User notified |
| 16:45 | Incident closed |
 
## MITRE ATT&CK Mapping
- T1566.001 - Phishing: Spearphishing Attachment
- T1204.002 - User Execution: Malicious File
- T1059.001 - Command and Scripting Interpreter: PowerShell
- T1053.005 - Scheduled Task/Job: Scheduled Task
- T1486 - Data Encrypted for Impact
 
## Detection Analysis
- **Detection Method:** Behavioral AI
- **Detection Time:** < 1 minute from execution
- **False Positive:** No
- **Detection Gap:** None identified
 
## Response Effectiveness
- **Containment Time:** 8 minutes
- **Eradication Time:** 15 minutes
- **Recovery Time:** 2 hours
- **Data Loss:** None
 
## Lessons Learned
1. **What Worked:**
   - Behavioral AI detected ransomware immediately
   - Automatic kill prevented encryption spread
   - Rollback restored affected files
   - SOC response within SLA
 
2. **Improvement Areas:**
   - User clicked despite phishing training
   - Email gateway did not block attachment
   - Need macro-blocking policy review
 
## Recommendations
1. Deploy email attachment sandboxing
2. Enable Office macro blocking by default
3. Schedule targeted phishing training for affected user
4. Create STAR rule for similar attack patterns
 
## Follow-Up Actions
- [ ] Block sending domain at email gateway
- [ ] Update firewall rules for C2 IPs
- [ ] Share IOCs with threat intelligence platform
- [ ] Schedule user security awareness training

4.6 Documentation and Reporting

Incident Report Generation Script:

function New-IncidentReport {
    param(
        [Parameter(Mandatory=$true)]
        [string]$ThreatId,
        [string]$ApiToken,
        [string]$ConsoleUrl,
        [string]$OutputPath = "C:\BIN\LOGS"
    )
 
    $headers = @{
        "Authorization" = "ApiToken $ApiToken"
        "Content-Type" = "application/json"
    }
 
    # Gather data
    $threat = (Invoke-RestMethod -Uri "$ConsoleUrl/web/api/v2.1/threats/$ThreatId" -Headers $headers).data
    $timeline = (Invoke-RestMethod -Uri "$ConsoleUrl/web/api/v2.1/threats/$ThreatId/timeline" -Headers $headers).data
 
    # Build report
    $report = @"
# SentinelOne Incident Report
 
## Executive Summary
- **Incident ID:** $ThreatId
- **Generated:** $(Get-Date -Format "yyyy-MM-dd HH:mm:ss")
- **Analyst:** $env:USERNAME
 
## Threat Details
| Field | Value |
|-------|-------|
| Threat Name | $($threat.threatInfo.threatName) |
| Classification | $($threat.threatInfo.classification) |
| Confidence | $($threat.threatInfo.confidenceLevel) |
| Detection Engine | $($threat.threatInfo.detectionEngines -join ', ') |
| Status | $($threat.threatInfo.mitigationStatus) |
| Resolved | $($threat.threatInfo.resolved) |
 
## Affected Endpoint
| Field | Value |
|-------|-------|
| Computer | $($threat.agentRealtimeInfo.computerName) |
| Domain | $($threat.agentRealtimeInfo.domain) |
| OS | $($threat.agentRealtimeInfo.osName) |
| User | $($threat.threatInfo.processUser) |
| IP Address | $($threat.agentRealtimeInfo.externalIp) |
 
## File Information
| Field | Value |
|-------|-------|
| File Name | $($threat.threatInfo.originatorProcess) |
| File Path | $($threat.threatInfo.filePath) |
| SHA256 | $($threat.threatInfo.sha256) |
| SHA1 | $($threat.threatInfo.sha1) |
| MD5 | $($threat.threatInfo.md5) |
 
## Timeline Summary
| Time | Event Type | Details |
|------|------------|---------|
 
"@
 
    # Add timeline events
    $timeline | Select-Object -First 20 | ForEach-Object {
        $report += "| $($_.createdAt) | $($_.eventType) | $($_.processName) |`n"
    }
 
    $report += @"
 
## Actions Taken
- Mitigation Status: $($threat.threatInfo.mitigationStatus)
- Rollback Status: $($threat.threatInfo.rollbackStatus)
 
## Recommendations
1. Review user security awareness
2. Update detection rules if needed
3. Share IOCs with threat intelligence
 
---
*Report generated by SentinelOne Automation*
"@
 
    # Save report
    $fileName = "IncidentReport-$ThreatId-$(Get-Date -Format 'yyyyMMdd-HHmmss').md"
    $fullPath = Join-Path $OutputPath $fileName
    $report | Out-File $fullPath -Encoding UTF8
 
    Write-Host "Report saved to: $fullPath" -ForegroundColor Green
    return $fullPath
}

SECTION 5: POWERSHELL AUTOMATION SCRIPTS

5.1 Automated Evidence Collection Script

<#
.SYNOPSIS
    Automated forensic evidence collection from SentinelOne
.DESCRIPTION
    Collects threat data, storyline, Deep Visibility queries, and endpoint artifacts
.PARAMETER ThreatId
    SentinelOne threat ID to investigate
.PARAMETER ApiToken
    SentinelOne API token
.PARAMETER ConsoleUrl
    SentinelOne console URL
.PARAMETER OutputPath
    Path to save collected evidence
.EXAMPLE
    .\Collect-S1Evidence.ps1 -ThreatId "123456" -ApiToken "token" -ConsoleUrl "https://tenant.sentinelone.net"
#>
 
[CmdletBinding()]
param(
    [Parameter(Mandatory=$true)]
    [string]$ThreatId,
 
    [Parameter(Mandatory=$true)]
    [string]$ApiToken,
 
    [Parameter(Mandatory=$true)]
    [string]$ConsoleUrl,
 
    [string]$OutputPath = "C:\Evidence"
)
 
$ErrorActionPreference = 'Stop'
 
# Create evidence folder
$evidenceFolder = Join-Path $OutputPath "S1-Evidence-$ThreatId-$(Get-Date -Format 'yyyyMMdd-HHmmss')"
New-Item -Path $evidenceFolder -ItemType Directory -Force | Out-Null
 
$headers = @{
    "Authorization" = "ApiToken $ApiToken"
    "Content-Type" = "application/json"
}
 
Write-Host "=== SentinelOne Evidence Collection ===" -ForegroundColor Cyan
Write-Host "Threat ID: $ThreatId"
Write-Host "Evidence Folder: $evidenceFolder`n"
 
# Initialize chain of custody
$chainOfCustody = @{
    CaseId = "S1-$ThreatId"
    CollectionStarted = Get-Date -Format "yyyy-MM-ddTHH:mm:ssZ"
    Collector = $env:USERNAME
    CollectorHost = $env:COMPUTERNAME
    Items = @()
}
 
try {
    # 1. Collect threat details
    Write-Host "[1/5] Collecting threat details..." -ForegroundColor Yellow
    $threat = Invoke-RestMethod -Uri "$ConsoleUrl/web/api/v2.1/threats/$ThreatId" -Headers $headers
    $threatFile = Join-Path $evidenceFolder "threat-details.json"
    $threat | ConvertTo-Json -Depth 20 | Out-File $threatFile
    $chainOfCustody.Items += @{
        ItemId = "EVD-001"
        Description = "Threat Details JSON"
        FileName = "threat-details.json"
        CollectedAt = Get-Date -Format "yyyy-MM-ddTHH:mm:ssZ"
        SHA256 = (Get-FileHash $threatFile -Algorithm SHA256).Hash
    }
    Write-Host "  Saved: threat-details.json" -ForegroundColor Green
 
    # 2. Collect timeline/storyline
    Write-Host "[2/5] Collecting threat timeline..." -ForegroundColor Yellow
    $timeline = Invoke-RestMethod -Uri "$ConsoleUrl/web/api/v2.1/threats/$ThreatId/timeline" -Headers $headers
    $timelineFile = Join-Path $evidenceFolder "threat-timeline.json"
    $timeline | ConvertTo-Json -Depth 20 | Out-File $timelineFile
    $chainOfCustody.Items += @{
        ItemId = "EVD-002"
        Description = "Threat Timeline/Storyline"
        FileName = "threat-timeline.json"
        CollectedAt = Get-Date -Format "yyyy-MM-ddTHH:mm:ssZ"
        SHA256 = (Get-FileHash $timelineFile -Algorithm SHA256).Hash
    }
    Write-Host "  Saved: threat-timeline.json" -ForegroundColor Green
 
    # 3. Collect agent details
    Write-Host "[3/5] Collecting endpoint details..." -ForegroundColor Yellow
    $agentId = $threat.data.agentRealtimeInfo.agentId
    $agent = Invoke-RestMethod -Uri "$ConsoleUrl/web/api/v2.1/agents?ids=$agentId" -Headers $headers
    $agentFile = Join-Path $evidenceFolder "endpoint-details.json"
    $agent | ConvertTo-Json -Depth 20 | Out-File $agentFile
    $chainOfCustody.Items += @{
        ItemId = "EVD-003"
        Description = "Endpoint Agent Details"
        FileName = "endpoint-details.json"
        CollectedAt = Get-Date -Format "yyyy-MM-ddTHH:mm:ssZ"
        SHA256 = (Get-FileHash $agentFile -Algorithm SHA256).Hash
    }
    Write-Host "  Saved: endpoint-details.json" -ForegroundColor Green
 
    # 4. Run Deep Visibility queries
    Write-Host "[4/5] Running Deep Visibility queries..." -ForegroundColor Yellow
    $endpoint = $threat.data.agentRealtimeInfo.computerName
    $sha256 = $threat.data.threatInfo.sha256
    $detectionTime = $threat.data.threatInfo.createdAt
 
    # Query for all activity around detection time
    $dvQueryBody = @{
        query = "EndpointName = `"$endpoint`" AND CreatedAt >= `"$detectionTime`""
        fromDate = $detectionTime
        toDate = (Get-Date).ToString("yyyy-MM-ddTHH:mm:ssZ")
        limit = 1000
    } | ConvertTo-Json
 
    try {
        $dvResults = Invoke-RestMethod -Uri "$ConsoleUrl/web/api/v2.1/dv/query" -Method POST -Headers $headers -Body $dvQueryBody
        $dvFile = Join-Path $evidenceFolder "deep-visibility-events.json"
        $dvResults | ConvertTo-Json -Depth 20 | Out-File $dvFile
        $chainOfCustody.Items += @{
            ItemId = "EVD-004"
            Description = "Deep Visibility Query Results"
            FileName = "deep-visibility-events.json"
            CollectedAt = Get-Date -Format "yyyy-MM-ddTHH:mm:ssZ"
            SHA256 = (Get-FileHash $dvFile -Algorithm SHA256).Hash
        }
        Write-Host "  Saved: deep-visibility-events.json" -ForegroundColor Green
    }
    catch {
        Write-Host "  WARNING: Deep Visibility query failed - $($_.Exception.Message)" -ForegroundColor Yellow
    }
 
    # 5. Generate summary report
    Write-Host "[5/5] Generating evidence summary..." -ForegroundColor Yellow
    $summary = @"
# Evidence Collection Summary
 
## Case Information
- **Threat ID:** $ThreatId
- **Collection Date:** $(Get-Date -Format "yyyy-MM-dd HH:mm:ss")
- **Collector:** $env:USERNAME
 
## Threat Summary
- **Name:** $($threat.data.threatInfo.threatName)
- **Classification:** $($threat.data.threatInfo.classification)
- **Confidence:** $($threat.data.threatInfo.confidenceLevel)
 
## Affected Endpoint
- **Computer:** $($threat.data.agentRealtimeInfo.computerName)
- **User:** $($threat.data.threatInfo.processUser)
 
## IOCs
- **SHA256:** $sha256
- **SHA1:** $($threat.data.threatInfo.sha1)
- **MD5:** $($threat.data.threatInfo.md5)
- **File Path:** $($threat.data.threatInfo.filePath)
 
## Collected Evidence
| Item ID | Description | SHA256 |
|---------|-------------|--------|
"@
 
    foreach ($item in $chainOfCustody.Items) {
        $summary += "| $($item.ItemId) | $($item.Description) | $($item.SHA256.Substring(0,16))... |`n"
    }
 
    $summaryFile = Join-Path $evidenceFolder "EVIDENCE-SUMMARY.md"
    $summary | Out-File $summaryFile
    Write-Host "  Saved: EVIDENCE-SUMMARY.md" -ForegroundColor Green
 
    # Save chain of custody
    $chainOfCustody.CollectionCompleted = Get-Date -Format "yyyy-MM-ddTHH:mm:ssZ"
    $cocFile = Join-Path $evidenceFolder "chain-of-custody.json"
    $chainOfCustody | ConvertTo-Json -Depth 10 | Out-File $cocFile
 
    Write-Host "`n[COLLECTION COMPLETE]" -ForegroundColor Green
    Write-Host "Evidence folder: $evidenceFolder"
    Write-Host "Items collected: $($chainOfCustody.Items.Count)"
}
catch {
    Write-Host "[ERROR] Collection failed: $($_.Exception.Message)" -ForegroundColor Red
    throw
}

5.2 Bulk Remediation Script

<#
.SYNOPSIS
    Bulk threat remediation across multiple endpoints
.DESCRIPTION
    Performs automated remediation actions on threats matching specified criteria
.PARAMETER Action
    Remediation action to perform
.PARAMETER Classification
    Threat classification to filter
.PARAMETER DaysBack
    Number of days to look back for threats
#>
 
[CmdletBinding()]
param(
    [Parameter(Mandatory=$true)]
    [ValidateSet('Kill','Quarantine','Remediate','Rollback','NetworkQuarantine')]
    [string]$Action,
 
    [Parameter(Mandatory=$false)]
    [ValidateSet('ransomware','trojan','malware','pua','cryptominer','all')]
    [string]$Classification = 'all',
 
    [int]$DaysBack = 1,
    [switch]$Resolved,
    [switch]$WhatIf,
 
    [Parameter(Mandatory=$true)]
    [string]$ApiToken,
 
    [Parameter(Mandatory=$true)]
    [string]$ConsoleUrl
)
 
$ErrorActionPreference = 'Stop'
$headers = @{
    "Authorization" = "ApiToken $ApiToken"
    "Content-Type" = "application/json"
}
 
Write-Host "=== SentinelOne Bulk Remediation ===" -ForegroundColor Cyan
Write-Host "Action: $Action"
Write-Host "Classification: $Classification"
Write-Host "Days Back: $DaysBack"
Write-Host "WhatIf Mode: $WhatIf`n"
 
# Build query
$dateFilter = (Get-Date).AddDays(-$DaysBack).ToString("yyyy-MM-ddT00:00:00Z")
$queryParams = "resolved=$($Resolved.ToString().ToLower())&createdAt__gte=$dateFilter"
 
if ($Classification -ne 'all') {
    $queryParams += "&classifications=$Classification"
}
 
$endpoint = "/web/api/v2.1/threats?$queryParams&limit=1000"
 
# Get threats
Write-Host "Querying threats..." -ForegroundColor Yellow
$threats = Invoke-RestMethod -Uri "$ConsoleUrl$endpoint" -Headers $headers
$threatCount = $threats.pagination.totalItems
 
if ($threatCount -eq 0) {
    Write-Host "No threats found matching criteria" -ForegroundColor Green
    exit 0
}
 
Write-Host "Found $threatCount threat(s)`n" -ForegroundColor Yellow
 
# Display threats
$threats.data | ForEach-Object {
    $status = if ($_.threatInfo.resolved) { "[RESOLVED]" } else { "[ACTIVE]" }
    Write-Host "  $status $($_.id): $($_.threatInfo.threatName) on $($_.agentRealtimeInfo.computerName)"
}
 
if ($WhatIf) {
    Write-Host "`n[WHATIF] Would perform $Action on $threatCount threat(s)" -ForegroundColor Yellow
    exit 0
}
 
# Confirm
$confirm = Read-Host "`nProceed with $Action on $threatCount threat(s)? (yes/no)"
if ($confirm -ne "yes") {
    Write-Host "Operation cancelled" -ForegroundColor Yellow
    exit 0
}
 
# Execute remediation
$threatIds = $threats.data | Select-Object -ExpandProperty id
$agentIds = $threats.data | Select-Object -ExpandProperty @{N="agentId";E={$_.agentRealtimeInfo.agentId}} -Unique
 
$results = @{
    Action = $Action
    StartTime = Get-Date -Format "yyyy-MM-ddTHH:mm:ssZ"
    ThreatCount = $threatCount
    Success = 0
    Failed = 0
    Details = @()
}
 
switch ($Action) {
    'Kill' {
        $body = @{data=@{ids=$threatIds}} | ConvertTo-Json
        $result = Invoke-RestMethod -Uri "$ConsoleUrl/web/api/v2.1/threats/actions/kill" -Method POST -Headers $headers -Body $body
        $results.Success = $result.data.affected
    }
    'Quarantine' {
        $body = @{data=@{ids=$threatIds}} | ConvertTo-Json
        $result = Invoke-RestMethod -Uri "$ConsoleUrl/web/api/v2.1/threats/actions/quarantine" -Method POST -Headers $headers -Body $body
        $results.Success = $result.data.affected
    }
    'Remediate' {
        $body = @{data=@{ids=$threatIds}} | ConvertTo-Json
        $result = Invoke-RestMethod -Uri "$ConsoleUrl/web/api/v2.1/threats/actions/remediate" -Method POST -Headers $headers -Body $body
        $results.Success = $result.data.affected
    }
    'Rollback' {
        $body = @{data=@{ids=$threatIds}} | ConvertTo-Json
        $result = Invoke-RestMethod -Uri "$ConsoleUrl/web/api/v2.1/threats/actions/rollback" -Method POST -Headers $headers -Body $body
        $results.Success = $result.data.affected
    }
    'NetworkQuarantine' {
        $body = @{data=@{ids=$agentIds}} | ConvertTo-Json
        $result = Invoke-RestMethod -Uri "$ConsoleUrl/web/api/v2.1/agents/actions/disconnect" -Method POST -Headers $headers -Body $body
        $results.Success = $result.data.affected
    }
}
 
$results.EndTime = Get-Date -Format "yyyy-MM-ddTHH:mm:ssZ"
$results.Failed = $threatCount - $results.Success
 
Write-Host "`n[REMEDIATION COMPLETE]" -ForegroundColor Green
Write-Host "Success: $($results.Success)"
Write-Host "Failed: $($results.Failed)"
 
# Save log
$logPath = "C:\BIN\LOGS\S1-BulkRemediation-$(Get-Date -Format 'yyyyMMdd-HHmmss').json"
$results | ConvertTo-Json -Depth 10 | Out-File $logPath
Write-Host "Log saved: $logPath"

5.3 Incident Report Generation Script

<#
.SYNOPSIS
    Generates comprehensive incident report from SentinelOne threat data
.DESCRIPTION
    Creates detailed incident documentation including timeline, IOCs, and MITRE mapping
#>
 
[CmdletBinding()]
param(
    [Parameter(Mandatory=$true)]
    [string]$ThreatId,
 
    [string]$IncidentId = "INC-$(Get-Date -Format 'yyyyMMdd')-001",
 
    [Parameter(Mandatory=$true)]
    [string]$ApiToken,
 
    [Parameter(Mandatory=$true)]
    [string]$ConsoleUrl,
 
    [string]$OutputPath = "C:\BIN\LOGS"
)
 
$headers = @{
    "Authorization" = "ApiToken $ApiToken"
    "Content-Type" = "application/json"
}
 
Write-Host "=== Generating Incident Report ===" -ForegroundColor Cyan
 
# Gather data
$threat = (Invoke-RestMethod -Uri "$ConsoleUrl/web/api/v2.1/threats/$ThreatId" -Headers $headers).data
$timeline = (Invoke-RestMethod -Uri "$ConsoleUrl/web/api/v2.1/threats/$ThreatId/timeline" -Headers $headers).data
 
# MITRE mapping based on classification
$mitreMapping = switch ($threat.threatInfo.classification) {
    'ransomware' { @("T1486 - Data Encrypted for Impact", "T1059 - Command and Scripting Interpreter") }
    'trojan'     { @("T1059 - Command and Scripting Interpreter", "T1071 - Application Layer Protocol") }
    'malware'    { @("T1059 - Command and Scripting Interpreter", "T1547 - Boot or Logon Autostart Execution") }
    default      { @("T1059 - Command and Scripting Interpreter") }
}
 
# Build report
$report = @"
# Incident Report: $IncidentId
 
## Executive Summary
 
| Field | Value |
|-------|-------|
| Incident ID | $IncidentId |
| SentinelOne Threat ID | $ThreatId |
| Report Generated | $(Get-Date -Format "yyyy-MM-dd HH:mm:ss UTC") |
| Analyst | $env:USERNAME |
| Status | $($threat.threatInfo.mitigationStatus) |
| Severity | $($threat.threatInfo.confidenceLevel) |
 
## Threat Classification
 
| Field | Value |
|-------|-------|
| Threat Name | $($threat.threatInfo.threatName) |
| Classification | $($threat.threatInfo.classification) |
| Confidence Level | $($threat.threatInfo.confidenceLevel) |
| Detection Engine | $($threat.threatInfo.detectionEngines -join ', ') |
| First Detected | $($threat.threatInfo.createdAt) |
| Mitigated At | $($threat.threatInfo.mitigatedAt) |
 
## Affected Endpoint
 
| Field | Value |
|-------|-------|
| Computer Name | $($threat.agentRealtimeInfo.computerName) |
| Domain | $($threat.agentRealtimeInfo.domain) |
| Operating System | $($threat.agentRealtimeInfo.osName) |
| Agent Version | $($threat.agentRealtimeInfo.agentVersion) |
| External IP | $($threat.agentRealtimeInfo.externalIp) |
| Affected User | $($threat.threatInfo.processUser) |
 
## Indicators of Compromise (IOCs)
 
### File Indicators
 
| Type | Value |
|------|-------|
| File Name | $($threat.threatInfo.originatorProcess) |
| File Path | $($threat.threatInfo.filePath) |
| SHA256 | ``$($threat.threatInfo.sha256)`` |
| SHA1 | ``$($threat.threatInfo.sha1)`` |
| MD5 | ``$($threat.threatInfo.md5)`` |
 
### Network Indicators
 
"@
 
# Add network IOCs from timeline
$networkEvents = $timeline | Where-Object { $_.eventType -match "Network|DNS|IP" }
if ($networkEvents) {
    $report += "| Destination | Port | Protocol |`n|------------|------|----------|`n"
    $networkEvents | Select-Object -First 10 | ForEach-Object {
        $report += "| $($_.dstIp) | $($_.dstPort) | $($_.protocol) |`n"
    }
} else {
    $report += "*No network indicators captured*`n"
}
 
$report += @"
 
## MITRE ATT&CK Mapping
 
"@
 
foreach ($technique in $mitreMapping) {
    $report += "- $technique`n"
}
 
$report += @"
 
## Attack Timeline
 
| Timestamp | Event Type | Process | Details |
|-----------|------------|---------|---------|
"@
 
$timeline | Select-Object -First 25 | ForEach-Object {
    $report += "| $($_.createdAt) | $($_.eventType) | $($_.processName) | $($_.processCmd.Substring(0, [Math]::Min(50, $_.processCmd.Length)))... |`n"
}
 
$report += @"
 
## Response Actions
 
| Action | Status | Timestamp |
|--------|--------|-----------|
| Kill Process | $($threat.threatInfo.mitigationStatus) | $($threat.threatInfo.mitigatedAt) |
| Quarantine File | $($threat.threatInfo.mitigationStatus) | $($threat.threatInfo.mitigatedAt) |
| Rollback | $($threat.threatInfo.rollbackStatus) | N/A |
| Network Quarantine | $($threat.agentRealtimeInfo.networkStatus) | N/A |
 
## Recommendations
 
1. **Immediate Actions:**
   - Verify complete remediation via Deep Visibility query
   - Reset credentials for affected user
   - Scan related endpoints for lateral movement
 
2. **Short-term Actions:**
   - Update email filtering rules for similar attacks
   - Create STAR rule for this attack pattern
   - Brief security team on attack technique
 
3. **Long-term Actions:**
   - Schedule security awareness training
   - Review and update detection policies
   - Add IOCs to threat intelligence platform
 
## Appendix
 
### Deep Visibility Query
``````sql
EndpointName = "$($threat.agentRealtimeInfo.computerName)" AND
SHA256 = "$($threat.threatInfo.sha256)"

Related Documentation

  • SentinelOne Threat Investigation Workflow
  • SentinelOne Forensics Rollback and Remediation

Report generated by SentinelOne Incident Report Automation "@

Save report

$fileName = "IncidentReport-$IncidentId-$(Get-Date -Format 'yyyyMMdd-HHmmss').md" $fullPath = Join-Path $OutputPath $fileName $report | Out-File $fullPath -Encoding UTF8

Write-Host "[COMPLETE] Report saved: $fullPath" -ForegroundColor Green


---

### 5.4 Rollback Status Monitoring Script

```powershell
<#
.SYNOPSIS
    Monitors rollback status for ransomware threats
.DESCRIPTION
    Tracks rollback progress and sends notifications on completion or failure
#>

[CmdletBinding()]
param(
    [Parameter(Mandatory=$true)]
    [string[]]$ThreatIds,

    [int]$PollIntervalSeconds = 30,
    [int]$TimeoutMinutes = 30,

    [Parameter(Mandatory=$true)]
    [string]$ApiToken,

    [Parameter(Mandatory=$true)]
    [string]$ConsoleUrl,

    [string]$NotificationWebhook  # Optional Teams/Slack webhook
)

$headers = @{
    "Authorization" = "ApiToken $ApiToken"
    "Content-Type" = "application/json"
}

Write-Host "=== SentinelOne Rollback Monitor ===" -ForegroundColor Cyan
Write-Host "Monitoring $($ThreatIds.Count) threat(s)"
Write-Host "Poll Interval: $PollIntervalSeconds seconds"
Write-Host "Timeout: $TimeoutMinutes minutes`n"

$startTime = Get-Date
$timeout = $startTime.AddMinutes($TimeoutMinutes)

$rollbackStatus = @{}
foreach ($id in $ThreatIds) {
    $rollbackStatus[$id] = @{
        Status = "pending"
        StartTime = $startTime
        EndTime = $null
        FilesRestored = 0
    }
}

function Send-Notification {
    param($Message, $Color = "good")

    if ($NotificationWebhook) {
        $body = @{
            text = $Message
            attachments = @(@{color = $Color})
        } | ConvertTo-Json

        try {
            Invoke-RestMethod -Uri $NotificationWebhook -Method POST -Body $body -ContentType "application/json"
        }
        catch {
            Write-Host "Failed to send notification: $($_.Exception.Message)" -ForegroundColor Yellow
        }
    }
}

$pending = $ThreatIds.Clone()

while ($pending.Count -gt 0 -and (Get-Date) -lt $timeout) {
    foreach ($threatId in $pending.Clone()) {
        try {
            $threat = (Invoke-RestMethod -Uri "$ConsoleUrl/web/api/v2.1/threats/$threatId" -Headers $headers).data
            $status = $threat.threatInfo.rollbackStatus

            $currentStatus = $rollbackStatus[$threatId]

            if ($status -ne $currentStatus.Status) {
                Write-Host "[$(Get-Date -Format 'HH:mm:ss')] Threat $threatId : $($currentStatus.Status) -> $status" -ForegroundColor Yellow

                $rollbackStatus[$threatId].Status = $status

                if ($status -eq "completed") {
                    $rollbackStatus[$threatId].EndTime = Get-Date
                    $duration = ($rollbackStatus[$threatId].EndTime - $rollbackStatus[$threatId].StartTime).TotalMinutes
                    Write-Host "  [SUCCESS] Rollback completed in $([math]::Round($duration,2)) minutes" -ForegroundColor Green
                    Send-Notification "Rollback completed for threat $threatId on $($threat.agentRealtimeInfo.computerName)" "good"
                    $pending = $pending | Where-Object { $_ -ne $threatId }
                }
                elseif ($status -eq "failed") {
                    $rollbackStatus[$threatId].EndTime = Get-Date
                    Write-Host "  [FAILED] Rollback failed - manual intervention required" -ForegroundColor Red
                    Send-Notification "Rollback FAILED for threat $threatId - manual intervention required" "danger"
                    $pending = $pending | Where-Object { $_ -ne $threatId }
                }
            }
        }
        catch {
            Write-Host "[ERROR] Failed to check threat $threatId : $($_.Exception.Message)" -ForegroundColor Red
        }
    }

    if ($pending.Count -gt 0) {
        Write-Host "[$(Get-Date -Format 'HH:mm:ss')] Waiting $PollIntervalSeconds seconds... ($($pending.Count) pending)" -ForegroundColor Gray
        Start-Sleep -Seconds $PollIntervalSeconds
    }
}

# Final summary
Write-Host "`n=== ROLLBACK MONITOR SUMMARY ===" -ForegroundColor Cyan

$completed = ($rollbackStatus.Values | Where-Object { $_.Status -eq "completed" }).Count
$failed = ($rollbackStatus.Values | Where-Object { $_.Status -eq "failed" }).Count
$pending = ($rollbackStatus.Values | Where-Object { $_.Status -notin @("completed", "failed") }).Count

Write-Host "Completed: $completed"
Write-Host "Failed: $failed"
Write-Host "Pending/Timeout: $pending"

if ($pending -gt 0) {
    Write-Host "`n[WARNING] Some rollbacks did not complete within timeout" -ForegroundColor Yellow
    Send-Notification "$pending rollback(s) did not complete within timeout - manual check required" "warning"
}

# Export results
$resultsPath = "C:\BIN\LOGS\RollbackMonitor-$(Get-Date -Format 'yyyyMMdd-HHmmss').json"
$rollbackStatus | ConvertTo-Json -Depth 5 | Out-File $resultsPath
Write-Host "`nResults saved: $resultsPath"

RELATED DOCUMENTATION

  • HOWTO- SentinelOne Control vs Complete Feature Comparison
  • HOWTO- SentinelOne Threat Investigation Workflow
  • HOWTO- SentinelOne Deep Visibility Threat Hunting
  • HOWTO- SentinelOne Remote Shell Operations
  • HOWTO- SentinelOne STAR Custom Detection Rules
  • HOWTO- SentinelOne PowerShell API Automation

SOURCES

  • SentinelOne Documentation Portal
  • SentinelOne API Documentation
  • MITRE ATT&CK Framework
  • NIST Computer Security Incident Handling Guide (SP 800-61)
  • SANS Incident Response Process

REVISION HISTORY

VersionDateAuthorChanges
1.02026-01-08CosmicBytezInitial creation

Related Reading

  • SentinelOne Control vs Complete Feature Comparison
  • SentinelOne Deep Visibility Threat Hunting
  • SentinelOne Threat Investigation Workflow
#sentinelone#edr#Security#threat-hunting#deployment#policy#automation#forensics#api#incident-response#mitre-attack#detection-rules#firewall

Related Articles

SentinelOne Control vs Complete Feature Comparison

This document provides a comprehensive comparison between SentinelOne Singularity Control and Singularity Complete SKUs to help MSP teams understand the...

17 min read

SentinelOne Deep Visibility Threat Hunting

Deep Visibility is SentinelOne's EDR telemetry engine that provides comprehensive endpoint data collection for threat hunting, incident investigation, and...

22 min read

SentinelOne Threat Investigation Workflow

When SentinelOne detects a threat on an endpoint, security analysts must quickly investigate the alert to determine if it's a genuine malware infection,...

21 min read
Back to all HOWTOs