This commit is contained in:
Luftmensch
2026-08-26 14:11:37 +07:00
commit e528419f9a
135 changed files with 413970 additions and 0 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
+97
View File
@@ -0,0 +1,97 @@
import re, json, sys, io
from openpyxl import load_workbook
from unidecode import unidecode
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
# Extract all checks from PowerShell script
ps_content = open(r'D:\VNPT-M\Tool\audit_tool\NEW\Update\audit_lhdsin\audit_check_script\audit_cis_windows.ps1', 'r', encoding='utf-8').read()
checks = re.findall(r'Write-CheckResult\s+"(.+?)"\s+"(.+?)"', ps_content)
print(f'PS script checks: {len(checks)}')
# Build criteria lookup: CheckId -> description
ps_criteria = {}
for cid, desc in checks:
full = f"{cid}. {desc}"
key = unidecode(full)
ps_criteria[key] = (cid, full)
# Load Excel checklist
wb = load_workbook(r'D:\VNPT-M\Tool\audit_tool\NEW\Update\audit_lhdsin\config\Windows_Checklist.xlsx')
ws = wb.worksheets[0]
# Build row mapping: scan Excel for criteria IDs (like "1.1.1" in column A)
# Compare unidecode'd criteria text to match PS output
excel_rows = {}
print(f'\nScanning Excel rows 1-{ws.max_row} for criteria IDs...')
for row in range(1, ws.max_row + 1):
val_a = ws.cell(row=row, column=1).value
val_b = ws.cell(row=row, column=2).value
# Try to find criteria ID in column A (like "1.1.1")
text_a = str(val_a).strip() if val_a else ""
text_b = str(val_b).strip() if val_b else ""
# Check if this row has a criteria ID pattern (like "1.1.1" or "1.1.1.")
# Also try matching the full text from column B
combined = f"{text_a} {text_b}".strip()
norm = unidecode(combined)
if norm in ps_criteria:
cid, full_text = ps_criteria[norm]
excel_rows[row] = full_text
del ps_criteria[norm] # Remove matched
# Now try matching by CheckId prefix in column A
still_unmatched = dict(ps_criteria)
for cid_key, (cid, full_text) in still_unmatched.items():
for row in range(1, ws.max_row + 1):
val_a = str(ws.cell(row=row, column=1).value or "").strip()
if val_a and cid in val_a:
excel_rows[row] = full_text
del ps_criteria[cid_key]
break
print(f'\nMatched via full text: {len(excel_rows)}')
print(f'Matched via ID search: {194 - len(ps_criteria) - len(excel_rows)}')
print(f'Still unmatched: {len(ps_criteria)}')
# For unmatched, find the closest row by ID pattern
# Parse CheckId like "1.1.1" into section numbers
for cid_key, (cid, full_text) in list(ps_criteria.items()):
parts = cid.split('.')
# Try to find a row where column A contains this ID prefix
found = False
for row in range(1, ws.max_row + 1):
val_a = str(ws.cell(row=row, column=1).value or "").strip()
if val_a == cid or val_a == cid + '.':
if row not in excel_rows:
excel_rows[row] = full_text
del ps_criteria[cid_key]
found = True
break
if not found:
print(f' No Excel row for: [{cid}] {full_text[:60]}')
print(f'\nFinal matched rows: {len(excel_rows)}')
print(f'Final unmatched: {len(ps_criteria)}')
# Build new config
new_data = []
for row in sorted(excel_rows.keys()):
new_data.append({str(row): excel_rows[row]})
new_config = {"data": new_data}
# Write new config
output_path = r'D:\VNPT-M\Tool\audit_tool\NEW\Update\audit_lhdsin\config\windows_config_new.json'
with open(output_path, 'w', encoding='utf-8') as f:
json.dump(new_config, f, ensure_ascii=False, indent=4)
print(f'\nNew config written to: {output_path}')
print(f'Entries: {len(new_data)}')
# Print summary of row mapping
print('\nSample row mapping:')
for row in sorted(excel_rows.keys())[:10]:
print(f' Row {row}: {excel_rows[row][:70]}')
+24
View File
@@ -0,0 +1,24 @@
import json
from unidecode import unidecode
with open(r'D:\VNPT-M\Tool\audit_tool\NEW\Update\audit_lhdsin\output\MEVAS-NTL-DATAN_2026_07_29-05_18_36.txt', 'r', encoding='utf-8', errors='replace') as f:
lines = f.readlines()
with open(r'D:\VNPT-M\Tool\audit_tool\NEW\Update\audit_lhdsin\tools\debug_output.txt', 'w', encoding='utf-8') as out:
for i, line in enumerate(lines):
if any(x in line for x in ['2.1.2', '2.1.15', '2.1.17', '2.1.21', '2.1.22']):
if 'Access' in line or 'Create' in line or 'Deny' in line or 'Enable' in line:
out.write(f'Line {i+1}:\n')
out.write(f' RAW: {repr(line.strip())}\n')
out.write(f' NORM: {unidecode(line.strip())}\n')
out.write('\n')
# Also show what's in the PS script for comparison
out.write('=== PS Script variants ===\n')
ps = open(r'D:\VNPT-M\Tool\audit_tool\NEW\Update\audit_lhdsin\audit_check_script\audit_cis_windows.ps1', 'r', encoding='utf-8').read()
import re
for m in re.finditer(r'Write-CheckResult\s+"(2\.1\.\d+)"\s+"(.+?)"', ps):
out.write(f' CheckId={m.group(1)} Desc={m.group(2)[:80]}\n')
out.write(f' Normalized: {unidecode(m.group(2))}\n')
print('Debug output written to tools/debug_output.txt')
+139
View File
@@ -0,0 +1,139 @@
Line 22:
RAW: '{"2.1.2. Cau hinh chinh sach \'Access this computer from the network\' [Ch% MS]" : "FAILED"}'
NORM: {"2.1.2. Cau hinh chinh sach 'Access this computer from the network' [Ch% MS]" : "FAILED"}
Line 34:
RAW: '{"2.1.15. Cau hinh chinh sach \'Create symbolic links\' [Ch% MS]" : "FAILED"}'
NORM: {"2.1.15. Cau hinh chinh sach 'Create symbolic links' [Ch% MS]" : "FAILED"}
Line 36:
RAW: '{"2.1.17. Cau hinh chinh sach \'Deny access to this computer from the network\' [Ch% MS]" : "FAILED"}'
NORM: {"2.1.17. Cau hinh chinh sach 'Deny access to this computer from the network' [Ch% MS]" : "FAILED"}
Line 39:
RAW: '{"2.1.20. Cau hinh chinh sach \'Deny log on locally\'" : "FAILED"}'
NORM: {"2.1.20. Cau hinh chinh sach 'Deny log on locally'" : "FAILED"}
Line 40:
RAW: '{"2.1.21. Cau hinh chinh sach \'Deny log on through Remote Desktop Services\' [Ch% MS]" : "FAILED"}'
NORM: {"2.1.21. Cau hinh chinh sach 'Deny log on through Remote Desktop Services' [Ch% MS]" : "FAILED"}
Line 41:
RAW: '{"2.1.22. Cau hinh chinh sach \'Enable computer and user accounts to be trusted for delegation\' [Ch% MS]" : "PASSED"}'
NORM: {"2.1.22. Cau hinh chinh sach 'Enable computer and user accounts to be trusted for delegation' [Ch% MS]" : "PASSED"}
Line 165:
RAW: "[2.1.2] Cau hinh chinh sach 'Access this computer from the network' [Ch% MS]"
NORM: [2.1.2] Cau hinh chinh sach 'Access this computer from the network' [Ch% MS]
Line 174:
RAW: "[2.1.15] Cau hinh chinh sach 'Create symbolic links' [Ch% MS]"
NORM: [2.1.15] Cau hinh chinh sach 'Create symbolic links' [Ch% MS]
Line 176:
RAW: "[2.1.17] Cau hinh chinh sach 'Deny access to this computer from the network' [Ch% MS]"
NORM: [2.1.17] Cau hinh chinh sach 'Deny access to this computer from the network' [Ch% MS]
Line 179:
RAW: "[2.1.20] Cau hinh chinh sach 'Deny log on locally'"
NORM: [2.1.20] Cau hinh chinh sach 'Deny log on locally'
Line 180:
RAW: "[2.1.21] Cau hinh chinh sach 'Deny log on through Remote Desktop Services' [Ch% MS]"
NORM: [2.1.21] Cau hinh chinh sach 'Deny log on through Remote Desktop Services' [Ch% MS]
=== PS Script variants ===
CheckId=2.1.1 Desc=Cau hinh chinh sach 'Access Credential Manager as a trusted caller'
Normalized: Cau hinh chinh sach 'Access Credential Manager as a trusted caller'
CheckId=2.1.2 Desc=Cau hinh chinh sach 'Access this computer from the network' [Chỉ DC]
Normalized: Cau hinh chinh sach 'Access this computer from the network' [Chi DC]
CheckId=2.1.2 Desc=Cau hinh chinh sach 'Access this computer from the network' [Chỉ MS]
Normalized: Cau hinh chinh sach 'Access this computer from the network' [Chi MS]
CheckId=2.1.3 Desc=Cau hinh chinh sach 'Act as part of the operating system'
Normalized: Cau hinh chinh sach 'Act as part of the operating system'
CheckId=2.1.4 Desc=Cau hinh chinh sach 'Add workstations to domain' [Chỉ DC]
Normalized: Cau hinh chinh sach 'Add workstations to domain' [Chi DC]
CheckId=2.1.5 Desc=Cau hinh chinh sach 'Adjust memory quotas for a process'
Normalized: Cau hinh chinh sach 'Adjust memory quotas for a process'
CheckId=2.1.6 Desc=Cau hinh chinh sach 'Allow log on locally'
Normalized: Cau hinh chinh sach 'Allow log on locally'
CheckId=2.1.7 Desc=Cau hinh chinh sach 'Allow log on through Remote Desktop Services' [Chỉ DC]
Normalized: Cau hinh chinh sach 'Allow log on through Remote Desktop Services' [Chi DC]
CheckId=2.1.7 Desc=Cau hinh chinh sach 'Allow log on through Remote Desktop Services' [Chỉ MS]
Normalized: Cau hinh chinh sach 'Allow log on through Remote Desktop Services' [Chi MS]
CheckId=2.1.8 Desc=Cau hinh chinh sach 'Back up files and directories'
Normalized: Cau hinh chinh sach 'Back up files and directories'
CheckId=2.1.9 Desc=Cau hinh chinh sach 'Change the system time'
Normalized: Cau hinh chinh sach 'Change the system time'
CheckId=2.1.10 Desc=Cau hinh chinh sach 'Change the time zone'
Normalized: Cau hinh chinh sach 'Change the time zone'
CheckId=2.1.11 Desc=Cau hinh chinh sach 'Create a pagefile'
Normalized: Cau hinh chinh sach 'Create a pagefile'
CheckId=2.1.12 Desc=Cau hinh chinh sach 'Create a token object'
Normalized: Cau hinh chinh sach 'Create a token object'
CheckId=2.1.13 Desc=Cau hinh chinh sach 'Create global objects'
Normalized: Cau hinh chinh sach 'Create global objects'
CheckId=2.1.14 Desc=Cau hinh chinh sach 'Create permanent shared objects'
Normalized: Cau hinh chinh sach 'Create permanent shared objects'
CheckId=2.1.15 Desc=Cau hinh chinh sach 'Create symbolic links' [Chỉ DC]
Normalized: Cau hinh chinh sach 'Create symbolic links' [Chi DC]
CheckId=2.1.15 Desc=Cau hinh chinh sach 'Create symbolic links' [Chỉ MS]
Normalized: Cau hinh chinh sach 'Create symbolic links' [Chi MS]
CheckId=2.1.16 Desc=Cau hinh chinh sach 'Debug programs'
Normalized: Cau hinh chinh sach 'Debug programs'
CheckId=2.1.17 Desc=Cau hinh chinh sach 'Deny access to this computer from the network' [Chỉ DC]
Normalized: Cau hinh chinh sach 'Deny access to this computer from the network' [Chi DC]
CheckId=2.1.17 Desc=Cau hinh chinh sach 'Deny access to this computer from the network' [Chỉ MS]
Normalized: Cau hinh chinh sach 'Deny access to this computer from the network' [Chi MS]
CheckId=2.1.18 Desc=Cau hinh chinh sach 'Deny log on as a batch job'
Normalized: Cau hinh chinh sach 'Deny log on as a batch job'
CheckId=2.1.19 Desc=Cau hinh chinh sach 'Deny log on as a service'
Normalized: Cau hinh chinh sach 'Deny log on as a service'
CheckId=2.1.20 Desc=Cau hinh chinh sach 'Deny log on locally'
Normalized: Cau hinh chinh sach 'Deny log on locally'
CheckId=2.1.21 Desc=Cau hinh chinh sach 'Deny log on through Remote Desktop Services' [Chỉ DC]
Normalized: Cau hinh chinh sach 'Deny log on through Remote Desktop Services' [Chi DC]
CheckId=2.1.21 Desc=Cau hinh chinh sach 'Deny log on through Remote Desktop Services' [Chỉ MS]
Normalized: Cau hinh chinh sach 'Deny log on through Remote Desktop Services' [Chi MS]
CheckId=2.1.22 Desc=Cau hinh chinh sach 'Enable computer and user accounts to be trusted for delegat
Normalized: Cau hinh chinh sach 'Enable computer and user accounts to be trusted for delegation' [Chi DC]
CheckId=2.1.22 Desc=Cau hinh chinh sach 'Enable computer and user accounts to be trusted for delegat
Normalized: Cau hinh chinh sach 'Enable computer and user accounts to be trusted for delegation' [Chi MS]
CheckId=2.1.23 Desc=Cau hinh chinh sach 'Force shutdown from a remote system'
Normalized: Cau hinh chinh sach 'Force shutdown from a remote system'
CheckId=2.1.24 Desc=Cau hinh chinh sach 'Generate security audits'
Normalized: Cau hinh chinh sach 'Generate security audits'
CheckId=2.1.25 Desc=Cau hinh chinh sach 'Impersonate a client after authentication' [Chỉ DC]
Normalized: Cau hinh chinh sach 'Impersonate a client after authentication' [Chi DC]
CheckId=2.1.25 Desc=Cau hinh chinh sach 'Impersonate a client after authentication' [Chỉ MS]
Normalized: Cau hinh chinh sach 'Impersonate a client after authentication' [Chi MS]
CheckId=2.1.26 Desc=Cau hinh chinh sach 'Increase scheduling priority'
Normalized: Cau hinh chinh sach 'Increase scheduling priority'
CheckId=2.1.27 Desc=Cau hinh chinh sach 'Load and unload device drivers'
Normalized: Cau hinh chinh sach 'Load and unload device drivers'
CheckId=2.1.28 Desc=Cau hinh chinh sach 'Lock pages in memory'
Normalized: Cau hinh chinh sach 'Lock pages in memory'
CheckId=2.1.29 Desc=Cau hinh chinh sach 'Manage auditing and security log' [Chỉ DC]
Normalized: Cau hinh chinh sach 'Manage auditing and security log' [Chi DC]
CheckId=2.1.29 Desc=Cau hinh chinh sach 'Manage auditing and security log' [Chỉ MS]
Normalized: Cau hinh chinh sach 'Manage auditing and security log' [Chi MS]
CheckId=2.1.30 Desc=Cau hinh chinh sach 'Modify an object label'
Normalized: Cau hinh chinh sach 'Modify an object label'
CheckId=2.1.31 Desc=Cau hinh chinh sach 'Modify firmware environment values'
Normalized: Cau hinh chinh sach 'Modify firmware environment values'
CheckId=2.1.32 Desc=Cau hinh chinh sach 'Perform volume maintenance tasks'
Normalized: Cau hinh chinh sach 'Perform volume maintenance tasks'
CheckId=2.1.33 Desc=Cau hinh chinh sach 'Profile single process'
Normalized: Cau hinh chinh sach 'Profile single process'
CheckId=2.1.34 Desc=Cau hinh chinh sach 'Profile system performance'
Normalized: Cau hinh chinh sach 'Profile system performance'
CheckId=2.1.35 Desc=Cau hinh chinh sach 'Replace a process level token'
Normalized: Cau hinh chinh sach 'Replace a process level token'
CheckId=2.1.36 Desc=Cau hinh chinh sach 'Restore files and directories'
Normalized: Cau hinh chinh sach 'Restore files and directories'
CheckId=2.1.37 Desc=Cau hinh chinh sach 'Shut down the system'
Normalized: Cau hinh chinh sach 'Shut down the system'
CheckId=2.1.38 Desc=Cau hinh chinh sach 'Synchronize directory service data' [Chỉ DC]
Normalized: Cau hinh chinh sach 'Synchronize directory service data' [Chi DC]
CheckId=2.1.39 Desc=Cau hinh chinh sach 'Take ownership of files or other objects'
Normalized: Cau hinh chinh sach 'Take ownership of files or other objects'
+22
View File
@@ -0,0 +1,22 @@
import re
ps = open(r'D:\VNPT-M\Tool\audit_tool\NEW\Update\audit_lhdsin\audit_check_script\audit_cis_windows.ps1', 'r', encoding='utf-8').read()
# Find variable definitions for CheckIdPrefix, LabelPrefix, Label
for m in re.finditer(r'\$(CheckIdPrefix|LabelPrefix|Label)\s*=\s*"(.+?)"', ps):
print(f'{m.group(1)} = "{m.group(2)}"')
# Find Write-CheckResult calls with variable CheckIds
print("\nWrite-CheckResult with variables:")
for m in re.finditer(r'Write-CheckResult\s+"(\$.+?)"\s+"(.+?)"', ps):
print(f' CheckId="{m.group(1)}" Desc="{m.group(2)[:80]}"')
# Also find the loop context around these calls
print("\nContext for variable-based checks:")
for m in re.finditer(r'(\$CheckIdPrefix\s*=\s*.+?)\n', ps):
start = max(0, m.start() - 50)
end = min(len(ps), m.end() + 300)
context = ps[start:end]
print(f' ---')
for line in context.split('\n')[:10]:
print(f' {line[:120]}')
Binary file not shown.
Binary file not shown.
+96
View File
@@ -0,0 +1,96 @@
{
"ubuntu": {
"icon": "🟠",
"display_name": "Ubuntu",
"versions": {
"ubuntu_2204": {
"name": "Ubuntu 22.04 Audit Check Script",
"file": "Hardenning_Ubuntu2204_2.0.2.zip",
"version": "v2.0.2",
"updated": "08/04/2026",
"os_version_label": "22.04",
"source_path": "tools/Hardenning_Ubuntu2204_2.0.2.zip"
},
"ubuntu_2004": {
"name": "Ubuntu 20.04 Audit Check Script",
"file": "Hardenning_Ubuntu2004_2.0.2.zip",
"version": "v2.0.2",
"updated": "08/04/2026",
"os_version_label": "20.04",
"source_path": "tools/Hardenning_Ubuntu2004_2.0.2.zip"
}
}
},
"centos": {
"icon": "🔵",
"display_name": "CentOS",
"versions": {
"centos_7": {
"name": "Centos 7 Audit Check Script",
"file": "hardening_centos_7_2.0.2.zip",
"version": "v2.0.2",
"updated": "15/04/2026",
"os_version_label": "7",
"source_path": "tools/hardening_centos_7_2.0.2.zip"
}
}
},
"rhel": {
"icon": "🎩",
"display_name": "RHEL",
"versions": {
"rhel_default": {
"name": "RHEL Audit Script",
"file": "audit_cis_rhel_v2.sh",
"version": "v2.1.0",
"updated": "03/02/2026",
"os_version_label": "",
"source_path": null
},
"rhel_8": {
"name": "RHEL 8 Audit Script",
"file": "Hardenning_RHEL8_2.0.2.zip",
"version": "v2.0.2",
"updated": "15/04/2026",
"os_version_label": "8",
"source_path": "tools/Hardenning_RHEL8_2.0.2.zip"
}
}
},
"oracle": {
"icon": "🔸",
"display_name": "Oracle Linux",
"versions": {
"oracle_default": {
"name": "Oracle Linux Audit Script",
"file": "oracle_linux_audit_v2.py",
"version": "v2.0.0",
"updated": "15/01/2026",
"os_version_label": "",
"source_path": null
}
}
},
"windows": {
"icon": "🪟",
"display_name": "Windows Server",
"versions": {
"windows_default": {
"name": "Windows Server Audit Script",
"file": "windows_audit.ps1",
"version": "v1.5.0",
"updated": "20/12/2025",
"os_version_label": "",
"source_path": null
},
"windows_windows_server": {
"name": "Windows Server Audit Script",
"file": "hardening_windows.zip",
"version": "v1",
"updated": "08/04/2026",
"os_version_label": "Windows Server",
"source_path": "tools/hardening_windows.zip"
}
}
}
}
+99
View File
@@ -0,0 +1,99 @@
import re, json, sys, io
from openpyxl import load_workbook
from unidecode import unidecode
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
ps = open(r'D:\VNPT-M\Tool\audit_tool\NEW\Update\audit_lhdsin\audit_check_script\audit_cis_windows.ps1', 'r', encoding='utf-8').read()
# 1. Static checks
static_checks = re.findall(r'Write-CheckResult\s+"([^$"].+?)"\s+"(.+?)"', ps)
criteria = [(cid, desc) for cid, desc in static_checks]
print(f'Static checks: {len(criteria)}')
# 2. Variable-based checks - expand from function calls
# Test-FirewallProfile
fw_calls = re.findall(r'Test-FirewallProfile\s+"(\w+)"\s+"([\d.]+)"\s+"(\w+)"', ps)
for profile, prefix, label in fw_calls:
criteria.append((f'{prefix}.1', f"Thiet lap trang thai 'Windows Firewall: {label} : Firewall state'"))
criteria.append((f'{prefix}.2', f"Thiet lap trang thai 'Windows Firewall: {label} : Inbound connections'"))
criteria.append((f'{prefix}.3', f"Thiet lap trang thai 'Windows Firewall: {label} : Outbound connections'"))
# Test-EventLogPolicy
log_calls = re.findall(r'Test-EventLogPolicy\s+"(\w+)"\s+"([\d.]+)"\s+"(\w+)"', ps)
for logname, prefix, label in log_calls:
criteria.append((f'{prefix}.1', f"Thiet lap chinh sach '{label} : Control Event Log behavior when the log file reaches its maximum size'"))
criteria.append((f'{prefix}.2', f"Thiet lap chinh sach '{label} : Specify the maximum log file size (KB)'"))
print(f'Total after expanding: {len(criteria)}')
# Build lookup: normalized_full_text -> full_text
ps_criteria = {}
for cid, desc in criteria:
full = f"{cid}. {desc}"
key = unidecode(full)
ps_criteria[key] = full
# Load Excel
wb = load_workbook(r'D:\VNPT-M\Tool\audit_tool\NEW\Update\audit_lhdsin\config\Windows_Checklist.xlsx')
ws = wb.worksheets[0]
excel_rows = {}
unmatched = {}
# Pass 1: match by full text (column B has the full criteria text)
for row in range(1, ws.max_row + 1):
val_a = str(ws.cell(row=row, column=1).value or "").strip()
val_b = str(ws.cell(row=row, column=2).value or "").strip()
combined = f"{val_a} {val_b}".strip()
norm = unidecode(combined)
if norm in ps_criteria:
excel_rows[row] = ps_criteria[norm]
del ps_criteria[norm]
# Pass 2: match just the CheckId in column A
still_unmatched = dict(ps_criteria)
for cid_key, full_text in still_unmatched.items():
cid = full_text.split('. ')[0] if '. ' in full_text else full_text.split()[0]
for row in range(1, ws.max_row + 1):
val_a = str(ws.cell(row=row, column=1).value or "").strip()
if val_a and cid in val_a and row not in excel_rows:
excel_rows[row] = full_text
del ps_criteria[cid_key]
break
# Pass 3: try matching by normalized column B only
still_unmatched2 = dict(ps_criteria)
for cid_key, full_text in still_unmatched2.items():
cid = full_text.split('. ')[0]
norm_cid = unidecode(cid)
for row in range(1, ws.max_row + 1):
val_b = str(ws.cell(row=row, column=2).value or "").strip()
if val_b:
norm_b = unidecode(val_b)
if norm_cid in norm_b.split()[0] and row not in excel_rows:
excel_rows[row] = full_text
del ps_criteria[cid_key]
break
print(f'\nMatched rows: {len(excel_rows)}')
print(f'Unmatched: {len(ps_criteria)}')
if ps_criteria:
print('\nUnmatched criteria (first 10):')
for i, (k, v) in enumerate(list(ps_criteria.items())[:10]):
print(f' [{v[:70]}]')
# Build new config
new_data = []
for row in sorted(excel_rows.keys()):
new_data.append({str(row): excel_rows[row]})
new_config = {"data": new_data}
output_path = r'D:\VNPT-M\Tool\audit_tool\NEW\Update\audit_lhdsin\config\windows_config.json'
with open(output_path, 'w', encoding='utf-8') as f:
json.dump(new_config, f, ensure_ascii=False, indent=4)
print(f'\nNew config written to: {output_path}')
print(f'Total entries: {len(new_data)}')
+150
View File
@@ -0,0 +1,150 @@
import re, json, sys, io
from openpyxl import load_workbook
from unidecode import unidecode
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
ps = open(r'D:\VNPT-M\Tool\audit_tool\NEW\Update\audit_lhdsin\audit_check_script\audit_cis_windows.ps1', 'r', encoding='utf-8').read()
# Strategy: find ALL lines with Write-CheckResult, regardless of conditional context
# Also handle the case where IsDomain branches produce different descriptions
all_checks = []
# Find all Write-CheckResult calls - including those inside conditionals
for m in re.finditer(r'Write-CheckResult\s+"([^"]+)"\s+"([^"]+)"', ps):
check_id = m.group(1)
desc = m.group(2)
if not check_id.startswith('$'):
all_checks.append((check_id, desc))
print(f'Direct calls (no variables): {len(all_checks)}')
# Now expand variable-based calls from Test-FirewallProfile and Test-EventLogPolicy
fw_calls = re.findall(r'Test-FirewallProfile\s+"(\w+)"\s+"([\d.]+)"\s+"(\w+)"', ps)
for profile, prefix, label in fw_calls:
all_checks.append((f'{prefix}.1', f"Thiet lap trang thai 'Windows Firewall: {label} : Firewall state'"))
all_checks.append((f'{prefix}.2', f"Thiet lap trang thai 'Windows Firewall: {label} : Inbound connections'"))
all_checks.append((f'{prefix}.3', f"Thiet lap trang thai 'Windows Firewall: {label} : Outbound connections'"))
log_calls = re.findall(r'Test-EventLogPolicy\s+"(\w+)"\s+"([\d.]+)"\s+"(\w+)"', ps)
for logname, prefix, label in log_calls:
all_checks.append((f'{prefix}.1', f"Thiet lap chinh sach '{label} : Control Event Log behavior when the log file reaches its maximum size'"))
all_checks.append((f'{prefix}.2', f"Thiet lap chinh sach '{label} : Specify the maximum log file size (KB)'"))
# Build criteria list, removing duplicates (same CheckId + same Description)
seen = set()
criteria_unique = []
for cid, desc in all_checks:
key = (cid, desc)
if key not in seen:
seen.add(key)
criteria_unique.append((cid, desc))
criteria = criteria_unique
print(f'Total unique criteria: {len(criteria)}')
# Build ps_criteria lookup
ps_criteria = {}
for cid, desc in criteria:
full = f"{cid}. {desc}"
key = unidecode(full)
ps_criteria[key] = full
# Load Excel
wb = load_workbook(r'D:\VNPT-M\Tool\audit_tool\NEW\Update\audit_lhdsin\config\Windows_Checklist.xlsx')
ws = wb.worksheets[0]
excel_rows = {}
# Pass 1: match by full unidecoded text
for row in range(1, ws.max_row + 1):
val_a = str(ws.cell(row=row, column=1).value or "").strip()
val_b = str(ws.cell(row=row, column=2).value or "").strip()
combined = f"{val_a} {val_b}".strip()
norm = unidecode(combined)
if norm in ps_criteria:
excel_rows[row] = ps_criteria[norm]
del ps_criteria[norm]
# Pass 2: match by CheckId prefix
still = dict(ps_criteria)
for cid_key, full_text in still.items():
cid = full_text.split('. ')[0]
for row in range(1, ws.max_row + 1):
if row in excel_rows:
continue
val_a = str(ws.cell(row=row, column=1).value or "").strip()
if val_a and cid in val_a:
excel_rows[row] = full_text
del ps_criteria[cid_key]
break
# Pass 3: match column B alone
still2 = dict(ps_criteria)
for cid_key, full_text in still2.items():
cid = full_text.split('. ')[0]
for row in range(1, ws.max_row + 1):
if row in excel_rows:
continue
val_b = str(ws.cell(row=row, column=2).value or "").strip()
if val_b:
norm_b = unidecode(val_b)
parts = norm_b.split()
if parts and cid in parts[0]:
excel_rows[row] = full_text
del ps_criteria[cid_key]
break
print(f'\nMatched rows: {len(excel_rows)}')
print(f'Unmatched: {len(ps_criteria)}')
if ps_criteria:
print('\nUnmatched check IDs:')
for k in sorted(ps_criteria.keys()):
cid = ps_criteria[k].split('. ')[0]
print(f' {cid}: {ps_criteria[k][:80]}')
# Build new config
new_data = []
for row in sorted(excel_rows.keys()):
new_data.append({str(row): excel_rows[row]})
new_config = {"data": new_data}
output_path = r'D:\VNPT-M\Tool\audit_tool\NEW\Update\audit_lhdsin\config\windows_config.json'
with open(output_path, 'w', encoding='utf-8') as f:
json.dump(new_config, f, ensure_ascii=False, indent=4)
print(f'\nNew config: {output_path}')
print(f'Total entries: {len(new_data)}')
# Verify against actual output
out_file = r'D:\VNPT-M\Tool\audit_tool\NEW\Update\audit_lhdsin\output\MEVAS-NTL-DATAN_2026_07_29-05_18_36.txt'
with open(out_file, 'r', encoding='utf-8', errors='replace') as f:
lines = f.read().splitlines()
audit_results = {}
for line in lines:
line = line.strip()
if line.startswith('{') and line.endswith('}'):
try:
parsed = json.loads(line)
key = unidecode(str(list(parsed.keys())[0]))
audit_results[key] = (str(list(parsed.values())[0]), line)
except:
pass
cfg_names = {unidecode(str(list(item.values())[0])) for item in new_config['data']}
output_names = set(audit_results.keys())
matched = cfg_names & output_names
output_only = output_names - cfg_names
print(f'Output lines: {len(output_names)}')
print(f'Config matches output: {len(matched)}/{len(output_names)}')
print(f'Output not in config: {len(output_only)}')
if output_only:
print('Missing from config:')
for n in sorted(list(output_only))[:5]:
print(f' {n[:80]}')
+149
View File
@@ -0,0 +1,149 @@
import re, json, sys, io
from openpyxl import load_workbook
from unidecode import unidecode
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
ps = open(r'D:\VNPT-M\Tool\audit_tool\NEW\Update\audit_lhdsin\audit_check_script\audit_cis_windows.ps1', 'r', encoding='utf-8').read()
# Collect ALL criteria including DC/MS variants
all_criteria = []
# Direct Write-CheckResult calls
for m in re.finditer(r'Write-CheckResult\s+"([^"]+)"\s+"([^"]+)"', ps):
check_id = m.group(1)
desc = m.group(2)
if not check_id.startswith('$'):
all_criteria.append((check_id, desc))
# Expand variable-based calls
fw_calls = re.findall(r'Test-FirewallProfile\s+"(\w+)"\s+"([\d.]+)"\s+"(\w+)"', ps)
for profile, prefix, label in fw_calls:
all_criteria.append((f'{prefix}.1', f"Thiet lap trang thai 'Windows Firewall: {label} : Firewall state'"))
all_criteria.append((f'{prefix}.2', f"Thiet lap trang thai 'Windows Firewall: {label} : Inbound connections'"))
all_criteria.append((f'{prefix}.3', f"Thiet lap trang thai 'Windows Firewall: {label} : Outbound connections'"))
log_calls = re.findall(r'Test-EventLogPolicy\s+"(\w+)"\s+"([\d.]+)"\s+"(\w+)"', ps)
for logname, prefix, label in log_calls:
all_criteria.append((f'{prefix}.1', f"Thiet lap chinh sach '{label} : Control Event Log behavior when the log file reaches its maximum size'"))
all_criteria.append((f'{prefix}.2', f"Thiet lap chinh sach '{label} : Specify the maximum log file size (KB)'"))
# Build full criteria names, keep duplicates (DC vs MS variants)
criteria_list = []
seen = set()
for cid, desc in all_criteria:
full = f"{cid}. {desc}"
key = (cid, unidecode(desc))
if key not in seen:
seen.add(key)
criteria_list.append((cid, desc, full))
print(f'Total criteria (with variants): {len(criteria_list)}')
# Load Excel
wb = load_workbook(r'D:\VNPT-M\Tool\audit_tool\NEW\Update\audit_lhdsin\config\Windows_Checklist.xlsx')
ws = wb.worksheets[0]
# Build Excel row mapping: try to find the best row for each criteria
# A row can have multiple criteria (DC + MS variants)
row_to_criteria = {} # row -> list of criteria full text
unmatched = list(criteria_list)
# Pass 1: match by full text
for row in range(1, ws.max_row + 1):
val_a = str(ws.cell(row=row, column=1).value or "").strip()
val_b = str(ws.cell(row=row, column=2).value or "").strip()
combined = f"{val_a} {val_b}".strip()
norm = unidecode(combined)
for cid, desc, full in list(unmatched):
if unidecode(full) == norm:
if row not in row_to_criteria:
row_to_criteria[row] = []
row_to_criteria[row].append(full)
unmatched.remove((cid, desc, full))
# Pass 2: match by CheckId in column A
for cid, desc, full in list(unmatched):
for row in range(1, ws.max_row + 1):
val_a = str(ws.cell(row=row, column=1).value or "").strip()
if val_a and cid in val_a:
if row not in row_to_criteria:
row_to_criteria[row] = []
if full not in row_to_criteria[row]:
row_to_criteria[row].append(full)
unmatched.remove((cid, desc, full))
break
# Pass 3: match by CheckId in column B
for cid, desc, full in list(unmatched):
for row in range(1, ws.max_row + 1):
if row in row_to_criteria:
continue
val_b = str(ws.cell(row=row, column=2).value or "").strip()
if val_b:
norm_b = unidecode(val_b)
parts = norm_b.split()
if parts and cid == parts[0].rstrip('.'):
if row not in row_to_criteria:
row_to_criteria[row] = []
if full not in row_to_criteria[row]:
row_to_criteria[row].append(full)
unmatched.remove((cid, desc, full))
break
print(f'\nMatched rows: {len(row_to_criteria)}')
print(f'Unmatched criteria: {len(unmatched)}')
if unmatched:
print('\nUnmatched:')
for cid, desc, full in unmatched[:10]:
print(f' {cid}: {full[:80]}')
# Build new config
new_data = []
for row in sorted(row_to_criteria.keys()):
for full_text in row_to_criteria[row]:
new_data.append({str(row): full_text})
new_config = {"data": new_data}
output_path = r'D:\VNPT-M\Tool\audit_tool\NEW\Update\audit_lhdsin\config\windows_config.json'
with open(output_path, 'w', encoding='utf-8') as f:
json.dump(new_config, f, ensure_ascii=False, indent=4)
print(f'\nNew config: {output_path}')
print(f'Total entries: {len(new_data)}')
# Verify against actual output
out_file = r'D:\VNPT-M\Tool\audit_tool\NEW\Update\audit_lhdsin\output\MEVAS-NTL-DATAN_2026_07_29-05_18_36.txt'
with open(out_file, 'r', encoding='utf-8', errors='replace') as f:
lines = f.read().splitlines()
audit_results = {}
for line in lines:
line = line.strip()
if line.startswith('{') and line.endswith('}'):
try:
parsed = json.loads(line)
key = unidecode(str(list(parsed.keys())[0]))
audit_results[key] = (str(list(parsed.values())[0]), line)
except:
pass
cfg_names = set()
for item in new_config['data']:
cfg_names.add(unidecode(str(list(item.values())[0])))
output_names = set(audit_results.keys())
matched = cfg_names & output_names
output_only = output_names - cfg_names
print(f'Output lines: {len(output_names)}')
print(f'Matched: {len(matched)}/{len(output_names)}')
print(f'Not in config: {len(output_only)}')
if output_only:
print('Still missing (first 5):')
for n in sorted(list(output_only))[:5]:
print(f' {n[:80]}')