SCENARIO
Full Remote Shell is a SentinelOne Complete feature that provides authorized administrators with secure, native command-line access to managed endpoints directly from the console. This capability enables rapid investigation, forensic collection, and remediation without physical access to the endpoint.
Use this guide when:
- Investigating active security incidents
- Collecting forensic artifacts from compromised endpoints
- Troubleshooting endpoint issues remotely
- Executing remediation actions during incident response
- Performing live triage on suspicious endpoints
- Collecting evidence for legal or compliance purposes
Prerequisites:
- SentinelOne Singularity Complete license
- Remote Shell enabled in endpoint policy
- Console access with IR Team or Admin role
- Two-factor authentication enabled on user account
- Target endpoint online and connected to console
Reference Documentation:
- SentinelOne Full Remote Shell
- Full Remote Shell Datasheet
- RemoteOps Script Library
- Remote Ops Scripts (GitHub)
REQUIREMENTS & ASSUMPTIONS
Technical Requirements
| Requirement | Details |
|---|---|
| SKU | Singularity Complete or higher |
| Agent Version | 3.0 or newer |
| Console Role | IR Team, SOC, or Admin |
| User MFA | Two-factor authentication required |
| Policy Setting | Remote Shell: Enabled |
| Endpoint Status | Online and connected |
Security Controls
SentinelOne implements multiple security layers for Remote Shell:
┌─────────────────────────────────────────────────────────────────────┐
│ REMOTE SHELL SECURITY LAYERS │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ 1. POLICY CONTROL Must be explicitly enabled per policy │
│ ↓ │
│ 2. ROLE-BASED ACCESS User must have appropriate console role │
│ ↓ │
│ 3. TWO-FACTOR AUTH MFA required before session start │
│ ↓ │
│ 4. SESSION PASSWORD Unique encryption password per session │
│ ↓ │
│ 5. AUDIT LOGGING Complete session recording and logging │
│ ↓ │
│ 6. SESSION TIMEOUT Automatic disconnect after inactivity │
│ │
└─────────────────────────────────────────────────────────────────────┘
Capabilities
What Remote Shell Can Do:
- Execute any native PowerShell command (Windows)
- Execute any native Bash/Zsh command (Linux/macOS)
- Navigate file systems
- View and manage processes
- Query network connections
- Access Windows Registry
- Collect forensic artifacts
- Execute scripts
- Install/uninstall applications
- Modify configurations
What Remote Shell Cannot Do:
- Bypass endpoint security controls
- Execute without audit logging
- Run without user authentication
- Access endpoints with disabled Remote Shell policy
- Connect to offline endpoints
POLICY CONFIGURATION
Enabling Remote Shell
Via Console:
- Navigate to Sentinels → Policy
- Select target policy (or create new)
- Go to Agent → Remote Shell section
- Configure settings:
Remote Shell Settings:
Enable Remote Shell: Yes
Require Password: Yes (Recommended)
Session Timeout: 30 minutes (Default)
Allow File Operations: Yes
Approval Required: Optional (for high-security environments)- Click Save Policy
Policy Recommendations by Endpoint Type
| Endpoint Type | Remote Shell | Approval Required | Session Timeout |
|---|---|---|---|
| Workstations | Disabled | N/A | N/A |
| Servers | Enabled | Optional | 30 min |
| Domain Controllers | Enabled | Yes | 15 min |
| Database Servers | Enabled | Yes | 15 min |
| Executive Workstations | Disabled | N/A | N/A |
| IT Admin Workstations | Enabled | No | 30 min |
| Jump Servers | Enabled | No | 60 min |
Approval Workflow (Optional)
For high-security environments, enable approval workflow:
- User requests Remote Shell access
- Designated approver receives notification
- Approver reviews request and approves/denies
- User receives approval notification
- User can initiate session
STARTING A REMOTE SHELL SESSION
Step-by-Step Process
-
Navigate to Endpoint
- Console → Sentinels → Endpoints
- Search for target endpoint
- Click endpoint name to open details
-
Verify Endpoint Status
- Status: Connected (green)
- Agent Version: 3.0+
- Policy: Remote Shell enabled
-
Initiate Remote Shell
- Click Actions dropdown
- Select Remote Shell
-
Complete MFA Challenge
- Enter 2FA code from authenticator app
- Click Verify
-
Set Session Password
- Enter unique session encryption password
- Password requirements: 8+ characters
- Click Connect
-
Wait for Connection
- Console establishes secure tunnel
- Shell prompt appears when ready
┌─────────────────────────────────────────────────────────────────────┐
│ Remote Shell - WORKSTATION-001 [Connected] │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ Windows PowerShell │
│ Copyright (C) Microsoft Corporation. All rights reserved. │
│ │
│ PS C:\Windows\system32> │
│ │
│ │
│ │
│ │
├─────────────────────────────────────────────────────────────────────┤
│ [Disconnect] Session Time: 00:05:23 Timeout: 24:37 │
└─────────────────────────────────────────────────────────────────────┘
Session Management
During Session:
- Command history available (up/down arrows)
- Tab completion supported
- Copy/paste enabled
- Session timer visible
- Manual disconnect available
Session Termination:
- Click Disconnect button
- Session timeout (automatic)
- Close browser tab (not recommended - leaves session orphaned)
- Agent disconnect (endpoint goes offline)
INVESTIGATION COMMANDS
Windows Investigation Commands
System Information
# Basic system information
Get-ComputerInfo | Select-Object CsName, WindowsVersion, OsArchitecture,
WindowsBuildLabEx, OsLastBootUpTime, CsUserName
# Detailed OS information
systeminfo
# Current user context
whoami /all
# Local users
Get-LocalUser | Select-Object Name, Enabled, LastLogon, PasswordLastSet
# Local administrators
Get-LocalGroupMember -Group "Administrators"
# Domain information (if domain-joined)
Get-ADDomain -ErrorAction SilentlyContinue
nltest /dsgetdc:
# Uptime
(Get-Date) - (Get-CimInstance Win32_OperatingSystem).LastBootUpTimeProcess Analysis
# All running processes with details
Get-Process | Select-Object Id, ProcessName, Path, StartTime, CPU,
@{N='Memory(MB)';E={[math]::Round($_.WorkingSet64/1MB,2)}} |
Sort-Object CPU -Descending | Format-Table -AutoSize
# Processes with command lines
Get-CimInstance Win32_Process | Select-Object ProcessId, Name, CommandLine |
Format-Table -AutoSize -Wrap
# Find suspicious processes (unsigned, unusual paths)
Get-Process | Where-Object {$_.Path -and $_.Path -notlike "C:\Windows\*" -and
$_.Path -notlike "C:\Program Files*"} |
Select-Object Id, ProcessName, Path
# Process tree (parent-child relationships)
Get-CimInstance Win32_Process | Select-Object ProcessId, ParentProcessId,
Name, CommandLine | Format-Table -AutoSize
# Specific process details
Get-Process -Name "suspicious" | Select-Object *
# Processes making network connections
Get-NetTCPConnection -State Established |
Select-Object LocalAddress, LocalPort, RemoteAddress, RemotePort,
@{N='Process';E={(Get-Process -Id $_.OwningProcess).ProcessName}},
OwningProcess | Format-Table -AutoSizeNetwork Analysis
# Active network connections
Get-NetTCPConnection -State Established |
Select-Object LocalAddress, LocalPort, RemoteAddress, RemotePort,
OwningProcess, @{N='Process';E={(Get-Process -Id $_.OwningProcess -ErrorAction SilentlyContinue).ProcessName}} |
Format-Table -AutoSize
# Listening ports
Get-NetTCPConnection -State Listen |
Select-Object LocalAddress, LocalPort, OwningProcess,
@{N='Process';E={(Get-Process -Id $_.OwningProcess).ProcessName}} |
Format-Table -AutoSize
# DNS cache
Get-DnsClientCache | Select-Object Entry, Data, TimeToLive |
Format-Table -AutoSize
# ARP table
Get-NetNeighbor | Where-Object {$_.State -eq "Reachable"} |
Select-Object IPAddress, LinkLayerAddress, InterfaceAlias
# Network configuration
Get-NetIPConfiguration | Select-Object InterfaceAlias, IPv4Address,
IPv4DefaultGateway, DNSServer
# Routing table
Get-NetRoute | Where-Object {$_.DestinationPrefix -ne "0.0.0.0/0"} |
Select-Object DestinationPrefix, NextHop, InterfaceAlias
# Firewall status
Get-NetFirewallProfile | Select-Object Name, Enabled
# Recent firewall blocks
Get-WinEvent -LogName "Microsoft-Windows-Windows Firewall With Advanced Security/Firewall" -MaxEvents 50 -ErrorAction SilentlyContinue |
Where-Object {$_.Id -eq 2004} | Select-Object TimeCreated, MessageFile System Analysis
# Recently modified files (last 24 hours)
Get-ChildItem -Path C:\Users -Recurse -File -ErrorAction SilentlyContinue |
Where-Object {$_.LastWriteTime -gt (Get-Date).AddDays(-1)} |
Select-Object FullName, LastWriteTime, Length |
Sort-Object LastWriteTime -Descending | Select-Object -First 50
# Files in suspicious locations
Get-ChildItem -Path "C:\Users\*\AppData\Local\Temp" -Recurse -File -ErrorAction SilentlyContinue |
Where-Object {$_.Extension -in ".exe",".dll",".ps1",".bat",".vbs",".js"} |
Select-Object FullName, LastWriteTime, Length
# Hidden files
Get-ChildItem -Path C:\ -Recurse -Hidden -File -ErrorAction SilentlyContinue |
Where-Object {$_.FullName -notlike "*\Windows\*"} |
Select-Object FullName, Attributes, LastWriteTime | Select-Object -First 50
# Alternate Data Streams
Get-ChildItem -Path C:\Users -Recurse -ErrorAction SilentlyContinue |
Get-Item -Stream * -ErrorAction SilentlyContinue |
Where-Object {$_.Stream -ne ':$DATA'} |
Select-Object FileName, Stream, Length
# Startup folder contents
Get-ChildItem "$env:ProgramData\Microsoft\Windows\Start Menu\Programs\Startup" -ErrorAction SilentlyContinue
Get-ChildItem "$env:APPDATA\Microsoft\Windows\Start Menu\Programs\Startup" -ErrorAction SilentlyContinue
# Downloads folder
Get-ChildItem "$env:USERPROFILE\Downloads" -Recurse -ErrorAction SilentlyContinue |
Select-Object Name, LastWriteTime, Length | Sort-Object LastWriteTime -Descending
# File hash calculation
Get-FileHash -Path "C:\path\to\suspicious\file.exe" -Algorithm SHA256Registry Analysis
# Run keys (persistence)
Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Run" -ErrorAction SilentlyContinue
Get-ItemProperty -Path "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Run" -ErrorAction SilentlyContinue
Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce" -ErrorAction SilentlyContinue
# Services
Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\*" -ErrorAction SilentlyContinue |
Where-Object {$_.ImagePath -and $_.ImagePath -notlike "*system32*"} |
Select-Object PSChildName, ImagePath, Start
# Winlogon (persistence)
Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" |
Select-Object Shell, Userinit
# Image File Execution Options (debugging hijack)
Get-ChildItem -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options" |
Where-Object {(Get-ItemProperty $_.PSPath).Debugger} |
Select-Object PSChildName, @{N='Debugger';E={(Get-ItemProperty $_.PSPath).Debugger}}
# AppInit DLLs
Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows" |
Select-Object AppInit_DLLs, LoadAppInit_DLLs
# Scheduled Tasks in registry
Get-ChildItem -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tasks" -ErrorAction SilentlyContinueScheduled Tasks
# All scheduled tasks
Get-ScheduledTask | Where-Object {$_.State -ne "Disabled"} |
Select-Object TaskName, TaskPath, State,
@{N='Actions';E={$_.Actions.Execute}} |
Format-Table -AutoSize -Wrap
# Detailed task information
Get-ScheduledTask | ForEach-Object {
$task = $_
$info = Get-ScheduledTaskInfo -TaskName $task.TaskName -TaskPath $task.TaskPath -ErrorAction SilentlyContinue
[PSCustomObject]@{
Name = $task.TaskName
Path = $task.TaskPath
State = $task.State
LastRun = $info.LastRunTime
NextRun = $info.NextRunTime
Action = ($task.Actions | Select-Object -First 1).Execute
}
} | Format-Table -AutoSize
# Suspicious scheduled tasks (non-Microsoft)
Get-ScheduledTask | Where-Object {$_.Author -notlike "*Microsoft*" -and $_.State -ne "Disabled"} |
Select-Object TaskName, Author, @{N='Action';E={$_.Actions.Execute}}Services
# All services
Get-Service | Select-Object Name, DisplayName, Status, StartType |
Sort-Object Status | Format-Table -AutoSize
# Running services with paths
Get-CimInstance Win32_Service | Where-Object {$_.State -eq "Running"} |
Select-Object Name, DisplayName, PathName, StartMode |
Format-Table -AutoSize -Wrap
# Services with unusual paths
Get-CimInstance Win32_Service |
Where-Object {$_.PathName -and $_.PathName -notlike "*system32*" -and
$_.PathName -notlike "*Program Files*"} |
Select-Object Name, PathName, State
# Recently created services
Get-WinEvent -FilterHashtable @{LogName='System';Id=7045} -MaxEvents 20 -ErrorAction SilentlyContinue |
Select-Object TimeCreated, @{N='ServiceName';E={$_.Properties[0].Value}},
@{N='ImagePath';E={$_.Properties[1].Value}}Event Log Analysis
# Failed logon attempts
Get-WinEvent -FilterHashtable @{LogName='Security';Id=4625} -MaxEvents 50 -ErrorAction SilentlyContinue |
Select-Object TimeCreated,
@{N='TargetUser';E={$_.Properties[5].Value}},
@{N='SourceIP';E={$_.Properties[19].Value}},
@{N='FailureReason';E={$_.Properties[8].Value}}
# Successful logons
Get-WinEvent -FilterHashtable @{LogName='Security';Id=4624} -MaxEvents 50 -ErrorAction SilentlyContinue |
Select-Object TimeCreated,
@{N='User';E={$_.Properties[5].Value}},
@{N='LogonType';E={$_.Properties[8].Value}},
@{N='SourceIP';E={$_.Properties[18].Value}}
# PowerShell execution
Get-WinEvent -FilterHashtable @{LogName='Microsoft-Windows-PowerShell/Operational';Id=4104} -MaxEvents 50 -ErrorAction SilentlyContinue |
Select-Object TimeCreated, @{N='ScriptBlock';E={$_.Properties[2].Value}} |
Format-Table -Wrap
# Process creation (requires audit policy)
Get-WinEvent -FilterHashtable @{LogName='Security';Id=4688} -MaxEvents 50 -ErrorAction SilentlyContinue |
Select-Object TimeCreated,
@{N='Process';E={$_.Properties[5].Value}},
@{N='CommandLine';E={$_.Properties[8].Value}}
# Account creation
Get-WinEvent -FilterHashtable @{LogName='Security';Id=4720} -MaxEvents 20 -ErrorAction SilentlyContinue |
Select-Object TimeCreated,
@{N='NewUser';E={$_.Properties[0].Value}},
@{N='CreatedBy';E={$_.Properties[4].Value}}
# Cleared event logs
Get-WinEvent -FilterHashtable @{LogName='Security';Id=1102} -ErrorAction SilentlyContinue |
Select-Object TimeCreated, @{N='ClearedBy';E={$_.Properties[1].Value}}User Activity
# Currently logged on users
query user
# User profiles
Get-CimInstance Win32_UserProfile |
Where-Object {$_.Special -eq $false} |
Select-Object LocalPath, LastUseTime, @{N='SID';E={$_.SID}}
# Recent RDP sessions
Get-WinEvent -FilterHashtable @{LogName='Microsoft-Windows-TerminalServices-LocalSessionManager/Operational';Id=21,25} -MaxEvents 20 -ErrorAction SilentlyContinue |
Select-Object TimeCreated, @{N='User';E={$_.Properties[0].Value}},
@{N='SourceIP';E={$_.Properties[2].Value}}, Id
# Browser history (Chrome)
$historyPath = "$env:LOCALAPPDATA\Google\Chrome\User Data\Default\History"
if (Test-Path $historyPath) {
Write-Host "Chrome history file exists at: $historyPath"
# Note: File is locked when Chrome is running
}
# Recent documents
Get-ChildItem "$env:APPDATA\Microsoft\Windows\Recent" -ErrorAction SilentlyContinue |
Select-Object Name, LastWriteTime | Sort-Object LastWriteTime -Descending | Select-Object -First 20Linux/macOS Investigation Commands
System Information
# System information
uname -a
hostnamectl
# OS details
cat /etc/os-release
# Uptime
uptime
# Current user
whoami
id
# All users
cat /etc/passwd | grep -v nologin | grep -v false
# Sudo users
grep -Po '^sudo.+:\K.*$' /etc/group
cat /etc/sudoers 2>/dev/null | grep -v "^#" | grep -v "^$"
# Last logins
last -n 20
# Currently logged in
w
whoProcess Analysis
# All processes with details
ps auxf
# Process tree
pstree -p
# Processes with network connections
netstat -tulpn 2>/dev/null || ss -tulpn
# Find processes by name
ps aux | grep -i "suspicious"
# Process details
ls -la /proc/[PID]/
cat /proc/[PID]/cmdline
cat /proc/[PID]/environ
# Open files by process
lsof -p [PID]
# Deleted but running files
ls -la /proc/*/exe 2>/dev/null | grep deletedNetwork Analysis
# Active connections
netstat -tulpn 2>/dev/null || ss -tulpn
# Established connections
netstat -an | grep ESTABLISHED || ss -an | grep ESTAB
# Routing table
route -n || ip route
# DNS configuration
cat /etc/resolv.conf
# Hosts file
cat /etc/hosts
# ARP cache
arp -a || ip neigh
# Firewall rules (iptables)
iptables -L -n 2>/dev/null
# Firewall rules (firewalld)
firewall-cmd --list-all 2>/dev/nullFile System Analysis
# Recently modified files
find / -type f -mtime -1 2>/dev/null | head -100
# Files in /tmp
ls -la /tmp /var/tmp
# Hidden files in home directories
find /home -name ".*" -type f 2>/dev/null
# SUID/SGID files
find / -type f \( -perm -4000 -o -perm -2000 \) 2>/dev/null
# World-writable files
find / -type f -perm -0002 2>/dev/null | head -50
# Large files
find / -type f -size +100M 2>/dev/null
# File hash
sha256sum /path/to/file
# Immutable files
lsattr -R / 2>/dev/null | grep "\-i\-"Persistence Mechanisms
# Cron jobs
cat /etc/crontab
ls -la /etc/cron.*
crontab -l
for user in $(cut -f1 -d: /etc/passwd); do echo "=== $user ==="; crontab -u $user -l 2>/dev/null; done
# Systemd services
systemctl list-unit-files --type=service | grep enabled
ls -la /etc/systemd/system/
# Init.d scripts
ls -la /etc/init.d/
# RC scripts
ls -la /etc/rc.local 2>/dev/null
cat /etc/rc.local 2>/dev/null
# Bash profiles
cat /etc/profile
cat /etc/bash.bashrc
cat ~/.bashrc
cat ~/.bash_profile
# SSH authorized keys
find / -name "authorized_keys" 2>/dev/null
cat ~/.ssh/authorized_keys 2>/dev/nullLog Analysis
# Authentication logs
cat /var/log/auth.log | tail -100 # Debian/Ubuntu
cat /var/log/secure | tail -100 # RHEL/CentOS
# System logs
cat /var/log/syslog | tail -100 # Debian/Ubuntu
cat /var/log/messages | tail -100 # RHEL/CentOS
# Failed logins
grep "Failed password" /var/log/auth.log | tail -50
grep "Failed password" /var/log/secure | tail -50
# Successful logins
grep "Accepted" /var/log/auth.log | tail -50
# Command history
cat ~/.bash_history
cat /root/.bash_history 2>/dev/null
# Kernel messages
dmesg | tail -50FORENSIC ARTIFACT COLLECTION
Windows Forensic Collection Script
<#
.SYNOPSIS
Forensic artifact collection via SentinelOne Remote Shell
.DESCRIPTION
Collects critical forensic artifacts for incident investigation
.NOTES
Run in SentinelOne Remote Shell session
#>
$CollectionPath = "C:\ForensicCollection_$(Get-Date -Format 'yyyyMMdd_HHmmss')"
New-Item -Path $CollectionPath -ItemType Directory -Force | Out-Null
Write-Host "=== Starting Forensic Collection ===" -ForegroundColor Cyan
Write-Host "Output Path: $CollectionPath"
# System Information
Write-Host "`n[1/10] Collecting System Information..." -ForegroundColor Yellow
systeminfo > "$CollectionPath\systeminfo.txt"
Get-ComputerInfo | Out-File "$CollectionPath\computerinfo.txt"
# Running Processes
Write-Host "[2/10] Collecting Process Information..." -ForegroundColor Yellow
Get-Process | Select-Object Id, ProcessName, Path, StartTime, CPU |
Export-Csv "$CollectionPath\processes.csv" -NoTypeInformation
Get-CimInstance Win32_Process | Select-Object ProcessId, Name, CommandLine, ParentProcessId |
Export-Csv "$CollectionPath\process_cmdlines.csv" -NoTypeInformation
# Network Connections
Write-Host "[3/10] Collecting Network Information..." -ForegroundColor Yellow
Get-NetTCPConnection | Export-Csv "$CollectionPath\tcp_connections.csv" -NoTypeInformation
Get-NetUDPEndpoint | Export-Csv "$CollectionPath\udp_endpoints.csv" -NoTypeInformation
Get-DnsClientCache | Export-Csv "$CollectionPath\dns_cache.csv" -NoTypeInformation
ipconfig /all > "$CollectionPath\ipconfig.txt"
netstat -anob > "$CollectionPath\netstat.txt"
# Services
Write-Host "[4/10] Collecting Service Information..." -ForegroundColor Yellow
Get-CimInstance Win32_Service |
Select-Object Name, DisplayName, State, StartMode, PathName |
Export-Csv "$CollectionPath\services.csv" -NoTypeInformation
# Scheduled Tasks
Write-Host "[5/10] Collecting Scheduled Tasks..." -ForegroundColor Yellow
Get-ScheduledTask | ForEach-Object {
[PSCustomObject]@{
Name = $_.TaskName
Path = $_.TaskPath
State = $_.State
Author = $_.Author
Action = ($_.Actions | ForEach-Object { $_.Execute }) -join "; "
}
} | Export-Csv "$CollectionPath\scheduled_tasks.csv" -NoTypeInformation
# Startup Items
Write-Host "[6/10] Collecting Startup Items..." -ForegroundColor Yellow
Get-CimInstance Win32_StartupCommand |
Select-Object Name, Command, Location, User |
Export-Csv "$CollectionPath\startup_items.csv" -NoTypeInformation
# Registry Persistence
Write-Host "[7/10] Collecting Registry Persistence Keys..." -ForegroundColor Yellow
$regOutput = @()
$persistenceKeys = @(
"HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Run",
"HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce",
"HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Run",
"HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce",
"HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon"
)
foreach ($key in $persistenceKeys) {
if (Test-Path $key) {
$props = Get-ItemProperty -Path $key -ErrorAction SilentlyContinue
$props.PSObject.Properties | Where-Object {$_.Name -notlike "PS*"} | ForEach-Object {
$regOutput += [PSCustomObject]@{
Key = $key
Name = $_.Name
Value = $_.Value
}
}
}
}
$regOutput | Export-Csv "$CollectionPath\registry_persistence.csv" -NoTypeInformation
# User Information
Write-Host "[8/10] Collecting User Information..." -ForegroundColor Yellow
Get-LocalUser | Export-Csv "$CollectionPath\local_users.csv" -NoTypeInformation
Get-LocalGroupMember -Group "Administrators" -ErrorAction SilentlyContinue |
Export-Csv "$CollectionPath\local_admins.csv" -NoTypeInformation
query user > "$CollectionPath\logged_on_users.txt" 2>&1
# Recent Files
Write-Host "[9/10] Collecting Recent File Activity..." -ForegroundColor Yellow
Get-ChildItem -Path "C:\Users" -Recurse -File -ErrorAction SilentlyContinue |
Where-Object {$_.LastWriteTime -gt (Get-Date).AddDays(-7)} |
Select-Object FullName, LastWriteTime, Length,
@{N='Owner';E={(Get-Acl $_.FullName -ErrorAction SilentlyContinue).Owner}} |
Sort-Object LastWriteTime -Descending |
Select-Object -First 500 |
Export-Csv "$CollectionPath\recent_files.csv" -NoTypeInformation
# Event Logs (Export as EVTX)
Write-Host "[10/10] Collecting Event Logs..." -ForegroundColor Yellow
$logPath = "$CollectionPath\EventLogs"
New-Item -Path $logPath -ItemType Directory -Force | Out-Null
$logs = @("Security", "System", "Application", "Microsoft-Windows-PowerShell/Operational")
foreach ($log in $logs) {
$safeName = $log -replace "[/\\]", "_"
try {
wevtutil epl $log "$logPath\$safeName.evtx" 2>$null
Write-Host " - Exported: $log" -ForegroundColor Green
} catch {
Write-Host " - Failed: $log" -ForegroundColor Red
}
}
# Create summary
Write-Host "`n=== Collection Complete ===" -ForegroundColor Cyan
$summary = @"
Forensic Collection Summary
===========================
Date: $(Get-Date)
Computer: $env:COMPUTERNAME
User: $env:USERNAME
Collection Path: $CollectionPath
Files Collected:
$(Get-ChildItem $CollectionPath -Recurse | Measure-Object | Select-Object -ExpandProperty Count) files
Total Size: $([math]::Round((Get-ChildItem $CollectionPath -Recurse | Measure-Object -Property Length -Sum).Sum / 1MB, 2)) MB
"@
$summary | Out-File "$CollectionPath\COLLECTION_SUMMARY.txt"
Write-Host $summary
Write-Host "`nUse SentinelOne File Fetch to retrieve: $CollectionPath" -ForegroundColor YellowLinux Forensic Collection Script
#!/bin/bash
# Linux Forensic Collection Script for SentinelOne Remote Shell
COLLECTION_DIR="/tmp/forensic_collection_$(date +%Y%m%d_%H%M%S)"
mkdir -p "$COLLECTION_DIR"
echo "=== Starting Linux Forensic Collection ==="
echo "Output Path: $COLLECTION_DIR"
# System Information
echo "[1/8] Collecting System Information..."
uname -a > "$COLLECTION_DIR/uname.txt"
cat /etc/os-release > "$COLLECTION_DIR/os-release.txt"
uptime > "$COLLECTION_DIR/uptime.txt"
df -h > "$COLLECTION_DIR/disk_usage.txt"
free -m > "$COLLECTION_DIR/memory.txt"
# Users and Groups
echo "[2/8] Collecting User Information..."
cat /etc/passwd > "$COLLECTION_DIR/passwd.txt"
cat /etc/group > "$COLLECTION_DIR/group.txt"
cat /etc/shadow > "$COLLECTION_DIR/shadow.txt" 2>/dev/null
last -n 100 > "$COLLECTION_DIR/last_logins.txt"
w > "$COLLECTION_DIR/current_users.txt"
# Processes
echo "[3/8] Collecting Process Information..."
ps auxf > "$COLLECTION_DIR/processes.txt"
pstree -p > "$COLLECTION_DIR/process_tree.txt"
# Network
echo "[4/8] Collecting Network Information..."
netstat -tulpn > "$COLLECTION_DIR/netstat.txt" 2>/dev/null || ss -tulpn > "$COLLECTION_DIR/ss.txt"
netstat -an > "$COLLECTION_DIR/all_connections.txt" 2>/dev/null || ss -an > "$COLLECTION_DIR/all_connections.txt"
cat /etc/resolv.conf > "$COLLECTION_DIR/dns.txt"
cat /etc/hosts > "$COLLECTION_DIR/hosts.txt"
ip addr > "$COLLECTION_DIR/ip_addr.txt"
ip route > "$COLLECTION_DIR/routes.txt"
arp -a > "$COLLECTION_DIR/arp.txt" 2>/dev/null || ip neigh > "$COLLECTION_DIR/arp.txt"
# Persistence
echo "[5/8] Collecting Persistence Mechanisms..."
mkdir -p "$COLLECTION_DIR/cron"
cp /etc/crontab "$COLLECTION_DIR/cron/" 2>/dev/null
cp -r /etc/cron.* "$COLLECTION_DIR/cron/" 2>/dev/null
for user in $(cut -f1 -d: /etc/passwd); do
crontab -u $user -l > "$COLLECTION_DIR/cron/crontab_$user.txt" 2>/dev/null
done
mkdir -p "$COLLECTION_DIR/systemd"
systemctl list-unit-files --type=service > "$COLLECTION_DIR/systemd/services.txt"
cp /etc/systemd/system/*.service "$COLLECTION_DIR/systemd/" 2>/dev/null
# SSH
echo "[6/8] Collecting SSH Information..."
mkdir -p "$COLLECTION_DIR/ssh"
find /home -name "authorized_keys" -exec cp {} "$COLLECTION_DIR/ssh/" \; 2>/dev/null
cp /root/.ssh/authorized_keys "$COLLECTION_DIR/ssh/root_authorized_keys" 2>/dev/null
cp /etc/ssh/sshd_config "$COLLECTION_DIR/ssh/" 2>/dev/null
# Logs
echo "[7/8] Collecting Log Files..."
mkdir -p "$COLLECTION_DIR/logs"
cp /var/log/auth.log* "$COLLECTION_DIR/logs/" 2>/dev/null
cp /var/log/secure* "$COLLECTION_DIR/logs/" 2>/dev/null
cp /var/log/syslog* "$COLLECTION_DIR/logs/" 2>/dev/null
cp /var/log/messages* "$COLLECTION_DIR/logs/" 2>/dev/null
# History
echo "[8/8] Collecting Command History..."
mkdir -p "$COLLECTION_DIR/history"
for user_home in /home/*; do
username=$(basename "$user_home")
cp "$user_home/.bash_history" "$COLLECTION_DIR/history/${username}_bash_history" 2>/dev/null
done
cp /root/.bash_history "$COLLECTION_DIR/history/root_bash_history" 2>/dev/null
# Create archive
echo "Creating archive..."
cd /tmp
tar -czf "forensic_collection.tar.gz" "$(basename $COLLECTION_DIR)"
echo ""
echo "=== Collection Complete ==="
echo "Archive: /tmp/forensic_collection.tar.gz"
echo "Use SentinelOne File Fetch to retrieve this file"REMEDIATION COMMANDS
Process Termination
# Kill process by name
Stop-Process -Name "malware" -Force
# Kill process by PID
Stop-Process -Id 1234 -Force
# Kill process and children
Get-CimInstance Win32_Process | Where-Object {$_.ParentProcessId -eq 1234} |
ForEach-Object { Stop-Process -Id $_.ProcessId -Force }
Stop-Process -Id 1234 -Force
# Kill all instances of a process
Get-Process -Name "malware" | Stop-Process -ForceFile Removal
# Remove malicious file
Remove-Item -Path "C:\path\to\malware.exe" -Force
# Remove directory and contents
Remove-Item -Path "C:\malware\directory" -Recurse -Force
# Remove hidden file
Remove-Item -Path "C:\path\to\hidden.exe" -Force -Hidden
# Securely delete (overwrite)
$path = "C:\path\to\sensitive\file.exe"
$bytes = [System.IO.File]::ReadAllBytes($path)
$random = New-Object System.Random
$random.NextBytes($bytes)
[System.IO.File]::WriteAllBytes($path, $bytes)
Remove-Item -Path $path -ForcePersistence Removal
# Remove Run key entry
Remove-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Run" -Name "MalwareEntry" -Force
Remove-ItemProperty -Path "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Run" -Name "MalwareEntry" -Force
# Remove scheduled task
Unregister-ScheduledTask -TaskName "MaliciousTask" -Confirm:$false
# Remove service
Stop-Service -Name "MaliciousService" -Force
sc.exe delete "MaliciousService"
# Remove startup shortcut
Remove-Item "$env:APPDATA\Microsoft\Windows\Start Menu\Programs\Startup\malware.lnk" -ForceAccount Management
# Disable suspicious account
Disable-LocalUser -Name "SuspiciousUser"
# Remove account from Administrators
Remove-LocalGroupMember -Group "Administrators" -Member "SuspiciousUser"
# Force password reset
Set-LocalUser -Name "CompromisedUser" -Password (ConvertTo-SecureString "TempP@ssw0rd!" -AsPlainText -Force)
Set-LocalUser -Name "CompromisedUser" -PasswordNeverExpires $false
# Delete malicious account
Remove-LocalUser -Name "MaliciousUser"Network Remediation
# Block outbound connection (firewall)
New-NetFirewallRule -DisplayName "Block C2 Server" -Direction Outbound -RemoteAddress "192.168.100.100" -Action Block
# Block executable from network access
New-NetFirewallRule -DisplayName "Block Malware Network" -Direction Outbound -Program "C:\path\to\malware.exe" -Action Block
# Clear DNS cache
Clear-DnsClientCache
# Flush ARP cache
netsh interface ip delete arpcacheREMOTEOPS SCRIPT ORCHESTRATION
Overview
RemoteOps (Remote Script Orchestration - RSO) extends Remote Shell by allowing execution of pre-built or custom scripts across multiple endpoints simultaneously.
Using RemoteOps
- Navigate to Sentinels → RemoteOps
- Select Script Library or upload custom script
- Select target endpoints (up to hundreds)
- Configure execution parameters
- Execute and monitor results
Built-in Script Categories
| Category | Examples |
|---|---|
| Forensic Collection | $MFT collection, Prefetch, Event Logs |
| System Information | Installed software, Hardware inventory |
| Network | Connection audit, DNS cache, Firewall rules |
| User Activity | Login history, Browser artifacts |
| Malware Hunting | IOC search, Hash validation |
| Remediation | Process kill, File removal, Service disable |
Custom Script Upload
# Example: Custom IOC search script
param(
[string]$HashList = "hash1,hash2,hash3"
)
$hashes = $HashList -split ","
$results = @()
foreach ($hash in $hashes) {
$files = Get-ChildItem -Path C:\ -Recurse -File -ErrorAction SilentlyContinue |
Where-Object { (Get-FileHash $_.FullName -Algorithm SHA256 -ErrorAction SilentlyContinue).Hash -eq $hash }
if ($files) {
$results += $files | Select-Object FullName, LastWriteTime, Length
}
}
if ($results) {
Write-Output "IOC FOUND:"
$results | Format-Table -AutoSize
} else {
Write-Output "No IOCs detected"
}BEST PRACTICES
Security Guidelines
Remote Shell Security Best Practices:
Policy Configuration:
- Enable only on endpoints requiring investigation capability
- Disable on standard user workstations
- Enable approval workflow for critical systems
- Set appropriate session timeouts
User Access:
- Limit Remote Shell to IR Team and senior admins
- Require MFA for all users
- Use unique session passwords
- Review access permissions regularly
Session Conduct:
- Document purpose before starting session
- Take screenshots of key findings
- Copy/paste commands to investigation notes
- End sessions promptly when complete
Audit and Compliance:
- Review session logs regularly
- Investigate unusual access patterns
- Export audit logs for compliance
- Include in security reviewsInvestigation Workflow
┌─────────────────────────────────────────────────────────────────────┐
│ REMOTE SHELL INVESTIGATION WORKFLOW │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ 1. DOCUMENT Record purpose, ticket #, authorization │
│ ↓ │
│ 2. CONNECT Initiate session with MFA and password │
│ ↓ │
│ 3. TRIAGE Quick system/process/network review │
│ ↓ │
│ 4. INVESTIGATE Deep dive into suspicious findings │
│ ↓ │
│ 5. COLLECT Gather forensic artifacts │
│ ↓ │
│ 6. REMEDIATE Remove threats (if authorized) │
│ ↓ │
│ 7. VERIFY Confirm remediation success │
│ ↓ │
│ 8. DOCUMENT Record findings and actions taken │
│ ↓ │
│ 9. DISCONNECT End session properly │
│ │
└─────────────────────────────────────────────────────────────────────┘
Investigation Checklist
## Remote Shell Investigation Checklist
### Pre-Session
- [ ] Ticket/case number documented
- [ ] Authorization obtained (if required)
- [ ] Investigation purpose defined
- [ ] Target endpoint identified and online
### Initial Triage (5 minutes)
- [ ] System information collected
- [ ] Current processes reviewed
- [ ] Network connections checked
- [ ] Logged-on users identified
- [ ] Obvious anomalies noted
### Deep Investigation (as needed)
- [ ] Suspicious processes analyzed
- [ ] Persistence mechanisms reviewed
- [ ] File system anomalies checked
- [ ] Event logs reviewed
- [ ] User activity examined
- [ ] Registry examined (Windows)
### Evidence Collection
- [ ] Relevant artifacts collected
- [ ] File hashes calculated
- [ ] Screenshots captured
- [ ] Commands documented
### Remediation (if authorized)
- [ ] Malicious processes terminated
- [ ] Persistence removed
- [ ] Malicious files removed
- [ ] Accounts disabled/removed
- [ ] Firewall rules added
### Post-Session
- [ ] Findings documented
- [ ] Evidence preserved
- [ ] Session ended properly
- [ ] Case notes updated
- [ ] Escalation completed (if needed)AUDIT AND COMPLIANCE
Session Logging
All Remote Shell sessions are automatically logged:
- Session start/end times
- User who initiated session
- Target endpoint
- All commands executed
- Session duration
Viewing Session History
- Navigate to Activity → Activity Log
- Filter: Activity Type = "Remote Shell"
- Review session details
Exporting Audit Logs
# Via API - Export Remote Shell audit logs
function Export-S1RemoteShellAudit {
param(
[string]$ApiToken,
[string]$ConsoleUrl,
[datetime]$StartDate = (Get-Date).AddDays(-30),
[datetime]$EndDate = (Get-Date),
[string]$OutputPath = ".\remote_shell_audit.csv"
)
$headers = @{
"Authorization" = "ApiToken $ApiToken"
"Content-Type" = "application/json"
}
$startDateStr = $StartDate.ToString("yyyy-MM-ddTHH:mm:ss.fffZ")
$endDateStr = $EndDate.ToString("yyyy-MM-ddTHH:mm:ss.fffZ")
$url = "$ConsoleUrl/web/api/v2.1/activities?activityTypes=4100&createdAt__gte=$startDateStr&createdAt__lte=$endDateStr&limit=1000"
$response = Invoke-RestMethod -Uri $url -Method GET -Headers $headers
$response.data | Select-Object createdAt,
@{N='User';E={$_.accountName}},
@{N='Endpoint';E={$_.primaryDescription}},
@{N='Action';E={$_.activityType}},
@{N='Details';E={$_.data | ConvertTo-Json -Compress}} |
Export-Csv -Path $OutputPath -NoTypeInformation
Write-Host "Exported $($response.data.Count) audit records to $OutputPath"
}TROUBLESHOOTING
Common Issues
Issue: Remote Shell option not available
- Verify Complete SKU license
- Check policy has Remote Shell enabled
- Confirm user has appropriate role (IR Team/Admin)
- Verify endpoint is online and connected
Issue: Session fails to connect
- Verify endpoint agent is running
- Check network connectivity between console and endpoint
- Confirm MFA is enabled on user account
- Try refreshing endpoint status
Issue: Commands not executing
- Check for typos in commands
- Verify proper PowerShell/Bash syntax
- Some commands require elevated privileges
- Check if endpoint has restricted execution policy
Issue: Session disconnects unexpectedly
- Session timeout reached (reconnect)
- Endpoint went offline
- Network interruption
- Browser/tab closed
Issue: Cannot execute certain commands
- Some commands blocked by endpoint security
- Execution policy restrictions
- Insufficient permissions
- Antivirus interference
Session Recovery
If disconnected unexpectedly:
- Return to endpoint in console
- Verify endpoint still online
- Initiate new Remote Shell session
- Complete MFA and password
- Continue investigation
Note: Previous session commands are not preserved; maintain your own command log.
RELATED DOCUMENTATION
- HOWTO- SentinelOne Deep Visibility Threat Hunting
- HOWTO- SentinelOne STAR Custom Detection Rules
- HOWTO- SentinelOne Forensics and Rollback (planned)
- HOWTO- SentinelOne Threat Investigation Workflow
SOURCES
- SentinelOne Full Remote Shell
- Full Remote Shell Datasheet
- RemoteOps Custom Script Actions
- Remote Script Orchestration
- SentinelOne Remote Ops Scripts (GitHub)
REVISION HISTORY
| Version | Date | Author | Changes |
|---|---|---|---|
| 1.0 | 2026-01-08 | CosmicBytez | Initial creation |