diff --git a/cybersecurity/Network Reputation Service/script-nrs.ps1 b/cybersecurity/Network Reputation Service/script-nrs.ps1 new file mode 100644 index 0000000..5a7b48c --- /dev/null +++ b/cybersecurity/Network Reputation Service/script-nrs.ps1 @@ -0,0 +1,521 @@ +# Script d'Audit Firewall - Network Reputation Service +# Auteur: Hubert Cornet +# Date: 03/09/2025 +# Version: 1.0 + +Clear-Host + +# Configuration globale +$ErrorActionPreference = "Continue" +$WarningPreference = "SilentlyContinue" + +### Functions ### + +## Function Write-ColorOutput +Function Write-ColorOutput { + Param( + [string]$Text, + [string]$Color = "White" + ) + + Try { + Write-Host $Text -ForegroundColor $Color + } + Catch { + Write-Host $Text + } +} + +## Function Prerequisites +Function Prerequisites { + Write-ColorOutput "`n=== Vérification des prérequis ===" "Cyan" + + # Vérification du fichier JSON + $JsonFile = Join-Path $PSScriptRoot "file-nrs.json" + + If(-not (Test-Path $JsonFile)) { + Write-ColorOutput "ERREUR: Le fichier 'file-nrs.json' n'existe pas!" "Red" + Write-ColorOutput "Veuillez télécharger ou créer le fichier depuis:" "Yellow" + Write-ColorOutput "https://github.com/your-repo/file-nrs.json" "Blue" + Write-ColorOutput "Le fichier doit être placé dans le même dossier que ce script." "Yellow" + + Return $false + } + + Write-ColorOutput "✓ Fichier 'file-nrs.json' trouvé" "Green" + + # Vérification/Installation des modules requis + $RequiredModules = @('PSWriteHTML', 'PSWriteColor') + + Foreach ($Module in $RequiredModules) { + If(-not (Get-Module -ListAvailable -Name $Module)) { + Write-ColorOutput "Installation du module $Module..." "Yellow" + + Try { + Install-Module -Name $Module -Force -Scope CurrentUser -AllowClobber + + Write-ColorOutput "✓ Module $Module installé" "Green" + } + Catch { + Write-ColorOutput "ERREUR: Impossible d'installer le module $Module : $($_.Exception.Message)" "Red" + + Return $false + } + } + Else { + Write-ColorOutput "✓ Module $Module disponible" "Green" + } + + Import-Module $Module -Force + } + + return $true +} + +## Function Check-Categories +Function Check-Categories { + Param( + [array]$Categories, + [string]$ProxyUrl = "", + [System.Management.Automation.PSCredential]$ProxyCredential = $null, + [int]$TimeoutSeconds = 10 + ) + + $AllResults = @() + $CategoryCount = 0 + + $BlockKeywors = @("site bloqué", "access denied", "filtrage web", "Access Denied", "Site Blocked") # Définir les mots-clés des page des blocage + + Foreach ($Category in $Categories.Categorie) { + $CategoryCount++ + + Show-ProgressBar -Current $CategoryCount -Total $Categories.Categorie.Count -Activity "Test des catégories" -Status "Catégorie: $($category.Categorie.nom)" + + Write-ColorOutput "`n=== Test de la catégorie: $($Category.nom) ===" "Cyan" + #Write-ColorOutput "Description: $($category.description)" "Gray" + + $CategoryResults = @() + $UrlCount = 0 + + Foreach ($UrlObj in $Category.urls) { + $UrlCount++ + + Show-ProgressBar -Current $UrlCount -Total $Category.urls.Count -Activity "Test des URLs de '$($Category.nom)'" -Status $UrlObj.url + + Write-ColorOutput "Test de: $($UrlObj.url)" "Yellow" + + #$Result = Get-UrlStatus -Url $UrlObj.url -ProxyUrl $ProxyUrl -ProxyCredential $ProxyCredential -TimeoutSeconds $TimeoutSeconds -BlockPageKeywords $BlockPageKeywords + + $Result = Get-UrlStatus $UrlObj.url $UrlObj.expected_action $BlockPageKeywords + + $TestResult = [PSCustomObject]@{ + Category = $category.nom + CategoryId = $category.id + Url = $urlObj.url + Reputation = $urlObj.reputation + ExpectedAction = $urlObj.expected_action + Status = $result.ActualResult + StatusCode = $result.StatusCode + ResponseTime = $result.ResponseTime + Error = $result.Details + Score = $result.Score + IsCorrect = (($TestResult.Status -eq "Bloqué" -and $UrlObj.expected_action -eq "block") -or ($TestResult.Status -eq "Autorisé" -and $UrlObj.expected_action -eq "allow")) + } + + $StatusColor = If($testResult.IsCorrect) { "Green" } Else { "Red" } + Write-ColorOutput " → Résultat: $($TestResult.Status) | Attendu: $($TestResult.ExpectedAction) | Correct: $($TestResult.IsCorrect)" $statusColor + + $categoryResults += $testResult + $allResults += $testResult + } + + $CategoryScore = Calculate-CategoryScore -Results $categoryResults + $CategoryGrade = Convert-ScoreToGrade -Score $categoryScore + + Write-ColorOutput "Score de la catégorie '$($Category.nom)': $categoryScore% (Note: $CategoryGrade)" "Magenta" + } + + Write-Progress -Activity "Test des catégories" -Completed + Write-Progress -Activity "Test des URLs" -Completed + + return $allResults +} + +## Function Show-ProgressBar +Function Show-ProgressBar { + Param( + [int]$Current, + [int]$Total, + [string]$Activity, + [string]$Status = "" + ) + + $Percent = [math]::Round(($Current / $Total) * 100, 1) + + Write-Progress -Activity $Activity -Status "$Status ($Current/$Total)" -PercentComplete $Percent +} + +## FunctionCalculate-CategoryScore +Function Calculate-CategoryScore { + Param( + [array]$Results + ) + + $TotalUrls = $Results.Count + $CorrectResults = 0 + + Foreach ($Result in $Results) { + $IsBlocked = $Result.Status -eq "Bloqué" + $ShouldBeBlocked = $result.ExpectedAction -eq "block" + + If(($IsBlocked -and $ShouldBeBlocked) -or (-not $IsBlocked -and -not $ShouldBeBlocked)) { + $CorrectResults++ + } + } + + If($TotalUrls -eq 0) { + Return 0 + } + + Return [math]::Round(($CorrectResults / $TotalUrls) * 100, 2) +} + +## Function Convert-ScoreToGrade +Function Convert-ScoreToGrade { + Param([double]$Score) + + switch ($Score) { + {$_ -ge 95} { return 'A+' } + {$_ -ge 90} { return 'A' } + {$_ -ge 85} { return 'B+' } + {$_ -ge 80} { return 'B' } + {$_ -ge 75} { return 'C+' } + {$_ -ge 70} { return 'C' } + {$_ -ge 65} { return 'D+' } + {$_ -ge 60} { return 'D' } + {$_ -ge 55} { return 'E+' } + {$_ -ge 50} { return 'E' } + {$_ -ge 45} { return 'F+' } + default { return 'F' } + } +} + +## Function Get-UrlStatus +Function Get-UrlStatus { + Param( + [string]$Url, + [string]$ExpectedAction, # 'allow' ou 'block' + [string[]]$BlockPageKeywords, # Exemple: @("Access Denied", "Site Blocked") + [string]$ProxyAddress = $null, + [string]$ProxyUseAuthentication = $null, + [int]$Timeout = 10 + ) + + $Result = [PSCustomObject]@{ + Url = $Url + Expected = $ExpectedAction + ActualResult = "Indéterminé" # Ce qui s'est réellement passé (Bloqué/Autorisé) + TestStatus = "Échec" # Le statut du test (Conforme/Non Conforme) + Score = $Null + StatusCode = "" + Details = "" + ResponseTime = "" + } + + # Préparation des paramètres pour Invoke-WebRequest (Splatting) + $IWRParams = @{ + Uri = $Url + UseBasicParsing = $True + TimeoutSec = $Timeout + ErrorAction = 'Stop' + } + + $Response = $Null + + # Ajout des paramètres du proxy s'ils sont fournis + If (-not [string]::IsNullOrEmpty($ProxyAddress)) { + $IWRParams.Add('Proxy', $ProxyAddress) + + If ($ProxyUseAuthentication) { + # Demande les identifiants de manière sécurisée et les ajoute à la commande + $Creds = Get-Credential -Message "Veuillez saisir les identifiants pour le proxy $ProxyAddress" + $IWRParams.Add('ProxyCredential', $Creds) + } + } + + # -- Exécution du test -- + Try { + # Exécution de la requête en utilisant les paramètres définis dans la hashtable + $Response = Invoke-WebRequest @IWRParams + + # On vérifie si la réponse contient des mots-clés de la page de blocage + $KeywordFound = $False + + Foreach ($Keyword in $BlockPageKeywords) { + If ($Response.Content -match $Keyword) { + $KeywordFound = $True + + break + } + } + + If ($KeywordFound) { + $Result.ActualResult = "Bloqué" +# $Result.Score = 1 + $Result.Details = "Page de blocage détectée." + $Result.StatusCode = $Response.StatusCode + } + Else { + $Result.ActualResult = "Autorisé" +# $Result.Score = 0 + $Result.Details = "Le site a été atteint sans blocage." + $Result.StatusCode = $Response.StatusCode + } + + } + Catch [System.Net.WebException] { + If ($_.Exception.Status -eq 'Timeout') { + $Result.ActualResult = "Bloqué (Timeout)" +# $Result.Score = 1 + $Result.Details = "La requête a expiré, indiquant un blocage probable par le pare-feu ou le proxy." + $Result.StatusCode = $Response.StatusCode + $Result.ResponseTime = "$Timeout" + } +# Elseif ($_.Exception.Response) { +# $Result.Status = "Bloqué (Erreur HTTP)" +# $Result.Score = 1 +# $Result.Details = "Réponse HTTP non-200 reçue : $($_.Exception.Response.StatusCode)" +# } + Else { + # On considère les autres erreurs réseau comme un blocage aussi + $Result.ActualResult = "Erreur de Connexion" + $Result.Details = "Impossible de joindre le serveur : $($_.Exception.Status)" + $Result.StatusCode = $Response.StatusCode + } + } + Catch { + $Result.ActualResult = "Erreur Script" + $Result.Details = "Erreur inattendue: $($_.Exception.Message)" + + #$Result.StatusCode = 0 <= A trouver + #$Result.ResponseTime = 0 <= A trouver + + # Un test en erreur ne doit pas donner de point + return $result + } + + # Le test est réussi si l'action attendue correspond au résultat réel. + If (($Result.Expected -eq 'block' -and $Result.ActualResult -eq 'Bloqué') -or ($Result.Expected -eq 'allow' -and $Result.ActualResult -eq 'Autorisé')) { + $Result.TestStatus = "Conforme" + $Result.Score = 1 # Le test est un succès ! + $Result.Details += " (Résultat conforme à l'attendu)" + } + Else { + $Result.TestStatus = "Non Conforme" + $Result.Score = 0 # Le test est un échec ! + $Result.Details += " (Résultat NON CONFORME; Attendu: $($Result.Expected); Obtenu: $($Result.ActualResult))" + } + + Return $Result +} + +## Function Generate-HtmlReport +Function Generate-HtmlReport { + Param( + [array]$Results, + [string]$OutputPath + ) + + Write-ColorOutput "Génération du rapport HTML..." "Yellow" + + # Calcul des scores + $Categories = $Results | Group-Object Category + $CategoryScores = @() + + Foreach ($Cat in $Categories) { + $Score = Calculate-CategoryScore -Results $Cat.Group + $Grade = Convert-ScoreToGrade -Score $Score + + $CategoryScores += [PSCustomObject]@{ + Category = $cat.Name + Score = $score + Grade = $grade + Color = $GradeColors[$grade] + TotalUrls = $cat.Group.Count + CorrectResults = ($cat.Group | Where-Object IsCorrect).Count + } + } + + # Score global + $globalScore = Calculate-CategoryScore -Results $Results + $globalGrade = Convert-ScoreToGrade -Score $globalScore + + # Création du rapport HTML + New-HTML -TitleText "Audit Firewall - Network Reputation Service" -Online -FilePath $OutputPath { + New-HTMLHeader { + New-HTMLText -Text "Audit Firewall - Network Reputation Service" -FontSize 28 -FontWeight bold -Color Blue -Alignment center + New-HTMLText -Text "Rapport généré le $(Get-Date -Format 'dd/MM/yyyy à HH:mm')" -FontSize 14 -Color Gray -Alignment center + } + + New-HTMLSection -HeaderText "Résumé Exécutif" -BackgroundColor LightBlue { + New-HTMLPanel { + New-HTMLText -Text "Score Global: $globalScore% - Note: $globalGrade" -FontSize 24 -FontWeight bold -Color $GradeColors[$globalGrade] + New-HTMLText -Text "Total des URLs testées: $($Results.Count)" -FontSize 16 + New-HTMLText -Text "URLs correctement filtrées: $(($Results | Where-Object IsCorrect).Count)" -FontSize 16 + New-HTMLText -Text "Taux de réussite: $([math]::Round((($Results | Where-Object IsCorrect).Count / $Results.Count) * 100, 2))%" -FontSize 16 + } + } + + New-HTMLSection -HeaderText "Scores par Catégorie" -BackgroundColor LightGray { + New-HTMLTable -DataTable $categoryScores -HideFooter { + New-HTMLTableHeader -Names "Category", "Score", "Grade", "TotalUrls", "CorrectResults" -Title "Scores par Catégorie" + New-HTMLTableCondition -Name 'Grade' -ComparisonType string -Operator eq -Value 'A+' -BackgroundColor '#28a745' -Color White + New-HTMLTableCondition -Name 'Grade' -ComparisonType string -Operator eq -Value 'A' -BackgroundColor '#52b83a' -Color White + New-HTMLTableCondition -Name 'Grade' -ComparisonType string -Operator eq -Value 'B+' -BackgroundColor '#7ac92e' -Color White + New-HTMLTableCondition -Name 'Grade' -ComparisonType string -Operator eq -Value 'B' -BackgroundColor '#a3da23' -Color Black + New-HTMLTableCondition -Name 'Grade' -ComparisonType string -Operator eq -Value 'C+' -BackgroundColor '#cceb17' -Color Black + New-HTMLTableCondition -Name 'Grade' -ComparisonType string -Operator eq -Value 'C' -BackgroundColor '#f5f90c' -Color Black + New-HTMLTableCondition -Name 'Grade' -ComparisonType string -Operator eq -Value 'D+' -BackgroundColor '#f7d808' -Color Black + New-HTMLTableCondition -Name 'Grade' -ComparisonType string -Operator eq -Value 'D' -BackgroundColor '#f9b604' -Color Black + New-HTMLTableCondition -Name 'Grade' -ComparisonType string -Operator eq -Value 'E+' -BackgroundColor '#fb9500' -Color White + New-HTMLTableCondition -Name 'Grade' -ComparisonType string -Operator eq -Value 'E' -BackgroundColor '#fd7300' -Color White + New-HTMLTableCondition -Name 'Grade' -ComparisonType string -Operator eq -Value 'F+' -BackgroundColor '#ff5100' -Color White + New-HTMLTableCondition -Name 'Grade' -ComparisonType string -Operator eq -Value 'F' -BackgroundColor '#dc3545' -Color White + } + } + + New-HTMLSection -HeaderText "Détail des Tests par Catégorie" -BackgroundColor White { + foreach ($category in $categories) { + $catScore = ($categoryScores | Where-Object Category -eq $category.Name).Score + $catGrade = ($categoryScores | Where-Object Category -eq $category.Name).Grade + + New-HTMLSection -HeaderText "$($category.Name) - Score: $catScore% ($catGrade)" -BackgroundColor LightYellow -Collapsible { + $detailedResults = $category.Group | Select-Object Url, Reputation, ExpectedAction, Status, IsCorrect, Error + New-HTMLTable -DataTable $detailedResults -HideFooter { + New-HTMLTableCondition -Name 'IsCorrect' -ComparisonType string -Operator eq -Value 'True' -BackgroundColor '#d4edda' -Color '#155724' + New-HTMLTableCondition -Name 'IsCorrect' -ComparisonType string -Operator eq -Value 'False' -BackgroundColor '#f8d7da' -Color '#721c24' + } + } + } + } + + New-HTMLSection -HeaderText "Barème de Notation" -BackgroundColor LightGreen -Collapsible { + $gradingScale = @( + [PSCustomObject]@{Grade='A+'; Score='95-100%'; Interpretation='Excellent / Parfait'} + [PSCustomObject]@{Grade='A'; Score='90-95%'; Interpretation='Très bon niveau de filtrage'} + [PSCustomObject]@{Grade='B+'; Score='85-90%'; Interpretation='Très bon'} + [PSCustomObject]@{Grade='B'; Score='80-85%'; Interpretation='Bon, mais quelques ajustements nécessaires'} + [PSCustomObject]@{Grade='C+'; Score='75-80%'; Interpretation='Assez bon'} + [PSCustomObject]@{Grade='C'; Score='70-75%'; Interpretation='Moyen, lacunes importantes'} + [PSCustomObject]@{Grade='D+'; Score='65-70%'; Interpretation='Passable'} + [PSCustomObject]@{Grade='D'; Score='60-65%'; Interpretation='Faible, filtrage inefficace'} + [PSCustomObject]@{Grade='E+'; Score='55-60%'; Interpretation='Très faible'} + [PSCustomObject]@{Grade='E'; Score='50-55%'; Interpretation='Insuffisant'} + [PSCustomObject]@{Grade='F+'; Score='45-50%'; Interpretation='Critique'} + [PSCustomObject]@{Grade='F'; Score='0-45%'; Interpretation='Très faible, action immédiate requise'} + ) + + New-HTMLTable -DataTable $gradingScale -HideFooter + } + } + + Write-ColorOutput "✓ Rapport généré: $OutputPath" "Green" +} + +## Function Main +Function Main { + Write-ColorOutput @" +╔══════════════════════════════════════════════════════════════════════════════╗ +║ AUDIT FIREWALL - NETWORK REPUTATION SERVICE ║ +║ Version 1.0 ║ +╚══════════════════════════════════════════════════════════════════════════════╝ +"@ "Cyan" + + # Vérification des prérequis + If(-not (Prerequisites)) { + Write-ColorOutput "ERREUR: Les prérequis ne sont pas satisfaits. Arrêt du script." "Red" + + Return + } + + # Chargement du fichier JSON + Try { + $JsonFile = Join-Path $PSScriptRoot "file-nrs.json" + $Categories = Get-Content $JsonFile -Raw -Encoding UTF8 | ConvertFrom-Json + + Write-ColorOutput "✓ Fichier JSON chargé avec $($Categories.categorie.Count) catégories" "Green" + } + Catch { + Write-ColorOutput "ERREUR: Impossible de charger le fichier JSON: $($_.Exception.Message)" "Red" + + Return + } + + # Création du dossier de sortie + $ReportDate = Get-Date -Format "dddd dd MMMM yyyy-HH mm" + $ReportsDir = Join-Path $PSScriptRoot "Rapports" + $OutputDir = Join-Path $ReportsDir $ReportDate + + If (-not (Test-Path $ReportsDir)) { + New-Item -ItemType Directory -Path $ReportsDir -Force | Out-Null + } + + If (-not (Test-Path $OutputDir)) { + New-Item -ItemType Directory -Path $OutputDir -Force | Out-Null + } + + Write-ColorOutput "`n Dossier de sortie: $outputDir" "Yellow" + + # Début des tests + Write-ColorOutput "`n=== DÉBUT DES TESTS ===" "Green" + $StartTime = Get-Date + + $AllResults = Check-Categories -Categories $Categories -ProxyUrl $ProxyUrl -ProxyCredential $ProxyCredential -TimeoutSeconds $TimeoutSeconds -BlockPageKeywords $BlockKeywors + + $EndTime = Get-Date + $Duration = $EndTime - $StartTime + + Write-ColorOutput "`n=== RÉSULTATS FINAUX ===" "Green" + Write-ColorOutput "`n Temps total d'exécution: $($duration.ToString('hh\:mm\:ss'))" "Yellow" + Write-ColorOutput "`n Total des URLs testées: $($allResults.Count)" "Yellow" + + # Calcul du score global + $GlobalScore = Calculate-CategoryScore -Results $AllResults + $GlobalGrade = Convert-ScoreToGrade -Score $GlobalScore + + Write-ColorOutput "`n `n Score global: $GlobalScore% - Note: $GlobalGrade" "Magenta" + + # Génération du rapport HTML + $ReportPath = Join-Path $OutputDir "Audit_Firewall_Report.html" + Generate-HtmlReport -Results $AllResults -OutputPath $ReportPath + + # Sauvegarde des résultats en JSON + $JsonResultsPath = Join-Path $outputDir "Results.json" + $AllResults | ConvertTo-Json -Depth 10 | Out-File -FilePath $JsonResultsPath -Encoding UTF8 + Write-ColorOutput "✓ Résultats sauvegardés: $JsonResultsPath" "Green" + + Write-ColorOutput "`n=== AUDIT TERMINÉ ===" "Green" + Write-ColorOutput "Rapport disponible à: $ReportPath" "Cyan" + + # Ouverture automatique du rapport + If (Get-Command "Start-Process" -ErrorAction SilentlyContinue) { + $OpenReport = Read-Host "Voulez-vous ouvrir le rapport maintenant? (O/N)" + If ($OpenReport -eq "O" -or $OpenReport -eq "o" -or $OpenReport -eq "Y" -or $OpenReport -eq "y") { + Start-Process $ReportPath + } + } +} + +### Main + +Clear-Host + +# Exécution du script principal +Try { + Main +} +Catch { + Write-ColorOutput "ERREUR FATALE: $($_.Exception.Message)" "Red" + Write-ColorOutput "Stack Trace: $($_.ScriptStackTrace)" "Red" +} +