viernes, 15 de mayo de 2026

SEGURIDAD. Pentesting opciones


El propósito de este post es establecer una base en la que basarnos para pedir una valoración de pentesting para nuestro negocio. Expondré algunas opciones de las muchas posibles, resumidas de manera que pueda ser un buen punto de partida.

Todo va en base a lo que se quiere conocer, el diseño de nuestra infraestructura, nube o On Premise, AD/Linux, el presupuesto, etc... 

La idea sería la ampliación o combinación de varias.

Debería ir acompañado de un contexto de como es la empresa, que tenemos, hacia donde vamos...

Alla voy


Opción 1
Perímetro Exterior de Data Centers
Objetivo
Evaluar la exposición de sistemas no diseñados para ser públicos o con acceso restringido y detectar vectores de entrada críticos
Alcance
  • IPs públicas:
    • CPD en hosting
    • VPN
    • Backup
    • Infraestructura CPD on Premise
  • Servicios:
    • RDP, SSH, administración remota
    • APIs internas expuestas
    • servicios legacy
    • Servicios restringidos
    • FTP, SFTP, FTPS, SSH, Http, Https, etc...
 Pruebas a realizar
  • Escaneo completo de superficie externa
  • Identificación de servicios no publicados
  • Vulnerabilidades de servicios expuestos
  • Detección de accesos administrativos expuestos
  • Password spraying / brute force controlado
  • Banner grabbing / fingerprinting
  • TLS / certificados
Valor de negocio

Este escenario identificaríamos:
  • Accesos “ocultos” mal expuestos
  • Riesgo de acceso directo a infraestructura crítica
  • Posibles vectores de ransomware inicial




Opción 2
Perímetro Exterior Web
Objetivo
Evaluar la seguridad de todos los servicios públicos accesibles por clientes/usuarios
Alcance
  • Webs corporativas o más importantes
  • Portales
  • Aplicaciones SaaS / proveedor
  • APIs públicas
  • dominios principales y subdominios
Pruebas
  • OWASP Top 10 completo:
    • XSS, SQLi, SSRF, etc.
  • Enumeración de subdominios
  • Seguridad de autenticación
  • Gestión de sesiones
  • FTP, SFTP, FTPS, SSH, Http, Https, etc...
  • Seguridad de autenticación (MFA test)
  • APIs:
    • autenticación
    • exposición de datos
Valor de negocio
Riesgo directo:
  • Exposición de datos de clientes
  • Compromiso reputacional
  • punto de entrada externo más probable


Opción 3
Perímetro Interno (LAN corporativa)
Objetivo
Simular compromiso interno desde usuario legítimo
Escenario
  • Usuario de dominio estándar
  • Acceso desde:
    • red servidores
    • red sede
 Pruebas
  • Enumeración AD (BloodHound)
  • Escalado de privilegios
  • Movimiento lateral:
    • SMB, WinRM, RDP
  • Ataques Kerberos:
    • Kerberoasting
    • AS-REP Roasting
  • Simulación ransomware lateral
  • FTP, SFTP, FTPS, SSH, Http, Https, etc...
  • Identificación de “caminos a Domain Admin”
  • Revisión de permisos:
    • shares
    • GPO
    • ACLs
Valor de negocio
Responde a:
  • Saber si un usuario comprometer el dominio
  • Qué impacto y alcance tendría un phishing o cifrado exitoso



Opción 4
Perímetro Interno WiFi
Objetivo
Evaluar el acceso a la red desde redes inalámbricas, con un usuario válido y otro sin atenticar.
Alcance
  • WiFi corporativo
  • WiFi invitados
  • SSID internos
 Pruebas
  • Ataques WPA/WPA2/WPA3
  • Rogue AP
  • Captura handshakes
  • Intentos de pivot a LAN
  • Segmentación de red
  • Pruebas desde la calle / perímetro físico
  • Validación NAC / acceso 802.1X

Valor de negocio
Evalúa:
  • Acceso desde visitante o atacante físico
  • Segmentación real de red


Opción 5
Perímetro Correo
Objetivo
Evaluar la seguridad del sistema de correo como vector de ataque principal
Alcance
  • Infraestructura de email
  • Gateway  o reenviadores de correo
 Pruebas
  • Simulación phishing controlado
  • SPF / DKIM / DMARC
  • suplantación dominio
  • bypass de filtros
  • análisis de links y adjuntos
  • análisis de MFA bypass
 Valor de negocio
 Evitar ataques reales como:
  • robo de credenciales
  • malware
  • fraude o suplantación

Espero os haya sido útil

by GoN | Published: May 2026 | Last Updated:

jueves, 14 de mayo de 2026

WINDOWS. GPO. Update-Install Adobe Acrobat


Propósito:

Nos ha llegado una alerta de seguridad de Acrobat, que requiere parchear urgentemente las versiones que estén expuestas.

El número de PCs de mi empresa es bastante elevado y no disponemos de un programa para distribuir software, con lo que me ha tocado preparar una GPO.

Para hacerla he completado lo siguiente:

  • Indica SI se actualizó o NO
  • Detecta versión antes y después
  • Te dice EXACTAMENTE qué ha fallado
  • Saca todo por pantalla en ejecución manual, no por GPO.
  • Log completo
  • Instalación silenciosa sin pedir credenciales )
  • Compatible con un EXE 

Pasos

La GPO arranca en el script de inicio del PC. Tarda unos minutos en hacer la actualización/instalación.


Si lo ejecutas a mano puedes seguir el proceso en pantalla:

Si dudas si esta funcionando cuando se aplica la GPO, abre el log que deja en cada máquina en el fichero C:\Windows\Temp\acrobat_fix.log

Aquí dejarémos la versión de Acrobat a instalar: \\NAS01\Adobe\AcroRdrDC2600121529_es_ES.exe

El Script:
$log = "C:\Windows\Temp\acrobat_fix.log"
$installer = "\\NAS01\Adobe\AcroRdrDC2600121529_es_ES.exe"

function Write-Log {
    param($text)
    $line = "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') - $text"
    Write-Host $line
    Add-Content -Path $log -Value $line
}

Write-Log "==== INICIO SCRIPT ===="

# Obtener versiones existentes
$apps = Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\* ,
                         HKLM:\Software\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\* |
        Where-Object { $_.DisplayName -match "Adobe.*(Acrobat|Reader)" }

if ($apps) {
    Write-Log "Adobe detectado → se elimina SIEMPRE"

    foreach ($app in $apps) {
        Write-Log "Desinstalando $($app.DisplayName)"

        if ($app.PSChildName) {
            Start-Process "msiexec.exe" -ArgumentList "/x $($app.PSChildName) /qn /norestart" -Wait
        }
    }
}
else {
    Write-Log "No había Adobe instalado"
}

# Espera para asegurar limpieza
Start-Sleep 5

# Instalación limpia
if (Test-Path $installer) {

    Write-Log "Instalando nueva versión (silent)..."

    $proc = Start-Process $installer -ArgumentList "/sAll /rs /rps /msi /qn /norestart" -Wait -PassThru

    Write-Log "Código salida instalación: $($proc.ExitCode)"

    if ($proc.ExitCode -eq 0) {
        Write-Log " INSTALACIÓN COMPLETA OK"
    }
    else {
        Write-Log " ERROR EN INSTALACIÓN"
    }

} else {
    Write-Log " Instalador no encontrado"
}

Write-Log "==== FIN SCRIPT ===="


by GoN | Published: May 2026 | Last Updated:

martes, 12 de mayo de 2026

WINDOWS. GPO. Alertas Windows


 Propósito:

El objetivo de este post es avisar a los usuarios que tienen pendiente un reinicio.

Para mi una de las peores cosas que tiene Microsoft es como alertar o advertir a los usuarios de un evento, sinceramente no me gusta nada los pequeños mensajes que pasan desapercibidos en la parte izquierda de la pantalla.

Otra cosa que no da muchas opciones Microsoft, es forzar un reinicio con un numero importante de alertas a los usuarios. Sin utilizar comandos, solo lo permite el Wsus un reinicio forzoso y sus avisos no son los mejores. Con lo que he tenido que pensar en otra manera de alertar a mis usuarios, de las muchas que hay se me ha ocurrido la siguiente, solo avisando, que he querido compartir aquí.

Aunque lo parezca, es uno de los script que me ha llevado más tiempo crear, he pasado por muchas formas y versiones y con la ayuda de Copilot ha acabado como aquí voy a explicar.

Lo he preparado para que salte en el logon de inicio y en cada bloqueo y desbloqueo de la pantalla. Dejará de aparecer cuando ya no tenga ningún reinicio pendiente.

Pasos

La GPO.

Como veréis es una GPO de usuario, no de máquina, ya que es la mejor manera de que las alertas interactúen con el usuario conectado.

Tenemos que crear en la GPO una tarea programada, esta tarea la inyectaremos en los PCs.




Argumentos: -NoProfile -ExecutionPolicy Bypass -WindowStyle Hidden -Command "& { $Source='\\Midominio.com\SYSVOL\midominio.com\scripts\WSUS\avisoreiniciopendiente.ps1'; $Target=$env:ProgramData+'\RebootAlert\avisoreiniciopendiente.ps1'; if (-not (Test-Path (Split-Path $Target))) { New-Item -ItemType Directory -Path (Split-Path $Target) -Force | Out-Null }; Copy-Item $Source $Target -Force; Start-Process powershell.exe -ArgumentList @('-NoProfile','-ExecutionPolicy','Bypass','-File', $Target) -WindowStyle Hidden }"









Poner el script en un recurso compartido donde puedan leer todos los usuarios.

Código:

# ==================================================

# ALERTA DE REINICIO PENDIENTE - PRODUCCIÓN

# ==================================================

# - Muestra aviso WPF si hay reinicio pendiente

# - Sin control de tiempo (sale siempre que haya reboot)

# - Evita doble ejecución mediante Mutex (que no salga dos veces seguidas la alerta)

# - Pensado para ejecución vía GPO / Tarea programada

# ==================================================

 

Add-Type -AssemblyName PresentationFramework

 

# --------------------------------------------------

# EVITAR DOBLE EJECUCIÓN DEL SCRIPT

# (necesario porque se lanza PowerShell oculto)# ==================================================

# ALERTA DE REINICIO PENDIENTE - PRODUCCIÓN

# ==================================================

# - Muestra aviso WPF si hay reinicio pendiente

# - Sin control de tiempo (sale siempre que haya reboot)

# - Evita doble ejecución mediante Mutex

# - Pensado para ejecución vía GPO / Tarea programada

# ==================================================

 

Add-Type -AssemblyName PresentationFramework

 

# --------------------------------------------------

# EVITAR DOBLE EJECUCIÓN DEL SCRIPT

# (necesario porque se lanza PowerShell oculto)

# --------------------------------------------------

$mutexName = "Global\RebootPendingAlertMutex"

$createdNew = $false

$mutex = New-Object System.Threading.Mutex($true, $mutexName, [ref]$createdNew)

 

if (-not $createdNew) {

    # Ya hay otra instancia ejecutándose

    exit

}

 

# --------------------------------------------------

# FUNCIÓN: Detectar reinicio pendiente

# --------------------------------------------------

function Test-PendingReboot {

 

    if (Test-Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired") {

        return $true

    }

 

    if (Test-Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootPending") {

        return $true

    }

 

    return $false

}

 

# --------------------------------------------------

# FUNCIÓN: Motivo del reinicio pendiente

# --------------------------------------------------

function Get-PendingRebootReason {

 

    if (Test-Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired") {

        return "actualizaciones de Windows"

    }

 

    if (Test-Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootPending") {

        return "actualizaciones del sistema"

    }

 

    return "tareas de mantenimiento del sistema"

}

 

# --------------------------------------------------

# SI NO HAY REINICIO PENDIENTE, SALIR

# --------------------------------------------------

if (-not (Test-PendingReboot)) {

    exit

}

 

# --------------------------------------------------

# OBTENER MOTIVO DEL REINICIO

# --------------------------------------------------

$rebootReason = Get-PendingRebootReason

 

# --------------------------------------------------

# VENTANA WPF

# --------------------------------------------------

[xml]$xaml = @"

<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

        Title="Miempresa. Reinicio pendiente"

        Height="240"

        Width="540"

        WindowStartupLocation="CenterScreen"

        ResizeMode="NoResize"

        Topmost="True">

 

    <Grid Margin="10">

        <Grid.RowDefinitions>

            <RowDefinition Height="Auto"/>

            <RowDefinition Height="*"/>

            <RowDefinition Height="Auto"/>

        </Grid.RowDefinitions>

 

        <!-- BARRA SUPERIOR ROJA -->

        <Border Background="#B71C1C" Grid.Row="0" Padding="10">

            <TextBlock Text="Reinicio pendiente."

                       Foreground="White"

                       FontSize="16"

                       FontWeight="Bold"

                       HorizontalAlignment="Center"/>

        </Border>

 

        <!-- TEXTO PRINCIPAL -->

        <Border Grid.Row="1" Padding="20">

            <TextBlock

                Text="El equipo necesita reiniciarse para completar $rebootReason.

 

Por favor, guarda tu trabajo y reinicia cuando te sea posible."

                TextWrapping="Wrap"

                TextAlignment="Center"

                VerticalAlignment="Center"

                FontSize="13"/>

        </Border>

 

        <!-- BOTÓN -->

        <Button Name="AceptarBtn"

                Grid.Row="2"

                Width="120"

                Height="35"

                Margin="10"

                HorizontalAlignment="Right"

                Background="#D32F2F"

                Foreground="White"

                FontWeight="Bold"

                Content="Aceptar"/>

    </Grid>

</Window>

"@

 

$reader = New-Object System.Xml.XmlNodeReader $xaml

$window = [Windows.Markup.XamlReader]::Load($reader)

 

$button = $window.FindName("AceptarBtn")

$button.Add_Click({ $window.Close() })

 

$window.ShowDialog() | Out-Null

 

# --------------------------------------------------

$mutexName = "Global\RebootPendingAlertMutex"

$createdNew = $false

$mutex = New-Object System.Threading.Mutex($true, $mutexName, [ref]$createdNew)

 

if (-not $createdNew) {

    # Ya hay otra instancia ejecutándose

    exit

}

 

# --------------------------------------------------

# FUNCIÓN: Detectar reinicio pendiente

# --------------------------------------------------

function Test-PendingReboot {

 

    if (Test-Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired") {

        return $true

    }

 

    if (Test-Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootPending") {

        return $true

    }

 

    return $false

}

 

# --------------------------------------------------

# FUNCIÓN: Motivo del reinicio pendiente

# --------------------------------------------------

function Get-PendingRebootReason {

 

    if (Test-Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired") {

        return "actualizaciones de Windows"

    }

 

    if (Test-Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootPending") {

        return "actualizaciones del sistema"

    }

 

    return "tareas de mantenimiento del sistema"

}

 

# --------------------------------------------------

# SI NO HAY REINICIO PENDIENTE, SALIR

# --------------------------------------------------

if (-not (Test-PendingReboot)) {

    exit

}

 

# --------------------------------------------------

# OBTENER MOTIVO DEL REINICIO

# --------------------------------------------------

$rebootReason = Get-PendingRebootReason

 

# --------------------------------------------------

# VENTANA WPF

# --------------------------------------------------

[xml]$xaml = @"

<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

        Title="Midominio. Reinicio pendiente"

        Height="240"

        Width="540"

        WindowStartupLocation="CenterScreen"

        ResizeMode="NoResize"

        Topmost="True">

 

    <Grid Margin="10">

        <Grid.RowDefinitions>

            <RowDefinition Height="Auto"/>

            <RowDefinition Height="*"/>

            <RowDefinition Height="Auto"/>

        </Grid.RowDefinitions>

 

        <!-- BARRA SUPERIOR ROJA -->

        <Border Background="#B71C1C" Grid.Row="0" Padding="10">

            <TextBlock Text="Reinicio pendiente."

                       Foreground="White"

                       FontSize="16"

                       FontWeight="Bold"

                       HorizontalAlignment="Center"/>

        </Border>

 

        <!-- TEXTO PRINCIPAL -->

        <Border Grid.Row="1" Padding="20">

            <TextBlock

                Text="El equipo necesita reiniciarse para completar $rebootReason.

 

Por favor, guarda tu trabajo y reinicia cuando te sea posible."

                TextWrapping="Wrap"

                TextAlignment="Center"

                VerticalAlignment="Center"

                FontSize="13"/>

        </Border>

 

        <!-- BOTÓN -->

        <Button Name="AceptarBtn"

                Grid.Row="2"

                Width="120"

                Height="35"

                Margin="10"

                HorizontalAlignment="Right"

                Background="#D32F2F"

                Foreground="White"

                FontWeight="Bold"

                Content="Aceptar"/>

    </Grid>

</Window>

"@

 

$reader = New-Object System.Xml.XmlNodeReader $xaml

$window = [Windows.Markup.XamlReader]::Load($reader)

 

$button = $window.FindName("AceptarBtn")

$button.Add_Click({ $window.Close() })

 

$window.ShowDialog() | Out-Null


Se me ocurre muchos puntos de mejora, pero los dejo para más adelante.

Sinceramente, se puede usar para lanzar cualquier tipo de alertas.

by GoN | Published: May 2026 | Last Updated: