@soulofzephir/pi-skill-pentesting 1.0.2 → 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 +1 -1
- package/skills/pentesting/SKILL.md +122 -112
- package/skills/pentesting/checklists/api-security.md +210 -0
- package/skills/pentesting/checklists/cloud-metadata.md +290 -0
- package/skills/pentesting/checklists/sensitive-data.md +323 -0
- package/skills/pentesting/checklists/subdomain.md +243 -0
- package/skills/pentesting/checklists/websocket.md +197 -0
- package/skills/pentesting/tools/exposed-files-scan.ps1 +141 -238
- package/skills/pentesting/tools/full-scan.ps1 +278 -316
- package/soulofzephir-pi-skill-pentesting-1.0.2.tgz +0 -0
- package/soulofzephir-pi-skill-pentesting-1.0.3.tgz +0 -0
- package/soulofzephir-pi-skill-pentesting-1.0.4.tgz +0 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
# Exposed Files Scanner
|
|
2
|
-
# Detects dangerous exposed files
|
|
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
|
-
|
|
36
|
-
@{ Path
|
|
37
|
-
@{ Path
|
|
38
|
-
@{ Path
|
|
39
|
-
@{ Path
|
|
40
|
-
@{ Path
|
|
41
|
-
@{ Path
|
|
42
|
-
@{ Path
|
|
43
|
-
@{ Path
|
|
44
|
-
@{ Path
|
|
45
|
-
@{ Path
|
|
46
|
-
@{ Path
|
|
47
|
-
@{ Path
|
|
48
|
-
@{ Path
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
@{ Path
|
|
52
|
-
@{ Path
|
|
53
|
-
@{ Path
|
|
54
|
-
@{ Path
|
|
55
|
-
@{ Path
|
|
56
|
-
@{ Path
|
|
57
|
-
@{ Path
|
|
58
|
-
@{ Path
|
|
59
|
-
@{ Path
|
|
60
|
-
@{ Path
|
|
61
|
-
@{ Path
|
|
62
|
-
@{ Path
|
|
63
|
-
@{ Path
|
|
64
|
-
@{ Path
|
|
65
|
-
@{ Path
|
|
66
|
-
@{ Path
|
|
67
|
-
@{ Path
|
|
68
|
-
@{ Path
|
|
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 "
|
|
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
|
-
$
|
|
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
|
|
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"]
|
|
87
|
+
$ContentType = $Response.Headers["Content-Type"]
|
|
151
88
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
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
|
-
|
|
162
|
-
|
|
163
|
-
"
|
|
164
|
-
|
|
165
|
-
|
|
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
|
-
|
|
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 "
|
|
184
|
-
Write-Host "
|
|
185
|
-
Write-Host "
|
|
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
|
|
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 "
|
|
197
|
-
Write-Host "
|
|
198
|
-
Write-Host "
|
|
199
|
-
Write-Host "
|
|
200
|
-
|
|
201
|
-
#
|
|
202
|
-
|
|
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 (
|
|
206
|
-
|
|
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
|
-
#
|
|
175
|
+
# Exposed Files Report
|
|
211
176
|
|
|
212
177
|
**Target:** $Target
|
|
178
|
+
**Domain:** $Domain
|
|
213
179
|
**Date:** $Date
|
|
214
|
-
**Scanner:** Exposed Files Scanner
|
|
180
|
+
**Scanner:** Exposed Files Scanner v2.0
|
|
181
|
+
**Author:** Rz (@soulofzephir)
|
|
215
182
|
|
|
216
183
|
---
|
|
217
184
|
|
|
218
|
-
##
|
|
185
|
+
## Summary
|
|
219
186
|
|
|
220
187
|
| Metric | Value |
|
|
221
188
|
|--------|-------|
|
|
222
189
|
| Files Scanned | $Scanned |
|
|
223
|
-
| Issues
|
|
224
|
-
|
|
|
225
|
-
|
|
|
226
|
-
|
|
|
227
|
-
|
|
|
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
|
-
##
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
##
|
|
211
|
+
## Remediation
|
|
304
212
|
|
|
305
|
-
-
|
|
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
|
-
**
|
|
217
|
+
**Generated:** $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')
|
|
318
218
|
"@
|
|
319
219
|
|
|
320
|
-
|
|
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 "
|
|
325
|
-
Write-Host "
|
|
326
|
-
Write-Host "
|
|
227
|
+
Write-Host "========================================" -ForegroundColor Green
|
|
228
|
+
Write-Host " Scan Complete!" -ForegroundColor Green
|
|
229
|
+
Write-Host "========================================" -ForegroundColor Green
|
|
327
230
|
Write-Host ""
|
|
328
|
-
Write-Host "
|
|
231
|
+
Write-Host "Report: $OutputFile" -ForegroundColor White
|
|
329
232
|
Write-Host ""
|
|
330
233
|
|
|
331
234
|
if ($CriticalCount -gt 0) {
|
|
332
|
-
Write-Host "
|
|
235
|
+
Write-Host "IMMEDIATE ACTION REQUIRED!" -ForegroundColor Red
|
|
333
236
|
}
|