100 lines
3.9 KiB
Python
100 lines
3.9 KiB
Python
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)}')
|