@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,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
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
# Full Security Scan - All-in-One
|
|
2
|
-
# Comprehensive security scanner
|
|
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 "
|
|
41
|
-
Write-Host "
|
|
42
|
-
Write-Host "
|
|
43
|
-
Write-Host "
|
|
44
|
-
Write-Host "
|
|
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 "
|
|
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
|
-
|
|
75
|
-
|
|
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 "
|
|
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
|
-
|
|
94
|
+
$HeaderGood += "CSP: Present"
|
|
95
|
+
Write-Host " CSP: Present" -ForegroundColor Green
|
|
85
96
|
$HeaderScore += 20
|
|
86
|
-
if ($CSP -match "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 "
|
|
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
|
-
|
|
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 "
|
|
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
|
-
|
|
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 "
|
|
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
|
-
|
|
131
|
+
$HeaderGood += "Referrer-Policy: $RP"
|
|
132
|
+
Write-Host " Referrer-Policy: Present" -ForegroundColor Green
|
|
116
133
|
$HeaderScore += 10
|
|
117
134
|
} else {
|
|
118
|
-
Write-Host "
|
|
135
|
+
Write-Host " Referrer-Policy: Missing" -ForegroundColor Yellow
|
|
119
136
|
$HeaderScore += 5
|
|
120
137
|
}
|
|
121
138
|
|
|
122
|
-
|
|
123
|
-
$
|
|
124
|
-
|
|
125
|
-
Write-Host "
|
|
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 "
|
|
145
|
+
Write-Host " Permissions-Policy: Missing" -ForegroundColor Yellow
|
|
129
146
|
$HeaderScore += 5
|
|
130
147
|
}
|
|
131
148
|
|
|
132
|
-
|
|
133
|
-
$
|
|
134
|
-
|
|
135
|
-
Write-Host "
|
|
136
|
-
$
|
|
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 "
|
|
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 "
|
|
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
|
-
|
|
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 "
|
|
155
|
-
|
|
156
|
-
|
|
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"
|
|
161
|
-
"/
|
|
162
|
-
"/
|
|
163
|
-
"/
|
|
164
|
-
"/
|
|
165
|
-
"/
|
|
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
|
-
|
|
219
|
+
$TrueExposedFiles = @()
|
|
220
|
+
$FalsePositiveFiles = @()
|
|
221
|
+
|
|
222
|
+
foreach ($item in $CriticalPaths) {
|
|
169
223
|
try {
|
|
170
|
-
$resp = Invoke-WebRequest -Uri "$Target$
|
|
171
|
-
if ($resp.StatusCode -ne 404) {
|
|
172
|
-
|
|
173
|
-
$
|
|
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 ($
|
|
179
|
-
Write-Host "
|
|
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 "
|
|
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
|
-
|
|
203
|
-
|
|
204
|
-
|
|
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
|
-
|
|
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 "
|
|
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 "
|
|
289
|
+
Write-Host " XSS: Possible reflection detected" -ForegroundColor Yellow
|
|
240
290
|
} else {
|
|
241
|
-
Write-Host "
|
|
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",
|
|
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 "
|
|
301
|
+
Write-Host " SQLi: Error detected" -ForegroundColor Yellow
|
|
256
302
|
} else {
|
|
257
|
-
Write-Host "
|
|
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 "
|
|
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 "
|
|
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 "
|
|
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 "
|
|
295
|
-
Write-Host "
|
|
296
|
-
Write-Host "
|
|
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
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
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
|
-
|
|
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
|
-
|
|
310
|
-
|
|
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
|
-
#
|
|
394
|
+
# Security Audit Report
|
|
314
395
|
|
|
315
396
|
**Target:** $Target
|
|
316
397
|
**Domain:** $Domain
|
|
317
398
|
**Date:** $Date
|
|
318
|
-
**Scanner:** Full Security Scan
|
|
399
|
+
**Scanner:** Full Security Scan v3.0
|
|
400
|
+
**Author:** Rz (@soulofzephir)
|
|
319
401
|
|
|
320
402
|
---
|
|
321
403
|
|
|
322
|
-
##
|
|
404
|
+
## Executive Summary
|
|
323
405
|
|
|
324
406
|
| Metric | Value |
|
|
325
407
|
|--------|-------|
|
|
326
|
-
|
|
|
327
|
-
|
|
|
328
|
-
|
|
|
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
|
-
|
|
|
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
|
-
##
|
|
416
|
+
## Security Headers
|
|
346
417
|
|
|
347
|
-
###
|
|
418
|
+
### Score: $HeaderScore/100 ($HeaderGrade)
|
|
348
419
|
|
|
349
|
-
|
|
350
|
-
|
|
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
|
-
|
|
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
|
-
##
|
|
428
|
+
## Exposed Files
|
|
378
429
|
|
|
379
|
-
|
|
380
|
-
|
|
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
|
-
##
|
|
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
|
-
|
|
444
|
+
$(if ($Remediation.Count -gt 0) { $Remediation -join "`n" })
|
|
410
445
|
|
|
411
446
|
---
|
|
412
447
|
|
|
413
|
-
##
|
|
414
|
-
|
|
415
|
-
Basic automated tests completed.
|
|
448
|
+
## Quick Links
|
|
416
449
|
|
|
417
|
-
|
|
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
|
-
|
|
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 "
|
|
500
|
-
Write-Host "
|
|
501
|
-
Write-Host "
|
|
461
|
+
Write-Host "========================================" -ForegroundColor Green
|
|
462
|
+
Write-Host " Scan Complete!" -ForegroundColor Green
|
|
463
|
+
Write-Host "========================================" -ForegroundColor Green
|
|
502
464
|
Write-Host ""
|
|
503
|
-
Write-Host "
|
|
465
|
+
Write-Host "Report: $OutputFile" -ForegroundColor White
|
|
504
466
|
Write-Host ""
|
|
505
|
-
Write-Host "
|
|
506
|
-
Write-Host "
|
|
507
|
-
Write-Host "
|
|
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 ""
|
|
Binary file
|
|
Binary file
|