@soulofzephir/pi-skill-pentesting 1.0.3 → 1.0.5

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@soulofzephir/pi-skill-pentesting",
3
- "version": "1.0.3",
3
+ "version": "1.0.5",
4
4
  "description": "Comprehensive pentesting & security check skill for Pi coding agent - headers, ports, SQLi, XSS, OWASP Top 10",
5
5
  "keywords": [
6
6
  "pi",
@@ -1,5 +1,5 @@
1
- # Exposed Files Scanner v1.0
2
- # Detects dangerous exposed files and directories
1
+ # Exposed Files Scanner v2.0
2
+ # Detects dangerous exposed files with false positive detection
3
3
 
4
4
  param(
5
5
  [Parameter(Mandatory=$false)]
@@ -11,10 +11,8 @@ param(
11
11
 
12
12
  $ErrorActionPreference = "Continue"
13
13
 
14
- # Get current date
15
14
  $Date = Get-Date -Format "yyyy-MM-dd"
16
15
 
17
- # Parse target URL
18
16
  if ($Target -match "https?://") {
19
17
  $Uri = [System.Uri]$Target
20
18
  $Domain = $Uri.Host
@@ -24,122 +22,61 @@ if ($Target -match "https?://") {
24
22
  $Target = "https://$Target"
25
23
  }
26
24
 
27
- # Create output filename
28
25
  $OutputFile = "$OutputDir/$Domain-exposed-$Date.md"
29
26
 
30
- # ═══════════════════════════════════════════════════════════
31
- # COMMON EXPOSED PATHS
32
- # ═══════════════════════════════════════════════════════════
33
-
34
27
  $ExposedPaths = @(
35
- # Configuration Files
36
- @{ Path = "/.env"; Risk = "CRITICAL"; Desc = "Environment variables - may contain secrets" },
37
- @{ Path = "/.env.local"; Risk = "CRITICAL"; Desc = "Local environment - secrets" },
38
- @{ Path = "/.env.production"; Risk = "CRITICAL"; Desc = "Production environment" },
39
- @{ Path = "/.git/config"; Risk = "CRITICAL"; Desc = "Git repository config - may expose remote" },
40
- @{ Path = "/.git/HEAD"; Risk = "HIGH"; Desc = "Git branch information" },
41
- @{ Path = "/.git/"; Risk = "CRITICAL"; Desc = "Full .git directory exposed" },
42
- @{ Path = "/wp-config.php"; Risk = "CRITICAL"; Desc = "WordPress config - DB + keys" },
43
- @{ Path = "/config.php"; Risk = "CRITICAL"; Desc = "PHP configuration" },
44
- @{ Path = "/settings.py"; Risk = "CRITICAL"; Desc = "Django/Python settings" },
45
- @{ Path = "/config.js"; Risk = "HIGH"; Desc = "Node.js configuration" },
46
- @{ Path = "/application.properties"; Risk = "CRITICAL"; Desc = "Java Spring config" },
47
- @{ Path = "/.htaccess"; Risk = "MEDIUM"; Desc = "Apache config" },
48
- @{ Path = "/.htpasswd"; Risk = "CRITICAL"; Desc = "HTTP Basic Auth hashes" },
49
-
50
- # Backup Files
51
- @{ Path = "/backup.zip"; Risk = "CRITICAL"; Desc = "Compressed backup" },
52
- @{ Path = "/backups.zip"; Risk = "CRITICAL"; Desc = "Compressed backup" },
53
- @{ Path = "/database.zip"; Risk = "CRITICAL"; Desc = "Database backup" },
54
- @{ Path = "/db.zip"; Risk = "CRITICAL"; Desc = "Database backup" },
55
- @{ Path = "/database.sql"; Risk = "CRITICAL"; Desc = "Database dump" },
56
- @{ Path = "/db.sql"; Risk = "CRITICAL"; Desc = "Database dump" },
57
- @{ Path = "/dump.sql"; Risk = "CRITICAL"; Desc = "Database dump" },
58
- @{ Path = "/backup.sql"; Risk = "CRITICAL"; Desc = "Database backup" },
59
- @{ Path = "/site.tar.gz"; Risk = "CRITICAL"; Desc = "Full site backup" },
60
- @{ Path = "/backup.tar.gz"; Risk = "CRITICAL"; Desc = "Full backup archive" },
61
- @{ Path = "/www.zip"; Risk = "CRITICAL"; Desc = "Web root backup" },
62
- @{ Path = "/backup/"; Risk = "HIGH"; Desc = "Backup directory" },
63
- @{ Path = "/backups/"; Risk = "HIGH"; Desc = "Backups directory" },
64
- @{ Path = "/db/"; Risk = "HIGH"; Desc = "Database directory" },
65
- @{ Path = "/*.bak"; Risk = "HIGH"; Desc = "Backup files" },
66
- @{ Path = "/*.backup"; Risk = "HIGH"; Desc = "Backup files" },
67
- @{ Path = "/old/"; Risk = "MEDIUM"; Desc = "Old files directory" },
68
- @{ Path = "/tmp/"; Risk = "MEDIUM"; Desc = "Temporary files" },
69
-
70
- # Admin & Debug Panels
71
- @{ Path = "/admin/"; Risk = "HIGH"; Desc = "Admin panel" },
72
- @{ Path = "/wp-admin/"; Risk = "HIGH"; Desc = "WordPress admin" },
73
- @{ Path = "/administrator/"; Risk = "HIGH"; Desc = "Administrator panel" },
74
- @{ Path = "/manage/"; Risk = "MEDIUM"; Desc = "Management panel" },
75
- @{ Path = "/phpmyadmin/"; Risk = "CRITICAL"; Desc = "Database UI - major exposure" },
76
- @{ Path = "/pma/"; Risk = "CRITICAL"; Desc = "phpMyAdmin alias" },
77
- @{ Path = "/mysql/"; Risk = "CRITICAL"; Desc = "MySQL admin" },
78
- @{ Path = "/debug/"; Risk = "CRITICAL"; Desc = "Debug mode enabled" },
79
- @{ Path = "/api/debug/"; Risk = "CRITICAL"; Desc = "API debug endpoint" },
80
- @{ Path = "/console/"; Risk = "HIGH"; Desc = "Debug console" },
81
- @{ Path = "/debug.php"; Risk = "CRITICAL"; Desc = "Debug script" },
82
- @{ Path = "/test.php"; Risk = "HIGH"; Desc = "Test script" },
83
- @{ Path = "/info.php"; Risk = "HIGH"; Desc = "PHP info exposure" },
84
- @{ Path = "/phpinfo.php"; Risk = "HIGH"; Desc = "PHP info exposure" },
85
-
86
- # Spring Boot Actuator
87
- @{ Path = "/actuator/"; Risk = "HIGH"; Desc = "Spring Boot actuator" },
88
- @{ Path = "/actuator/env"; Risk = "CRITICAL"; Desc = "Environment variables" },
89
- @{ Path = "/actuator/heapdump"; Risk = "CRITICAL"; Desc = "Heap dump - contains secrets" },
90
- @{ Path = "/actuator/threaddump"; Risk = "HIGH"; Desc = "Thread information" },
91
- @{ Path = "/actuator/metrics"; Risk = "MEDIUM"; Desc = "Application metrics" },
92
- @{ Path = "/actuator/configprops"; Risk = "CRITICAL"; Desc = "Configuration properties" },
93
- @{ Path = "/health"; Risk = "MEDIUM"; Desc = "Health check endpoint" },
94
-
95
- # API Documentation
96
- @{ Path = "/swagger/"; Risk = "MEDIUM"; Desc = "Swagger UI" },
97
- @{ Path = "/swagger-ui/"; Risk = "MEDIUM"; Desc = "Swagger documentation" },
98
- @{ Path = "/swagger-ui.html"; Risk = "MEDIUM"; Desc = "Swagger HTML" },
99
- @{ Path = "/api-docs/"; Risk = "MEDIUM"; Desc = "API documentation" },
100
- @{ Path = "/v2/api-docs/"; Risk = "MEDIUM"; Desc = "OpenAPI v2" },
101
- @{ Path = "/v3/api-docs/"; Risk = "MEDIUM"; Desc = "OpenAPI v3" },
102
- @{ Path = "/graphiql/"; Risk = "HIGH"; Desc = "GraphQL IDE" },
103
- @{ Path = "/graphql"; Risk = "MEDIUM"; Desc = "GraphQL endpoint" },
104
- @{ Path = "/api/"; Risk = "LOW"; Desc = "API base path" },
105
- @{ Path = "/api/v1/"; Risk = "LOW"; Desc = "API v1" },
106
-
107
- # Log Files
108
- @{ Path = "/logs/"; Risk = "HIGH"; Desc = "Log directory" },
109
- @{ Path = "/error.log"; Risk = "HIGH"; Desc = "Error log" },
110
- @{ Path = "/access.log"; Risk = "HIGH"; Desc = "Access log" },
111
- @{ Path = "/debug.log"; Risk = "HIGH"; Desc = "Debug log" },
112
- @{ Path = "/application.log"; Risk = "HIGH"; Desc = "Application log" },
113
- @{ Path = "/console.log"; Risk = "MEDIUM"; Desc = "Console log" },
114
-
115
- # Information Disclosure
116
- @{ Path = "/robots.txt"; Risk = "LOW"; Desc = "Reveals hidden paths" },
117
- @{ Path = "/sitemap.xml"; Risk = "LOW"; Desc = "Site structure" },
118
- @{ Path = "/security.txt"; Risk = "LOW"; Desc = "Security contact" },
119
- @{ Path = "/humans.txt"; Risk = "LOW"; Desc = "Developer information" },
120
- @{ Path = "/crossdomain.xml"; Risk = "LOW"; Desc = "Flash policy" },
121
- @{ Path = "/.well-known/security.txt"; Risk = "LOW"; Desc = "Security policy" }
28
+ @{ Path="/.env"; Risk="CRITICAL"; Desc="Environment variables with secrets" },
29
+ @{ Path="/.env.local"; Risk="CRITICAL"; Desc="Local environment" },
30
+ @{ Path="/.git/config"; Risk="CRITICAL"; Desc="Git repository config" },
31
+ @{ Path="/.git/HEAD"; Risk="HIGH"; Desc="Git branch info" },
32
+ @{ Path="/.git/"; Risk="CRITICAL"; Desc="Full .git directory" },
33
+ @{ Path="/wp-config.php"; Risk="CRITICAL"; Desc="WordPress config" },
34
+ @{ Path="/config.php"; Risk="HIGH"; Desc="PHP configuration" },
35
+ @{ Path="/settings.py"; Risk="HIGH"; Desc="Python/Django settings" },
36
+ @{ Path="/config.js"; Risk="HIGH"; Desc="Node.js config" },
37
+ @{ Path="/application.properties"; Risk="CRITICAL"; Desc="Java Spring config" },
38
+ @{ Path="/backup.zip"; Risk="CRITICAL"; Desc="Compressed backup" },
39
+ @{ Path="/backups.zip"; Risk="CRITICAL"; Desc="Compressed backup" },
40
+ @{ Path="/database.sql"; Risk="CRITICAL"; Desc="Database dump" },
41
+ @{ Path="/db.sql"; Risk="CRITICAL"; Desc="Database dump" },
42
+ @{ Path="/dump.sql"; Risk="CRITICAL"; Desc="Database dump" },
43
+ @{ Path="/backup.sql"; Risk="CRITICAL"; Desc="Database backup" },
44
+ @{ Path="/admin/"; Risk="HIGH"; Desc="Admin panel" },
45
+ @{ Path="/wp-admin/"; Risk="HIGH"; Desc="WordPress admin" },
46
+ @{ Path="/administrator/"; Risk="HIGH"; Desc="Admin panel" },
47
+ @{ Path="/phpmyadmin/"; Risk="CRITICAL"; Desc="Database UI" },
48
+ @{ Path="/pma/"; Risk="CRITICAL"; Desc="phpMyAdmin alias" },
49
+ @{ Path="/debug/"; Risk="CRITICAL"; Desc="Debug mode enabled" },
50
+ @{ Path="/api/debug/"; Risk="CRITICAL"; Desc="API debug" },
51
+ @{ Path="/actuator/"; Risk="HIGH"; Desc="Spring Boot actuator" },
52
+ @{ Path="/actuator/env"; Risk="CRITICAL"; Desc="Environment variables" },
53
+ @{ Path="/actuator/heapdump"; Risk="CRITICAL"; Desc="Heap dump" },
54
+ @{ Path="/swagger-ui/"; Risk="MEDIUM"; Desc="API documentation" },
55
+ @{ Path="/swagger/"; Risk="MEDIUM"; Desc="Swagger UI" },
56
+ @{ Path="/graphiql/"; Risk="HIGH"; Desc="GraphQL IDE" },
57
+ @{ Path="/graphql"; Risk="MEDIUM"; Desc="GraphQL endpoint" },
58
+ @{ Path="/logs/"; Risk="HIGH"; Desc="Log directory" },
59
+ @{ Path="/error.log"; Risk="HIGH"; Desc="Error log" },
60
+ @{ Path="/access.log"; Risk="MEDIUM"; Desc="Access log" },
61
+ @{ Path="/robots.txt"; Risk="LOW"; Desc="Reveals paths" },
62
+ @{ Path="/sitemap.xml"; Risk="LOW"; Desc="Site structure" }
122
63
  )
123
64
 
124
- # ═══════════════════════════════════════════════════════════
125
- # SCAN FUNCTION
126
- # ═══════════════════════════════════════════════════════════
127
-
128
- Write-Host ""
129
- Write-Host "╔═══════════════════════════════════════════════════╗" -ForegroundColor Cyan
130
- Write-Host "║ 🔍 Exposed Files Scanner v1.0 ║" -ForegroundColor Cyan
131
- Write-Host "╚═══════════════════════════════════════════════════╝" -ForegroundColor Cyan
132
65
  Write-Host ""
133
- Write-Host "Target: $Target" -ForegroundColor White
66
+ Write-Host "========================================" -ForegroundColor Cyan
67
+ Write-Host " Exposed Files Scanner v2.0" -ForegroundColor Cyan
68
+ Write-Host " Target: $Domain" -ForegroundColor Cyan
69
+ Write-Host "========================================" -ForegroundColor Cyan
134
70
  Write-Host ""
135
71
 
136
- $FoundIssues = @()
72
+ $TrueIssues = @()
73
+ $FalsePositives = @()
137
74
  $Scanned = 0
138
75
 
139
76
  foreach ($item in $ExposedPaths) {
140
77
  $Scanned++
141
78
  $Progress = [math]::Round(($Scanned / $ExposedPaths.Count) * 100)
142
- Write-Progress -Activity "Scanning exposed files..." -Status "$Progress% complete" -PercentComplete $Progress
79
+ Write-Progress -Activity "Scanning..." -Status "$Progress% complete" -PercentComplete $Progress
143
80
 
144
81
  $URL = "$Target$($item.Path)"
145
82
 
@@ -147,187 +84,153 @@ foreach ($item in $ExposedPaths) {
147
84
  $Response = Invoke-WebRequest -Uri $URL -Method Head -TimeoutSec 5 -ErrorAction SilentlyContinue
148
85
 
149
86
  if ($Response.StatusCode -ne 404 -and $Response.StatusCode -ne 403) {
150
- $ContentType = $Response.Headers["Content-Type"] -join ", "
87
+ $ContentType = $Response.Headers["Content-Type"]
151
88
 
152
- $Finding = [PSCustomObject]@{
153
- Path = $item.Path
154
- StatusCode = $Response.StatusCode
155
- Risk = $item.Risk
156
- Description = $item.Desc
157
- ContentType = $ContentType
89
+ # Check for false positive (SPA routing)
90
+ $IsFalsePositive = $false
91
+ if ($item.Path -notmatch "\.(zip|sql|env|tar|gz|bak|backup)" -and
92
+ $ContentType -match "text/html|application/octet-stream") {
93
+ # Check if it's actually HTML content
94
+ try {
95
+ $BodyResp = Invoke-WebRequest -Uri $URL -TimeoutSec 5 -ErrorAction SilentlyContinue
96
+ $Body = $BodyResp.Content.Substring(0, [Math]::Min(500, $BodyResp.Content.Length))
97
+
98
+ if ($Body -match "<html|<!doctype|<head|<body|root|<div" -and $Body.Length -lt 2000) {
99
+ $IsFalsePositive = $true
100
+ }
101
+
102
+ # Check for actual sensitive content
103
+ if ($Body -match "DB_HOST|DB_PASS|PASSWORD|SECRET|API_KEY|aws_key|database|backup") {
104
+ $IsFalsePositive = $false
105
+ }
106
+ } catch {}
158
107
  }
159
- $FoundIssues += $Finding
160
108
 
161
- $Color = switch ($item.Risk) {
162
- "CRITICAL" { "Red" }
163
- "HIGH" { "Yellow" }
164
- "MEDIUM" { "Cyan" }
165
- "LOW" { "Gray" }
109
+ if ($IsFalsePositive) {
110
+ $FalsePositives += $item
111
+ Write-Host "[FP] $($item.Path) (HTTP $($Response.StatusCode)) - Likely SPA" -ForegroundColor Gray
112
+ } else {
113
+ $TrueIssues += $item
114
+ $Color = switch ($item.Risk) {
115
+ "CRITICAL" { "Red" }
116
+ "HIGH" { "Yellow" }
117
+ "MEDIUM" { "Cyan" }
118
+ "LOW" { "Gray" }
119
+ }
120
+ Write-Host "[!] FOUND: $($item.Path) ($($item.Risk))" -ForegroundColor $Color
166
121
  }
167
-
168
- Write-Host "⚠️ FOUND [$($item.Risk)]: $($item.Path)" -ForegroundColor $Color
169
- Write-Host " Status: $($Response.StatusCode) | Type: $($ContentType.Substring(0, [Math]::Min(50, $ContentType.Length)))" -ForegroundColor Gray
170
122
  }
171
- } catch {
172
- # Connection error or timeout - not found
173
- }
123
+ } catch {}
174
124
  }
175
125
 
176
126
  Write-Progress -Activity "Scanning" -Completed
177
127
 
178
- # ═══════════════════════════════════════════════════════════
179
- # SUMMARY
180
- # ═══════════════════════════════════════════════════════════
128
+ $CriticalCount = ($TrueIssues | Where-Object { $_.Risk -eq "CRITICAL" }).Count
129
+ $HighCount = ($TrueIssues | Where-Object { $_.Risk -eq "HIGH" }).Count
130
+ $MediumCount = ($TrueIssues | Where-Object { $_.Risk -eq "MEDIUM" }).Count
131
+ $LowCount = ($TrueIssues | Where-Object { $_.Risk -eq "LOW" }).Count
132
+ $FPCount = $FalsePositives.Count
181
133
 
182
134
  Write-Host ""
183
- Write-Host "═══════════════════════════════════════════════════" -ForegroundColor Cyan
184
- Write-Host "📊 SCAN SUMMARY" -ForegroundColor Cyan
185
- Write-Host "═══════════════════════════════════════════════════" -ForegroundColor Cyan
135
+ Write-Host "========================================" -ForegroundColor Cyan
136
+ Write-Host " SCAN SUMMARY" -ForegroundColor Cyan
137
+ Write-Host "========================================" -ForegroundColor Cyan
186
138
  Write-Host ""
187
-
188
- $CriticalCount = ($FoundIssues | Where-Object { $_.Risk -eq "CRITICAL" }).Count
189
- $HighCount = ($FoundIssues | Where-Object { $_.Risk -eq "HIGH" }).Count
190
- $MediumCount = ($FoundIssues | Where-Object { $_.Risk -eq "MEDIUM" }).Count
191
- $LowCount = ($FoundIssues | Where-Object { $_.Risk -eq "LOW" }).Count
192
-
193
139
  Write-Host "Files Scanned: $Scanned" -ForegroundColor White
194
- Write-Host "Issues Found: $($FoundIssues.Count)" -ForegroundColor Yellow
140
+ Write-Host "True Issues: $($TrueIssues.Count)" -ForegroundColor $(if($TrueIssues.Count -gt 0){"Red"}else{"Green"})
141
+ Write-Host "False Positives: $FPCount" -ForegroundColor Gray
195
142
  Write-Host ""
196
- Write-Host "🔴 CRITICAL: $CriticalCount" -ForegroundColor Red
197
- Write-Host "🟠 HIGH: $HighCount" -ForegroundColor Yellow
198
- Write-Host "🟡 MEDIUM: $MediumCount" -ForegroundColor Cyan
199
- Write-Host "🟢 LOW: $LowCount" -ForegroundColor Gray
200
-
201
- # ═══════════════════════════════════════════════════════════
202
- # GENERATE REPORT
203
- # ═══════════════════════════════════════════════════════════
143
+ Write-Host "CRITICAL: $CriticalCount" -ForegroundColor Red
144
+ Write-Host "HIGH: $HighCount" -ForegroundColor Yellow
145
+ Write-Host "MEDIUM: $MediumCount" -ForegroundColor Cyan
146
+ Write-Host "LOW: $LowCount" -ForegroundColor Gray
147
+
148
+ # Generate Report
149
+ $TrueSection = if ($TrueIssues.Count -gt 0) {
150
+ $t = "| Path | Risk | Description |`n|------|------|-------------|`n"
151
+ foreach ($i in $TrueIssues) {
152
+ $t += "| $($i.Path) | $($i.Risk) | $($i.Desc) |`n"
153
+ }
154
+ $t
155
+ } else {
156
+ "No sensitive files exposed."
157
+ }
204
158
 
205
- if (-not (Test-Path $OutputDir)) {
206
- New-Item -ItemType Directory -Path $OutputDir -Force | Out-Null
159
+ $FPSection = if ($FalsePositives.Count -gt 0) {
160
+ $f = "These paths returned HTML/SPA content, not actual sensitive files:`n`n"
161
+ foreach ($i in $FalsePositives) {
162
+ $f += "- $($i.Path) - HTTP 200 (SPA routing)`n"
163
+ }
164
+ $f
165
+ } else {
166
+ "None detected."
207
167
  }
208
168
 
169
+ $Remediation = @()
170
+ if ($CriticalCount -gt 0) { $Remediation += "1. **URGENT**: Remove or protect critical files" }
171
+ if ($HighCount -gt 0) { $Remediation += "2. Add authentication to admin/debug panels" }
172
+ if ($FPCount -gt 0) { $Remediation += "3. (Info) False positives detected - not real issues" }
173
+
209
174
  $Report = @"
210
- # 🔍 Exposed Files Report
175
+ # Exposed Files Report
211
176
 
212
177
  **Target:** $Target
178
+ **Domain:** $Domain
213
179
  **Date:** $Date
214
- **Scanner:** Exposed Files Scanner v1.0
180
+ **Scanner:** Exposed Files Scanner v2.0
181
+ **Author:** Rz (@soulofzephir)
215
182
 
216
183
  ---
217
184
 
218
- ## 📋 Summary
185
+ ## Summary
219
186
 
220
187
  | Metric | Value |
221
188
  |--------|-------|
222
189
  | Files Scanned | $Scanned |
223
- | Issues Found | $($FoundIssues.Count) |
224
- | 🔴 CRITICAL | $CriticalCount |
225
- | 🟠 HIGH | $HighCount |
226
- | 🟡 MEDIUM | $MediumCount |
227
- | 🟢 LOW | $LowCount |
190
+ | True Issues | $($TrueIssues.Count) |
191
+ | False Positives | $FPCount |
192
+ | CRITICAL | $CriticalCount |
193
+ | HIGH | $HighCount |
194
+ | MEDIUM | $MediumCount |
195
+ | LOW | $LowCount |
228
196
 
229
197
  ---
230
198
 
231
- ## 🚨 Critical Issues
232
-
233
- $(if ($CriticalCount -gt 0) {
234
- $FoundIssues | Where-Object { $_.Risk -eq "CRITICAL" } | ForEach-Object {
235
- @"
236
- ### Found: $($_.Path)
237
-
238
- | Field | Value |
239
- |-------|-------|
240
- | Status Code | $($_.StatusCode) |
241
- | Risk Level | 🔴 $($_.Risk) |
242
- | Content Type | $($_.ContentType) |
243
-
244
- **Description:** $($_.Description)
199
+ ## True Security Issues
245
200
 
246
- **Recommendation:** Immediate action required. Remove or restrict access.
201
+ $TrueSection
247
202
 
248
203
  ---
249
- "@
250
- }
251
- } else {
252
- "✅ No critical issues found"
253
- })
254
-
255
- ## 🟠 High Risk Issues
256
-
257
- $(if ($HighCount -gt 0) {
258
- $FoundIssues | Where-Object { $_.Risk -eq "HIGH" } | ForEach-Object {
259
- @"
260
- - **$($_.Path)** - $($_.Description) (HTTP $($_.StatusCode))
261
- "@
262
- }
263
- } else {
264
- "✅ No high-risk issues found"
265
- })
266
-
267
- ## 🟡 Medium Risk Issues
268
-
269
- $(if ($MediumCount -gt 0) {
270
- $FoundIssues | Where-Object { $_.Risk -eq "MEDIUM" } | ForEach-Object {
271
- @"
272
- - **$($_.Path)** - $($_.Description) (HTTP $($_.StatusCode))
273
- "@
274
- }
275
- } else {
276
- "✅ No medium-risk issues found"
277
- })
278
-
279
- ## 🟢 Low Risk Issues
280
-
281
- $(if ($LowCount -gt 0) {
282
- $FoundIssues | Where-Object { $_.Risk -eq "LOW" } | ForEach-Object {
283
- @"
284
- - **$($_.Path)** - $($_.Description) (HTTP $($_.StatusCode))
285
- "@
286
- }
287
- } else {
288
- "✅ No low-risk issues found"
289
- })
290
204
 
291
- ---
292
-
293
- ## 📝 All Findings
205
+ ## False Positives
294
206
 
295
- | Path | Status | Risk | Description |
296
- |------|--------|------|-------------|
297
- $(foreach ($issue in $FoundIssues) {
298
- "| $($issue.Path) | $($issue.StatusCode) | $($issue.Risk) | $($issue.Description) |"
299
- })
207
+ $FPSection
300
208
 
301
209
  ---
302
210
 
303
- ## 🛡️ Remediation Checklist
211
+ ## Remediation
304
212
 
305
- - [ ] Block .env files in web server config
306
- - [ ] Disable .git directory listing
307
- - [ ] Remove backup files from web root
308
- - [ ] Protect admin panels with IP restriction
309
- - [ ] Disable debug mode in production
310
- - [ ] Secure Spring Boot actuator endpoints
311
- - [ ] Add authentication to API documentation
312
- - [ ] Disable directory listing
313
- - [ ] Remove test/debug files
213
+ $(if ($Remediation.Count -gt 0) { $Remediation -join "`n" } else { "No immediate action required." })
314
214
 
315
215
  ---
316
216
 
317
- **Report Generated:** $(Get-Date -Format "yyyy-MM-dd HH:mm:ss")
217
+ **Generated:** $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')
318
218
  "@
319
219
 
320
- # Save report
220
+ if (-not (Test-Path $OutputDir)) {
221
+ New-Item -ItemType Directory -Path $OutputDir -Force | Out-Null
222
+ }
223
+
321
224
  $Report | Out-File -FilePath $OutputFile -Encoding UTF8
322
225
 
323
226
  Write-Host ""
324
- Write-Host "═══════════════════════════════════════════════════" -ForegroundColor Cyan
325
- Write-Host "Scan Complete!" -ForegroundColor Green
326
- Write-Host "═══════════════════════════════════════════════════" -ForegroundColor Cyan
227
+ Write-Host "========================================" -ForegroundColor Green
228
+ Write-Host " Scan Complete!" -ForegroundColor Green
229
+ Write-Host "========================================" -ForegroundColor Green
327
230
  Write-Host ""
328
- Write-Host "📄 Report: $OutputFile" -ForegroundColor White
231
+ Write-Host "Report: $OutputFile" -ForegroundColor White
329
232
  Write-Host ""
330
233
 
331
234
  if ($CriticalCount -gt 0) {
332
- Write-Host "⚠️ IMMEDIATE ACTION REQUIRED for critical findings!" -ForegroundColor Red
235
+ Write-Host "IMMEDIATE ACTION REQUIRED!" -ForegroundColor Red
333
236
  }
@@ -1,5 +1,5 @@
1
- # Full Security Scan - All-in-One v2.0
2
- # Comprehensive security scanner combining all tools
1
+ # Full Security Scan - All-in-One v3.0
2
+ # Comprehensive security scanner with detailed reporting
3
3
 
4
4
  param(
5
5
  [Parameter(Mandatory=$false)]
@@ -11,10 +11,6 @@ param(
11
11
 
12
12
  $ErrorActionPreference = "Continue"
13
13
 
14
- # ═══════════════════════════════════════════════════════════
15
- # CONFIGURATION
16
- # ═══════════════════════════════════════════════════════════
17
-
18
14
  $Date = Get-Date -Format "yyyy-MM-dd"
19
15
 
20
16
  if ($Target -match "https?://") {
@@ -32,164 +28,239 @@ if (-not (Test-Path $OutputDir)) {
32
28
  New-Item -ItemType Directory -Path $OutputDir -Force | Out-Null
33
29
  }
34
30
 
35
- # ═══════════════════════════════════════════════════════════
36
- # BANNER
37
- # ═══════════════════════════════════════════════════════════
38
-
39
31
  Write-Host ""
40
- Write-Host "╔═══════════════════════════════════════════════════╗" -ForegroundColor Cyan
41
- Write-Host " 🛡️ FULL SECURITY SCAN v2.0" -ForegroundColor Cyan
42
- Write-Host " Target: $Domain" -ForegroundColor Cyan
43
- Write-Host " Date: $Date" -ForegroundColor Cyan
44
- Write-Host "╚═══════════════════════════════════════════════════╝" -ForegroundColor Cyan
32
+ Write-Host "========================================" -ForegroundColor Cyan
33
+ Write-Host " Full Security Scan v3.0" -ForegroundColor Cyan
34
+ Write-Host " Target: $Domain" -ForegroundColor Cyan
35
+ Write-Host " Date: $Date" -ForegroundColor Cyan
36
+ Write-Host "========================================" -ForegroundColor Cyan
45
37
  Write-Host ""
46
38
 
47
- # ═══════════════════════════════════════════════════════════
48
- # PHASE 1: SECURITY HEADERS
49
- # ═══════════════════════════════════════════════════════════
50
-
51
- Write-Host "═══════════════════════════════════════════════════" -ForegroundColor Cyan
52
- Write-Host "🔒 PHASE 1: Security Headers" -ForegroundColor Cyan
53
- Write-Host "═══════════════════════════════════════════════════" -ForegroundColor Cyan
54
-
55
39
  $HeaderScore = 0
56
40
  $HeaderIssues = @()
41
+ $HeaderGood = @()
42
+ $ExposedFiles = @()
43
+ $OpenPorts = @()
44
+ $CORSIssues = @()
45
+ $FalsePositives = @()
46
+ $TechStack = @()
47
+
48
+ # PHASE 1: Headers
49
+ Write-Host "Phase 1: Security Headers" -ForegroundColor Yellow
57
50
 
58
51
  try {
59
52
  $Response = Invoke-WebRequest -Uri $Target -Method Head -TimeoutSec 15 -ErrorAction Stop
60
53
  $Headers = $Response.Headers
54
+
55
+ # Detect Server/Technology
56
+ $Server = $Headers["Server"]
57
+ $XPB = $Headers["X-Powered-By"]
58
+ $CFRay = $Response.Headers["CF-Ray"]
59
+ $CFCache = $Response.Headers["CF-Cache-Status"]
60
+
61
+ if ($Server) { $TechStack += "Server: $Server" }
62
+ if ($XPB) { $TechStack += "X-Powered-By: $XPB" }
63
+ if ($CFRay) { $TechStack += "CDN: Cloudflare" }
64
+ if ($CFCache) { $TechStack += "CDN Cache: Active" }
65
+
61
66
  } catch {
62
67
  try {
63
68
  $Response = Invoke-WebRequest -Uri ($Target -replace "^https", "http") -Method Head -TimeoutSec 15 -ErrorAction Stop
64
69
  $Headers = $Response.Headers
65
70
  } catch {
66
- Write-Host "Cannot connect to target" -ForegroundColor Red
71
+ Write-Host "Cannot connect to target" -ForegroundColor Red
67
72
  $Headers = @{}
68
73
  }
69
74
  }
70
75
 
71
- # HSTS
72
76
  $HSTS = $Headers["Strict-Transport-Security"]
73
77
  if ($HSTS) {
74
- Write-Host "HSTS: Present" -ForegroundColor Green
75
- if ($HSTS -match "max-age=([3-9]\d{5,}|\d{7,})") { $HeaderScore += 15 } else { $HeaderScore += 8 }
78
+ $HeaderGood += "HSTS: Present"
79
+ Write-Host " HSTS: Present" -ForegroundColor Green
80
+ if ($HSTS -match "max-age=([3-9]\d{5,}|\d{7,})") {
81
+ $HeaderScore += 15
82
+ $HeaderGood += "HSTS: max-age >= 1 year"
83
+ } elseif ($HSTS -match "max-age=\d{5,6}") {
84
+ $HeaderScore += 8
85
+ $HeaderIssues += "HSTS max-age < 1 year (recommended: 31536000)"
86
+ }
76
87
  } else {
77
- Write-Host "HSTS: Missing" -ForegroundColor Red
88
+ Write-Host " HSTS: Missing" -ForegroundColor Red
78
89
  $HeaderIssues += "HSTS not implemented"
79
90
  }
80
91
 
81
- # CSP
82
92
  $CSP = $Headers["Content-Security-Policy"]
83
93
  if ($CSP) {
84
- Write-Host "CSP: Present" -ForegroundColor Green
94
+ $HeaderGood += "CSP: Present"
95
+ Write-Host " CSP: Present" -ForegroundColor Green
85
96
  $HeaderScore += 20
86
- if ($CSP -match "unsafe-inline") { $HeaderIssues += "CSP contains unsafe-inline" }
97
+ if ($CSP -match "unsafe-inline") {
98
+ $HeaderIssues += "CSP contains 'unsafe-inline' (XSS risk)"
99
+ Write-Host " Warning: Contains unsafe-inline" -ForegroundColor Yellow
100
+ }
101
+ if ($CSP -match "unsafe-eval") {
102
+ $HeaderIssues += "CSP contains 'unsafe-eval'"
103
+ }
87
104
  } else {
88
- Write-Host "CSP: Missing" -ForegroundColor Red
105
+ Write-Host " CSP: Missing" -ForegroundColor Red
89
106
  $HeaderIssues += "CSP not implemented (XSS risk)"
90
107
  }
91
108
 
92
- # X-Content-Type-Options
93
109
  $XCTO = $Headers["X-Content-Type-Options"]
94
110
  if ($XCTO -eq "nosniff") {
95
- Write-Host "X-Content-Type-Options: nosniff" -ForegroundColor Green
111
+ $HeaderGood += "X-Content-Type-Options: nosniff"
112
+ Write-Host " X-Content-Type-Options: nosniff" -ForegroundColor Green
96
113
  $HeaderScore += 10
97
114
  } else {
98
- Write-Host "X-Content-Type-Options: Missing" -ForegroundColor Red
115
+ Write-Host " X-Content-Type-Options: Missing" -ForegroundColor Red
99
116
  $HeaderIssues += "X-Content-Type-Options not set"
100
117
  }
101
118
 
102
- # X-Frame-Options
103
119
  $XFO = $Headers["X-Frame-Options"]
104
120
  if ($XFO -eq "DENY" -or $XFO -eq "SAMEORIGIN") {
105
- Write-Host "X-Frame-Options: $XFO" -ForegroundColor Green
121
+ $HeaderGood += "X-Frame-Options: $XFO"
122
+ Write-Host " X-Frame-Options: $XFO" -ForegroundColor Green
106
123
  $HeaderScore += if ($XFO -eq "DENY") { 10 } else { 8 }
107
124
  } else {
108
- Write-Host "X-Frame-Options: Missing" -ForegroundColor Red
125
+ Write-Host " X-Frame-Options: Missing" -ForegroundColor Red
109
126
  $HeaderIssues += "X-Frame-Options not set (clickjacking risk)"
110
127
  }
111
128
 
112
- # Referrer-Policy
113
129
  $RP = $Headers["Referrer-Policy"]
114
130
  if ($RP) {
115
- Write-Host "Referrer-Policy: $RP" -ForegroundColor Green
131
+ $HeaderGood += "Referrer-Policy: $RP"
132
+ Write-Host " Referrer-Policy: Present" -ForegroundColor Green
116
133
  $HeaderScore += 10
117
134
  } else {
118
- Write-Host "⚠️ Referrer-Policy: Missing" -ForegroundColor Yellow
135
+ Write-Host " Referrer-Policy: Missing" -ForegroundColor Yellow
119
136
  $HeaderScore += 5
120
137
  }
121
138
 
122
- # Cache-Control
123
- $CC = $Headers["Cache-Control"]
124
- if ($CC -match "no-store|no-cache") {
125
- Write-Host "✅ Cache-Control: Secure" -ForegroundColor Green
139
+ $PP = $Headers["Permissions-Policy"]
140
+ if ($PP) {
141
+ $HeaderGood += "Permissions-Policy: Present"
142
+ Write-Host " Permissions-Policy: Present" -ForegroundColor Green
126
143
  $HeaderScore += 10
127
144
  } else {
128
- Write-Host "⚠️ Cache-Control: Check if sensitive data cached" -ForegroundColor Yellow
145
+ Write-Host " Permissions-Policy: Missing" -ForegroundColor Yellow
129
146
  $HeaderScore += 5
130
147
  }
131
148
 
132
- # Server
133
- $Server = $Headers["Server"]
134
- if ($Server -match "/\d|Advanced") {
135
- Write-Host "⚠️ Server: Leaks version - $Server" -ForegroundColor Yellow
136
- $HeaderIssues += "Server header leaks version"
149
+ $CC = $Headers["Cache-Control"]
150
+ if ($CC -match "no-store|no-cache|private") {
151
+ $HeaderGood += "Cache-Control: $CC"
152
+ Write-Host " Cache-Control: $CC" -ForegroundColor Green
153
+ $HeaderScore += 5
154
+ } else {
155
+ Write-Host " Cache-Control: Not optimal" -ForegroundColor Yellow
156
+ $HeaderScore += 2
157
+ }
158
+
159
+ # Check Server for version leaks
160
+ if ($Server -match "/\d|Apache/[0-9]|nginx/[0-9]|Microsoft-IIS/[0-9]") {
161
+ Write-Host " Server: Leaks version - $Server" -ForegroundColor Yellow
162
+ $HeaderIssues += "Server header leaks version: $Server"
163
+ } elseif ($Server) {
164
+ Write-Host " Server: $Server" -ForegroundColor Gray
137
165
  }
138
166
 
139
- # X-Powered-By
140
- $XPB = $Headers["X-Powered-By"]
141
167
  if ($XPB) {
142
- Write-Host "⚠️ X-Powered-By: $XPB" -ForegroundColor Yellow
143
- $HeaderIssues += "X-Powered-By leaks technology"
168
+ Write-Host " X-Powered-By: $XPB" -ForegroundColor Yellow
169
+ $HeaderIssues += "X-Powered-By leaks technology: $XPB"
144
170
  }
145
171
 
172
+ # Check CORS
146
173
  Write-Host ""
147
- Write-Host "📊 Header Score: $HeaderScore/100" -ForegroundColor $(if($HeaderScore -ge 70){"Green"}else{"Red"})
174
+ Write-Host "Phase 1b: CORS Analysis" -ForegroundColor Yellow
175
+
176
+ $ACAO = $Headers["Access-Control-Allow-Origin"]
177
+ $ACAC = $Headers["Access-Control-Allow-Credentials"]
178
+ $ACAM = $Headers["Access-Control-Allow-Methods"]
148
179
 
149
- # ═══════════════════════════════════════════════════════════
150
- # PHASE 2: EXPOSED FILES
151
- # ═══════════════════════════════════════════════════════════
180
+ if ($ACAO) {
181
+ Write-Host " CORS Origin: $ACAO" -ForegroundColor $(if($ACAO -eq "*"){"Yellow"}else{"Green"})
182
+ if ($ACAO -eq "*") {
183
+ $CORSIssues += "CORS allows all origins (Access-Control-Allow-Origin: *)"
184
+ Write-Host " Warning: Allows all origins" -ForegroundColor Yellow
185
+ }
186
+ }
187
+
188
+ if ($ACAC -eq "true" -and $ACAO -eq "*") {
189
+ $CORSIssues += "CORS: Wildcard with credentials (invalid but misconfigured)"
190
+ Write-Host " CRITICAL: Wildcard with credentials!" -ForegroundColor Red
191
+ }
192
+
193
+ if ($ACAM) {
194
+ Write-Host " CORS Methods: $ACAM" -ForegroundColor Gray
195
+ }
152
196
 
153
197
  Write-Host ""
154
- Write-Host "═══════════════════════════════════════════════════" -ForegroundColor Cyan
155
- Write-Host "🔍 PHASE 2: Exposed Files Check" -ForegroundColor Cyan
156
- Write-Host "═══════════════════════════════════════════════════" -ForegroundColor Cyan
198
+ Write-Host " Header Score: $HeaderScore/100" -ForegroundColor $(if($HeaderScore -ge 70){"Green"}else{"Red"})
199
+
200
+ # PHASE 2: Exposed Files
201
+ Write-Host ""
202
+ Write-Host "Phase 2: Exposed Files" -ForegroundColor Yellow
157
203
 
158
- $ExposedFiles = @()
159
204
  $CriticalPaths = @(
160
- "/.env", "/.git/config", "/.git/HEAD", "/.git/",
161
- "/wp-config.php", "/config.php", "/settings.py",
162
- "/backup.zip", "/database.sql", "/db.sql",
163
- "/admin/", "/debug/", "/phpmyadmin/", "/pma/",
164
- "/actuator/env", "/actuator/heapdump",
165
- "/swagger-ui/", "/graphiql/"
205
+ @{ Path="/.env"; Risk="CRITICAL"; Desc="Environment variables" },
206
+ @{ Path="/.git/config"; Risk="CRITICAL"; Desc="Git repository" },
207
+ @{ Path="/.git/"; Risk="CRITICAL"; Desc="Git directory" },
208
+ @{ Path="/config.php"; Risk="HIGH"; Desc="PHP configuration" },
209
+ @{ Path="/settings.py"; Risk="HIGH"; Desc="Python settings" },
210
+ @{ Path="/backup.zip"; Risk="CRITICAL"; Desc="Backup archive" },
211
+ @{ Path="/database.sql"; Risk="CRITICAL"; Desc="Database dump" },
212
+ @{ Path="/db.sql"; Risk="CRITICAL"; Desc="Database dump" },
213
+ @{ Path="/admin/"; Risk="HIGH"; Desc="Admin panel" },
214
+ @{ Path="/debug/"; Risk="HIGH"; Desc="Debug endpoint" },
215
+ @{ Path="/phpmyadmin/"; Risk="CRITICAL"; Desc="Database UI" },
216
+ @{ Path="/actuator/env"; Risk="CRITICAL"; Desc="Spring Boot env" }
166
217
  )
167
218
 
168
- foreach ($path in $CriticalPaths) {
219
+ $TrueExposedFiles = @()
220
+ $FalsePositiveFiles = @()
221
+
222
+ foreach ($item in $CriticalPaths) {
169
223
  try {
170
- $resp = Invoke-WebRequest -Uri "$Target$path" -Method Head -TimeoutSec 5 -ErrorAction SilentlyContinue
171
- if ($resp.StatusCode -ne 404) {
172
- Write-Host "⚠️ FOUND: $path (HTTP $($resp.StatusCode))" -ForegroundColor Red
173
- $ExposedFiles += $path
224
+ $resp = Invoke-WebRequest -Uri "$Target$($item.Path)" -Method Head -TimeoutSec 5 -ErrorAction SilentlyContinue
225
+ if ($resp.StatusCode -ne 404 -and $resp.StatusCode -ne 403) {
226
+ $ContentType = $resp.Headers["Content-Type"]
227
+ $BodyPreview = ""
228
+
229
+ # Check if it's a real sensitive file or SPA
230
+ if ($ContentType -match "text/html|application/octet-stream" -and $item.Path -notmatch "\.zip|\.sql|\.env|\.git") {
231
+ # Check body content
232
+ try {
233
+ $bodyResp = Invoke-WebRequest -Uri "$Target$($item.Path)" -TimeoutSec 5 -ErrorAction SilentlyContinue
234
+ $BodyPreview = $bodyResp.Content.Substring(0, [Math]::Min(200, $bodyResp.Content.Length))
235
+ } catch {}
236
+
237
+ if ($BodyPreview -match "root|div|html|<!" -and $BodyPreview.Length -lt 1000) {
238
+ # Likely SPA false positive
239
+ $FalsePositiveFiles += $item
240
+ Write-Host " [FP] $($item.Path) - HTTP $($resp.StatusCode) (likely SPA)" -ForegroundColor Gray
241
+ } else {
242
+ # Real exposed file
243
+ $TrueExposedFiles += $item
244
+ Write-Host " FOUND: $($item.Path) (HTTP $($resp.StatusCode))" -ForegroundColor Red
245
+ }
246
+ } else {
247
+ # Real file
248
+ $TrueExposedFiles += $item
249
+ Write-Host " FOUND: $($item.Path) (HTTP $($resp.StatusCode))" -ForegroundColor Red
250
+ }
174
251
  }
175
252
  } catch {}
176
253
  }
177
254
 
178
- if ($ExposedFiles.Count -eq 0) {
179
- Write-Host "No critical files exposed" -ForegroundColor Green
255
+ if ($TrueExposedFiles.Count -eq 0) {
256
+ Write-Host " No sensitive files exposed" -ForegroundColor Green
180
257
  }
181
258
 
182
- # ═══════════════════════════════════════════════════════════
183
- # PHASE 3: PORT CHECK
184
- # ═══════════════════════════════════════════════════════════
185
-
259
+ # PHASE 3: Port Check
186
260
  Write-Host ""
187
- Write-Host "═══════════════════════════════════════════════════" -ForegroundColor Cyan
188
- Write-Host "🔌 PHASE 3: Quick Port Check" -ForegroundColor Cyan
189
- Write-Host "═══════════════════════════════════════════════════" -ForegroundColor Cyan
261
+ Write-Host "Phase 3: Port Check" -ForegroundColor Yellow
190
262
 
191
263
  $Ports = @(80, 443, 8080, 3306, 5432, 6379, 27017, 22)
192
- $OpenPorts = @()
193
264
 
194
265
  foreach ($Port in $Ports) {
195
266
  try {
@@ -198,311 +269,202 @@ foreach ($Port in $Ports) {
198
269
  $Wait = $Result.AsyncWaitHandle.WaitOne(500)
199
270
 
200
271
  if ($Wait -and $TCP.Connected) {
201
- $Service = switch ($Port) {
202
- 80 { "HTTP" }
203
- 443 { "HTTPS" }
204
- 8080 { "HTTP-Alt" }
205
- 3306 { "MySQL" }
206
- 5432 { "PostgreSQL" }
207
- 6379 { "Redis" }
208
- 27017 { "MongoDB" }
209
- 22 { "SSH" }
210
- }
211
- $Risk = if ($Port -in @(3306, 5432, 6379, 27017)) { "HIGH" } else { "INFO" }
212
-
213
- Write-Host "⚠️ Port $Port ($Service) - OPEN" -ForegroundColor $(if($Risk -eq "HIGH"){"Red"}else{"Yellow"})
214
- $OpenPorts += [PSCustomObject]@{ Port = $Port; Service = $Service; Risk = $Risk }
272
+ $Service = switch ($Port) { 80{"HTTP"} 443{"HTTPS"} 8080{"HTTP-Alt"} 3306{"MySQL"} 5432{"PostgreSQL"} 6379{"Redis"} 27017{"MongoDB"} 22{"SSH"} }
273
+ $Risk = if ($Port -in @(3306,5432,6379,27017)) { "HIGH" } else { "INFO" }
274
+ Write-Host " Port $Port ($Service) - OPEN" -ForegroundColor $(if($Risk -eq "HIGH"){"Red"}else{"Gray"})
275
+ $OpenPorts += [PSCustomObject]@{ Port=$Port; Service=$Service; Risk=$Risk }
215
276
  }
216
277
  $TCP.Close()
217
278
  } catch {}
218
279
  }
219
280
 
220
- if ($OpenPorts.Count -eq 0) {
221
- Write-Host "✅ No common ports detected" -ForegroundColor Green
222
- }
223
-
224
- # ═══════════════════════════════════════════════════════════
225
- # PHASE 4: BASIC INJECTION TEST
226
- # ═══════════════════════════════════════════════════════════
227
-
281
+ # PHASE 4: Injection Tests
228
282
  Write-Host ""
229
- Write-Host "═══════════════════════════════════════════════════" -ForegroundColor Cyan
230
- Write-Host "💉 PHASE 4: Basic Injection Tests" -ForegroundColor Cyan
231
- Write-Host "═══════════════════════════════════════════════════" -ForegroundColor Cyan
283
+ Write-Host "Phase 4: Injection Tests" -ForegroundColor Yellow
232
284
 
233
- # XSS Test
234
- Write-Host "Testing XSS..." -ForegroundColor Gray
235
285
  $XSSPayload = "<script>alert(1)</script>"
236
286
  try {
237
287
  $Response = Invoke-WebRequest -Uri "$Target/search?q=$XSSPayload" -TimeoutSec 10 -ErrorAction SilentlyContinue
238
288
  if ($Response.Content -match [regex]::Escape($XSSPayload)) {
239
- Write-Host "⚠️ Possible XSS reflection detected" -ForegroundColor Yellow
289
+ Write-Host " XSS: Possible reflection detected" -ForegroundColor Yellow
240
290
  } else {
241
- Write-Host " No obvious XSS reflection" -ForegroundColor Green
291
+ Write-Host " XSS: No obvious reflection" -ForegroundColor Green
242
292
  }
243
- } catch {
244
- Write-Host "✅ No obvious XSS reflection" -ForegroundColor Green
245
- }
293
+ } catch { Write-Host " XSS: No obvious reflection" -ForegroundColor Green }
246
294
 
247
- # SQLi Test
248
- Write-Host "Testing SQL Injection..." -ForegroundColor Gray
249
295
  $SQLPayload = "' OR '1'='1"
250
296
  try {
251
297
  $Response = Invoke-WebRequest -Uri "$Target/?id=$SQLPayload" -TimeoutSec 10 -ErrorAction SilentlyContinue
252
- $SQLErrors = @("SQL syntax", "MySQL", "PostgreSQL", "sqlite", "Microsoft SQL", "Warning: mysql", "error in your SQL")
298
+ $SQLErrors = @("SQL syntax","MySQL","PostgreSQL","sqlite","Microsoft SQL","Warning: mysql")
253
299
  $Found = $SQLErrors | Where-Object { $Response.Content -match $_ }
254
300
  if ($Found) {
255
- Write-Host "⚠️ SQL error detected in response" -ForegroundColor Yellow
301
+ Write-Host " SQLi: Error detected" -ForegroundColor Yellow
256
302
  } else {
257
- Write-Host " No obvious SQL errors" -ForegroundColor Green
303
+ Write-Host " SQLi: No obvious errors" -ForegroundColor Green
258
304
  }
259
- } catch {
260
- Write-Host "✅ No obvious SQL errors" -ForegroundColor Green
261
- }
262
-
263
- # ═══════════════════════════════════════════════════════════
264
- # PHASE 5: SSL/TLS CHECK
265
- # ═══════════════════════════════════════════════════════════
305
+ } catch { Write-Host " SQLi: No obvious errors" -ForegroundColor Green }
266
306
 
307
+ # PHASE 5: SSL Check
267
308
  Write-Host ""
268
- Write-Host "═══════════════════════════════════════════════════" -ForegroundColor Cyan
269
- Write-Host "🔐 PHASE 5: SSL/TLS Check" -ForegroundColor Cyan
270
- Write-Host "═══════════════════════════════════════════════════" -ForegroundColor Cyan
271
-
272
- $SSLIssues = @()
309
+ Write-Host "Phase 5: SSL/TLS Check" -ForegroundColor Yellow
273
310
 
274
311
  if ($Scheme -eq "https") {
275
- Write-Host "HTTPS enabled" -ForegroundColor Green
276
-
277
- # Check HSTS
278
- if ($HSTS -notmatch "max-age=([3-9]\d{5,}|\d{7,})") {
279
- Write-Host "⚠️ HSTS max-age should be at least 1 year" -ForegroundColor Yellow
280
- $SSLIssues += "HSTS max-age too short"
281
- }
282
-
283
- Write-Host "📝 For full SSL analysis: https://ssllabs.com/ssltest/analyze.html?d=$Domain" -ForegroundColor Cyan
312
+ Write-Host " HTTPS: Enabled" -ForegroundColor Green
284
313
  } else {
285
- Write-Host "HTTPS not enforced" -ForegroundColor Red
286
- $SSLIssues += "HTTPS not enabled"
314
+ Write-Host " HTTPS: NOT enforced" -ForegroundColor Red
287
315
  }
288
316
 
289
- # ═══════════════════════════════════════════════════════════
290
317
  # SUMMARY
291
- # ═══════════════════════════════════════════════════════════
292
-
293
318
  Write-Host ""
294
- Write-Host "═══════════════════════════════════════════════════" -ForegroundColor Cyan
295
- Write-Host "📊 SCAN SUMMARY" -ForegroundColor Cyan
296
- Write-Host "═══════════════════════════════════════════════════" -ForegroundColor Cyan
319
+ Write-Host "========================================" -ForegroundColor Cyan
320
+ Write-Host " SCAN SUMMARY" -ForegroundColor Cyan
321
+ Write-Host "========================================" -ForegroundColor Cyan
297
322
  Write-Host ""
323
+ Write-Host "Header Score: $HeaderScore/100" -ForegroundColor $(if($HeaderScore -ge 70){"Green"}else{"Red"})
324
+ Write-Host "True Exposed: $($TrueExposedFiles.Count)" -ForegroundColor $(if($TrueExposedFiles.Count -gt 0){"Red"}else{"Green"})
325
+ Write-Host "False Positives: $($FalsePositiveFiles.Count)" -ForegroundColor Gray
326
+ Write-Host "Open Ports: $($OpenPorts.Count)" -ForegroundColor $(if(($OpenPorts | Where-Object{$_.Risk -eq "HIGH"}).Count -gt 0){"Red"}else{"Green"})
327
+
328
+ # Determine Overall Risk
329
+ $CriticalPorts = ($OpenPorts | Where-Object { $_.Risk -eq "HIGH" }).Count
330
+ $OverallRisk = if ($TrueExposedFiles.Count -gt 0 -or $CriticalPorts -gt 2 -or $HeaderScore -lt 40) { "HIGH" }
331
+ elseif ($TrueExposedFiles.Count -gt 0 -or $CriticalPorts -gt 0 -or $CORSIssues.Count -gt 0) { "MEDIUM" }
332
+ elseif ($HeaderScore -lt 70 -or $FalsePositiveFiles.Count -gt 0) { "LOW" }
333
+ else { "LOW" }
334
+
335
+ # Generate Report
336
+ $HeaderGrade = if ($HeaderScore -ge 90) { "A - Excellent" }
337
+ elseif ($HeaderScore -ge 80) { "B - Good" }
338
+ elseif ($HeaderScore -ge 70) { "B - Good" }
339
+ elseif ($HeaderScore -ge 50) { "C - Needs Improvement" }
340
+ else { "D/F - Poor" }
341
+
342
+ $IssuesSection = if ($HeaderIssues.Count -gt 0) { "- " + ($HeaderIssues -join "`n- ") } else { "None" }
343
+
344
+ $ExposedSection = ""
345
+ if ($TrueExposedFiles.Count -gt 0) {
346
+ $ExposedSection = "| Path | Status | Risk | Description |`n"
347
+ $ExposedSection += "|------|--------|------|-------------|`n"
348
+ foreach ($f in $TrueExposedFiles) {
349
+ $ExposedSection += "| $($f.Path) | OPEN | $($f.Risk) | $($f.Desc) |`n"
350
+ }
351
+ } else {
352
+ $ExposedSection = "No sensitive files actually exposed."
353
+ }
298
354
 
299
- Write-Host "🔒 Header Score: $HeaderScore/100" -ForegroundColor $(if($HeaderScore -ge 70){"Green"}else{"Red"})
300
- Write-Host "🔍 Exposed Files: $($ExposedFiles.Count)" -ForegroundColor $(if($ExposedFiles.Count -gt 0){"Yellow"}else{"Green"})
301
- Write-Host "🔌 Open Ports: $($OpenPorts.Count)" -ForegroundColor $(if(($OpenPorts | Where-Object {$_.Risk -eq "HIGH"}).Count -gt 0){"Red"}else{"Green"})
302
- Write-Host "💉 Injection: Basic tests completed" -ForegroundColor Green
303
- Write-Host "🔐 SSL/TLS: HTTPS $($SSLIssues.Count -eq 0 ? 'OK' : 'Issues')" -ForegroundColor $(if($SSLIssues.Count -eq 0){"Green"}else{"Yellow"})
355
+ $FalsePOSection = ""
356
+ if ($FalsePositiveFiles.Count -gt 0) {
357
+ $FalsePOSection = "### False Positives (Not Real Issues)`n`n"
358
+ $FalsePOSection += "These paths returned HTML/SPA content, not actual sensitive files:`n`n"
359
+ foreach ($f in $FalsePositiveFiles) {
360
+ $FalsePOSection += "- $($f.Path) - HTTP 200 (SPA routing)`n"
361
+ }
362
+ $FalsePOSection += "`n"
363
+ }
304
364
 
305
- # ═══════════════════════════════════════════════════════════
306
- # GENERATE REPORT
307
- # ═══════════════════════════════════════════════════════════
365
+ $CORSSection = ""
366
+ if ($CORSIssues.Count -gt 0) {
367
+ $CORSSection = "### CORS Issues`n`n"
368
+ foreach ($c in $CORSIssues) {
369
+ $CORSSection += "- $c`n"
370
+ }
371
+ $CORSSection += "`n"
372
+ }
308
373
 
309
- Write-Host ""
310
- Write-Host "📝 Generating detailed report..." -ForegroundColor Yellow
374
+ $PortSection = ""
375
+ if ($OpenPorts.Count -gt 0) {
376
+ $PortSection = "| Port | Service | Risk |`n|------|---------|------|`n"
377
+ foreach ($p in $OpenPorts) {
378
+ $PortSection += "| $($p.Port) | $($p.Service) | $($p.Risk) |`n"
379
+ }
380
+ } else {
381
+ $PortSection = "No common ports detected.`n"
382
+ }
383
+
384
+ $Remediation = @()
385
+ if ($TrueExposedFiles.Count -gt 0) { $Remediation += "1. **URGENT: Remove exposed sensitive files**" }
386
+ if ($CORSIssues.Count -gt 0) { $Remediation += "2. Review CORS policy" }
387
+ if ($HeaderIssues -match "unsafe-inline") { $Remediation += "3. Consider removing unsafe-inline from CSP" }
388
+ if ($HeaderScore -lt 70) { $Remediation += "4. Improve security headers" }
389
+ if ($Remediation.Count -eq 0) { $Remediation += "1. Continue monitoring security" }
390
+
391
+ $TechSection = if ($TechStack.Count -gt 0) { "- " + ($TechStack -join "`n- ") } else { "Not detected" }
311
392
 
312
393
  $Report = @"
313
- # 🛡️ Full Security Audit Report
394
+ # Security Audit Report
314
395
 
315
396
  **Target:** $Target
316
397
  **Domain:** $Domain
317
398
  **Date:** $Date
318
- **Scanner:** Full Security Scan v2.0
399
+ **Scanner:** Full Security Scan v3.0
400
+ **Author:** Rz (@soulofzephir)
319
401
 
320
402
  ---
321
403
 
322
- ## 📋 Executive Summary
404
+ ## Executive Summary
323
405
 
324
406
  | Metric | Value |
325
407
  |--------|-------|
326
- | Target | $Target |
327
- | Scan Date | $Date |
328
- | Header Score | $HeaderScore/100 |
329
- | Exposed Files | $($ExposedFiles.Count) |
408
+ | Header Score | $HeaderScore/100 ($HeaderGrade) |
409
+ | True Exposed Files | $($TrueExposedFiles.Count) |
410
+ | False Positives | $($FalsePositiveFiles.Count) |
330
411
  | Open Ports | $($OpenPorts.Count) |
331
- | SSL Issues | $($SSLIssues.Count) |
332
-
333
- ### Overall Risk Assessment
334
-
335
- $(if ($HeaderScore -lt 50 -or $ExposedFiles.Count -gt 0 -or ($OpenPorts | Where-Object {$_.Risk -eq "HIGH"}).Count -gt 0) {
336
- "🔴 **HIGH RISK** - Issues found requiring immediate attention"
337
- } elseif ($HeaderScore -lt 70 -or $ExposedFiles.Count -gt 0) {
338
- "🟠 **MEDIUM RISK** - Some security improvements recommended"
339
- } else {
340
- "🟢 **LOW RISK** - Minor issues to address"
341
- })
412
+ | **Overall Risk** | **$OverallRisk** |
342
413
 
343
414
  ---
344
415
 
345
- ## 🔒 1. Security Headers Analysis
416
+ ## Security Headers
346
417
 
347
- ### Header Score: $HeaderScore/100
418
+ ### Score: $HeaderScore/100 ($HeaderGrade)
348
419
 
349
- $(if ($HeaderScore -ge 90) { "✅ **Grade A - Excellent**" }
350
- elseif ($HeaderScore -ge 70) { "✅ **Grade B - Good**" }
351
- elseif ($HeaderScore -ge 50) { "⚠️ **Grade C - Needs Improvement**" }
352
- else { "❌ **Grade D/F - Poor**" })
420
+ #### Good Headers
421
+ $($HeaderGood -join "`n")
353
422
 
354
- | Header | Status |
355
- |--------|--------|
356
- | HSTS | $(if ($HSTS) { "✅ Present" } else { "❌ Missing" }) |
357
- | CSP | $(if ($CSP) { "✅ Present" } else { "❌ Missing" }) |
358
- | X-Content-Type-Options | $(if ($XCTO -eq "nosniff") { "✅ nosniff" } else { "❌ Missing" }) |
359
- | X-Frame-Options | $(if ($XFO) { "✅ $XFO" } else { "❌ Missing" }) |
360
- | Referrer-Policy | $(if ($RP) { "✅ Present" } else { "⚠️ Missing" }) |
361
- | Cache-Control | $(if ($CC) { "✅ Present" } else { "⚠️ Missing" }) |
362
- | Server | $(if ($Server) { "⚠️ $Server" } else { "✅ Hidden" }) |
363
- | X-Powered-By | $(if ($XPB) { "⚠️ $XPB" } else { "✅ Hidden" }) |
364
-
365
- ### Issues Found
366
-
367
- $(if ($HeaderIssues.Count -gt 0) {
368
- foreach ($issue in $HeaderIssues) {
369
- "- ⚠️ $issue"
370
- }
371
- } else {
372
- "✅ No major header issues"
373
- })
423
+ #### Issues Found
424
+ $IssuesSection
374
425
 
375
426
  ---
376
427
 
377
- ## 🔍 2. Exposed Files Check
428
+ ## Exposed Files
378
429
 
379
- $(if ($ExposedFiles.Count -gt 0) {
380
- "### 🚨 Found $($ExposedFiles.Count) Exposed Files"
381
- } else {
382
- "### ✅ No Critical Files Exposed"
383
- })
384
-
385
- | Path | Risk |
386
- |------|------|
387
- $(foreach ($file in $ExposedFiles) {
388
- "| $file | 🔴 CRITICAL |"
389
- })
390
-
391
- **Recommendation:** Remove or protect these files from public access.
430
+ ### True Exposures
431
+ $ExposedSection
392
432
 
433
+ $FalsePOSection
434
+ ## CORS Analysis
435
+ $CORSSection
436
+ ## Port Scan Results
437
+ $PortSection
438
+ ## Technology Stack
439
+ $TechSection
393
440
  ---
394
441
 
395
- ## 🔌 3. Port Scan Results
396
-
397
- $(if (($OpenPorts | Where-Object {$_.Risk -eq "HIGH"}).Count -gt 0) {
398
- "### 🚨 High-Risk Ports Open"
399
- } else {
400
- "### ✅ No High-Risk Ports Detected"
401
- })
402
-
403
- | Port | Service | Risk |
404
- |------|---------|------|
405
- $(foreach ($p in $OpenPorts) {
406
- "| $($p.Port) | $($p.Service) | $(if($p.Risk -eq "HIGH"){"🔴 HIGH"}else{"🟢 INFO"}) |"
407
- })
442
+ ## Remediation
408
443
 
409
- **Recommendation:** Database ports (3306, 5432, 6379, 27017) should never be exposed to the internet.
444
+ $(if ($Remediation.Count -gt 0) { $Remediation -join "`n" })
410
445
 
411
446
  ---
412
447
 
413
- ## 💉 4. Injection Tests
414
-
415
- Basic automated tests completed.
448
+ ## Quick Links
416
449
 
417
- | Test | Status |
418
- |------|--------|
419
- | XSS Reflection | ⚠️ Review manually |
420
- | SQL Injection | ⚠️ Review manually |
421
-
422
- **Note:** For comprehensive injection testing, use:
423
- - SQLMap: \`sqlmap -u "$Target"\`
424
- - Dalfox: \`dalfox url "$Target"\`
450
+ - Security Headers: https://securityheaders.com/?q=$Domain
451
+ - SSL Labs: https://ssllabs.com/ssltest/analyze.html?d=$Domain
425
452
 
426
453
  ---
427
454
 
428
- ## 🔐 5. SSL/TLS
429
-
430
- $(if ($Scheme -eq "https") {
431
- "✅ HTTPS is enabled"
432
- } else {
433
- "❌ HTTPS is NOT enabled"
434
- })
435
-
436
- $(if ($SSLIssues.Count -gt 0) {
437
- "### ⚠️ SSL Issues:"
438
- foreach ($issue in $SSLIssues) {
439
- "- $issue"
440
- }
441
- })
442
-
443
- **Full SSL Analysis:** https://ssllabs.com/ssltest/analyze.html?d=$Domain
444
-
445
- ---
446
-
447
- ## 🛡️ Remediation Priority
448
-
449
- ### Immediate (Critical)
450
- 1. Implement missing security headers
451
- 2. Remove/block exposed sensitive files (.env, .git/, backups)
452
- 3. Close database ports from public access
453
-
454
- ### Short-term
455
- 1. Enable HSTS with long max-age
456
- 2. Configure Content-Security-Policy
457
- 3. Set up proper Cache-Control
458
- 4. Hide server information
459
-
460
- ### Long-term
461
- 1. Regular security scanning
462
- 2. Implement OWASP Top 10 controls
463
- 3. Set up monitoring and alerting
464
- 4. Security headers automated testing
465
-
466
- ---
467
-
468
- ## 🔗 Recommended Tools for Deeper Analysis
469
-
470
- | Tool | Purpose |
471
- |------|---------|
472
- | Nuclei | Vulnerability scanning |
473
- | SQLMap | SQL injection testing |
474
- | Dalfox | XSS scanning |
475
- | Nmap | Full port scan |
476
- | testssl.sh | SSL/TLS audit |
477
- | Burp Suite | Web vulnerability testing |
478
-
479
- ---
480
-
481
- ## 📄 Report Location
482
-
483
- **File:** \`$OutputFile\`
484
- **Generated:** $(Get-Date -Format "yyyy-MM-dd HH:mm:ss")
485
- **Author:** Rz (@soulofzephir)
486
-
487
- ---
488
-
489
- **⚠️ Disclaimer:** This is an automated scan. Manual testing recommended for comprehensive security assessment.
455
+ **Generated:** $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')
490
456
  "@
491
457
 
492
458
  $Report | Out-File -FilePath $OutputFile -Encoding UTF8
493
459
 
494
- # ═══════════════════════════════════════════════════════════
495
- # COMPLETE
496
- # ═══════════════════════════════════════════════════════════
497
-
498
460
  Write-Host ""
499
- Write-Host "═══════════════════════════════════════════════════" -ForegroundColor Green
500
- Write-Host " FULL SCAN COMPLETE!" -ForegroundColor Green
501
- Write-Host "═══════════════════════════════════════════════════" -ForegroundColor Green
461
+ Write-Host "========================================" -ForegroundColor Green
462
+ Write-Host " Scan Complete!" -ForegroundColor Green
463
+ Write-Host "========================================" -ForegroundColor Green
502
464
  Write-Host ""
503
- Write-Host "📄 Report: $OutputFile" -ForegroundColor White
465
+ Write-Host "Report: $OutputFile" -ForegroundColor White
504
466
  Write-Host ""
505
- Write-Host "🔗 Quick Links:" -ForegroundColor Cyan
506
- Write-Host " Headers: https://securityheaders.com/?q=$Domain"
507
- Write-Host " SSL: https://ssllabs.com/ssltest/analyze.html?d=$Domain"
467
+ Write-Host "Quick Links:" -ForegroundColor Cyan
468
+ Write-Host " Headers: https://securityheaders.com/?q=$Domain"
469
+ Write-Host " SSL: https://ssllabs.com/ssltest/analyze.html?d=$Domain"
508
470
  Write-Host ""