feat: add bash cybersecurity audit and hardening functions
12 funciones Bash del dominio cybersecurity: auditoria de red y servicios (analyze_dns, audit_http_headers, inspect_ssl_cert, list_active_connections, enumerate_subdomains, geolocate_ip), auditoria de sistema (audit_ssh_config, check_firewall, detect_suspicious_users), y utilidades crypto (encrypt_file, generate_password, verify_file_hash). Dominio nuevo en bash/functions/.
This commit is contained in:
@@ -0,0 +1,162 @@
|
||||
#!/usr/bin/env bash
|
||||
# detect_suspicious_users
|
||||
# -----------------------
|
||||
# Revisa el sistema en busca de usuarios potencialmente sospechosos:
|
||||
# UIDs 0 extras, shells válidas, homes en rutas inusuales, grupos privilegiados
|
||||
# y sesiones activas.
|
||||
#
|
||||
# USO (directo):
|
||||
# detect_suspicious_users
|
||||
#
|
||||
# Depende de: /etc/passwd, getent, w, lastlog
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
source "$SCRIPT_DIR/../shell/bash_colors.sh"
|
||||
source "$SCRIPT_DIR/../shell/bash_log.sh"
|
||||
bash_colors
|
||||
bash_log_init
|
||||
|
||||
# ─── Constantes ───────────────────────────────────────────────────────────────
|
||||
|
||||
_SUSPICIOUS_VALID_SHELLS=("/bin/bash" "/bin/sh" "/bin/zsh" "/bin/fish" "/usr/bin/bash" "/usr/bin/zsh" "/usr/bin/fish")
|
||||
_SUSPICIOUS_PRIVILEGED_GROUPS=("sudo" "wheel" "docker" "adm" "lxd" "libvirt" "kvm" "disk" "shadow")
|
||||
_SUSPICIOUS_SYSTEM_USERS_MAX_UID=999
|
||||
|
||||
# ─── Funciones puras ──────────────────────────────────────────────────────────
|
||||
|
||||
_sus_is_valid_shell() {
|
||||
local shell="$1"
|
||||
for s in "${_SUSPICIOUS_VALID_SHELLS[@]}"; do
|
||||
[[ "$shell" == "$s" ]] && return 0
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
_sus_is_system_user() {
|
||||
local uid="$1"
|
||||
[[ "$uid" -le $_SUSPICIOUS_SYSTEM_USERS_MAX_UID ]]
|
||||
}
|
||||
|
||||
_sus_is_unusual_home() {
|
||||
local home="$1"
|
||||
[[ ! "$home" =~ ^(/home|/root|/var|/srv|/nonexistent|/tmp) ]]
|
||||
}
|
||||
|
||||
# ─── Funciones de efecto ──────────────────────────────────────────────────────
|
||||
|
||||
_sus_show_uid0_users() {
|
||||
echo -e "${PURPLE}════════ Usuarios con UID 0 (root) ═════════════${NC}"
|
||||
echo ""
|
||||
|
||||
local found=0
|
||||
while IFS=: read -r username _ uid _; do
|
||||
if [[ "$uid" -eq 0 ]]; then
|
||||
if [[ "$username" == "root" ]]; then
|
||||
echo -e " ${GREEN}[ok]${NC} root (esperado)"
|
||||
else
|
||||
echo -e " ${RED}[x]${NC} ${username} tiene UID 0 -- SOSPECHOSO"
|
||||
fi
|
||||
found=$((found + 1))
|
||||
fi
|
||||
done < /etc/passwd
|
||||
|
||||
if [[ $found -eq 1 ]]; then
|
||||
echo ""
|
||||
success "Solo root tiene UID 0"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
}
|
||||
|
||||
_sus_show_users_with_shell() {
|
||||
echo -e "${PURPLE}════════ Usuarios con shell de login válida ═════${NC}"
|
||||
echo ""
|
||||
echo -e " ${GRAY}(excluye usuarios de sistema con UID <= ${_SUSPICIOUS_SYSTEM_USERS_MAX_UID})${NC}"
|
||||
echo ""
|
||||
|
||||
local found=0
|
||||
while IFS=: read -r username _ uid _ _ home shell; do
|
||||
if ! _sus_is_system_user "$uid" && _sus_is_valid_shell "$shell"; then
|
||||
echo -e " ${CYAN}*${NC} ${username} (UID ${uid}) -- shell: ${shell} -- home: ${home}"
|
||||
found=$((found + 1))
|
||||
fi
|
||||
done < /etc/passwd
|
||||
|
||||
[[ $found -eq 0 ]] && info "No se encontraron usuarios normales con shell válida"
|
||||
echo ""
|
||||
}
|
||||
|
||||
_sus_show_unusual_homes() {
|
||||
echo -e "${PURPLE}════════ Usuarios con home inusual ══════════════${NC}"
|
||||
echo ""
|
||||
|
||||
local found=0
|
||||
while IFS=: read -r username _ uid _ _ home shell; do
|
||||
if _sus_is_valid_shell "$shell" && _sus_is_unusual_home "$home"; then
|
||||
echo -e " ${YELLOW}[!]${NC} ${username} -- home: ${home}"
|
||||
found=$((found + 1))
|
||||
fi
|
||||
done < /etc/passwd
|
||||
|
||||
[[ $found -eq 0 ]] && success "No se detectaron homes en rutas inusuales"
|
||||
echo ""
|
||||
}
|
||||
|
||||
_sus_show_privileged_groups() {
|
||||
echo -e "${PURPLE}════════ Grupos privilegiados y sus miembros ════${NC}"
|
||||
echo ""
|
||||
|
||||
for group in "${_SUSPICIOUS_PRIVILEGED_GROUPS[@]}"; do
|
||||
local members
|
||||
members="$(getent group "$group" 2>/dev/null | cut -d: -f4 || true)"
|
||||
if [[ -n "$members" ]]; then
|
||||
echo -e " ${YELLOW}*${NC} ${group}: ${members}"
|
||||
fi
|
||||
done
|
||||
|
||||
echo ""
|
||||
}
|
||||
|
||||
_sus_show_active_sessions() {
|
||||
echo -e "${PURPLE}════════ Sesiones activas ═══════════════════════${NC}"
|
||||
echo ""
|
||||
|
||||
w 2>/dev/null | while IFS= read -r line; do
|
||||
echo -e " ${DIM_GRAY}${line}${NC}"
|
||||
done
|
||||
|
||||
echo ""
|
||||
}
|
||||
|
||||
_sus_show_last_logins() {
|
||||
echo -e "${PURPLE}════════ Últimos logins por usuario ═════════════${NC}"
|
||||
echo ""
|
||||
|
||||
if command -v lastlog &>/dev/null; then
|
||||
lastlog 2>/dev/null | awk 'NR==1 || $NF != "logged" {
|
||||
if (NR==1 || $2 != "**Never") printf " %-16s %-10s %s\n", $1, $2, $NF
|
||||
}' | grep -v "^$" | while IFS= read -r line; do
|
||||
echo -e " ${DIM_GRAY}${line}${NC}"
|
||||
done
|
||||
else
|
||||
warning "lastlog no disponible"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
}
|
||||
|
||||
# ─── Punto de entrada ─────────────────────────────────────────────────────────
|
||||
|
||||
detect_suspicious_users() {
|
||||
_sus_show_uid0_users
|
||||
_sus_show_users_with_shell
|
||||
_sus_show_unusual_homes
|
||||
_sus_show_privileged_groups
|
||||
_sus_show_last_logins
|
||||
_sus_show_active_sessions
|
||||
}
|
||||
|
||||
# Ejecutar si se llama directamente
|
||||
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
|
||||
detect_suspicious_users "$@"
|
||||
fi
|
||||
Reference in New Issue
Block a user