Monitor your network using Telegram
This script uses Telegram to notify you about the devices connected to your network. When you run the script, it starts a Telegram bot that you can interact with. The bot allows you to start the network scan and get a list of all currently connected devices on your network. You can receive notifications about new devices connected or disconnected on your network through Telegram, that way you can keep track of all the devices that are connected to your network wherever you are. The script makes it easy to monitor your network, you can receive notifications on your phone or computer and take actions if needed.
Create your config file
In the folder of the project you need to create the conf.json
file that will contain some imporatant informations used in the script.
{
"TOKEN": YOUR_TELEGRAM_TOKEN, //str
"CHAT_ID": YOUR_USER_CHAT_ID, //str
"NETWORK": NETWORK_TO_MONITOR, //str: "192.168.1.0/24"
"INTERVAL": SCAN_NETWORK_INTERVAL //int: 60
}
Download and install Npcap
To be able to scan the network, the scapy library needs a dependency to be installed called Npcap
Installing Npcap on Linux:
- Download the Npcap package for Linux from the Npcap website.
- Open a terminal and navigate to the directory where the Npcap package is located.
- Use the command sudo dpkg -i npcap-version.deb to install the package, replacing “version” with the version number of the package you downloaded.
- Use the command sudo apt-get install -f to install any missing dependencies.
- Once the installation is complete, use the command sudo ldconfig to update the library cache.
Installing Npcap on Windows:
- Download the Npcap installer for Windows from the Npcap website.
- Run the installer, and click on “Next” to begin the installation process.
- Select the “Npcap” and “WinPcap compatibility” options.
- Read and accept the license agreement.
- Choose the installation location, and click on “Next” to continue.
- Click on “Install” to begin the installation process.
- Once the installation is complete, click on “Finish” to close the installer.
Getting your API key and your chat ID
Creating a Telegram bot using BotFather is a simple process. Here are the steps to create a Telegram bot using BotFather:
- Open Telegram and search for @BotFather.
- Start a chat with BotFather by clicking on the search result.
- Send the command ‘/newbot’ to BotFather to create a new bot.
- BotFather will ask you to choose a name for your bot. Pick a name that you like and send it to BotFather.
- BotFather will then ask you to choose a username for your bot. The username must end in “bot” (e.g., mynewbot) and should be unique.
- Once you have chosen a username, BotFather will give you a token. This token is used to authenticate your bot with the Telegram servers. Keep this token safe, as you will need it later.
In order to get your Telegram chat ID, you will need to do the following:
- Start a chat with the bot @RawDataBot.
- Send the command /start to the bot.
- The bot should respond with your Telegram informations. Grab the chat ID that you need.
Send the command /start to the bot.
Script overview
This Python script utilizes the Scapy library to scan a network for connected devices and the Telegram bot API to send notifications when a new device is connected or disconnected. The script also uses the macvendors.com API and a local file to determine the vendor of a device based on its MAC address.
The script begins by defining several functions:
- The
get_mac_vendor
function takes in a MAC address as a string and returns the vendor of that address. If the vendor cannot be determined, the function returns ‘Unknown’. - The
start_command
function scans the network and sends a message to the Telegram bot when a new device is connected or disconnected. - The
showall_command
function sends a message to the Telegram bot with the connected devices. - The
error
function prints the update and error message if an error occurs in the Telegram bot. - The
start_bot
function starts the Telegram bot and sets up the command handlers.
Let’s code
from scapy.all import *
from telegram.ext import *
import json
import time
import requests
def get_mac_vendor(mac):
"""
This function takes in a MAC address as a string and returns the vendor of that address.
If the vendor cannot be determined, the function returns 'Unknown'.
:param mac: the mac address in question
:return: the vendor name or 'Unknown' if not found
"""
url = "https://api.macvendors.com/" + mac
r = requests.get(url)
# Check if the API call is successful (status code 200)
if r.status_code == 200:
return r.text
# format the mac address
mac = mac.upper().replace(':', '')[0:6]
try:
# open the local file to search for the mac address
with open("mac-vendor.txt", "r", encoding='utf-8') as f:
for line in f:
if mac in line:
# return the vendor name after the mac address in the file
return line[7:]
except FileNotFoundError:
exit("Error: mac-vendor.txt file not found.")
# if mac address is not found in the file or file not found
return 'Unknown'
The get_mac_vendor
function is a key component of the script, as it is used to determine the vendor of a device based on its MAC address. The function takes in a MAC address as a string and returns the vendor of that address.
The function first makes an API call to macvendors.com using the requests
library, passing in the MAC address in question as a parameter. The API call returns the vendor name as a string, and the function returns this string if the API call is successful (status code 200).
If the API call is not successful, the function then formats the MAC address by converting it to uppercase and removing the colons. The function then opens a local file called mac-vendor.txt
and searches for the MAC address in question. If the MAC address is found in the file, the function returns the vendor name that appears after the MAC address in the file.
If the MAC address is not found in the file or the file is not found, the function returns ‘Unknown’. This indicates that the vendor of the device could not be determined.
The get_mac_vendor
function is a crucial component of the script as it helps identify the different devices connected to the network, it allows to know who the device belongs to and can be useful in identifying unknown devices on the network.
def start_command(update, context):
"""
This function scans the network and sends a message to the Telegram bot when a new device is connected or disconnected.
:param update: update object for the Telegram bot
:param context: context object for the Telegram bot
"""
connected_hosts = {}
old_hosts = []
while True:
# scan the network
ans, _ = arping(NETWORK, verbose=0)
hosts = [host[1].src for host in ans]
# check for new or updated devices
for host in ans:
mac_address = host[1].src
mac_vendor = get_mac_vendor(mac_address).strip()
ip_address = host[1].psrc
if mac_address not in connected_hosts:
msg = "New device connected: {} ({} - {})".format(
mac_vendor, ip_address, mac_address)
context.bot.send_message(chat_id=CHAT_ID, text=msg)
connected_hosts[mac_address] = (mac_vendor, ip_address)
# check for disconnected devices
for mac_address in old_hosts:
if mac_address not in hosts:
mac_vendor, ip_address = connected_hosts[mac_address]
msg = "Device disconnected: {} ({} - {})".format(
mac_vendor, ip_address, mac_address)
context.bot.send_message(chat_id=CHAT_ID, text=msg)
del connected_hosts[mac_address]
old_hosts = hosts
time.sleep(INTERVAL)
The start_command
function is responsible for periodically scanning the network and sending notifications to a Telegram bot when a new device is connected or disconnected. This function is executed when the start
command is sent to the Telegram bot.
The function starts by initializing two dictionaries, connected_hosts
and old_hosts
, and enters an infinite loop.
In each iteration of the loop, the function uses the Scapy library’s arping
function to scan the network specified by the constant NETWORK
and store the hosts in a list. It then compares the list of current hosts to the old_hosts
list, which contains the previously connected hosts.
For each new or updated host in the current list, the function retrieves the vendor information by calling the get_mac_vendor
function, passing in the host’s MAC address as a parameter. The function then sends a message to the Telegram bot with the following format: “New device connected: [vendor name] ([IP address] - [MAC address])”.
For each host in the old_hosts
list that is no longer in the current list, the function sends a message to the Telegram bot with the following format: “Device disconnected: [vendor name] ([IP address] - [MAC address])”.
After sending the notifications, the function updates the old_hosts
list with the current list of hosts and waits for INTERVAL
seconds before beginning the next iteration of the loop.
This function is the core of the script, it scans the network periodically and sends notifications to Telegram about the new and disconnected devices. The function also uses the get_mac_vendor function to identify the vendors of the devices. This allows the user to know which devices are connected to the network and who they belong to.
def showall_command(update, context):
"""
This function sends a message to the Telegram bot with the connected devices.
:param update: update object for the Telegram bot
:param context: context object for the Telegram bot
"""
msg = ""
ans, _ = arping(NETWORK, verbose=0)
# check for new or updated devices
for host in ans:
mac_address = host[1].src
mac_vendor = get_mac_vendor(mac_address).strip()
ip_address = host[1].psrc
msg += "[+] {} ({} - {})\n".format(mac_vendor, ip_address, mac_address)
context.bot.send_message(chat_id=CHAT_ID, text=msg)
The showall_command
function is responsible for sending a message to the Telegram bot containing a list of all currently connected devices on the network. This function is executed when the showall
command is sent to the Telegram bot.
This function is useful for getting an overview of all the devices that are currently connected to the network. It allows the user to check which devices are connected to the network and who they belong to, even if no new device was connected or disconnected. This function can be useful in identifying unknown devices on the network and keeping track of all the devices that are connected to the network.
def error(update, context):
"""
This function prints the update and error message if an error occurs in the Telegram bot.
:param update: update object for the Telegram bot
:param context: context object for the Telegram bot
"""
print(f"Update {update} caused error {context.error}")
The error
function is a simple error-handling function that is called when an error occurs while using the Telegram bot. The function takes in two arguments: update
and context
.
It is important to have an error function in the script because when working with Telegram API or any other API errors can occur, it can be caused by different reasons, for example, the bot token is incorrect or the bot is blocked by the user. By having an error function the developer can catch the errors and take appropriate actions to fix them. It is a best practice to include an error function in any script that utilizes an API to ensure that errors are handled gracefully.
def start_bot():
"""
This function starts the Telegram bot and sets up the command handlers.
"""
updater = Updater(
TOKEN, use_context=True)
dp = updater.dispatcher
dp.add_handler(CommandHandler("start", start_command, run_async=True))
dp.add_handler(CommandHandler("showall", showall_command))
dp.add_error_handler(error)
updater.start_polling()
print("[+] BOT has started")
with open('conf.json') as f:
conf = json.load(f)
TOKEN = conf["TOKEN"]
CHAT_ID = conf["CHAT_ID"]
NETWORK = conf["NETWORK"]
INTERVAL = conf["INTERVAL"]
start_bot()
The start_bot
function is used to initialize and set up the Telegram bot. It is the last function called in the script, and it starts the bot and sets up the command handlers.
The function starts by initializing the Telegram bot using the Updater
class from the telegram.ext
library. The Updater
class takes in a bot token, which is a unique identifier that is used to authenticate the bot with the Telegram servers.
Once the bot is initialized, the function sets up the command handlers for the start
and showall
commands using the dispatcher
object from the Updater
class. The start
command is handled by the start_command
function, and the showall
command is handled by the showall_command
function. This means that when the start
command is sent to the bot, the start_command
function is executed, and when the showall
command is sent to the bot, the showall_command
function is executed.
The function also registers the error
function as a handler for any errors that may occur while using the Telegram bot. This allows the script to catch and handle any errors gracefully.
Finally, the function starts the bot by calling the start_polling()
method on the Updater
class. This starts a background thread that listens for incoming updates from Telegram and sends them to the appropriate command handlers.
Overall, the start_bot
function is responsible for initializing and setting up the Telegram bot, and it allows the script to receive commands from Telegram and execute the appropriate functions. This function is crucial for the script as it enables the Telegram bot to receive commands and execute the network scan and notifications.
You can find the entire code on github here.
HAPPY HACKING.