Téléverser les fichiers vers "/"
This commit is contained in:
1 parent
d0451c9f51
commit
11f99a588f
3 files changed
+124
-1
No files matched your search
@@ -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.
|
||||
@@ -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.'
|
||||
}
|
||||
@@ -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')
|
||||
Reference in new issue
Block a user