nox-openclaw-hunter 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +140 -0
- package/bin/nox.js +2 -0
- package/dist/branding.d.ts +39 -0
- package/dist/branding.d.ts.map +1 -0
- package/dist/branding.js +66 -0
- package/dist/branding.js.map +1 -0
- package/dist/cli.d.ts +15 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +94 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/export.d.ts +21 -0
- package/dist/commands/export.d.ts.map +1 -0
- package/dist/commands/export.js +616 -0
- package/dist/commands/export.js.map +1 -0
- package/dist/commands/index.d.ts +8 -0
- package/dist/commands/index.d.ts.map +1 -0
- package/dist/commands/index.js +8 -0
- package/dist/commands/index.js.map +1 -0
- package/dist/commands/isolate.d.ts +30 -0
- package/dist/commands/isolate.d.ts.map +1 -0
- package/dist/commands/isolate.js +547 -0
- package/dist/commands/isolate.js.map +1 -0
- package/dist/commands/purge.d.ts +22 -0
- package/dist/commands/purge.d.ts.map +1 -0
- package/dist/commands/purge.js +295 -0
- package/dist/commands/purge.js.map +1 -0
- package/dist/commands/scan.d.ts +23 -0
- package/dist/commands/scan.d.ts.map +1 -0
- package/dist/commands/scan.js +155 -0
- package/dist/commands/scan.js.map +1 -0
- package/dist/detector/app-bundle.d.ts +13 -0
- package/dist/detector/app-bundle.d.ts.map +1 -0
- package/dist/detector/app-bundle.js +27 -0
- package/dist/detector/app-bundle.js.map +1 -0
- package/dist/detector/cli-binary.d.ts +12 -0
- package/dist/detector/cli-binary.d.ts.map +1 -0
- package/dist/detector/cli-binary.js +66 -0
- package/dist/detector/cli-binary.js.map +1 -0
- package/dist/detector/config.d.ts +21 -0
- package/dist/detector/config.d.ts.map +1 -0
- package/dist/detector/config.js +337 -0
- package/dist/detector/config.js.map +1 -0
- package/dist/detector/detection-config.d.ts +24 -0
- package/dist/detector/detection-config.d.ts.map +1 -0
- package/dist/detector/detection-config.js +242 -0
- package/dist/detector/detection-config.js.map +1 -0
- package/dist/detector/docker.d.ts +10 -0
- package/dist/detector/docker.d.ts.map +1 -0
- package/dist/detector/docker.js +94 -0
- package/dist/detector/docker.js.map +1 -0
- package/dist/detector/index.d.ts +50 -0
- package/dist/detector/index.d.ts.map +1 -0
- package/dist/detector/index.js +155 -0
- package/dist/detector/index.js.map +1 -0
- package/dist/detector/network.d.ts +34 -0
- package/dist/detector/network.d.ts.map +1 -0
- package/dist/detector/network.js +205 -0
- package/dist/detector/network.js.map +1 -0
- package/dist/detector/process.d.ts +16 -0
- package/dist/detector/process.d.ts.map +1 -0
- package/dist/detector/process.js +47 -0
- package/dist/detector/process.js.map +1 -0
- package/dist/detector/service.d.ts +17 -0
- package/dist/detector/service.d.ts.map +1 -0
- package/dist/detector/service.js +51 -0
- package/dist/detector/service.js.map +1 -0
- package/dist/enforcer/docker-cleaner.d.ts +30 -0
- package/dist/enforcer/docker-cleaner.d.ts.map +1 -0
- package/dist/enforcer/docker-cleaner.js +163 -0
- package/dist/enforcer/docker-cleaner.js.map +1 -0
- package/dist/enforcer/file-remover.d.ts +34 -0
- package/dist/enforcer/file-remover.d.ts.map +1 -0
- package/dist/enforcer/file-remover.js +137 -0
- package/dist/enforcer/file-remover.js.map +1 -0
- package/dist/enforcer/index.d.ts +33 -0
- package/dist/enforcer/index.d.ts.map +1 -0
- package/dist/enforcer/index.js +142 -0
- package/dist/enforcer/index.js.map +1 -0
- package/dist/enforcer/process-killer.d.ts +18 -0
- package/dist/enforcer/process-killer.d.ts.map +1 -0
- package/dist/enforcer/process-killer.js +80 -0
- package/dist/enforcer/process-killer.js.map +1 -0
- package/dist/enforcer/service-stopper.d.ts +23 -0
- package/dist/enforcer/service-stopper.d.ts.map +1 -0
- package/dist/enforcer/service-stopper.js +95 -0
- package/dist/enforcer/service-stopper.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -0
- package/dist/isolator/firewall.d.ts +25 -0
- package/dist/isolator/firewall.d.ts.map +1 -0
- package/dist/isolator/firewall.js +114 -0
- package/dist/isolator/firewall.js.map +1 -0
- package/dist/isolator/index.d.ts +63 -0
- package/dist/isolator/index.d.ts.map +1 -0
- package/dist/isolator/index.js +201 -0
- package/dist/isolator/index.js.map +1 -0
- package/dist/isolator/lockdown.d.ts +22 -0
- package/dist/isolator/lockdown.d.ts.map +1 -0
- package/dist/isolator/lockdown.js +401 -0
- package/dist/isolator/lockdown.js.map +1 -0
- package/dist/isolator/quarantine.d.ts +39 -0
- package/dist/isolator/quarantine.d.ts.map +1 -0
- package/dist/isolator/quarantine.js +364 -0
- package/dist/isolator/quarantine.js.map +1 -0
- package/dist/mdm/index.d.ts +93 -0
- package/dist/mdm/index.d.ts.map +1 -0
- package/dist/mdm/index.js +414 -0
- package/dist/mdm/index.js.map +1 -0
- package/dist/mdm/intune.d.ts +69 -0
- package/dist/mdm/intune.d.ts.map +1 -0
- package/dist/mdm/intune.js +409 -0
- package/dist/mdm/intune.js.map +1 -0
- package/dist/mdm/jamf.d.ts +58 -0
- package/dist/mdm/jamf.d.ts.map +1 -0
- package/dist/mdm/jamf.js +441 -0
- package/dist/mdm/jamf.js.map +1 -0
- package/dist/mdm/jumpcloud.d.ts +73 -0
- package/dist/mdm/jumpcloud.d.ts.map +1 -0
- package/dist/mdm/jumpcloud.js +470 -0
- package/dist/mdm/jumpcloud.js.map +1 -0
- package/dist/mdm/templates/detect.ps1.d.ts +30 -0
- package/dist/mdm/templates/detect.ps1.d.ts.map +1 -0
- package/dist/mdm/templates/detect.ps1.js +463 -0
- package/dist/mdm/templates/detect.ps1.js.map +1 -0
- package/dist/mdm/templates/detect.sh.d.ts +30 -0
- package/dist/mdm/templates/detect.sh.d.ts.map +1 -0
- package/dist/mdm/templates/detect.sh.js +474 -0
- package/dist/mdm/templates/detect.sh.js.map +1 -0
- package/dist/mdm/templates/enforce.ps1.d.ts +33 -0
- package/dist/mdm/templates/enforce.ps1.d.ts.map +1 -0
- package/dist/mdm/templates/enforce.ps1.js +681 -0
- package/dist/mdm/templates/enforce.ps1.js.map +1 -0
- package/dist/mdm/templates/enforce.sh.d.ts +33 -0
- package/dist/mdm/templates/enforce.sh.d.ts.map +1 -0
- package/dist/mdm/templates/enforce.sh.js +591 -0
- package/dist/mdm/templates/enforce.sh.js.map +1 -0
- package/dist/platform/darwin.d.ts +6 -0
- package/dist/platform/darwin.d.ts.map +1 -0
- package/dist/platform/darwin.js +192 -0
- package/dist/platform/darwin.js.map +1 -0
- package/dist/platform/index.d.ts +43 -0
- package/dist/platform/index.d.ts.map +1 -0
- package/dist/platform/index.js +27 -0
- package/dist/platform/index.js.map +1 -0
- package/dist/platform/linux.d.ts +6 -0
- package/dist/platform/linux.d.ts.map +1 -0
- package/dist/platform/linux.js +134 -0
- package/dist/platform/linux.js.map +1 -0
- package/dist/platform/windows.d.ts +6 -0
- package/dist/platform/windows.d.ts.map +1 -0
- package/dist/platform/windows.js +134 -0
- package/dist/platform/windows.js.map +1 -0
- package/dist/reporter/console.d.ts +27 -0
- package/dist/reporter/console.d.ts.map +1 -0
- package/dist/reporter/console.js +431 -0
- package/dist/reporter/console.js.map +1 -0
- package/dist/reporter/index.d.ts +11 -0
- package/dist/reporter/index.d.ts.map +1 -0
- package/dist/reporter/index.js +13 -0
- package/dist/reporter/index.js.map +1 -0
- package/dist/reporter/json.d.ts +61 -0
- package/dist/reporter/json.d.ts.map +1 -0
- package/dist/reporter/json.js +75 -0
- package/dist/reporter/json.js.map +1 -0
- package/dist/reporter/webhook.d.ts +57 -0
- package/dist/reporter/webhook.d.ts.map +1 -0
- package/dist/reporter/webhook.js +230 -0
- package/dist/reporter/webhook.js.map +1 -0
- package/dist/types/config.d.ts +116 -0
- package/dist/types/config.d.ts.map +1 -0
- package/dist/types/config.js +6 -0
- package/dist/types/config.js.map +1 -0
- package/dist/types/detection.d.ts +85 -0
- package/dist/types/detection.d.ts.map +1 -0
- package/dist/types/detection.js +5 -0
- package/dist/types/detection.js.map +1 -0
- package/dist/types/enforcement.d.ts +33 -0
- package/dist/types/enforcement.d.ts.map +1 -0
- package/dist/types/enforcement.js +5 -0
- package/dist/types/enforcement.js.map +1 -0
- package/dist/types/index.d.ts +8 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +8 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/isolation.d.ts +55 -0
- package/dist/types/isolation.d.ts.map +1 -0
- package/dist/types/isolation.js +5 -0
- package/dist/types/isolation.js.map +1 -0
- package/dist/utils/exec.d.ts +48 -0
- package/dist/utils/exec.d.ts.map +1 -0
- package/dist/utils/exec.js +103 -0
- package/dist/utils/exec.js.map +1 -0
- package/dist/utils/fs.d.ts +34 -0
- package/dist/utils/fs.d.ts.map +1 -0
- package/dist/utils/fs.js +111 -0
- package/dist/utils/fs.js.map +1 -0
- package/dist/utils/index.d.ts +7 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +7 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/logger.d.ts +14 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +48 -0
- package/dist/utils/logger.js.map +1 -0
- package/docs/intune.md +390 -0
- package/docs/jamf.md +400 -0
- package/docs/jumpcloud.md +510 -0
- package/package.json +65 -0
|
@@ -0,0 +1,463 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PowerShell detection script template for MDM deployment.
|
|
3
|
+
* Targets Windows systems.
|
|
4
|
+
*/
|
|
5
|
+
import { VERSION, COMPANY } from '../../branding.js';
|
|
6
|
+
/**
|
|
7
|
+
* Escape a string for safe use in PowerShell scripts.
|
|
8
|
+
* Escapes characters that could enable script injection.
|
|
9
|
+
*/
|
|
10
|
+
function escapePowerShellString(str) {
|
|
11
|
+
// Remove null bytes
|
|
12
|
+
let escaped = str.replace(/\0/g, '');
|
|
13
|
+
// Escape backticks (PowerShell escape character)
|
|
14
|
+
escaped = escaped.replace(/`/g, '``');
|
|
15
|
+
// Escape dollar signs (variable interpolation)
|
|
16
|
+
escaped = escaped.replace(/\$/g, '`$');
|
|
17
|
+
// Escape double quotes
|
|
18
|
+
escaped = escaped.replace(/"/g, '`"');
|
|
19
|
+
return escaped;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Validate URL format for MDM scripts.
|
|
23
|
+
*/
|
|
24
|
+
function validateMdmUrl(url) {
|
|
25
|
+
try {
|
|
26
|
+
const parsed = new URL(url);
|
|
27
|
+
if (!['http:', 'https:'].includes(parsed.protocol)) {
|
|
28
|
+
throw new Error('Invalid protocol');
|
|
29
|
+
}
|
|
30
|
+
return escapePowerShellString(url);
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
throw new Error(`Invalid webhook URL: ${url}`);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Generate detection PowerShell script.
|
|
38
|
+
*/
|
|
39
|
+
export function generateDetectPowerShellScript(options = {}) {
|
|
40
|
+
const { webhookUrl, webhookToken, gatewayPort = 18789, verbose = false } = options;
|
|
41
|
+
// Validate and sanitize inputs to prevent script injection
|
|
42
|
+
const safeWebhookUrl = webhookUrl ? validateMdmUrl(webhookUrl) : undefined;
|
|
43
|
+
const safeWebhookToken = webhookToken ? escapePowerShellString(webhookToken) : undefined;
|
|
44
|
+
// Validate gateway port
|
|
45
|
+
if (gatewayPort < 1 || gatewayPort > 65535 || !Number.isInteger(gatewayPort)) {
|
|
46
|
+
throw new Error(`Invalid gateway port: ${gatewayPort}`);
|
|
47
|
+
}
|
|
48
|
+
const webhookSection = safeWebhookUrl
|
|
49
|
+
? `
|
|
50
|
+
# Webhook configuration
|
|
51
|
+
$WebhookUrl = "${safeWebhookUrl}"
|
|
52
|
+
$WebhookToken = "${safeWebhookToken || ''}"
|
|
53
|
+
|
|
54
|
+
function Send-Webhook {
|
|
55
|
+
param(
|
|
56
|
+
[string]$Status,
|
|
57
|
+
[string]$Severity,
|
|
58
|
+
[string]$Details
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
$payload = @{
|
|
62
|
+
event = "openclaw.detection"
|
|
63
|
+
version = "1.0"
|
|
64
|
+
timestamp = (Get-Date).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ")
|
|
65
|
+
status = $Status
|
|
66
|
+
severity = $Severity
|
|
67
|
+
host = @{
|
|
68
|
+
hostname = $env:COMPUTERNAME
|
|
69
|
+
os = "Windows"
|
|
70
|
+
osVersion = [System.Environment]::OSVersion.VersionString
|
|
71
|
+
arch = $env:PROCESSOR_ARCHITECTURE
|
|
72
|
+
user = $env:USERNAME
|
|
73
|
+
domain = $env:USERDOMAIN
|
|
74
|
+
}
|
|
75
|
+
details = $Details
|
|
76
|
+
source = @{
|
|
77
|
+
tool = "nox-openclaw-detector"
|
|
78
|
+
version = "${VERSION}"
|
|
79
|
+
vendor = "${COMPANY}"
|
|
80
|
+
}
|
|
81
|
+
} | ConvertTo-Json -Depth 10
|
|
82
|
+
|
|
83
|
+
try {
|
|
84
|
+
$headers = @{
|
|
85
|
+
"Content-Type" = "application/json"
|
|
86
|
+
}
|
|
87
|
+
if ($WebhookToken) {
|
|
88
|
+
$headers["Authorization"] = "Bearer $WebhookToken"
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
Invoke-RestMethod -Uri $WebhookUrl -Method Post -Headers $headers -Body $payload -TimeoutSec 30 -ErrorAction SilentlyContinue | Out-Null
|
|
92
|
+
} catch {
|
|
93
|
+
# Silently ignore webhook errors
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
`
|
|
97
|
+
: '';
|
|
98
|
+
const verboseLog = verbose
|
|
99
|
+
? `
|
|
100
|
+
function Write-VerboseLog {
|
|
101
|
+
param([string]$Message)
|
|
102
|
+
Write-Host "[DEBUG] $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') $Message" -ForegroundColor Gray
|
|
103
|
+
}
|
|
104
|
+
`
|
|
105
|
+
: `
|
|
106
|
+
function Write-VerboseLog {
|
|
107
|
+
param([string]$Message)
|
|
108
|
+
# No-op when not verbose
|
|
109
|
+
}
|
|
110
|
+
`;
|
|
111
|
+
return `<#
|
|
112
|
+
.SYNOPSIS
|
|
113
|
+
Nox OpenClaw Detection Script for Windows
|
|
114
|
+
|
|
115
|
+
.DESCRIPTION
|
|
116
|
+
This script detects OpenClaw AI agent installations on Windows systems.
|
|
117
|
+
Generated by nox-openclaw-detector v${VERSION}
|
|
118
|
+
${COMPANY} - https://nox.security
|
|
119
|
+
|
|
120
|
+
.OUTPUTS
|
|
121
|
+
Exit Code 0 - OpenClaw NOT detected (clean)
|
|
122
|
+
Exit Code 1 - OpenClaw DETECTED
|
|
123
|
+
Exit Code 2 - Script error
|
|
124
|
+
|
|
125
|
+
.EXAMPLE
|
|
126
|
+
.\\detect-openclaw.ps1
|
|
127
|
+
|
|
128
|
+
.NOTES
|
|
129
|
+
Version: ${VERSION}
|
|
130
|
+
Author: ${COMPANY}
|
|
131
|
+
#>
|
|
132
|
+
|
|
133
|
+
#Requires -Version 5.1
|
|
134
|
+
|
|
135
|
+
[CmdletBinding()]
|
|
136
|
+
param()
|
|
137
|
+
|
|
138
|
+
$ErrorActionPreference = "SilentlyContinue"
|
|
139
|
+
|
|
140
|
+
# Configuration
|
|
141
|
+
$GatewayPort = ${gatewayPort}
|
|
142
|
+
$OpenClawFound = $false
|
|
143
|
+
$DetectionDetails = [System.Collections.ArrayList]::new()
|
|
144
|
+
${verboseLog}
|
|
145
|
+
${webhookSection}
|
|
146
|
+
|
|
147
|
+
# Add detection detail
|
|
148
|
+
function Add-Detail {
|
|
149
|
+
param([string]$Detail)
|
|
150
|
+
[void]$script:DetectionDetails.Add($Detail)
|
|
151
|
+
Write-VerboseLog "Detection: $Detail"
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
# Check environment
|
|
155
|
+
function Test-Environment {
|
|
156
|
+
Write-VerboseLog "Running as user: $env:USERNAME"
|
|
157
|
+
Write-VerboseLog "Computer: $env:COMPUTERNAME"
|
|
158
|
+
Write-VerboseLog "OS: $([System.Environment]::OSVersion.VersionString)"
|
|
159
|
+
Write-VerboseLog "Architecture: $env:PROCESSOR_ARCHITECTURE"
|
|
160
|
+
Write-VerboseLog "Running as Admin: $([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)"
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
# Check for CLI binary in common locations
|
|
164
|
+
function Test-CliBinary {
|
|
165
|
+
Write-VerboseLog "Checking for CLI binary..."
|
|
166
|
+
|
|
167
|
+
$cliPaths = @(
|
|
168
|
+
"$env:LOCALAPPDATA\\Programs\\openclaw\\openclaw.exe",
|
|
169
|
+
"$env:ProgramFiles\\OpenClaw\\openclaw.exe",
|
|
170
|
+
"\${env:ProgramFiles(x86)}\\OpenClaw\\openclaw.exe",
|
|
171
|
+
"$env:USERPROFILE\\AppData\\Local\\Programs\\openclaw\\openclaw.exe",
|
|
172
|
+
"$env:USERPROFILE\\.local\\bin\\openclaw.exe"
|
|
173
|
+
)
|
|
174
|
+
|
|
175
|
+
foreach ($cliPath in $cliPaths) {
|
|
176
|
+
if (Test-Path $cliPath) {
|
|
177
|
+
$script:OpenClawFound = $true
|
|
178
|
+
|
|
179
|
+
# Try to get version
|
|
180
|
+
$version = ""
|
|
181
|
+
try {
|
|
182
|
+
$versionOutput = & $cliPath --version 2>$null
|
|
183
|
+
if ($versionOutput) {
|
|
184
|
+
$version = $versionOutput.Trim()
|
|
185
|
+
}
|
|
186
|
+
} catch {}
|
|
187
|
+
|
|
188
|
+
if ($version) {
|
|
189
|
+
Add-Detail "CLI binary found at $cliPath (version: $version)"
|
|
190
|
+
} else {
|
|
191
|
+
Add-Detail "CLI binary found at $cliPath"
|
|
192
|
+
}
|
|
193
|
+
return
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
# Check PATH
|
|
198
|
+
$cliInPath = Get-Command "openclaw" -ErrorAction SilentlyContinue
|
|
199
|
+
if ($cliInPath) {
|
|
200
|
+
$script:OpenClawFound = $true
|
|
201
|
+
Add-Detail "CLI binary found in PATH: $($cliInPath.Source)"
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
# Check for configuration directories
|
|
206
|
+
function Test-ConfigDirectory {
|
|
207
|
+
Write-VerboseLog "Checking for configuration directories..."
|
|
208
|
+
|
|
209
|
+
$configPaths = @(
|
|
210
|
+
"$env:USERPROFILE\\.openclaw",
|
|
211
|
+
"$env:APPDATA\\OpenClaw",
|
|
212
|
+
"$env:LOCALAPPDATA\\OpenClaw"
|
|
213
|
+
)
|
|
214
|
+
|
|
215
|
+
foreach ($configPath in $configPaths) {
|
|
216
|
+
if (Test-Path $configPath -PathType Container) {
|
|
217
|
+
$script:OpenClawFound = $true
|
|
218
|
+
|
|
219
|
+
$configFile = Join-Path $configPath "openclaw.json"
|
|
220
|
+
if (Test-Path $configFile) {
|
|
221
|
+
Add-Detail "Config directory found at $configPath (with config file)"
|
|
222
|
+
} else {
|
|
223
|
+
Add-Detail "Config directory found at $configPath"
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
# Check other user profiles (requires admin)
|
|
229
|
+
if (([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
|
|
230
|
+
$userProfiles = Get-ChildItem "C:\\Users" -Directory -ErrorAction SilentlyContinue | Where-Object { $_.Name -notin @("Public", "Default", "Default User", "All Users") }
|
|
231
|
+
foreach ($profile in $userProfiles) {
|
|
232
|
+
$otherConfigPath = Join-Path $profile.FullName ".openclaw"
|
|
233
|
+
if ((Test-Path $otherConfigPath) -and ($otherConfigPath -ne "$env:USERPROFILE\\.openclaw")) {
|
|
234
|
+
$script:OpenClawFound = $true
|
|
235
|
+
Add-Detail "Config directory found for user $($profile.Name): $otherConfigPath"
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
# Check for running processes
|
|
242
|
+
function Test-Processes {
|
|
243
|
+
Write-VerboseLog "Checking for running processes..."
|
|
244
|
+
|
|
245
|
+
$processes = Get-Process -Name "*openclaw*" -ErrorAction SilentlyContinue
|
|
246
|
+
if ($processes) {
|
|
247
|
+
$script:OpenClawFound = $true
|
|
248
|
+
$processInfo = $processes | ForEach-Object { "$($_.Name) (PID: $($_.Id))" }
|
|
249
|
+
Add-Detail "OpenClaw processes running: $($processInfo -join ', ')"
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
# Also check by path/command line
|
|
253
|
+
$wmiProcesses = Get-CimInstance Win32_Process -ErrorAction SilentlyContinue |
|
|
254
|
+
Where-Object { $_.CommandLine -like "*openclaw*" -or $_.ExecutablePath -like "*openclaw*" }
|
|
255
|
+
|
|
256
|
+
if ($wmiProcesses) {
|
|
257
|
+
foreach ($proc in $wmiProcesses) {
|
|
258
|
+
if (-not ($processes | Where-Object { $_.Id -eq $proc.ProcessId })) {
|
|
259
|
+
$script:OpenClawFound = $true
|
|
260
|
+
Add-Detail "OpenClaw-related process: $($proc.Name) (PID: $($proc.ProcessId))"
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
# Check for gateway port
|
|
267
|
+
function Test-GatewayPort {
|
|
268
|
+
Write-VerboseLog "Checking for gateway port $GatewayPort..."
|
|
269
|
+
|
|
270
|
+
# Use Test-NetConnection (Windows 8+/Server 2012+)
|
|
271
|
+
try {
|
|
272
|
+
$portTest = Test-NetConnection -ComputerName localhost -Port $GatewayPort -WarningAction SilentlyContinue -ErrorAction SilentlyContinue
|
|
273
|
+
if ($portTest.TcpTestSucceeded) {
|
|
274
|
+
$script:OpenClawFound = $true
|
|
275
|
+
Add-Detail "Gateway port $GatewayPort is listening"
|
|
276
|
+
return
|
|
277
|
+
}
|
|
278
|
+
} catch {}
|
|
279
|
+
|
|
280
|
+
# Fallback: check listening ports via netstat
|
|
281
|
+
try {
|
|
282
|
+
$listening = netstat -an | Select-String ":$GatewayPort.*LISTENING"
|
|
283
|
+
if ($listening) {
|
|
284
|
+
$script:OpenClawFound = $true
|
|
285
|
+
Add-Detail "Gateway port $GatewayPort is listening (via netstat)"
|
|
286
|
+
}
|
|
287
|
+
} catch {}
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
# Check for Windows service
|
|
291
|
+
function Test-WindowsService {
|
|
292
|
+
Write-VerboseLog "Checking for Windows services..."
|
|
293
|
+
|
|
294
|
+
$serviceNames = @(
|
|
295
|
+
"openclaw",
|
|
296
|
+
"OpenClawGateway",
|
|
297
|
+
"bot.molt.gateway"
|
|
298
|
+
)
|
|
299
|
+
|
|
300
|
+
foreach ($serviceName in $serviceNames) {
|
|
301
|
+
$service = Get-Service -Name $serviceName -ErrorAction SilentlyContinue
|
|
302
|
+
if ($service) {
|
|
303
|
+
$script:OpenClawFound = $true
|
|
304
|
+
Add-Detail "Windows service found: $($service.Name) (Status: $($service.Status))"
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
# Also search by display name
|
|
309
|
+
$services = Get-Service -ErrorAction SilentlyContinue | Where-Object { $_.DisplayName -like "*openclaw*" -or $_.Name -like "*openclaw*" }
|
|
310
|
+
foreach ($service in $services) {
|
|
311
|
+
if ($service.Name -notin $serviceNames) {
|
|
312
|
+
$script:OpenClawFound = $true
|
|
313
|
+
Add-Detail "Windows service found: $($service.DisplayName) ($($service.Name)) - Status: $($service.Status)"
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
# Check for scheduled tasks
|
|
319
|
+
function Test-ScheduledTasks {
|
|
320
|
+
Write-VerboseLog "Checking for scheduled tasks..."
|
|
321
|
+
|
|
322
|
+
try {
|
|
323
|
+
$tasks = Get-ScheduledTask -ErrorAction SilentlyContinue |
|
|
324
|
+
Where-Object { $_.TaskName -like "*openclaw*" -or $_.TaskPath -like "*openclaw*" }
|
|
325
|
+
|
|
326
|
+
foreach ($task in $tasks) {
|
|
327
|
+
$script:OpenClawFound = $true
|
|
328
|
+
Add-Detail "Scheduled task found: $($task.TaskName) (State: $($task.State))"
|
|
329
|
+
}
|
|
330
|
+
} catch {}
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
# Check for registry entries
|
|
334
|
+
function Test-Registry {
|
|
335
|
+
Write-VerboseLog "Checking registry entries..."
|
|
336
|
+
|
|
337
|
+
$registryPaths = @(
|
|
338
|
+
"HKLM:\\SOFTWARE\\OpenClaw",
|
|
339
|
+
"HKCU:\\SOFTWARE\\OpenClaw",
|
|
340
|
+
"HKLM:\\SOFTWARE\\WOW6432Node\\OpenClaw"
|
|
341
|
+
)
|
|
342
|
+
|
|
343
|
+
foreach ($regPath in $registryPaths) {
|
|
344
|
+
if (Test-Path $regPath) {
|
|
345
|
+
$script:OpenClawFound = $true
|
|
346
|
+
Add-Detail "Registry key found: $regPath"
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
# Check Run keys for startup entries
|
|
351
|
+
$runKeys = @(
|
|
352
|
+
"HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run",
|
|
353
|
+
"HKCU:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run"
|
|
354
|
+
)
|
|
355
|
+
|
|
356
|
+
foreach ($runKey in $runKeys) {
|
|
357
|
+
try {
|
|
358
|
+
$entries = Get-ItemProperty $runKey -ErrorAction SilentlyContinue
|
|
359
|
+
$entries.PSObject.Properties | Where-Object { $_.Value -like "*openclaw*" } | ForEach-Object {
|
|
360
|
+
$script:OpenClawFound = $true
|
|
361
|
+
Add-Detail "Startup entry found: $($_.Name) in $runKey"
|
|
362
|
+
}
|
|
363
|
+
} catch {}
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
# Check for Docker containers and images
|
|
368
|
+
function Test-Docker {
|
|
369
|
+
$dockerCmd = Get-Command "docker" -ErrorAction SilentlyContinue
|
|
370
|
+
if (-not $dockerCmd) {
|
|
371
|
+
return
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
Write-VerboseLog "Checking for Docker artifacts..."
|
|
375
|
+
|
|
376
|
+
try {
|
|
377
|
+
# Check running containers
|
|
378
|
+
$containers = docker ps --filter "name=openclaw" --format "{{.Names}}" 2>$null
|
|
379
|
+
if ($containers) {
|
|
380
|
+
$script:OpenClawFound = $true
|
|
381
|
+
Add-Detail "Docker containers running: $($containers -join ', ')"
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
# Check stopped containers
|
|
385
|
+
$stoppedContainers = docker ps -a --filter "name=openclaw" --filter "status=exited" --format "{{.Names}}" 2>$null
|
|
386
|
+
if ($stoppedContainers) {
|
|
387
|
+
$script:OpenClawFound = $true
|
|
388
|
+
Add-Detail "Docker containers (stopped): $($stoppedContainers -join ', ')"
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
# Check images
|
|
392
|
+
$images = docker images --filter "reference=*openclaw*" --format "{{.Repository}}:{{.Tag}}" 2>$null
|
|
393
|
+
if ($images) {
|
|
394
|
+
$script:OpenClawFound = $true
|
|
395
|
+
Add-Detail "Docker images found: $($images -join ', ')"
|
|
396
|
+
}
|
|
397
|
+
} catch {}
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
# Main detection routine
|
|
401
|
+
function Invoke-Detection {
|
|
402
|
+
Test-Environment
|
|
403
|
+
|
|
404
|
+
# Run all detection checks
|
|
405
|
+
Test-CliBinary
|
|
406
|
+
Test-ConfigDirectory
|
|
407
|
+
Test-Processes
|
|
408
|
+
Test-GatewayPort
|
|
409
|
+
Test-WindowsService
|
|
410
|
+
Test-ScheduledTasks
|
|
411
|
+
Test-Registry
|
|
412
|
+
Test-Docker
|
|
413
|
+
|
|
414
|
+
# Compile results
|
|
415
|
+
$detailsString = if ($DetectionDetails.Count -gt 0) { $DetectionDetails -join "; " } else { "" }
|
|
416
|
+
|
|
417
|
+
# Send webhook notification
|
|
418
|
+
${safeWebhookUrl ? `
|
|
419
|
+
if ($OpenClawFound) {
|
|
420
|
+
Send-Webhook -Status "detected" -Severity "high" -Details $detailsString
|
|
421
|
+
} else {
|
|
422
|
+
Send-Webhook -Status "clean" -Severity "info" -Details "No OpenClaw installation detected"
|
|
423
|
+
}
|
|
424
|
+
` : ''}
|
|
425
|
+
|
|
426
|
+
# Output results
|
|
427
|
+
if ($OpenClawFound) {
|
|
428
|
+
Write-Host "OPENCLAW DETECTED" -ForegroundColor Red
|
|
429
|
+
Write-Host "Details: $detailsString"
|
|
430
|
+
exit 1
|
|
431
|
+
} else {
|
|
432
|
+
Write-Host "OpenClaw not detected" -ForegroundColor Green
|
|
433
|
+
exit 0
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
# Run main function
|
|
438
|
+
try {
|
|
439
|
+
Invoke-Detection
|
|
440
|
+
} catch {
|
|
441
|
+
Write-Host "Detection error: $_" -ForegroundColor Red
|
|
442
|
+
exit 2
|
|
443
|
+
}
|
|
444
|
+
`;
|
|
445
|
+
}
|
|
446
|
+
/**
|
|
447
|
+
* Get script metadata for documentation.
|
|
448
|
+
*/
|
|
449
|
+
export function getDetectPowerShellMetadata() {
|
|
450
|
+
return {
|
|
451
|
+
filename: 'detect-openclaw.ps1',
|
|
452
|
+
extension: '.ps1',
|
|
453
|
+
platform: 'windows',
|
|
454
|
+
description: 'PowerShell detection script for Windows',
|
|
455
|
+
requirements: ['PowerShell 5.1+', 'Windows 8/Server 2012 or later'],
|
|
456
|
+
exitCodes: {
|
|
457
|
+
0: 'OpenClaw not detected (clean)',
|
|
458
|
+
1: 'OpenClaw detected',
|
|
459
|
+
2: 'Script error',
|
|
460
|
+
},
|
|
461
|
+
};
|
|
462
|
+
}
|
|
463
|
+
//# sourceMappingURL=detect.ps1.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detect.ps1.js","sourceRoot":"","sources":["../../../src/mdm/templates/detect.ps1.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shell detection script template for MDM deployment.
|
|
3
|
+
* Targets macOS and Linux systems.
|
|
4
|
+
*/
|
|
5
|
+
export interface DetectShellOptions {
|
|
6
|
+
webhookUrl?: string;
|
|
7
|
+
webhookToken?: string;
|
|
8
|
+
gatewayPort?: number;
|
|
9
|
+
verbose?: boolean;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Generate detection shell script.
|
|
13
|
+
*/
|
|
14
|
+
export declare function generateDetectShellScript(options?: DetectShellOptions): string;
|
|
15
|
+
/**
|
|
16
|
+
* Get script metadata for documentation.
|
|
17
|
+
*/
|
|
18
|
+
export declare function getDetectShellMetadata(): {
|
|
19
|
+
filename: string;
|
|
20
|
+
extension: string;
|
|
21
|
+
platform: string;
|
|
22
|
+
description: string;
|
|
23
|
+
requirements: string[];
|
|
24
|
+
exitCodes: {
|
|
25
|
+
0: string;
|
|
26
|
+
1: string;
|
|
27
|
+
2: string;
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
//# sourceMappingURL=detect.sh.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detect.sh.d.ts","sourceRoot":"","sources":["../../../src/mdm/templates/detect.sh.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,MAAM,WAAW,kBAAkB;IACjC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAmCD;;GAEG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,GAAE,kBAAuB,GAAG,MAAM,CAoalF;AAED;;GAEG;AACH,wBAAgB,sBAAsB;;;;;;;;;;;EAarC"}
|