
Quién está en nuestra WIFI
Python
Publicado el 29 de Septiembre del 2024 por Hilario (144 códigos)
419 visualizaciones desde el 29 de Septiembre del 2024

----------------------------------------------------------------------------------------------------------
En este ejemplo, vamos a realizar una propuesta de estudio para el Aula 18, sobre desarrollo de programación, para crear un programa en Python que determine, qué usuarios o dispositivos están conectados a tu red Wi-Fi, en un sistema operativo Linux (como Ubuntu), podemos usar una combinación de herramientas de red disponibles en Linux, como arp-scan o nmap.
Aquí te dejo un ejemplo básico que utiliza arp-scan, una herramienta que escanea la red en busca de dispositivos conectados.
********************************************************************
En este ejemplo iremos describiendo paso a paso, el proceso de creación de
nuestro programa.
-------------------------------------------------------------------------
Pasos para instalar y usar el script:
Instalar arp-scan: Primero, debes instalar la herramienta arp-scan si no la tienes en tu sistema. Abre una terminal y ejecuta:
sudo apt-get install arp-scan
Crear el programa en Python:
Crea un archivo Python con el siguiente código, por ejemplo, llámalo Ejercicio_Aula_Sep_29.py:
Nota:
Necesitas tener privilegios de root para usar arp-scan, de ahí que el script deba ejecutarse con sudo.
Este es un método sencillo para obtener información de los dispositivos conectados a la misma red Wi-Fi.
Para incluir el nombre de la interfaz de red del terminal (como wlan0, eth0, etc.), podemos hacer que el programa detecte automáticamente la interfaz de red que está en uso para conectarse a la red Wi-Fi. Esto es necesario ya que arp-scan puede requerir que especifiques la interfaz de red correcta en lugar de asumirlo por defecto.
También podemos usar el comando ip link para listar las interfaces de red y determinar cuál está activa.
Otra cosa que podemos hacer es modificar el programa para que, cuando sea necesario ejecutar sudo, no tengas que invocar el script desde la línea de comandos con sudo. En su lugar, el propio programa pedirá la contraseña de superusuario automáticamente si no se está ejecutando con privilegios de administrador.
Python tiene una librería llamada os que permite verificar si el programa se está ejecutando como root. Si no es así, podemos utilizar sudo para ejecutar el propio script.
Verifica si el script está siendo ejecutado con permisos de superusuario usando os.geteuid().
Si no se está ejecutando con permisos de root (es decir, si el identificador de usuario efectivo no es 0), el programa se reiniciará automáticamente con sudo.
Usa subprocess.run(['sudo', 'python3'] + sys.argv) para reejecutar el script actual con sudo. Esto mantiene cualquier argumento que hayas pasado al script.
Lógica del programa:
El script primero comprueba si tiene privilegios de superusuario usando check_sudo().
Si no es así, se reinicia automáticamente con sudo para obtener los permisos necesarios y ejecutar el comando arp-scan correctamente.
Después de obtener los permisos adecuados, continúa con el flujo normal: obtener la interfaz de red y ejecutar el escaneo de dispositivos.
Ejecución del script:
Ahora puedes ejecutar el script sin tener que usar sudo manualmente:
Este enfoque es útil cuando quieres asegurarte de que el script siempre tenga privilegios adecuados para ejecutar comandos que requieren permisos elevados, como arp-scan.
Se utiliza getpass.getpass() para solicitar la contraseña de sudo al usuario de forma segura (sin que la contraseña se muestre en la pantalla).
Opción -S de sudo:
Se ha añadido la opción -S al comando sudo en subprocess.run(). Esto permite que sudo acepte la contraseña desde la entrada estándar (stdin) en lugar de solicitarla directamente a través de la terminal.
Enviar la contraseña a stdin:
La contraseña introducida por el usuario se pasa a través del parámetro input de subprocess.run(), que envía la contraseña directamente al comando sudo.
Flujo del programa:
Si el script detecta que no tiene permisos de superusuario, solicitará la contraseña y reejecutará el script automáticamente con sudo, utilizando la contraseña ingresada por el usuario.
Ejecución del script:
Puedes ejecutar el script sin sudo como antes, y se pedirá la contraseña si es necesario:
Cuando se soliciten permisos de superusuario, el script pedirá la contraseña en la terminal. Si la contraseña es correcta, se volverá a ejecutar el script con los permisos adecuados.
Nota:
Este enfoque es útil para evitar tener que ejecutar el script directamente con sudo, y también para mejorar la seguridad al no dejar la contraseña visible.
Una solución simple es asegurarse de que el script se está ejecutando directamente desde una terminal interactiva real. Pero si deseas que la entrada de la contraseña funcione correctamente en cualquier contexto, puedes usar una combinación de herramientas para evitar este error. Una opción es hacer que el propio comando sudo solicite la contraseña en lugar de gestionarla mediante getpass.
Ya no solicitamos manualmente la contraseña usando getpass. En lugar de eso, simplemente dejamos que sudo maneje la solicitud de la contraseña en la terminal.
Ejecutar con sudo:
Si el script no se está ejecutando como superusuario, se reiniciará automáticamente con sudo (sudo python3 script.py), y sudo pedirá la contraseña al usuario de manera normal. Esto evita problemas relacionados con la entrada de contraseña a través de getpass en ciertos entornos.
Flujo del programa:
El script verifica si tiene permisos de superusuario y, si no es así, se reinicia con sudo, permitiendo que sudo maneje la interacción con el usuario para la contraseña.
Ejecución del script:
Puedes ejecutar el script como de costumbre, sin sudo, y el programa pedirá la contraseña automáticamente cuando sea necesario:
Puesdes poner en el bash de tu consola
Copiar código
python3 Ejercicio_Aula_Sep_29.py
Si no tienes permisos de superusuario, sudo te pedirá la contraseña de forma normal, como lo haría en cualquier comando de terminal.
Nota:
Este enfoque garantiza que la entrada de la contraseña sea gestionada directamente por sudo, lo que evitará problemas con el manejo de la contraseña en diferentes entornos.
Cuando ejecutas el comando con sudo, el sistema te pedirá la contraseña de superusuario antes de ejecutar el script. Dado que ya estás ejecutando el script con permisos elevados, no necesitarás incluir la lógica para reiniciar el script con sudo dentro del código.
Simplificación del código si usas sudo directamente
Si prefieres siempre ejecutar el script directamente con sudo, puedes simplificar el código y eliminar la verificación de superusuario. Aquí te dejo una versión simplificada del programa, ya que no necesitas verificar si el script tiene permisos de root (esto será garantizado por el uso de sudo en la terminal):
bash
Copiar código
sudo python3 Ejercicio_Aula_Sep_29.py
Este enfoque es más sencillo si ya estás acostumbrado a ejecutar comandos que requieren permisos de superusuario.
Nota:
Importante comprobar otra vez: Asegúrate de que tienes instalada la herramienta arp-scan en tu sistema, ya que es esencial para este programa. Puedes instalarla ejecutando:
bash
Copiar código
sudo apt-get install arp-scan
Ahora que ejecutas el script con sudo desde el principio, no tendrás problemas relacionados con permisos.
En caso de problemas.
Es extraño que al ejecutar el script con sudo no obtengas ningún resultado, ya que el uso de sudo debería garantizar que arp-scan tenga los permisos necesarios para funcionar correctamente. Sin embargo, podrían estar ocurriendo algunos problemas que podemos revisar:
Posibles causas:
arp-scan no está instalado: Asegúrate de que la herramienta arp-scan está instalada. Si no lo está, puedes instalarla con:
bash
Copiar código
sudo apt-get install arp-scan
Interfaz de red incorrecta: Puede que la interfaz que el script detecta no sea la correcta (por ejemplo, si estás conectado a través de Wi-Fi pero detecta una interfaz Ethernet). Verifica que la interfaz detectada sea la que está en uso.
Para confirmar qué interfaz de red estás usando, también puedes ejecutar manualmente:
bash
Copiar código
ip link
Asegúrate de que la interfaz que está en "estado UP" (activa) es la que quieres escanear. Si no es la correcta, podemos modificar el código para especificar manualmente la interfaz.
bash
Copiar código
sudo arp-scan -I INTERFAZ -l
Reemplaza INTERFAZ por el nombre de tu interfaz de red activa (por ejemplo, wlp3s0 si es Wi-Fi).
Permisos de sudo en el script: A veces, sudo puede no pasar bien la contraseña o no funcionar adecuadamente dentro de un script. Si este es el caso, prueba ejecutando todo manualmente para asegurarte de que el problema no esté en la interacción con sudo.
Ajustes al script:
Vamos a ajustar el script para que imprima más información de depuración, lo que nos ayudará a identificar el problema exacto.
Ejecuta este código modificado para que imprima más detalles de depuración, como la salida del comando ip link. Esto nos permitirá verificar qué interfaz está detectando.
Si el script detecta la interfaz incorrecta o ninguna interfaz, revisa el comando ip link para asegurarte de que tienes la interfaz correcta en estado "UP".
Prueba arp-scan manualmente en la terminal con la interfaz correcta:
bash
Copiar código
sudo arp-scan -I INTERFAZ -l
Si arp-scan manualmente funciona bien, pero el script no, entonces es posible que haya un problema en cómo el script maneja los comandos.
Análisis adicional, con estas preguntas puedes solucionar los errores, haceroslas en el Aula, siempre se aprende:
¿El script detecta correctamente tu interfaz de red?
¿La salida de arp-scan manual te muestra resultados?
Estos pasos nos ayudarán a depurar el problema.onales.
A continuacion os pongo una salida típica del comando hecha en la consola de mi portatil, hacerlo en el Aula:
sudo arp-scan -I wlo1 -l
Interface: wlo1, type: EN10MB, MAC: 1c:4d:70:0e:0e:fc, IPv4: 192.168.0.18
Starting arp-scan 1.9.7 with 256 hosts (https://github.com/royhills/arp-scan)
192.168.0.1 3c:98:72:2e:4f:f2 Sercomm Corporation.
192.168.0.19 64:66:24:aa:34:b6 Sagemcom Broadband SAS
192.168.0.13 7e:cb:c5:38:37:f0 (Unknown: locally administered)
Dado que el comando arp-scan funciona perfectamente cuando lo ejecutas manualmente en la terminal pero no dentro del programa Python, es probable que el problema esté relacionado con cómo el script maneja la salida de arp-scan. Puede haber varios factores que están afectando la forma en que el programa ejecuta arp-scan o captura su salida.
Al eliminar la captura de salida para que puedas ver directamente los resultados en la terminal en lugar de capturarlos en el script.
Usa subprocess.Popen en lugar de subprocess.run para tener un control más fino sobre cómo se maneja la salida.
Cambios realizados:
subprocess.Popen:
Usamos subprocess.Popen en lugar de subprocess.run para ejecutar arp-scan y leer la salida en tiempo real. Esto nos da más control sobre cómo se captura y procesa la salida.
Impresión en tiempo real:
Ahora el programa imprime la salida directamente en la terminal mientras se ejecuta arp-scan, tal como sucede cuando ejecutas el comando manualmente. Esto debería darte los mismos resultados que ves cuando lo ejecutas en la terminal.
Ejecución:
Guarda este nuevo código en tu archivo Ejercicio_Aula_Sep_29.py
Ejecuta el programa con sudo:
bash
Copiar código
sudo python3 Ejercicio_Aula_Sep_29.py
Qué esperar:
Ahora, deberías ver la salida de arp-scan directamente en la terminal, tal como sucede cuando lo ejecutas manualmente. Esto debería ayudarte a identificar si hay algún problema con la captura de la salida o la ejecución dentro del programa Python.
También podemos modificar el código para que sudo lea la contraseña desde la entrada estándar (-S), lo que permitirá que el programa te pida la contraseña y la pase correctamente a sudo.
Opción sudo -S:
Ahora el comando sudo usa la opción -S, que permite que la contraseña sea leída desde la entrada estándar (stdin).
Manejo de la contraseña:
Utilizamos la función getpass.getpass() para solicitar la contraseña del usuario de forma segura sin que se muestre en pantalla.
La contraseña se pasa al proceso sudo a través de process.communicate().
Pasos para ejecutar:
Guarda el script Ejercicio_Aula_Sep_29.py
Ejecuta el script sin sudo porque el propio script manejará la contraseña:
bash
Copiar código
python3 Ejercicio_Aula_Sep_29.py
¿Qué esperar?
El programa te pedirá que ingreses tu contraseña de sudo.
Una vez ingresada la contraseña, el comando arp-scan debería ejecutarse correctamente y mostrar los dispositivos conectados a la red.
Ahora podemos probar estos, queridos alunmnos para mirar si funcionan las modificaciones.
----------------------------------------------------------------------
----------------------------------------------------------------------
VAMOS A COLOCAR AQUI EL CODIGO FINAL, DESPUES DE TODAS LAS MODIFICACIONES REALIZADAS-
******************************************************************
import subprocess
import re
import getpass
def get_network_interface():
try:
# Ejecutar 'ip link' para obtener las interfaces de red
print("Ejecutando 'ip link' para obtener la interfaz de red...")
result = subprocess.run(['ip', 'link'], capture_output=True, text=True)
if result.returncode != 0:
print("Error al ejecutar ip link:", result.stderr)
return None
# Imprimir la salida completa para depuración
print("Salida completa de 'ip link':")
print(result.stdout)
# Usar una expresión regular para encontrar interfaces que estén activas (estado UP)
interfaces = re.findall(r'\d+: (\w+):.*state UP', result.stdout)
if interfaces:
# Retornar la primera interfaz que esté en estado UP
return interfaces[0]
else:
print("No se encontraron interfaces de red activas.")
return None
except Exception as e:
print(f"Error al obtener la interfaz de red: {e}")
return None
def scan_network(interface):
try:
# Pedir la contraseña del superusuario
password = getpass.getpass("Introduce la contraseña de sudo: ")
# Ejecutar el comando 'arp-scan' especificando la interfaz con sudo -S
print(f"Ejecutando 'arp-scan' en la interfaz {interface}...")
# Usar subprocess.Popen para pasar la contraseña al comando sudo
process = subprocess.Popen(['sudo', '-S', 'arp-scan', '-I', interface, '-l'],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
text=True)
# Pasar la contraseña al proceso
stdout, stderr = process.communicate(input=password + '\n')
# Imprimir la salida del escaneo
if process.returncode == 0:
print("Dispositivos conectados a la red:")
print(stdout)
else:
print(f"Error al ejecutar arp-scan: {stderr}")
except Exception as e:
print(f"Hubo un error al escanear la red: {e}")
if __name__ == "__main__":
print("Obteniendo la interfaz de red activa...")
interface = get_network_interface()
if interface:
print(f"Interfaz de red activa: {interface}")
print("Escaneando dispositivos conectados a la red Wi-Fi...")
scan_network(interface)
else:
print("No se encontró ninguna interfaz de red activa. Verifica tu conexión.")
********************************************************************
GRACIAS, NOS VEREMOS EN EL AULA.
102 visualizaciones durante los últimos 90 días