Skip to content

Reportes generados

Mindset & Code edited this page Aug 18, 2026 · 3 revisions

Reportes generados

🇬🇧 English first · 🇪🇸 Español más abajo.

Each run writes two files into the working directory. They are for different readers, which is the point of writing both.

vulnerability_report.md — for a person

Written in Spanish, with four numbered sections, built by string concatenation in generate_report():

# 🛡️ Reporte de Escaneo de Vulnerabilidades - 192.168.1.100

**Fecha del Escaneo:** 2026-08-18 11:42:07
**Objetivo (IP):** `192.168.1.100`
**Herramienta de Simulación:** Nmap (Simulado)

## 1. Resumen Ejecutivo
Se encontraron **4** puertos abiertos y **2** vulnerabilidades potenciales. …

## 2. Puertos Abiertos Encontrados
| Puerto | Servicio | Estado |
| :--- | :--- | :--- |
| 23 | Telnet | Abierto |
| 80 | HTTP (Web Server) | Abierto |

## 3. Vulnerabilidades Detectadas
### 🚨 Puerto 23 - Telnet (Severidad: Critical)
**Descripción:** Telnet transmits data in plaintext, including passwords. MUST be
disabled and replaced with SSH (Port 22).

## 4. Recomendaciones de Mitigación
*   Deshabilitar el servicio Telnet (Puerto 23) inmediatamente y usar SSH…

Two things to notice, because they are real and not incidental:

  • The report header and section titles are in Spanish; the finding descriptions are in English. They come from the description strings in analyze_vulnerabilities(), which were written in English. It is a genuine inconsistency, not a design choice.
  • Section 4 is a fixed list. The same three recommendations print on every run, whether or not the corresponding finding was raised. They read as advice rather than as conclusions from this scan.

The timestamp is datetime.now() at the moment of the run, so it is the only part of the report that is never the same twice by construction.

raw_scan_data.json — for a machine

Three keys, assembled in __main__ and dumped with indent=4:

{
    "target_ip": "192.168.1.100",
    "open_ports": {
        "23": "Telnet",
        "80": "HTTP (Web Server)"
    },
    "vulnerabilities": [
        {
            "port": 23,
            "service": "Telnet",
            "severity": "Critical",
            "description": "Telnet transmits data in plaintext, …"
        }
    ]
}

open_ports is an object keyed by port number, not a list — JSON turns the Python integer keys into strings, so a consumer reads "23" and not 23. There is no metadata block, no results wrapper, no timestamp and no severity counters: whoever consumes this counts the entries in vulnerabilities itself.

Why two formats

The Markdown goes to whoever has to decide; the JSON goes to whatever has to process it. Splitting them is the habit worth showing: a finding that only exists inside a PDF cannot be tracked, and a finding that only exists inside a JSON cannot be acted on by the person who signs the budget.

On frameworks

The triage order reflects the reasoning of the ISC2 CC Security Operations domain: plaintext protocols before missing encryption, and exposed management services before both.

It does not implement CVSS. There is no vector string, no base score and no scoring function anywhere in the file — severities are four fixed labels assigned by rule. Claiming a CVSS basis would be claiming a calculation that does not happen.


🇪🇸 Español

Cada ejecución escribe dos ficheros en el directorio de trabajo. Son para lectores distintos, y esa es la razón de escribir los dos.

vulnerability_report.md — para una persona

En castellano, con cuatro secciones numeradas, construido concatenando cadenas en generate_report(). La estructura es la del bloque de arriba.

Dos cosas que conviene ver, porque son reales y no accidentales:

  • La cabecera y los títulos van en castellano; las descripciones de los hallazgos, en inglés. Salen de las cadenas description de analyze_vulnerabilities(), que se escribieron en inglés. Es una incoherencia de verdad, no una decisión de diseño.
  • La sección 4 es una lista fija. Las mismas tres recomendaciones se imprimen en cada ejecución, se haya levantado o no el hallazgo correspondiente. Se leen como consejos, no como conclusiones de este escaneo.

La marca de tiempo es datetime.now() en el momento de la ejecución, así que es la única parte del informe que por construcción nunca se repite.

raw_scan_data.json — para una máquina

Tres claves, montadas en __main__ y volcadas con indent=4: target_ip, open_ports y vulnerabilities.

open_ports es un objeto indexado por número de puerto, no una lista — JSON convierte las claves enteras de Python en cadenas, así que quien lo consume lee "23" y no 23. No hay bloque metadata, ni envoltorio results, ni marca de tiempo, ni contadores por severidad: quien consuma esto cuenta él mismo las entradas de vulnerabilities.

Por qué dos formatos

El Markdown va para quien tiene que decidir; el JSON, para lo que tiene que procesarlo. Separarlos es la costumbre que merece la pena enseñar: un hallazgo que solo existe dentro de un PDF no se puede seguir, y uno que solo existe dentro de un JSON no lo puede atender quien firma el presupuesto.

Sobre los marcos de referencia

El orden de triaje responde al razonamiento del dominio Security Operations de la ISC2 CC: los protocolos en texto plano antes que la falta de cifrado, y los servicios de administración expuestos antes que ambos.

No implementa CVSS. No hay cadena de vector, ni puntuación base, ni función de cálculo en ninguna parte del fichero: las severidades son cuatro etiquetas fijas asignadas por regla. Decir que se basa en CVSS sería atribuirle un cálculo que no ocurre.