Control de cambio de contraseñas en cuentas locales

Logo de Linkedin
Este script en PowerShell revela un enfoque sofisticado para gestionar eventos de seguridad relacionados con cambios de contraseña en Windows. El script extrae detalles de eventos, genera un informe en HTML y lo envía por correo electrónico, utilizando configuración cifrada para mayor seguridad.

Elementos que componen esta solución:

Archivos

1. ConfigurarControl.ps1

2. ControlDeCambioClave.ps1

3. NotificacionCorreoCambioClave.xml

ConfigurarControl.ps1:

Este script de PowerShell crea una aplicación gráfica para configurar un sistema de notificación de correo electrónico, enfocado en el envío seguro y cifrado de las configuraciones. A continuación, se desglosan sus partes:

1. Importación de Ensamblados 


        Add-Type -AssemblyName System.Windows.Forms
        Add-Type -AssemblyName System.Drawing
        Add-Type -AssemblyName System.Security
        ... 
Copied!
  • Descripción: Estos comandos cargan los ensamblados necesarios para:
    • Crear formularios y controles gráficos (System.Windows.Forms).
    • Manejar gráficos e imágenes (System.Drawing).
    • Usar funciones de seguridad, como cifrado (System.Security).
    • Funciones:

      2. Creación del Directorio de Configuración

      
                  $path = "C:\Windows\PowerShell\"
          if (-Not (Test-Path -Path $path)) {
              New-Item -Path $path -ItemType Directory
          }
       
      Copied!
    • Verifica si el directorio C:\Windows\PowerShell\ existe. 
    •  Si no, lo crea para almacenar configuraciones relacionadas.
    • 3. Carga de Imagen Base64

      
      $LPNG = "Imagen64"
      $lenbytes = [Convert]::FromBase64String($LPNG)
      $lenmemoria = New-Object System.IO.MemoryStream
      $lenmemoria.Write($lenbytes, 0, $lenbytes.Length)
      $lenmemoria.Position = 0
      $imagenl = [System.Drawing.Image]::FromStream($lenmemoria, $true)
       
      Copied!
    • Decodifica una imagen codificada en Base64 ($LPNG).
    • La convierte a un objeto Image para su uso en el formulario.
    • 4. Gestión de Claves de Cifrado

      
              function Get-EncryptionKey {
          if (-not (Test-Path $keyFile)) {
              $key = New-Object byte[] 32
              [Security.Cryptography.RNGCryptoServiceProvider]::Create().GetBytes($key)
              $key | Set-Content $keyFile -Encoding Byte
          }
          return Get-Content $keyFile -Encoding Byte
      }
       
      Copied!
    • Genera una clave de cifrado de 32 bytes si no existe.
    • La guarda en un archivo (email_config_key.txt) para su reutilización.
    • 
             function Protect-EmailConfig {
          param ([PSCustomObject]$Config)
          ...
          $aes = [System.Security.Cryptography.Aes]::Create()
          $aes.Key = $key
          $aes.GenerateIV()
          ...
      }
      
      Copied!
    • Convierte las configuraciones del correo a JSON.
    • Cifra los datos usando AES con la clave generada.
    • 
          function Unprotect-EmailConfig {
          $key = Get-EncryptionKey
          ...
          $aes.IV = $encryptedData[0..15]
          $decryptor = $aes.CreateDecryptor()
          ...
          }
      
      Copied!

        5. Creación del Formulario Gráfico

        El formulario (System.Windows.Forms.Form) incluye:
        Propiedades Generales:
      • Tamaño: 440x600.
      • Color de fondo: LightSteelBlue.
      • Posición: Centrada en pantalla.
      • Estilo de borde: FixedDialog.

      • Componentes Principales

        
            $pictureBox = New-Object System.Windows.Forms.PictureBox
            $pictureBox.Image = $imagenl
        
        
        Copied!
        Muestra la imagen decodificada en la parte superior.
        Campos de Entrada
      • Servidor de correo: TextBox.
      • Puerto y Protocolo: RadioButton para seleccionar SSL o STARTTLS.
      • Autenticación: Configuración anónima o con usuario/contraseña.
      • Botones
      • Probar conexión: Verifica la configuración mediante un correo de prueba.
      • Configurar: Guarda los datos cifrados en el archivo de configuración.
      • 6. Prueba de Conexión

        
            $botonProbar.Add_Click({
            try {
                ...
                $clienteSmtp.Send($mensajeCorreo)
                ...
            }
            catch {
                ...
            }
            })
        
        
        
        Copied!
      • Intenta enviar un correo de prueba.
      • Muestra un mensaje en caso de éxito o error.
      • 7. Configuración Final

        
           $botonConfigurar.Add_Click({
            $configuracion = @{
                Servidor = $textoServidor.Text
                ...
            }
            Protect-EmailConfig $configuracion
            ...
            })
        
        
        Copied!
      • Guarda las configuraciones ingresadas como un objeto cifrado.
      • Intenta importar una tarea programada desde un archivo XML para automatizar notificaciones.
      • ConfigurarControl.ps1:

        Este script monitorea eventos relacionados con cambios de contraseña en Windows (ID 4724). Genera un informe en HTML con los detalles del evento y lo envía por correo electrónico utilizando configuraciones seguras.

        1. Componentes Principales
        a) Cifrado y Descifrado
        El cifrado asegura que las credenciales de correo electrónico estén protegidas. Utiliza AES para descifrar las configuraciones almacenadas.

      • Obtención de la clave de cifrado:
      •  

        
                function Get-EncryptionKey {
            if (-not (Test-Path $keyFile)) {
                Write-Log "No se encontró el archivo de clave. Asegúrese de que existe en $keyFile" -Level "ERROR"
                exit
            }
            return Get-Content $keyFile -Encoding Byte
            } 
        
        Copied!
      • Descifrado del archivo de configuración:
      • 
             function Unprotect-EmailConfig {
            $key = Get-EncryptionKey
            $encryptedData = Get-Content $emailConfigFile -Encoding Byte
            
            $aes = [System.Security.Cryptography.Aes]::Create()
            $aes.Key = $key
            $aes.IV = $encryptedData[0..15]
            
            $decryptor = $aes.CreateDecryptor()
            $decryptedBytes = $decryptor.TransformFinalBlock($encryptedData, 16, $encryptedData.Length - 16)
            $jsonConfig = [System.Text.Encoding]::UTF8.GetString($decryptedBytes)
            
            return $jsonConfig | ConvertFrom-Json
        }
        
        
        Copied!
        b) Gestión de Logs
        El script registra eventos en un archivo de log y los muestra en la consola:
        
                function Write-Log {
            param (
                [string]$Message,
                [string]$Level = "INFO"
            )
            $timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
            $logMessage = "$timestamp [$Level] $Message"
            Add-Content -Path $logFile -Value $logMessage
            Write-Host $logMessage
            }
        
        
        Copied!
        c) Detección del Evento
        Busca el evento más reciente con ID 4724 en el registro de seguridad:
        
                $event = Get-WinEvent -FilterHashtable @{LogName='Security'; ID=4724} -MaxEvents 1
        
        Copied!
        Si no se encuentra, registra un mensaje de advertencia:
        
                catch {
            Write-Log "No se encontraron eventos 4724 (cambio de contraseña)." -Level "WARN"
            exit
        }
        
        Copied!
        d) Envío del Correo Electrónico
      • Configura y envía el correo con los detalles del evento:
      • 
                $smtpClient = New-Object Net.Mail.SmtpClient($smtpServer, $smtpPort)
        $smtpClient.EnableSsl = $emailConfig.Protocolo -in @("SSL", "STARTTLS")
        
        if ($emailConfig.Autenticacion -eq "UsuarioContrasena") {
            $smtpClient.Credentials = New-Object System.Net.NetworkCredential($emailConfig.Usuario, $emailConfig.Contrasena)
        }
        
        $mailMessage = New-Object Net.Mail.MailMessage
        $mailMessage.From = $from
        foreach ($to in $toAddresses) {
            $mailMessage.To.Add($to)
        }
        $mailMessage.Subject = $subject
        $mailMessage.Body = $htmlBody
        $mailMessage.IsBodyHtml = $true
        
        
        Copied!

        NotificacionCorreoCambioClave.xml

        Este archivo XML es una configuración para una tarea programada en Task Scheduler (Programador de Tareas) de Windows. Se utiliza para automatizar la ejecución de un script de PowerShell (ControlDeCambioClave.ps1) cuando se dispara un evento específico en los registros del sistema (logs). Aquí está el desglose de su propósito y componentes:
        Propósito
        Este XML configura una tarea llamada NotificacionCorreoCambioClave. Su función es monitorear eventos del tipo 4724 (Intento de restablecimiento de contraseña) en el registro de eventos de seguridad de Windows y ejecutar automáticamente un script de PowerShell para gestionar dicho evento, probablemente enviando una notificación o realizando una acción administrativa.

        Descarga los archivos

        ConfigurarControl.ps1 ControlDeCambiosClave.ps1 Tarea