1. Tuberías y flujos estándar
En los sistemas derivados de UNIX, las tareas complejas de análisis no se resuelven con programas monolíticos, sino componiendo utilidades especializadas que se comunican mediante tuberías o pipelines. Cada herramienta realiza una operación elemental, como filtrar, proyectar columnas, ordenar o contar, y la combinación de todas ellas permite resumir en segundos registros de millones de líneas sin depender de software adicional, algo especialmente valioso en la respuesta ante incidentes sobre un servidor comprometido, donde no conviene instalar nada.
1.1. Descriptores y redirecciones
Todo proceso dispone de tres flujos estándar:
| Descriptor | Nombre | Uso |
|---|---|---|
|
Entrada estándar, stdin |
Datos que recibe el proceso |
|
Salida estándar, stdout |
Resultados; es lo que viaja por la tubería |
|
Salida de error, stderr |
Mensajes de error; no atraviesa la tubería |
La tubería a | b conecta la salida estándar de a con la entrada estándar de b. Las redirecciones permiten, además, dirigir cada flujo a un fichero:
| Sintaxis | Efecto |
|---|---|
|
Redirige la salida estándar sobrescribiendo o añadiendo |
|
Descarta los mensajes de error, como los avisos de permiso denegado de |
|
Envía los errores al mismo destino que la salida estándar |
|
Toma la entrada estándar de un fichero |
1.2. Privilegios y redirecciones
|
En
|
Aplique también el principio de mínimo privilegio dentro de la tubería: solo el comando que lee el fichero protegido necesita sudo; el resto del procesamiento debe ejecutarse como usuario sin privilegios.
1.3. Tuberías robustas en scripts
El código de salida de una tubería es, por defecto, el del último comando. En grep patrón fichero_inexistente | wc -l, grep falla pero wc devuelve 0, y el script continúa como si todo fuera correcto. En los scripts de auditoría debe activarse:
set -o pipefail
Con esta opción, la tubería devuelve el código del último comando que haya fallado. El array PIPESTATUS de Bash contiene además el código de cada etapa.
2. Utilidades elementales
2.1. Proyección de columnas con cut
# Campos 1 y 7 de /etc/passwd
cut -d: -f1,7 /etc/passwd
# Caracteres 1 a 15, que contienen la marca temporal en el formato clásico de syslog
sudo head -n 5 /var/log/auth.log | cut -c1-15
cut solo admite un delimitador de un carácter y no agrupa separadores consecutivos. Para la salida de ps, ss o df, alineada con un número variable de espacios, debe usarse awk o normalizar antes los espacios con tr -s ' '.
2.2. Ordenación con sort
| Opción | Efecto |
|---|---|
|
Orden numérico |
|
Orden inverso |
|
Separador de campos |
|
Clave de ordenación limitada al campo |
|
Elimina duplicados tras ordenar |
|
Orden de versiones, útil también para direcciones IPv4 |
|
Orden de tamaños con sufijos, como |
# Cuentas ordenadas por UID
sort -t: -k3,3n /etc/passwd
# Direcciones IPv4 en orden numérico real, no lexicográfico
printf '10.0.0.10\n10.0.0.9\n192.168.1.1\n' | sort -V
2.3. Recuento de frecuencias con uniq
uniq solo detecta líneas duplicadas consecutivas, por lo que la entrada debe ordenarse antes con sort.
-
-cantepone el número de repeticiones. -
-dmuestra solo las líneas repetidas. -
-umuestra solo las líneas que no se repiten.
# Número de cuentas por intérprete de órdenes
cut -d: -f7 /etc/passwd | sort | uniq -c | sort -rn
|
Use |
2.4. Transformación de caracteres con tr
# Conversión a mayúsculas
echo "alerta de seguridad" | tr '[:lower:]' '[:upper:]'
# Eliminación de los retornos de carro de un script creado en Windows
tr -d '\r' < script_windows.sh > script_linux.sh
# Compresión de espacios repetidos para poder usar cut
ps aux | tr -s ' ' | cut -d' ' -f1,2,11
2.5. Recuento, muestreo y seguimiento
-
wc -lcuenta líneas;wc -c, bytes. -
head -n Nytail -n Nmuestran las primeras o las últimasNlíneas. -
tail -fsigue un fichero en tiempo real.tail -Fademás lo reabre cuando el sistema de rotación lo sustituye, lo que lo hace preferible para supervisar registros.
2.6. Bifurcación, ejecución por lotes y comparación
-
teecopia la entrada a un fichero y a la salida estándar, lo que permite guardar un resultado intermedio como evidencia sin interrumpir la tubería. -
xargsconvierte líneas de entrada en argumentos de otro comando. Con nombres de fichero debe usarse siemprefind … -print0 | xargs -0, ya que un nombre con espacios o saltos de línea, que un atacante puede crear deliberadamente, rompería la tubería o haría que el comando actuara sobre otro fichero. -
commcompara dos ficheros ordenados y muestra en tres columnas las líneas exclusivas del primero, las exclusivas del segundo y las comunes. Con-13muestra solo lo nuevo en el segundo fichero, lo que resulta idóneo para comparar contra una línea base. -
diffmuestra las diferencias línea a línea entre dos ficheros.
|
Con los conceptos explicados hasta aquí, ya puede realizar el Ejercicio 1. Preparación del laboratorio y utilidades básicas y el Ejercicio 2. Ordenación, recuento y tuberías robustas. |
3. Flujos de detección y análisis forense
3.1. Ataques de fuerza bruta contra SSH
Un ataque de fuerza bruta o de diccionario contra SSH, recogido en MITRE ATT&CK como Brute Force (T1110), genera una secuencia de eventos Failed password. La siguiente tubería identifica las diez direcciones con más intentos:
sudo grep 'Failed password' /var/log/auth.log \
| grep -oE 'from ([0-9]{1,3}\.){3}[0-9]{1,3}' \
| cut -d' ' -f2 \
| sort | uniq -c | sort -rn \
| head -n 10
-
grepselecciona los eventos de autenticación fallida. -
grep -oEextrae la dirección precedida defrom, lo que evita capturar otras secuencias numéricas del mensaje. -
cutelimina la palabrafrom. -
sortagrupa las direcciones idénticas. -
uniq -ccuenta los intentos de cada dirección. -
sort -rnordena de mayor a menor número de intentos. -
headlimita el informe a las diez primeras.
En sistemas sin rsyslog, la fuente equivalente es el diario de systemd:
sudo journalctl -u ssh --since '-24h' -o cat \
| grep 'Failed password' \
| grep -oE 'from ([0-9]{1,3}\.){3}[0-9]{1,3}' \
| cut -d' ' -f2 | sort | uniq -c | sort -rn | head -n 10
La opción -o cat elimina la marca temporal y el nombre del proceso, de modo que el resto de la tubería no depende del formato del registro.
|
Este análisis es retrospectivo. La respuesta automática ante estos patrones, mediante el bloqueo temporal de la dirección en el cortafuegos, se estudia en la guía de Fail2ban, cuyos filtros son precisamente expresiones regulares aplicadas a estos mismos registros. |
3.2. Cuentas objetivo del ataque
sudo grep 'Failed password for' /var/log/auth.log \
| sed -E 's/.*Failed password for (invalid user )?([^ ]+) from.*/\2/' \
| sort | uniq -c | sort -rn | head -n 10
El resultado permite distinguir un ataque dirigido contra cuentas administrativas conocidas, como root o admin, de una enumeración masiva de nombres, y comprobar si alguna de las cuentas atacadas existe realmente en el sistema.
3.3. Identificadores de usuario duplicados
Cada cuenta debe tener un UID único, como exige el CIS Benchmark en el control Ensure no duplicate UIDs exist. Dos cuentas con el mismo UID son, a efectos del núcleo, la misma identidad, y comparten ficheros y privilegios:
# UID repetidos
cut -d: -f3 /etc/passwd | sort -n | uniq -d
# Cuentas implicadas en cada UID repetido
awk -F: '{ c[$3]++; n[$3] = n[$3] " " $1 } END { for (u in c) if (c[u] > 1) print "UID " u ":" n[u] }' /etc/passwd
3.4. Comparación con una línea base de ficheros SetUID
Un fichero con el bit SetUID se ejecuta con la identidad de su propietario. La aparición de un nuevo binario SetUID de root es una técnica clásica de persistencia y escalada de privilegios, catalogada como Abuse Elevation Control Mechanism: Setuid and Setgid (T1548.001). La detección consiste en guardar una línea base del sistema recién bastionado y compararla periódicamente:
# Línea base, generada sobre el sistema recién instalado y bastionado
sudo find / -xdev -type f -perm -4000 -print 2>/dev/null | LC_ALL=C sort > suid_base.txt
# Comprobación posterior: ficheros SetUID que no estaban en la línea base
sudo find / -xdev -type f -perm -4000 -print 2>/dev/null | LC_ALL=C sort | LC_ALL=C comm -13 suid_base.txt -
-xdev evita descender a otros sistemas de ficheros, como /proc o los montajes de red. La línea base debe almacenarse fuera del sistema auditado o protegida contra escritura, ya que un atacante con privilegios podría modificarla.
|
Con los conceptos explicados en esta sección, ya puede realizar el Ejercicio 3. Investigación de un ataque de fuerza bruta y el Ejercicio 4. Línea base de ficheros SetUID. |
4. Recetario de tuberías para la inspección del sistema
-
Número de cuentas de usuario humano frente a cuentas de sistema:
awk -F: '{ if ($3 >= 1000 && $3 != 65534) h++; else s++ } END { print "Humanas:", h+0, "Sistema:", s+0 }' /etc/passwdEl UID
65534corresponde anobodyy no debe contarse como usuario humano. -
Puertos en escucha y proceso asociado, sin cabecera:
sudo ss -tulpnH | awk '{ print $1, $5, $7 }' | sort -u -
Ficheros SetUID agrupados por propietario:
sudo find / -xdev -type f -perm -4000 -printf '%u\n' 2>/dev/null | sort | uniq -c | sort -rn-printfevita encadenarfindconlsmediantexargs, lo que fallaría con nombres que contengan espacios. -
Comandos más ejecutados mediante
sudo:sudo grep -h 'COMMAND=' /var/log/auth.log | sed -E 's/.*COMMAND=//' | sort | uniq -c | sort -rn | head -n 10 -
Registros de
/etc/shadowcon un número de campos distinto de 9:sudo awk -F: 'NF != 9 { print "Línea " NR }' /etc/shadow -
Inicios de sesión correctos por usuario y dirección de origen:
sudo grep -h 'Accepted' /var/log/auth.log | awk '{ for (i=1;i<=NF;i++) if ($i=="for") u=$(i+1); else if ($i=="from") ip=$(i+1); print u, ip }' | sort | uniq -c | sort -rn -
Ficheros modificados en
/etcen las últimas 24 horas:sudo find /etc -xdev -type f -mtime -1 -printf '%TY-%Tm-%Td %TH:%TM %p\n' | sort
5. Ejercicios prácticos
Los ejercicios deben realizarse en orden sobre una máquina virtual Debian o Ubuntu de pruebas. Trabajan sobre ficheros de muestra situados en ~/lab_filtrado/tuberias. El último ejercicio elimina el laboratorio.
| Nº | Ejercicio | Competencia que desarrolla |
|---|---|---|
1 |
Usar |
|
2 |
Combinar |
|
3 |
Reconstruir un incidente a partir de registros |
|
4 |
Detectar persistencia comparando con una línea base |
|
5 |
Revertir el laboratorio |
5.1. Ejercicio 1. Preparación del laboratorio y utilidades básicas
Realice los siguientes pasos:
-
Cree el laboratorio con una copia de
/etc/passwdque incluye una cuenta con UID duplicado y un registro de autenticación de muestra:mkdir -p ~/lab_filtrado/tuberias && cd ~/lab_filtrado/tuberias cp /etc/passwd passwd echo 'operador:x:1001:1001:Operador:/home/operador:/bin/bash' >> passwd echo 'mantenimiento:x:1001:1001:Mantenimiento:/home/mant:/bin/bash' >> passwd cat > auth.log << 'EOF' Oct 18 08:01:12 srv01 sshd[1201]: Failed password for root from 203.0.113.45 port 51234 ssh2 Oct 18 08:01:15 srv01 sshd[1201]: Failed password for root from 203.0.113.45 port 51234 ssh2 Oct 18 08:01:19 srv01 sshd[1201]: Failed password for root from 203.0.113.45 port 51234 ssh2 Oct 18 08:01:20 srv01 sshd[1203]: Failed password for invalid user admin from 198.51.100.23 port 40022 ssh2 Oct 18 08:01:24 srv01 sshd[1203]: Failed password for invalid user admin from 198.51.100.23 port 40022 ssh2 Oct 18 08:01:31 srv01 sshd[1207]: Failed password for invalid user oracle from 198.51.100.23 port 40030 ssh2 Oct 18 08:01:33 srv01 sshd[1208]: Failed password for invalid user test from 198.51.100.24 port 40031 ssh2 Oct 18 08:01:40 srv01 sshd[1209]: Failed password for operador from 192.0.2.10 port 50098 ssh2 Oct 18 08:02:01 srv01 sshd[1210]: Accepted password for operador from 192.0.2.10 port 50100 ssh2 Oct 18 08:03:44 srv01 sudo: operador : TTY=pts/0 ; PWD=/home/operador ; USER=root ; COMMAND=/usr/bin/apt update Oct 18 08:04:10 srv01 sudo: operador : TTY=pts/0 ; PWD=/home/operador ; USER=root ; COMMAND=/bin/bash Oct 18 08:05:02 srv01 sshd[1250]: Failed password for root from 203.0.113.45 port 51302 ssh2 Oct 18 08:05:09 srv01 sshd[1250]: Failed password for root from 203.0.113.45 port 51302 ssh2 Oct 18 08:07:12 srv01 sshd[1290]: Accepted password for root from 203.0.113.45 port 51400 ssh2 Oct 18 08:07:40 srv01 sudo: operador : TTY=pts/0 ; PWD=/home/operador ; USER=root ; COMMAND=/usr/bin/apt update Oct 18 08:08:02 srv01 useradd[1302]: new user: name=sysupdate, UID=0, GID=0, home=/root, shell=/bin/bash, from=/dev/pts/1 EOF -
Muestre el nombre y el intérprete de cada cuenta de
passwdconcut, y cuente cuántas cuentas hay en total. -
Extraiga con
cutla marca temporal de las tres primeras líneas deauth.log. -
Muestre el PID, el usuario y la orden de los procesos del sistema combinando
ps aux,tr -sycut. Compare el resultado conps -eo pid,user,comm.
5.2. Ejercicio 2. Ordenación, recuento y tuberías robustas
Realice los siguientes pasos:
-
Cuente cuántas cuentas de
passwdusan cada intérprete, de mayor a menor. -
Detecte los UID duplicados de
passwdy muestre los nombres de las cuentas implicadas. -
Ordene estas direcciones primero con
sorty después consort -V, y explique la diferencia:10.0.0.10,10.0.0.9,10.0.0.100. -
Ejecute
grep Failed noexiste.log | wc -l; echo $?y repita la orden trasset -o pipefail. Muestre también el contenido dePIPESTATUS. Desactive la opción al terminar conset +o pipefail.
5.3. Ejercicio 3. Investigación de un ataque de fuerza bruta
Realice los siguientes pasos:
-
Obtenga el número de intentos fallidos por dirección IP, de mayor a menor.
-
Obtenga las cuentas atacadas y su número de intentos. Indique cuáles no existen en
passwd. -
Determine si alguna dirección con intentos fallidos ha conseguido después un acceso correcto. Guarde la lista de direcciones sospechosas en
ips_sospechosas.txtconteesin dejar de verla en pantalla. -
Construya la cronología de todos los eventos de la dirección más sospechosa y muestre todo lo registrado desde su acceso correcto. Identifique la técnica de persistencia empleada por el atacante.
5.4. Ejercicio 4. Línea base de ficheros SetUID
Realice los siguientes pasos:
-
Cree un directorio que simula un árbol de binarios, con dos ficheros SetUID legítimos, y genere la línea base:
mkdir -p bin_simulado for f in passwd sudo ls "mi script"; do printf '#!/bin/sh\n' > "bin_simulado/$f"; done chmod u+s bin_simulado/passwd bin_simulado/sudo find bin_simulado -type f -perm -4000 -print | LC_ALL=C sort > suid_base.txt cat suid_base.txt -
Simule la acción de un atacante: añada un nuevo fichero SetUID y active el bit en
mi script. Detecte los cambios comparando con la línea base mediantecomm. -
Muestre los permisos de los ficheros SetUID detectados con
ls -l, primero confind | xargs ls -ly después confind -print0 | xargs -0 ls -l. Explique qué ocurre conmi scripten el primer caso. -
En su sistema real, genere el inventario de ficheros SetUID agrupados por propietario.
5.5. Ejercicio 5. Limpieza del entorno
-
Elimine el directorio del laboratorio, que incluye los ficheros SetUID simulados.
6. Recursos y referencias
-
The Linux Command Line, de William Shotts: Obra de referencia sobre redirecciones, tuberías y utilidades de texto, de libre descarga.
https://linuxcommand.org/tlcl.php -
GNU Coreutils Manual: Documentación oficial de
cut,sort,uniq,tr,comm,teey el resto de utilidades básicas.
https://www.gnu.org/software/coreutils/manual/ -
POSIX.1-2024, volumen de utilidades: Comportamiento estandarizado de las herramientas de texto.
https://pubs.opengroup.org/onlinepubs/9799919799/idx/utilities.html -
Data Science at the Command Line, de Jeroen Janssens: Técnicas avanzadas de limpieza y agregación de datos en la terminal.
https://jeroenjanssens.com/dsatcl/ -
MITRE ATT&CK T1110, Brute Force, y T1548.001, Setuid and Setgid:
https://attack.mitre.org/techniques/T1110/
https://attack.mitre.org/techniques/T1548/001/
7. Licencia
Licencia CC BY-NC-ND 4.0
Esta página forma parte del curso Bastionado de Redes y Sistemas © 2026 de José Juan Sánchez Hernández y su contenido se distribuye bajo una licencia Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International.
Esta licencia exige que quienes reutilicen el material otorguen el debido crédito al autor. Permite copiar y redistribuir el material en cualquier medio o formato, únicamente en su forma original, y solo para fines no comerciales.