
Kit de herramientas de endurecimiento de seguridad para sistemas heredados COBOL — detección de Unicode invisible, análisis de límites de formato, integridad de transformación de código fuente
Kit de herramientas de auditoría de seguridad para sistemas heredados COBOL
Parte de la Metodología de Investigación VTR | DOI: 10.5281/zenodo.22063208 Estado: Reproducible | Licencia: MIT | Área: Infraestructura Crítica
Detecta divergencias en el contexto de compilación, ataques con Unicode invisible y patrones COBOL inseguros en fuentes GnuCOBOL. El mismo archivo fuente compilado con -fixed vs -free produce programas diferentes — esta herramienta hace que esa divergencia sea observable y reproducible.
git clone https://github.com/LuisCastellanos-dev/cobol-shield
cd cobol-shield
bash tools/poc_compiler_flag.sh
Esta herramienta no afirma ni demuestra ejecución remota de código, escalada de privilegios ni explotación de red. Los hallazgos se clasifican como CONFIRMADO, PROBABLE u OBSERVADO según la metodología VTR — la clasificación refleja la solidez de la evidencia, no la gravedad del impacto.
Kit de herramientas de auditoría de seguridad para sistemas heredados COBOL
Detecta ataques con Unicode invisible, patrones COBOL inseguros y problemas de integridad en la transformación de formato en fuentes GnuCOBOL. Validado con GnuCOBOL 3.1.2. El comportamiento en IBM Enterprise COBOL o Micro Focus no está verificado — la semántica de las banderas específicas del compilador puede diferir.
PIC X acepta todo. Tu batch no debería.
cobol-shield cubre dos superficies de amenaza distintas:
1. Caracteres Unicode Invisibles — CVE-2021-42574 y vectores de la clase Glassworm que eluden la revisión visual del código y corrompen campos PIC X de forma silenciosa.
2. Análisis Estático COBOL — patrones inseguros en fuentes heredadas: working-storage sin inicializar, desbordamiento no controlado en STRING/UNSTRING, discrepancias de tamaño en REDEFINES y condiciones posicionales de formato fijo que cambian de significado bajo transformación.
| Archivo | Propósito |
|---|---|
tools/check-invisibles.py | Verificador de CI — sale con 1 al detectar Unicode invisible |
tools/clean-invisibles.py | Sanitizador con registro de auditoría forense |
src/AUDITOR-INVISIBLE.cob | Validador de bytes en COBOL usando HEX-OF |
tools/cobol_rules.py | Reglas de análisis estático R-01 a R-04 |
tools/transform_renumber.py | Simulador de desplazamiento de renumeración en formato fijo (Fase 2) |
tools/poc_compiler_flag.sh | PoC definitivo — mismo archivo, -fixed vs -free, divergencia de bandera del compilador |
tools/poc_differential.sh | PoC diferencial de Fase 2 — FUENTE A vs FUENTE B (migración manual) |
Cada regla produce una salida VTR Finding Schema v1 compatible con
cryptofault y vtr-forensic-img mediante context_loader.
| Regla | Nombre | Severidad | Clasificación |
|---|---|---|---|
| R-01 | UNINITIALIZED_WS | Alta | HECHO |
| R-02 | UNSTRING_NO_OVERFLOW | Alta | HECHO |
| R-03 | REDEFINES_SIZE_MISMATCH | Alta | HECHO |
| R-04 | FORMAT_BOUNDARY_ANALYSIS | Info | PROYECCION |
R-01 — UNINITIALIZED_WS Detecta variables de Working-Storage declaradas sin cláusula VALUE y sin INITIALIZE ni MOVE en la PROCEDURE DIVISION. Riesgo silencioso de comportamiento indefinido en entornos batch y CICS.
R-02 — UNSTRING_NO_OVERFLOW Detecta sentencias STRING/UNSTRING sin manejo de ON OVERFLOW. Truncamiento silencioso cuando la entrada supera la longitud del campo destino.
R-03 — REDEFINES_SIZE_MISMATCH Detecta REDEFINES donde el campo redefinido declara más bytes que su base. Riesgo de violación de límites de memoria — comportamiento dependiente del compilador.
R-04 — FORMAT_BOUNDARY_ANALYSIS (Fase 1 — solo observaciones) Detecta condiciones posicionales en fuentes COBOL de formato fijo:
COL73_NONEMPTY — contenido no vacío en el área de identificación (cols 73–80)COL7_VERB — verbo ejecutable COBOL en una línea comentada (col7 = * / / / D)SOURCE_BOUNDARY — contenido más allá de la col 80R-04 produce severity=info, classification=PROYECCION. Documenta
condiciones de formato — no vulnerabilidades. El impacto requiere análisis
diferencial de transformación (Fase 2).
La tesis central: un archivo COBOL de formato fijo tiene semántica diferente según la bandera del compilador usada para construirlo — y esa bandera vive fuera del archivo fuente.
Demostrado con GnuCOBOL 3.1.2, un único artefacto, sin modificación:
bash tools/poc_compiler_flag.sh
cobc -x -fixed poc-same-file.cbl → compila → salida: 0000001000
cobc -x -free poc-same-file.cbl → 10 errores de compilación
Bajo -fixed: la línea 6 col7=* es el indicador de comentario — MOVE 999999
está inactivo, el programa se ejecuta y muestra 1000.
Bajo -free: los números de secuencia 000100...001000 se interpretan como literales
numéricos — se reporta que falta el encabezado PROGRAM-ID, cada línea produce
un error. El mismo archivo es sintácticamente inválido.
La bandera del compilador no está dentro del archivo fuente. Vive en el Makefile, la configuración de CI o la invocación del operador. Cambiarla — intencional o accidentalmente — cambia si el programa es válido y qué hace.
Evidencia: corpus/fixed-format/poc-evidence.md
SHA-256 y registro completo de errores documentados.
Un PoC anterior demuestra la misma tesis mediante migración manual:
FUENTE A (formato fijo, col7='*' inactivo): salida → 0000001000
FUENTE B (formato libre, código activo): salida → 0000999999
SHA-256 A: b70a948a0df5e8f685e82f5bffc9c4710f2c0a7a23b6294e7ca20092c2d25d37
SHA-256 B: f5fd80f79ed3e5be97628f89790256d6fba80605dce2b7985b729b5fef6f26d5
Limitación: la FUENTE B es una representación manual de una migración incorrecta, no la salida de IBM Z Open Editor o IBM SCU bajo renumeración real. El PoC de bandera del compilador anterior no tiene esta limitación.
Rangos detectados:
| Punto de código | Nombre | Riesgo |
|---|---|---|
| U+0001–U+001F | Controles C0 | Abend en batch |
| U+200B–U+200F | Ancho Cero | Corrupción de datos, truncamiento VSAM |
| U+202A–U+202E | Anulación Bidi | Trojan Source — CVE-2021-42574 |
| U+2066–U+2069 | Aislamiento Bidi | Suplantación de dirección |
| U+FE00–U+FE0F | Selectores de Variación | Esteganografía de la clase Glassworm |
| U+E000–U+F8FF | Área de Uso Privado | Ocultación de payload |
| U+FEFF | BOM | Byte antepuesto silencioso |
# Inspección a nivel de byte
hexdump -C source.cob | grep -E "e2 80 (8b|ae)"
# Verificación Unicode en CI — sale con 1 al detectar
python3 tools/check-invisibles.py .
# Sanitizar con registro de auditoría forense
python3 tools/clean-invisibles.py . --report audit-$(date +%Y%m%d).log
# Ejecutar reglas de análisis estático
python3 -c "
from tools.cobol_rules import scan_path_r01, scan_path_r02, scan_path_r03, scan_path_r04
import json
for f in scan_path_r02('your-source.cbl'):
print(f.to_json())
"
# PoC diferencial de transformación
bash tools/poc_differential.sh
- name: Check for invisible Unicode
run: python3 tools/check-invisibles.py .
PIC X(n) es un búfer de bytes sin procesar. Acepta cualquier secuencia de bytes sin
validación. Cuando una capa de API Zowe pasa JSON a un copybook COBOL mediante
MOVE, el Unicode invisible entra en el registro de forma silenciosa.