tis-windows-password-policy

17
Define the local Windows password policy.
395 downloads
Download
See build result See VirusTotal scan
tis-windows-password-policy icon
  • package : tis-windows-password-policy
  • name : Windows Password Policy
  • version : 17
  • categories : Security
  • maintainer : WAPT Team,Tranquil IT, Kévin Guérineau
  • editor : Microsoft
  • licence :
  • locale :
  • target_os : windows
  • impacted_process :
  • architecture : all
  • signature_date : 2024-09-11 10:59
  • size : 7.13 Ko
package           : tis-windows-password-policy
version           : 17
architecture      : all
section           : base
priority          : optional
name              : Windows Password Policy
categories        : Security
maintainer        : WAPT Team,Tranquil IT, Kévin Guérineau
description       : Define the local Windows password policy.
depends           : 
conflicts         : 
maturity          : PROD
locale            : 
target_os         : windows
min_wapt_version  : 2.3
sources           : 
installed_size    : 
impacted_process  : 
description_fr    : Définir la politique locale de mots de passe Windows.
description_pl    : Definiowanie lokalnych zasad haseł systemu Windows.
description_de    : Definieren Sie die lokale Windows-Kennwortrichtlinie.
description_es    : Definir la política local de contraseñas de Windows.
description_pt    : Definir a política de palavra-passe local do Windows.
description_it    : Definire il criterio delle password locali di Windows.
description_nl    : Definieer het lokale Windows wachtwoordbeleid.
description_ru    : Определите локальную политику паролей Windows.
audit_schedule    : 
editor            : Microsoft
keywords          : 
licence           : 
homepage          : 
package_uuid      : f349a8c4-bebb-4ffb-83c9-0b475abc8a11
valid_from        : 
valid_until       : 
forced_install_on : 
changelog         : 
min_os_version    : 
max_os_version    : 
icon_sha256sum    : 9420721210f5d9c50c9e35c9fdbf0a088b30e165df8311c5f2176ce60e122475
signer            : Tranquil IT
signer_fingerprint: 8c5127a75392be9cc9afd0dbae1222a673072c308c14d88ab246e23832e8c6bb
signature_date    : 2024-09-11T10:59:38.000000
signed_attributes : package,version,architecture,section,priority,name,categories,maintainer,description,depends,conflicts,maturity,locale,target_os,min_wapt_version,sources,installed_size,impacted_process,description_fr,description_pl,description_de,description_es,description_pt,description_it,description_nl,description_ru,audit_schedule,editor,keywords,licence,homepage,package_uuid,valid_from,valid_until,forced_install_on,changelog,min_os_version,max_os_version,icon_sha256sum,signer,signer_fingerprint,signature_date,signed_attributes
signature         : RHH/U68+jL8BD5miR1+8rerW8Y4hyt94dooiDQW0uXUGynFtuPBmwIO7xhPDOvMgL7gV36gVSYMq4z7T2UDUzVYKeAeG8iZLrlDeCs/7LgIcv9YigPeHrbXtvewmkyD1D0pqYFSa4zQF3G7xTQhv42Y4g5uJn6Go8gb0Qzdoer1hmz2qO6l6ComywqwIuuBtkvccuCWxrHP/7108dyyNHlLrzyzhU0rp5OWk+7VIB66+Md+aL2Q04GFOxqWH5pOPmK+FRTdUAta4b41oaXifviM8UWe2ODqPkyilEf6dpOto2tqAw59wyH/PS4tgNa+Wx3VRiptFA8h8blk3P6Hobw==
# -*- coding: utf-8 -*-
from setuphelpers import *
import codecs

# Documentation : https://learn.microsoft.com/en-us/previous-versions/windows/it-pro/windows-xp/bb490698(v=technet.10)?redirectedfrom=MSDN

forcelogoff = "no"
minpwlen = 14
maxpwage = 365
minpwage = 1
uniquepw = 24
lockout_threshold = 5
lockout_duration = 15
reset_lockout_count = 15
set_complexity = True
clear_store_pw = False
admin_account_lockout = True


def decode_file(src_file:None,dest_file:None):

    encoded_text = open(src_file, 'rb').read()     #you should read in binary mode to get the BOM correctly
    bom = codecs.BOM_UTF16_LE                               #print dir(codecs) for other encodings
    assert encoded_text.startswith(bom)                     #make sure the encoding is what you expect, otherwise you'll get wrong data
    encoded_text = encoded_text[len(bom):]                  #strip away the BOM
    decoded_text = encoded_text.decode('utf-16le')

    f = open(dest_file, 'wb')
    f.write(decoded_text.encode('utf-8'))
    f.close()


def encode_file(src_file,dest_file):
    encoded_text = open(src_file, 'rb').read()     #you should read in binary mode to get the BOM correctly
    decoded_text = encoded_text.decode('utf-8')

    f = open(dest_file, 'wb')
    f.write(decoded_text.encode('utf-16le'))
    f.close()


def install():
    print(f"Set local password policy")
    run(f"net accounts /forcelogoff:{forcelogoff} /minpwlen:{minpwlen} /maxpwage:{maxpwage} /minpwage:{minpwage} /uniquepw:{uniquepw} \
        /lockoutthreshold:{lockout_threshold} /lockoutwindow:{reset_lockout_count} /lockoutduration:{lockout_duration}")

    run(r'C:\Windows\system32\secedit.exe /export /cfg secconfig.ini /areas SECURITYPOLICY')

    decoded_file = "decoded_secconfig.ini"
    decode_file("secconfig.ini", decoded_file)

    print('Set complexity password')
    if set_complexity:
        if inifile_hasoption(decoded_file,"System Access","PasswordComplexity"):
            if inifile_readstring(decoded_file,"System Access","PasswordComplexity") == "0":
                inifile_writestring(decoded_file,"System Access","PasswordComplexity", "1")
    if not clear_store_pw:
        if inifile_hasoption(decoded_file,"System Access","ClearTextPassword"):
            if inifile_readstring(decoded_file,"System Access","ClearTextPassword") == "1":
                inifile_writestring(decoded_file,"System Access","ClearTextPassword","0")
    if admin_account_lockout:
        if inifile_hasoption(decoded_file,"System Access","AllowAdministratorLockout"):
            if inifile_readstring(decoded_file,"System Access","AllowAdministratorLockout") == "0":
                inifile_writestring(decoded_file,"System Access","AllowAdministratorLockout","1")

    encoded_file = "encoded_secconfig.ini"
    encode_file(decoded_file, encoded_file)

    run(rf'C:\Windows\system32\secedit.exe /import /cfg {encoded_file} /overwrite /areas SECURITYPOLICY /db wapt_secconfig /quiet')
    run(r'C:\Windows\system32\secedit.exe /configure /db wapt_secconfig /overwrite /areas SECURITYPOLICY /quiet')

    registry_set(HKEY_LOCAL_MACHINE,r'SYSTEM\CurrentControlSet\Control\SAM', 'RelaxMinimumPasswordLengthLimits', 1)

def uninstall():

    uninstall_dir = makepath('C:','Windows','Temp','secedit_dir')
    mkdirs(uninstall_dir)

    run("net accounts /forcelogoff:no /minpwlen:0 /maxpwage:UNLIMITED /minpwage:0 /uniquepw:0 \
        /lockoutthreshold:0 /lockoutwindow:30 /lockoutduration:30")

    run(r'C:\Windows\system32\secedit.exe /export /cfg C:\Windows\Temp\secconfig.ini /areas SECURITYPOLICY')

    decoded_file = makepath(uninstall_dir,"decoded_secconfig.ini")
    decode_file("C:\Windows\Temp\secconfig.ini",decoded_file)

    print('Unset complexity password')
    inifile_writestring(decoded_file,"System Access","PasswordComplexity", "0")
    inifile_writestring(decoded_file,"System Access","ClearTextPassword","0")
    inifile_writestring(decoded_file,"System Access","AllowAdministratorLockout","1")

    encoded_file = makepath(uninstall_dir,'encode_decoded_secconfig.ini')
    encode_file(decoded_file, encoded_file)

    run(rf'C:\Windows\system32\secedit.exe /import /cfg {encoded_file} /overwrite /areas SECURITYPOLICY /db wapt_secconfig /quiet')
    run(r'C:\Windows\system32\secedit.exe /configure /db wapt_secconfig /overwrite /areas SECURITYPOLICY /quiet')

    remove_tree(uninstall_dir)

    registry_set(HKEY_LOCAL_MACHINE,r'SYSTEM\CurrentControlSet\Control\SAM', 'RelaxMinimumPasswordLengthLimits', 0)


def audit():

    audit_dir = makepath('C:','Windows','Temp','secconfig_audit')
    mkdirs(audit_dir)
    audit_file = makepath(audit_dir,"secconfig.ini")

    run(rf'C:\Windows\system32\secedit.exe /export /cfg {audit_file} /areas SECURITYPOLICY')

    decoded_file = makepath(audit_dir,'decoded_secconfig.ini')
    decode_file(audit_file, decoded_file)

    parameter_in_fault = []

    error = False
    params = {"ForceLogoffWhenHourExpire ":forcelogoff},{'MinimumPasswordAge':minpwage},{'MaximumPasswordAge':maxpwage},{'MinimumPasswordLength':minpwlen}, \
        {"PasswordHistorySize":uniquepw},{"LockoutBadCount":lockout_threshold},{"LockoutDuration":lockout_duration},{"ResetLockoutCount":reset_lockout_count},  \
        {'PasswordComplexity':set_complexity},{"ClearTextPassword":clear_store_pw},{"AllowAdministratorLockout":admin_account_lockout}
    for option in params:
        for i in option:
            if inifile_hasoption(decoded_file,"System Access",i):
                if inifile_readstring(decoded_file,"System Access",i) == str(option[i]):
                    print(f"{i} is in correct value : {option[i]}")
                elif str(option[i]) == "True":
                    if inifile_readstring(decoded_file,"System Access",i) == "1":
                        print(f"{i} is in correct value : {option[i]}")
                    else:
                        print(f'{i} isn\'t in correct value : {inifile_readstring(decoded_file,"System Access",i)} expected {option[i]}')
                        parameter_in_fault.append(i)
                        error = True
                elif str(option[i]) == "False":
                    if inifile_readstring(decoded_file,"System Access",i) == "0":
                        print(f"{i} is in correct value : {option[i]}")
                    else:
                        print(f'{i} isn\'t in correct value : {inifile_readstring(decoded_file,"System Access",i)} expected {option[i]}')
                        parameter_in_fault.append(i)
                        error = True
                else:
                    print(f'{i} isn\'t in correct value : {inifile_readstring(decoded_file,"System Access",i)} expected {option[i]}')
                    parameter_in_fault.append(i)
                    error = True

    remove_tree(audit_dir)

    if error:
        WAPT.write_audit_data_if_changed("Windows password policy", 'Parameters in fault', parameter_in_fault, keep_days=365)
        return "ERROR"
    else:
        WAPT.write_audit_data_if_changed("Windows password policy", 'Parameters in fault', "OK", keep_days=365)
        return "OK"
# -*- coding: utf-8 -*-
from setuphelpers import *

def update_package():
    commit_count = params.get("commit_count",0)

    control.version = commit_count
    control.save_control_to_wapt()
38d056ab130f7bf7c481c12636a4e9959de36561d3dfcbe54c6e3571bc0c1dc3 : WAPT/certificate.crt
3e6e170f854e05307ff48098e0131022d715492e6a5089ffb602ef21b41c9555 : WAPT/control
9420721210f5d9c50c9e35c9fdbf0a088b30e165df8311c5f2176ce60e122475 : WAPT/icon.png
 : __pycache__
bb43bdb4342f8ef6d7e90de83599ac8df40f532d22299ba004f3ebdaf3c011ae : luti.json
8c1ff5876988be8b7629d36091c796d7a3a10c5c76131024179e362ee480420e : setup.py
0506431355ece6d296efc398fc457515203e9532b5caa24d3e4c3d28dd277059 : update_package.py