This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
# -*- coding: utf-8; -*- | |
# Author: Santiago Saavedra <ssaavedra@gpul.org> | |
# License: MIT | |
# Description: | |
# This script detects raspberries and sorts them by last-seen time. | |
# It also tries to inspect whether they still have their default | |
# password set. | |
# We found it specially interesting in IoT Hackathons and the like | |
# for participants to easily spot theirs (and actively remember | |
# them to change their passwords). | |
from datetime import datetime | |
import os, pty, re, subprocess | |
from time import sleep | |
import urllib2 as request | |
import pxssh | |
raspis = [] | |
dhcp_re = re.compile("^.*DHCPACK on ([0-9.]+) to ([a-f0-9:]+).*$") | |
raspi_manufacturer = 'b8:27:eb' | |
def hardware_matches(machine): | |
return machine[:len(raspi_manufacturer)].lower() == raspi_manufacturer.lower() | |
def detect_raspis_dhcp(): | |
## Modify this URL to point to a DHCP log so that we don't need to poke arp. | |
url = "http://hackatoniot/dhcp.txt" | |
f = request.urlopen(url) | |
data = f.read() | |
f.close() | |
lines = data.split("\n") | |
for line in lines: | |
matches = dhcp_re.match(line) | |
if matches: | |
if hardware_matches(matches.group(2)): | |
# print("{0} matches hw {1}".format(line, matches.group(2))) | |
yield matches.group(1) | |
def detect_raspis_nmap(): | |
## Change NMAP range if it is another subnet. | |
nmap_cmd = "sudo nmap -T5 -sP 192.168.13.0/24 | awk '/^Nmap/{ip=$NF}/B8:27:EB/{print ip}'" | |
result = subprocess.check_output(nmap_cmd, shell=True) | |
return result.split("\n") | |
def add_ordered_raspis(current_hardware=[]): | |
for hw in current_hardware: | |
if hw not in raspis: | |
raspis.insert(0, hw) | |
for hw in list(raspis): | |
if hw not in current_hardware: | |
raspis.remove(hw) | |
def check_default_pw(ip, user="pi", pw="raspberry"): | |
s = pxssh.pxssh() | |
s.force_password = True | |
try: | |
s.login(ip, user, pw) | |
s.sendline('hostname') | |
s.prompt() | |
hostname = s.before | |
s.logout() | |
return "[INSECURE!]" | |
except: | |
return "[OK]" | |
def main(): | |
global raspis | |
while True: | |
current_hardware = set(detect_raspis_nmap()) | |
add_ordered_raspis(current_hardware) | |
default_pw = {} | |
for line in raspis: | |
default_pw[line] = check_default_pw(line) | |
os.system('clear') | |
print("Connected berries @ {0:%H:%M:%S}".format(datetime.now())) | |
for line in raspis: | |
print("{ip} {maybeEnter}".format(ip=line, maybeEnter=default_pw[line])) | |
sleep(10) | |
if __name__ == '__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment