Automatización del análisis de registros

CiberseguridadBeginner
Practicar Ahora

Introducción

Como administrador de sistemas o analista de seguridad, a menudo te encontrarás con archivos de registro (logs) masivos generados por servidores web como Apache o Nginx. Leer manualmente miles de líneas de registros para encontrar actividad maliciosa es insostenible y propenso al error humano.

En este laboratorio, asumirás el rol de un responsable de seguridad. Escribirás un script de Python diseñado para procesar registros de acceso de servidores web Apache. Al utilizar la biblioteca de Expresiones Regulares (re) de Python, extraerás automáticamente direcciones IP y detectarás firmas conocidas de ataques de inyección SQL (SQLi). Finalmente, exportarás estos hallazgos a un informe CSV estructurado para su posterior análisis.

Este módulo es donde Python comienza a convertirse en un multiplicador de capacidad para el analista, más que en un simple lenguaje de programación. Los registros son uno de los ejemplos más claros de trabajo que es demasiado repetitivo para una revisión manual cuidadosa, pero lo suficientemente estructurado para que la automatización sea de ayuda inmediata.

Leer archivos de registro en Python

En este paso, aprenderás a usar Python para abrir y leer un archivo de registro. El entorno ya ha sido preparado con un archivo de registro de Apache de muestra llamado access.log en tu directorio de trabajo.

Leer archivos línea por línea es un patrón de automatización fundamental. Es más escalable que copiar datos a mano y te prepara para añadir lógica de filtrado, análisis, conteo y generación de informes sin cambiar el enfoque básico de ingesta.

Primero, veamos el contenido del archivo de registro de muestra para entender con qué estamos trabajando. Usa el comando cat en tu terminal para imprimir el contenido del archivo.

cat access.log

Deberías ver varias líneas de registros de acceso estándar de Apache. Algunas de estas líneas contienen solicitudes web normales, mientras que otras contienen intentos sospechosos de inyección SQL.

Ahora, creemos un script de Python para leer este archivo mediante programación. Usaremos el editor de texto nano para crear un archivo llamado log_analyzer.py.

nano log_analyzer.py

En Python, la función open() se utiliza para abrir un archivo, y la sentencia with asegura que el archivo se cierre correctamente después de que hayamos terminado de leerlo. Copia y pega el siguiente código de Python en tu editor nano:

def analyze_logs(file_path):
    print(f"Opening log file: {file_path}")

    ## Open the file in read mode ('r')
    with open(file_path, 'r') as file:
        ## Read the file line by line
        for line in file:
            ## Print each line, stripping the extra newline character
            print(line.strip())

if __name__ == "__main__":
    log_file = "access.log"
    analyze_logs(log_file)

Guarda el archivo en nano presionando Ctrl+O, luego Enter para confirmar el nombre del archivo. Si deseas seguir construyendo el script antes de probarlo, puedes permanecer en nano y pasar al siguiente paso. Usa Ctrl+X solo cuando estés listo para volver a la terminal.

Ejecuta tu script de Python recién creado usando el comando python3:

python3 log_analyzer.py

Verás que el script muestra exactamente las mismas líneas de registro que viste anteriormente con el comando cat. Esto confirma que tu script de Python puede procesar con éxito los datos de registro línea por línea.

Aplicar Regex para la extracción de IP

En este paso, mejorarás tu script de Python para extraer automáticamente la dirección IP de cada línea de registro. Para hacer esto, usaremos Expresiones Regulares (Regex). Regex es una herramienta poderosa para encontrar patrones en el texto.

Las expresiones regulares son útiles porque los registros están semiestructurados: siguen patrones, pero generalmente no en forma de objetos de Python limpios. Regex te da una manera de describir el patrón de texto que deseas y dejar que el intérprete haga el trabajo repetitivo de coincidencia.

Python proporciona un módulo incorporado llamado re para trabajar con expresiones regulares. Necesitamos importar este módulo y definir un patrón que coincida con una dirección IPv4. Una dirección IPv4 consta de cuatro números (que van de 0 a 255) separados por puntos.

Si log_analyzer.py todavía está abierto en nano, continúa editándolo allí. De lo contrario, ábrelo de nuevo con:

nano log_analyzer.py

Actualiza tu script para incluir el módulo re y la lógica para buscar direcciones IP. Reemplaza todo el contenido del archivo con el siguiente código:

import re

def analyze_logs(file_path):
    print(f"Analyzing log file: {file_path}\n")

    ## Define a Regex pattern for an IPv4 address
    ## \b ensures word boundaries, \d{1,3} matches 1 to 3 digits, \. matches a literal dot
    ip_pattern = r'\b(?:\d{1,3}\.){3}\d{1,3}\b'

    with open(file_path, 'r') as file:
        for line in file:
            ## re.findall returns a list of all matches in the string
            ips_found = re.findall(ip_pattern, line)

            if ips_found:
                ## We take the first IP found in the line
                source_ip = ips_found[0]
                print(f"Extracted IP: {source_ip}")

if __name__ == "__main__":
    log_file = "access.log"
    analyze_logs(log_file)

Guarda el archivo con Ctrl+O y Enter. Si deseas probar esta versión intermedia ahora, sal con Ctrl+X y ejecuta el script. Si no, puedes continuar directamente al siguiente paso.

python3 log_analyzer.py

Deberías ver una salida similar a esta:

Analyzing log file: access.log

Extracted IP: 192.168.1.10
Extracted IP: 10.0.0.15
Extracted IP: 172.16.0.5
Extracted IP: 192.168.1.22
Extracted IP: 10.0.0.25

El script ahora ignora con éxito el resto del texto del registro y aísla solo las direcciones IP de origen utilizando el poder de Regex.

Detectar firmas de SQLi

En este paso, añadirás una función de detección de seguridad a tu script. La inyección SQL (SQLi) es un ataque web común donde se insertan sentencias SQL maliciosas en los campos de entrada.

Esto convierte al script de un analizador a un detector. En lugar de solo extraer campos, ahora estás aplicando lógica de seguridad para decidir qué líneas merecen atención. Ese cambio de la recolección a la interpretación es lo que hace que la automatización sea operativamente valiosa.

Los atacantes a menudo usan palabras clave específicas como UNION SELECT para robar datos, o ' OR '1'='1 para omitir la autenticación. Podemos usar Regex para escanear las líneas de registro en busca de estas firmas de ataque conocidas.

Si todavía estás editando el mismo archivo en nano, sigue trabajando allí. De lo contrario, ábrelo de nuevo:

nano log_analyzer.py

Definiremos un nuevo patrón de Regex para detectar frases comunes de SQLi. Usaremos (?i) para hacer que la búsqueda no distinga entre mayúsculas y minúsculas, lo que significa que detectará UNION, union o uNiOn. Actualiza tu script para que coincida con el siguiente código:

import re

def analyze_logs(file_path):
    print(f"Scanning log file for SQLi attacks: {file_path}\n")

    ip_pattern = r'\b(?:\d{1,3}\.){3}\d{1,3}\b'

    ## Define a Regex pattern for SQL Injection signatures
    ## (?i) makes it case-insensitive
    ## It looks for 'union select' OR 'or 1=1' variations
    sqli_pattern = r"(?i)(union.*select|or\s+1\s*=\s*1|'.*or.*')"

    with open(file_path, 'r') as file:
        for line in file:
            ips_found = re.findall(ip_pattern, line)
            source_ip = ips_found[0] if ips_found else "Unknown IP"

            ## re.search returns a match object if the pattern is found, otherwise None
            if re.search(sqli_pattern, line):
                print(f"[ALERT] SQL Injection detected from IP: {source_ip}")
                print(f"Raw Log: {line.strip()}\n")

if __name__ == "__main__":
    log_file = "access.log"
    analyze_logs(log_file)

Guarda el archivo con Ctrl+O y Enter. Sal de nano con Ctrl+X solo cuando estés listo para ejecutar el script desde la terminal.

python3 log_analyzer.py

Tu salida ahora debería señalar específicamente las solicitudes maliciosas:

Scanning log file for SQLi attacks: access.log

[ALERT] SQL Injection detected from IP: 10.0.0.15
Raw Log: 10.0.0.15 - - [10/Oct/2026:13:55:45 -0700] "GET /login.php?user=admin' OR '1'='1 HTTP/1.1" 200 5120

[ALERT] SQL Injection detected from IP: 192.168.1.22
Raw Log: 192.168.1.22 - - [10/Oct/2026:13:56:12 -0700] "GET /products.php?id=1 UNION SELECT username, password FROM users HTTP/1.1" 200 4012

Tu script ahora actúa como un Sistema de Detección de Intrusiones (IDS) básico, identificando automáticamente las solicitudes sospechosas en el archivo de registro.

Exportar a un informe CSV

En este paso final, formatearás los resultados y los guardarás en un archivo CSV (Valores Separados por Comas). Imprimir en la terminal es excelente para probar, pero los equipos de seguridad necesitan informes estructurados que puedan abrirse en software de hojas de cálculo o ser ingeridos por otras herramientas.

Python tiene un módulo csv incorporado que hace que escribir archivos CSV sea muy fácil.

Si mantuviste el archivo abierto, continúa editándolo. De lo contrario, ábrelo de nuevo:

nano log_analyzer.py

Importaremos el módulo csv, abriremos un nuevo archivo llamado report.csv en modo de escritura ('w') y escribiremos nuestros hallazgos en él. Reemplaza tu código con esta versión final:

import re
import csv

def analyze_logs(file_path, output_csv):
    print(f"Analyzing logs and generating report: {output_csv}...")

    ip_pattern = r'\b(?:\d{1,3}\.){3}\d{1,3}\b'
    sqli_pattern = r"(?i)(union.*select|or\s+1\s*=\s*1|'.*or.*')"

    ## Open the output CSV file in write mode
    with open(output_csv, 'w', newline='') as csv_file:
        writer = csv.writer(csv_file)
        ## Write the header row
        writer.writerow(['Source IP', 'SQLi Detected', 'Raw Log'])

        with open(file_path, 'r') as file:
            for line in file:
                clean_line = line.strip()
                ips_found = re.findall(ip_pattern, clean_line)
                source_ip = ips_found[0] if ips_found else "Unknown IP"

                ## Check if SQLi is detected
                sqli_detected = "Yes" if re.search(sqli_pattern, clean_line) else "No"

                ## Write the data row to the CSV
                writer.writerow([source_ip, sqli_detected, clean_line])

    print("Report generation finished.")

if __name__ == "__main__":
    log_file = "access.log"
    report_file = "report.csv"
    analyze_logs(log_file, report_file)

Guarda el archivo y ejecuta el script:

python3 log_analyzer.py

Verás un mensaje indicando que la generación del informe está completa. Ahora, verifiquemos que el archivo CSV se creó y comprobemos su contenido usando el comando cat:

cat report.csv

Deberías ver una salida CSV perfectamente formateada:

Source IP,SQLi Detected,Raw Log
192.168.1.10,No,192.168.1.10 - - [10/Oct/2026:13:55:36 -0700] "GET /index.html HTTP/1.1" 200 2326
10.0.0.15,Yes,10.0.0.15 - - [10/Oct/2026:13:55:45 -0700] "GET /login.php?user=admin' OR '1'='1 HTTP/1.1" 200 5120
172.16.0.5,No,172.16.0.5 - - [10/Oct/2026:13:56:01 -0700] "POST /api/data HTTP/1.1" 404 134
192.168.1.22,Yes,192.168.1.22 - - [10/Oct/2026:13:56:12 -0700] "GET /products.php?id=1 UNION SELECT username, password FROM users HTTP/1.1" 200 4012
10.0.0.25,No,10.0.0.25 - - [10/Oct/2026:13:57:00 -0700] "GET /about.html HTTP/1.1" 200 1024

Resumen

En este laboratorio, pasaste con éxito de la lectura manual de registros al análisis automatizado utilizando Python. Aprendiste a leer y procesar archivos de texto línea por línea utilizando el manejo de archivos incorporado de Python. También utilizaste el módulo re para aplicar Expresiones Regulares con el fin de extraer formatos de datos específicos, como direcciones IP. Además, implementaste lógica de detección de seguridad comparando firmas conocidas de ataques de inyección SQL contra los datos de registro sin procesar. Finalmente, practicaste la exportación de datos estructurados a un informe CSV utilizando el módulo csv, facilitando el intercambio y el análisis posterior de los resultados.

Estas habilidades forman la base de la automatización de seguridad y el análisis de datos, permitiéndote manejar conjuntos de datos masivos de manera eficiente.