Téléverser les fichiers vers "/"

This commit is contained in:
pcosson committed 2026-10-30 08:48:13 +00:00
1 parent d0451c9f51
commit 11f99a588f
3 files changed
+124 -1

No files matched your search

+25 -1
View File
@@ -1,2 +1,26 @@
# comi-hardening-windows
# Com itari Windows hardening safe v1 (WAPT source)
SOURCE ONLY: must build and sign with the organization's WAPT tooling. Not yet Windows/WAPT-tested.
## Scope
Five HKLM registry settings: disable AutoRun and AutoPlay (including non-volume devices), disable lock-screen camera and slideshows. No account / password / LAPS change. No WAPT, firewall, network, SMB, BitLocker, Microsoft Defender, antivirus, remote desktop, printing or power settings change.
## Safeguards
- Initial values saved once in `%ProgramData%\Comitari\HardeningSafe\original-values.json` before any modifications.
- Reinstallation idempotent; uninstall conditional: restores only values still equal to package target, leaving externally modified values unchanged.
- No reboot forced. Audit implemented.
- State persists after uninstall intentionally, so repeated uninstall does not overwrite third-party edits.
- Policy owner can override package; audit then reports WARNING.
## Deployment
1. Inspect `setup.py` and `hardening.ps1` in an isolated preproduction repository.
2. Validate registry settings and resulting behavior on a Windows 11 25H2 representative workstation, especially AutoPlay workflow.
3. Build/sign WAPT package with organization's key. Do not distribute unsigned sources as a ready-to-deploy binary.
4. Deploy to 1 test PC, verify WAPT agent/check-in, LapsByWAPT password rotation and recovery, business apps, USB workflows.
5. Expand to 3-5 devices for 48h and later to waves. Remove machine dependency before `wapt-get remove`; see WAPT docs on remove vs uninstall.
6. Verify rollback in pilot via `wapt-get uninstall comitari-hardening-safe` (function call) and validate state.
IMPORTANT: `wapt-get remove` is NOT assured to execute a custom uninstall() function. Follow your WAPT version's verified removal workflow and audit this before promotion.
## Deliberately deferred
Windows LAPS controls 10701-10703 (LapsByWAPT alternative); firewall enforcement; VBS/HVCI/Credential Guard; ASR; NTLM/SMB guest/signing; SMBv1 removal; BitLocker; print drivers; user rights; audit logging and command-line collection; remote admin; LLMNR and NetBIOS. These require separate pilot checks.
+66
View File
@@ -0,0 +1,66 @@
param([ValidateSet('install','audit','uninstall')][string]$Action = 'audit')
$ErrorActionPreference = 'Stop'
$stateDir = Join-Path $env:ProgramData 'Comitari\HardeningSafe'
$stateFile = Join-Path $stateDir 'original-values.json'
# Only low-impact, machine-wide controls. Deliberately excludes Windows LAPS, accounts,
# services, remote management, networking, firewall policy, BitLocker and Defender.
$settings = @(
@{ Path='HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer'; Name='NoAutorun'; Value=1 },
@{ Path='HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer'; Name='NoDriveTypeAutoRun'; Value=255 },
@{ Path='HKLM:\SOFTWARE\Policies\Microsoft\Windows\Explorer'; Name='NoAutoplayfornonVolume'; Value=1 },
@{ Path='HKLM:\SOFTWARE\Policies\Microsoft\Windows\Personalization'; Name='NoLockScreenCamera'; Value=1 },
@{ Path='HKLM:\SOFTWARE\Policies\Microsoft\Windows\Personalization'; Name='NoLockScreenSlideshow'; Value=1 }
)
function Read-Value($path, $name) {
if (-not (Test-Path -LiteralPath $path)) { return @{ Exists=$false; Value=$null } }
$key = Get-Item -LiteralPath $path
if ($key.GetValueNames() -contains $name) {
return @{ Exists=$true; Value=[int]$key.GetValue($name) }
}
return @{ Exists=$false; Value=$null }
}
function Write-Value($path, $name, [int]$value) {
if (-not (Test-Path -LiteralPath $path)) { New-Item -Path $path -Force | Out-Null }
New-ItemProperty -LiteralPath $path -Name $name -Value $value -PropertyType DWord -Force | Out-Null
}
if ($Action -eq 'install') {
if (-not (Test-Path -LiteralPath $stateDir)) { New-Item -Path $stateDir -ItemType Directory -Force | Out-Null }
if (-not (Test-Path -LiteralPath $stateFile)) {
$original = @()
foreach ($setting in $settings) {
$old = Read-Value $setting.Path $setting.Name
$original += [pscustomobject]@{ Path=$setting.Path; Name=$setting.Name; Exists=$old.Exists; Value=$old.Value; Target=$setting.Value }
}
$json = ConvertTo-Json -InputObject @($original) -Depth 5
$temp = "$stateFile.tmp"
[System.IO.File]::WriteAllText($temp, $json, [System.Text.UTF8Encoding]::new($false))
Move-Item -LiteralPath $temp -Destination $stateFile -Force
}
foreach ($setting in $settings) { Write-Value $setting.Path $setting.Name $setting.Value }
Write-Output 'Installed conservative hardening; LapsByWAPT untouched.'
}
elseif ($Action -eq 'audit') {
$failed = @()
foreach ($setting in $settings) {
$actual = Read-Value $setting.Path $setting.Name
if (-not $actual.Exists -or $actual.Value -ne $setting.Value) { $failed += "$($setting.Name) != $($setting.Value)" }
}
if ($failed.Count -gt 0) { $failed | ForEach-Object { Write-Output $_ }; exit 1 }
Write-Output 'All 5 settings compliant.'
}
else {
if (-not (Test-Path -LiteralPath $stateFile)) { throw 'No saved baseline; refusing blind rollback.' }
$original = @(Get-Content -LiteralPath $stateFile -Raw | ConvertFrom-Json)
foreach ($item in $original) {
$current = Read-Value $item.Path $item.Name
# Do not override later changes made by GPO or another administrator.
if (-not $current.Exists -or $current.Value -ne [int]$item.Target) {
Write-Output "Skipped externally changed setting: $($item.Name)"
continue
}
if ($item.Exists) { Write-Value $item.Path $item.Name ([int]$item.Value) }
else { Remove-ItemProperty -LiteralPath $item.Path -Name $item.Name -ErrorAction Stop }
}
# Keep baseline for forensic trace; uninstall is idempotent only for settings still matching targets.
Write-Output 'Conditional rollback completed; LapsByWAPT untouched.'
}
+33
View File
@@ -0,0 +1,33 @@
# -*- coding: utf-8 -*-
from setuphelpers import *
import os
import subprocess
uninstallkey = []
def _run(action):
script = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'hardening.ps1')
result = subprocess.run(['powershell.exe', '-NoProfile', '-NonInteractive', '-ExecutionPolicy', 'Bypass', '-File', script, '-Action', action], capture_output=True, text=True)
print(result.stdout)
if result.stderr:
print(result.stderr)
if result.returncode != 0:
raise Exception('Hardening %s failed with code %s' % (action, result.returncode))
def install():
_run('install')
def audit():
try:
_run('audit')
return 'OK'
except Exception as exc:
print(exc)
return 'WARNING'
def uninstall():
_run('uninstall')