📜 Script Completo htbmachines.sh

Este es el script completo utilizado para realizar búsquedas y obtener información sobre máquinas en Hack The Box. El script incluye varias funcionalidades como buscar máquinas por nombre, IP, dificultad, sistema operativo y habilidades. A continuación, encontrarás todo el código del script:

#!/bin/bash

# Colores
greenColour="\e[0;32m\033[1m"
endColour="\033[0m\e[0m"
redColour="\e[0;31m\033[1m"
blueColour="\e[0;34m\033[1m"
yellowColour="\e[0;33m\033[1m"
purpleColour="\e[0;35m\033[1m"
turquoiseColour="\e[0;36m\033[1m"
grayColour="\e[0;37m\033[1m"

# Variables globales
main_url="https://htbmachines.github.io/bundle.js"

# Ctrl+C
function ctrl_c() {
    echo -e "\n\n${redColour}[!] Saliendo...${endColour}\n"
    tput cnorm
    exit 1
}
trap ctrl_c INT

# Panel de ayuda
function helpPanel() {
    echo -e "\n${yellowColour}[+] Uso:${endColour}"
    echo -e "\t${purpleColour}-m <máquina>${endColour} → Buscar máquina por nombre"
    echo -e "\t${purpleColour}-i <IP>${endColour} → Buscar la máquina por IP "
    echo -e "\t${purpleColour}-y <máquina>${endColour} → Obtener link de la resolución de la máquina  "
    echo -e "\t${purpleColour}-o <sistema_operativo>${endColour} → Buscar máquina por sistema operativo  "
    echo -e "\t${purpleColour}-s <skills>${endColour} → Buscar máquina por skills"
    echo -e "\t${purpleColour}-d <nivel>${endColour} → Filtra por dificultad  "
    echo -e "\t${purpleColour}-u${endColour} → Comprobar y actualizar"
    echo -e "\t${purpleColour}-h${endColour} → Mostrar este panel de ayuda\n"
}

# Búsqueda de máquinas (placeholder)
function searchMachine() {
    machineName="$1"
    echo -e "\n${yellowColour}[+] Listando las propiedades de la máquina ${blueColour}$machineName${endColour}\n" 
    checker_maquina=$(grep "$machineName" bundle.js)
 
    if [ -n "$checker_maquina" ]; then
    	cat bundle.js | awk "/name: \"$machineName\"/,/resuelta:/" |
    	grep -vE "id:|sku|resuelta" |
    	tr -d '"' | tr -d ',' |
    	sed 's/^ *//' |
    	while read line; do
        	key=$(echo "$line" | cut -d':' -f1 | xargs)
        	value=$(echo "$line" | cut -d':' -f2- | xargs)
        	echo -e "${purpleColour}$key:${endColour} ${greenColour}$value${endColour}"
    	done	
    	echo
    else 
        echo -e "\n${redColour}[!] No se encontró ninguna máquina con el nombre ${blueColour}$machineName${endColour}\n"
        return 1
    fi
}
function searchIP() {
    ipAddress="$1"
    machineName="$(cat bundle.js | grep "ip: \"$ipAddress\"" -B 3 | grep "name: " | awk 'NF{print $NF}' | tr -d '"' | tr -d ',')"

    if [ -n "$machineName" ]; then
        echo -e "\n${yellowColour}[+] La IP ${blueColour}$ipAddress${yellowColour} corresponde a la máquina ${blueColour}$machineName${endColour}\n"
        echo -e "${yellowColour}[+] Estas son sus propiedades:${endColour}\n"
        searchMachine "$machineName"
    else
        echo -e "\n${redColour}[!] No se encontró ninguna máquina con la IP ${blueColour}$ipAddress${endColour}\n"
    fi
}

function getYoutubeLink() {
    machineName="$1"
    youtubeLink=$(awk '/name: "'"$machineName"'"/,/resuelta:/' bundle.js | grep -vE "id:|sku|resuelta" | grep youtube | tr -d '"' | tr -d ',' | sed 's/^ *//')

    if [ -n "$youtubeLink" ]; then
        echo -e "\n${yellowColour}📺 [LINK ENCONTRADO]${endColour} 🔍"
        echo -e "${blueColour}Máquina:${endColour} ${purpleColour}$machineName${endColour}"
        echo -e "${greenColour}▶️ YouTube:${endColour} ${blueColour}$youtubeLink${endColour}\n"
    else
        echo -e "\n${redColour}❌ No se encontró un enlace de YouTube para la máquina ${purpleColour}$machineName${endColour}\n"
    fi
}
function filtrar_nivel() {
    nivel="$1"
 results_check=$(cat bundle.js | grep "dificultad: \"$nivel\"" -B 5 | grep name | awk 'NF{print $NF}' | tr -d '"' | tr -d ',')
    if [ -n "$results_check" ]; then
        echo -e "\n${yellowColour}[+]${endColour} ${purpleColour}Estas son las máquinas con dificultad ${greenColour}$nivel${purpleColour}:${endColour}"
        echo "$results_check" | column
    
    else
    	# Obtener los niveles disponibles si la dificultad no existe
    	categoria_niveles=$(cat bundle.js | grep "dificultad: " | awk -F': ' '{print $2}' | sort | uniq | tr -d '"' | tr -d ',')

    	# Mostrar el mensaje de error con niveles disponibles
    	echo -e "\n${redColour}[!]${endColour} ${yellowColour}La dificultad '${purpleColour}$nivel${endColour} ${yellowColour}no existe.${endColour}\n"
    
    	# Usar 'column' para mostrar los niveles en columnas
    	echo -e "\n${yellowColour}[+] Estos son los niveles disponibles:${endColour}\n"
    	echo "$categoria_niveles" | column
    fi

    
}
function searchSo() {

	so="$1"
	os_results=$(cat bundle.js | grep "so: \"$so\"" -B 5 | grep "name: " | awk 'NF{print $NF}' | tr -d '"' | tr -d ',' )

	if [ -n "$os_results" ]; then
		echo -e "\n${yellowColour}[+]${endColour} ${purpleColour}Estas son las máquinas del sistema operativo ${greenColour}$so ${purpleColour}:${endColour}"
        	echo "$os_results" | column
	else
		
        	echo -e "\n${redColour}❌ No se encontró máquinas del sistema operativo $so ${purpleColour} $so ${endColour}\n"
	fi

}
function getOsDifficultyMachines() {
    difficulty="$1"
    os="$2"

    check_results="$(cat bundle.js | grep "so: \"$os\"" -C 4 | grep "dificultad: \"$difficulty\"" -B 5 | grep "name: " | awk 'NF{print $NF}' | tr -d '"' | tr -d ',')"

    if [ -n "$check_results" ]; then
        echo -e "\n${yellowColour}[+]${endColour} ${purpleColour}Máquinas con SO ${greenColour}$os${endColour} ${purpleColour}y dificultad ${greenColour}$difficulty${endColour}${purpleColour}:${endColour}\n"
        echo "$check_results" | column
    else
        echo -e "\n${redColour}❌ No se encontraron máquinas con SO ${purpleColour}$os${endColour} ${redColour}y dificultad ${purpleColour}$difficulty${endColour}\n"

        # Mostrar opciones válidas como sugerencia (opcional)
        echo -e "${yellowColour}[+] Niveles disponibles:${endColour}"
        cat bundle.js | grep "dificultad: " | awk -F': ' '{print $2}' | tr -d '",' | sort -u | column
        echo -e "\n${yellowColour}[+] Sistemas operativos disponibles:${endColour}"
        cat bundle.js | grep "so: " | awk -F': ' '{print $2}' | tr -d '",' | sort -u | column
    fi
}
function searchSkills() {
    skills="$1"
    check_results="$(cat bundle.js | grep -i "skills:.*$skills" -B 6 | grep "name: " | awk 'NF{print $NF}' | tr -d '"' | tr -d ',' )"
    
    if [ -n "$check_results" ]; then
        echo -e "\n${yellowColour}[+]${endColour} ${purpleColour}Estas son las máquinas con la skill ${greenColour}$skills ${purpleColour}:${endColour}"
        echo "$check_results" | column
    else
        # Mostrar mensaje de error más útil
        echo -e "\n${redColour}[!]${endColour} ${yellowColour}No se encontraron máquinas con la skill '${purpleColour}$skills${endColour}${yellowColour}'.${endColour}"
    fi
}

# Actualizar archivos
function updateFiles() {
    tput civis

    if [ ! -f bundle.js ]; then
        echo -e "${yellowColour}[+] Descargando archivo por primera vez...${endColour}"
        curl -s $main_url > bundle.js
        js-beautify bundle.js | sponge bundle.js
        echo -e "${greenColour}[✓] Archivo descargado correctamente.${endColour}\n"
    else
        echo -e "${yellowColour}[+] Verificando actualizaciones...${endColour}"
        curl -s $main_url > bundle_tmp.js
        js-beautify bundle_tmp.js | sponge bundle_tmp.js

        md5_original_value=$(md5sum bundle.js | awk '{print $1}')
        md5_tmp_value=$(md5sum bundle_tmp.js | awk '{print $1}')

        if [ "$md5_tmp_value" == "$md5_original_value" ]; then
            echo -e "${blueColour}[=] No hay actualizaciones disponibles.${endColour}"
            rm bundle_tmp.js
        else
            echo -e "${greenColour}[↑] Se han encontrado actualizaciones.${endColour}"
            rm bundle.js && mv bundle_tmp.js bundle.js
            echo -e "${greenColour}[✓] Actualizada correctamente.${endColour}"
        fi
    fi

    tput cnorm
}

# Indicadores y lógica principal
declare -i parameter_counter=0
# Chivatos
declare -i chivato_difficulty=0
declare -i chivato_os=0
while getopts "m:i:y:d:o:s:hu" arg; do
    case $arg in
        m) machineName=$OPTARG; let parameter_counter+=1;;
        u) let parameter_counter+=2;;
        i) ipAddress=$OPTARG; let parameter_counter+=3;;
        y) machineName=$OPTARG; let parameter_counter+=4;;
	d) nivel=$OPTARG; chivato_difficulty=1; let parameter_counter+=5;;
	o) so=$OPTARG;  chivato_os=1; let parameter_counter+=6;;
	s) skills=$OPTARG; let parameter_counter+=7;;

        h) ;;
    esac
done

if [ $parameter_counter -eq 1 ]; then
    searchMachine "$machineName"
elif [ $parameter_counter -eq 2 ]; then
    updateFiles
elif [ $parameter_counter -eq 3 ]; then
	searchIP "$ipAddress"
elif [ $parameter_counter -eq 4 ]; then
	 getYoutubeLink "$machineName"
elif [ $parameter_counter -eq 5 ]; then
	filtrar_nivel $nivel
elif [ $parameter_counter -eq 6 ]; then
	searchSo $so
elif [ $chivato_difficulty -eq 1 ] && [ $chivato_os -eq 1 ] ; then
	getOsDifficultyMachines $nivel $so
elif [ $parameter_counter -eq 7 ]; then
	searchSkills  "$skills"

else
    helpPanel
fi

Para obtener más detalles sobre cómo utilizar el script, consulta los ejemplos de uso en 💡 Ejemplo de uso. Si deseas conocer los parámetros y cómo personalizar su funcionamiento, puedes revisar la sección de 🛠️ Parámetros del script. Además, si te interesa entender cómo funcionan las distintas funciones del script, puedes consultar la 🧩 Explicación de las funciones del script.