Demostración de Validación de Entrada e Integridad de Código

CompTIABeginner
Practicar Ahora

Introducción

En este laboratorio, explorará dos conceptos fundamentales de seguridad: la validación de entradas (input validation) y la integridad del código (code integrity). La validación de entradas es la práctica de asegurar que cualquier entrada que un programa recibe sea segura y esté bien formada antes de ser procesada. Esta es una defensa crítica contra una amplia gama de ataques, incluida la inyección de comandos (command injection). La integridad del código implica verificar que el código de su aplicación no ha sido alterado o corrompido por una parte no autorizada.

Aprenderá estos conceptos a través de un enfoque práctico. Primero, creará un script de shell simple que es intencionalmente vulnerable a la inyección de comandos. Luego, explotará esta vulnerabilidad para comprender el riesgo. Después, asegurará el script implementando una sanitización de entradas adecuada. Finalmente, aprenderá a usar hashes criptográficos para verificar la integridad de su script, asegurando que no ha sido manipulado.

Crear un Script Simple con Entrada de Usuario

En este paso, creará un script Bash sencillo que solicitará al usuario un nombre de archivo y luego mostrará información detallada sobre ese archivo utilizando el comando ls -l. Esta versión inicial del script no tendrá ninguna verificación de seguridad.

Primero, use el editor nano para crear un nuevo archivo llamado check_file.sh en el directorio ~/project.

nano ~/project/check_file.sh

Ahora, agregue el siguiente código al archivo. Este script pedirá un nombre de archivo, leerá la entrada en una variable llamada filename y luego ejecutará ls -l sobre ese nombre de archivo utilizando el comando eval. Tenga en cuenta que usar eval con entrada del usuario es una vulnerabilidad de seguridad grave.

#!/bin/bash

echo "Please enter a filename to check:"
read filename
echo "Checking details for: $filename"
eval "ls -l $filename"

Presione Ctrl+X, luego Y y Enter para guardar el archivo y salir de nano.

A continuación, deberá hacer que el script sea ejecutable para poder ejecutarlo. Use el comando chmod para agregar permisos de ejecución.

chmod +x ~/project/check_file.sh

Ahora, ejecutemos el script para verlo en acción. Usaremos testfile.txt, que se creó para usted en el entorno de laboratorio.

./check_file.sh

El script le pedirá una entrada. Escriba testfile.txt y presione Enter.

Please enter a filename to check:
testfile.txt
Checking details for: testfile.txt
-rw-rw-r-- 1 labex labex 0 Aug  4 15:19 testfile.txt

Ha creado y ejecutado con éxito un script sencillo que toma la entrada del usuario. En el siguiente paso, verá cómo se puede explotar este script.

Simular un Ataque Básico de Inyección de Comandos

En este paso, verá cómo el script creado en el paso anterior es vulnerable a un ataque de inyección de comandos. La inyección de comandos ocurre cuando un atacante puede ejecutar comandos arbitrarios en el sistema operativo anfitrión a través de una aplicación vulnerable.

Nuestro script es vulnerable porque utiliza eval para ejecutar un comando que incluye la entrada del usuario ($filename) sin verificar primero si la entrada es segura. El comando eval trata toda la cadena como un comando a ejecutar, lo que lo hace particularmente peligroso. Un atacante puede explotar esto proporcionando una entrada que incluya comandos adicionales del shell.

Ejecutemos el script nuevamente.

./check_file.sh

Esta vez, cuando se le solicite un nombre de archivo, ingrese la siguiente cadena. El punto y coma (;) es un carácter especial en el shell que separa comandos.

testfile.txt; whoami

Después de presionar Enter, verá la siguiente salida:

Please enter a filename to check:
testfile.txt; whoami
Checking details for: testfile.txt; whoami
-rw-rw-r-- 1 labex labex 0 Aug  4 15:19 testfile.txt
labex

Observe lo que sucedió. El script primero ejecutó ls -l testfile.txt como se esperaba. Sin embargo, debido al punto y coma y al uso de eval, el shell luego ejecutó el segundo comando, whoami, que imprimió el nombre de usuario actual (labex). Esto demuestra una inyección de comandos exitosa. El comando eval hizo esto posible al tratar toda la entrada como código ejecutable. Un atacante podría usar esta vulnerabilidad para ejecutar comandos mucho más peligrosos.

Nota: Si hubiera usado ls -l $filename sin eval (como en la versión original), el ataque no habría funcionado porque el shell habría tratado testfile.txt; whoami como argumentos separados para ls, lo que resultaría en mensajes de error como "cannot access 'testfile.txt;'" y "cannot access 'whoami'". El comando eval es lo que hace posible la inyección de comandos en este ejemplo.

Implementar la Sanitización de Entradas para Prevenir Inyecciones

En este paso, modificará el script para prevenir ataques de inyección de comandos sanitizando la entrada del usuario y eliminando el peligroso comando eval. La sanitización de entrada es el proceso de limpiar o filtrar la entrada para eliminar o neutralizar caracteres potencialmente maliciosos.

Nuestra estrategia será:

  1. Eliminar el peligroso comando eval y usar la ejecución directa de comandos con el entrecomillado adecuado.
  2. Verificar si el nombre de archivo de entrada contiene solo caracteres permitidos. Para un nombre de archivo típico, podemos crear una lista blanca de caracteres, como letras, números, guiones bajos, guiones y puntos. Rechazaremos cualquier entrada que contenga otros caracteres, como el punto y coma.

Abra el script check_file.sh nuevamente con nano.

nano ~/project/check_file.sh

Modifique el script para incluir una verificación de validación utilizando una expresión regular. Reemplace el contenido existente con el siguiente código:

#!/bin/bash

echo "Please enter a filename to check:"
read filename

## Input sanitization: only allow alphanumeric characters, underscores, hyphens, and dots.
if [[ "$filename" =~ ^[a-zA-Z0-9_.-]+$ ]]; then
  echo "Checking details for: $filename"
  ls -l "$filename"
else
  echo "Error: Invalid filename. Malicious input detected."
fi

Los cambios clave son:

  1. Eliminación del peligroso comando eval.
  2. Adición del entrecomillado adecuado alrededor de "$filename" en el comando ls.
  3. La declaración if con validación de entrada. La expresión [[ "$filename" =~ ^[a-zA-Z0-9_.-]+$ ]] verifica si la variable filename contiene solo los caracteres del conjunto especificado desde el principio (^) hasta el final ($).

Presione Ctrl+X, Y y Enter para guardar los cambios.

Ahora, intentemos el mismo ataque nuevamente. Ejecute el script:

./check_file.sh

Ingrese la entrada maliciosa testfile.txt; whoami y presione Enter.

Please enter a filename to check:
testfile.txt; whoami
Error: Invalid filename. Malicious input detected.

Como puede ver, el script ahora detecta los caracteres inválidos e imprime un mensaje de error en lugar de ejecutar el comando malicioso whoami. El ataque se previene con éxito.

Verificar la Integridad del Script con Hashing

En este paso, aprenderá cómo verificar la integridad de su script utilizando un hash criptográfico. Esto asegura que el script no ha sido modificado o manipulado por un atacante después de que lo haya asegurado. Utilizaremos la utilidad sha256sum, que calcula un hash SHA-256.

Primero, generemos un hash para nuestro script seguro check_file.sh y guardémoslo en un archivo. Este archivo actuará como nuestra firma "conocida como buena".

sha256sum ~/project/check_file.sh > ~/project/check_file.sha256

Este comando calcula el hash SHA-256 de check_file.sh y redirige la salida a un nuevo archivo llamado check_file.sha256. Veamos el contenido de este archivo.

cat ~/project/check_file.sha256

Verá una larga cadena de caracteres seguida del nombre del archivo. Esta cadena es el hash único de su script.

e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855  /home/labex/project/check_file.sh

(Nota: Su valor de hash será diferente.)

Ahora, simulemos una modificación no autorizada. Agregaremos un comentario simple al final del script. Incluso un cambio pequeño como este debería alterar el hash por completo.

echo "## A harmless comment" >> ~/project/check_file.sh

El script ha sido modificado. Para verificar su integridad, podemos usar sha256sum con la opción -c (check), que lee el hash de nuestro archivo de firma y lo compara con el hash actual del script.

sha256sum -c ~/project/check_file.sha256

El comando informará un fallo porque el archivo ha cambiado.

/home/labex/project/check_file.sh: FAILED
sha256sum: WARNING: 1 computed checksum did NOT match

Esto confirma que la integridad del script se ha visto comprometida. Esta técnica es esencial para garantizar que el código que está ejecutando es el código en el que confía.

Resumen

¡Felicitaciones por completar este laboratorio! Ha adquirido experiencia práctica con dos principios de seguridad críticos.

Aprendió cómo identificar y prevenir vulnerabilidades de inyección de comandos implementando la sanitización de entrada. Al validar la entrada del usuario contra una lista blanca de caracteres permitidos, aseguró con éxito un script de shell vulnerable.

También aprendió cómo garantizar la integridad del código utilizando hashes criptográficos. Al generar una suma de verificación SHA-256 para su script, pudo crear una firma verificable que puede detectar cualquier modificación no autorizada.

Estas habilidades son fundamentales para escribir código seguro y mantener la seguridad de cualquier sistema.