2019-10-06 23:25:02 +02:00
|
|
|
__author__ = 'evilsocket@gmail.com'
|
|
|
|
__version__ = '1.0.0'
|
2019-10-07 16:23:38 +02:00
|
|
|
__name__ = 'grid'
|
2019-10-06 23:25:02 +02:00
|
|
|
__license__ = 'GPL3'
|
2019-10-07 16:23:38 +02:00
|
|
|
__description__ = 'This plugin signals the unit cryptographic identity and list of pwned networks and list of pwned networks to api.pwnagotchi.ai'
|
2019-10-06 23:25:02 +02:00
|
|
|
|
2019-10-07 13:06:29 +02:00
|
|
|
import os
|
2019-10-06 23:25:02 +02:00
|
|
|
import logging
|
|
|
|
import requests
|
2019-10-07 13:06:29 +02:00
|
|
|
import glob
|
2019-10-09 23:14:02 +02:00
|
|
|
import json
|
2019-10-07 10:25:46 +02:00
|
|
|
import subprocess
|
2019-10-06 23:25:02 +02:00
|
|
|
import pwnagotchi
|
2019-10-07 13:06:29 +02:00
|
|
|
import pwnagotchi.utils as utils
|
2019-10-07 19:59:28 +02:00
|
|
|
from pwnagotchi.utils import WifiInfo, extract_from_pcap
|
2019-10-06 23:25:02 +02:00
|
|
|
|
|
|
|
OPTIONS = dict()
|
2019-10-07 13:06:29 +02:00
|
|
|
REPORT = utils.StatusFile('/root/.api-report.json', data_format='json')
|
2019-10-06 23:25:02 +02:00
|
|
|
|
|
|
|
|
|
|
|
def on_loaded():
|
2019-10-08 15:09:32 +02:00
|
|
|
logging.info("grid plugin loaded.")
|
2019-10-06 23:25:02 +02:00
|
|
|
|
|
|
|
|
2019-10-07 13:06:29 +02:00
|
|
|
def parse_pcap(filename):
|
2019-10-08 14:54:03 +02:00
|
|
|
logging.info("grid: parsing %s ..." % filename)
|
2019-10-07 13:06:29 +02:00
|
|
|
|
2019-10-07 15:32:44 +02:00
|
|
|
net_id = os.path.basename(filename).replace('.pcap', '')
|
|
|
|
|
|
|
|
if '_' in net_id:
|
|
|
|
# /root/handshakes/ESSID_BSSID.pcap
|
|
|
|
essid, bssid = net_id.split('_')
|
|
|
|
else:
|
|
|
|
# /root/handshakes/BSSID.pcap
|
|
|
|
essid, bssid = '', net_id
|
|
|
|
|
|
|
|
it = iter(bssid)
|
|
|
|
bssid = ':'.join([a + b for a, b in zip(it, it)])
|
|
|
|
|
|
|
|
info = {
|
2019-10-07 19:59:28 +02:00
|
|
|
WifiInfo.ESSID: essid,
|
|
|
|
WifiInfo.BSSID: bssid,
|
2019-10-07 15:32:44 +02:00
|
|
|
}
|
2019-10-07 13:06:29 +02:00
|
|
|
|
|
|
|
try:
|
2019-10-07 19:59:28 +02:00
|
|
|
info = extract_from_pcap(filename, [WifiInfo.BSSID, WifiInfo.ESSID])
|
2019-10-07 13:06:29 +02:00
|
|
|
except Exception as e:
|
2019-10-08 14:54:03 +02:00
|
|
|
logging.error("grid: %s" % e)
|
2019-10-07 13:06:29 +02:00
|
|
|
|
2019-10-07 19:59:28 +02:00
|
|
|
return info[WifiInfo.ESSID], info[WifiInfo.BSSID]
|
2019-10-07 15:32:44 +02:00
|
|
|
|
|
|
|
|
2019-10-11 09:37:50 +02:00
|
|
|
def is_excluded(what):
|
|
|
|
for skip in OPTIONS['exclude']:
|
|
|
|
skip = skip.lower()
|
|
|
|
what = what.lower()
|
|
|
|
if skip in what or skip.replace(':', ':') in what:
|
|
|
|
return True
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
2019-10-11 16:19:40 +02:00
|
|
|
def grid_call(path, obj):
|
|
|
|
# pwngrid-peer is running on port 8666
|
|
|
|
api_address = 'http://127.0.0.1:8666/api/v1%s' % path
|
|
|
|
r = requests.post(api_address, headers=None, json=obj)
|
|
|
|
if r.status_code != 200:
|
|
|
|
raise Exception("(status %d) %s" % (r.status_code, r.text))
|
|
|
|
|
|
|
|
|
|
|
|
def grid_update_data(last_session):
|
|
|
|
brain = {}
|
|
|
|
try:
|
|
|
|
with open('/root/brain.json') as fp:
|
|
|
|
brain = json.load(fp)
|
|
|
|
except:
|
|
|
|
pass
|
|
|
|
|
|
|
|
data = {
|
2019-10-11 17:24:27 +02:00
|
|
|
'session': {
|
|
|
|
'duration': last_session.duration,
|
|
|
|
'epochs': last_session.epochs,
|
|
|
|
'train_epochs': last_session.train_epochs,
|
|
|
|
'avg_reward': last_session.avg_reward,
|
|
|
|
'min_reward': last_session.min_reward,
|
|
|
|
'max_reward': last_session.max_reward,
|
|
|
|
'deauthed': last_session.deauthed,
|
|
|
|
'associated': last_session.associated,
|
|
|
|
'handshakes': last_session.handshakes,
|
|
|
|
'peers': last_session.peers,
|
|
|
|
},
|
2019-10-11 16:19:40 +02:00
|
|
|
'uname': subprocess.getoutput("uname -a"),
|
|
|
|
'brain': brain,
|
|
|
|
'version': pwnagotchi.version
|
|
|
|
}
|
|
|
|
|
|
|
|
logging.debug("updating grid data:\n%s" % data)
|
|
|
|
|
|
|
|
grid_call("/data", data)
|
|
|
|
|
|
|
|
|
|
|
|
def grid_report_ap(essid, bssid):
|
|
|
|
try:
|
|
|
|
grid_call("/report/ap", {
|
|
|
|
'essid': essid,
|
|
|
|
'bssid': bssid,
|
|
|
|
})
|
|
|
|
return True
|
|
|
|
except Exception as e:
|
|
|
|
logging.exception("error while reporting ap %s(%s)" % (essid, bssid))
|
|
|
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
2019-10-08 14:54:03 +02:00
|
|
|
def on_internet_available(agent):
|
2019-10-07 13:06:29 +02:00
|
|
|
global REPORT
|
|
|
|
|
2019-10-11 16:19:40 +02:00
|
|
|
logging.debug("internet available")
|
2019-10-11 09:37:50 +02:00
|
|
|
|
2019-10-11 16:19:40 +02:00
|
|
|
try:
|
|
|
|
grid_update_data(agent.last_session)
|
|
|
|
except Exception as e:
|
|
|
|
logging.error("error connecting to the pwngrid-peer service: %s" % e)
|
|
|
|
return
|
2019-10-07 13:06:29 +02:00
|
|
|
|
2019-10-11 16:19:40 +02:00
|
|
|
try:
|
2019-10-11 09:37:50 +02:00
|
|
|
logging.debug("checking pcaps")
|
|
|
|
|
2019-10-11 16:19:40 +02:00
|
|
|
pcap_files = glob.glob(os.path.join(agent.config()['bettercap']['handshakes'], "*.pcap"))
|
2019-10-07 13:06:29 +02:00
|
|
|
num_networks = len(pcap_files)
|
|
|
|
reported = REPORT.data_field_or('reported', default=[])
|
|
|
|
num_reported = len(reported)
|
|
|
|
num_new = num_networks - num_reported
|
|
|
|
|
|
|
|
if num_new > 0:
|
|
|
|
if OPTIONS['report']:
|
2019-10-08 14:54:03 +02:00
|
|
|
logging.info("grid: %d new networks to report" % num_new)
|
2019-10-11 09:37:50 +02:00
|
|
|
logging.debug("OPTIONS: %s" % OPTIONS)
|
|
|
|
logging.debug(" exclude: %s" % OPTIONS['exclude'])
|
2019-10-08 14:54:03 +02:00
|
|
|
|
2019-10-07 13:06:29 +02:00
|
|
|
for pcap_file in pcap_files:
|
|
|
|
net_id = os.path.basename(pcap_file).replace('.pcap', '')
|
2019-10-11 09:37:50 +02:00
|
|
|
if net_id not in reported:
|
|
|
|
if is_excluded(net_id):
|
|
|
|
logging.info("skipping %s due to exclusion filter" % pcap_file)
|
|
|
|
continue
|
|
|
|
|
2019-10-07 13:06:29 +02:00
|
|
|
essid, bssid = parse_pcap(pcap_file)
|
|
|
|
if bssid:
|
2019-10-11 09:37:50 +02:00
|
|
|
if is_excluded(essid) or is_excluded(bssid):
|
|
|
|
logging.debug("not reporting %s due to exclusion filter" % pcap_file)
|
|
|
|
|
2019-10-11 16:19:40 +02:00
|
|
|
elif grid_report_ap(essid, bssid):
|
|
|
|
reported.append(net_id)
|
|
|
|
REPORT.update(data={'reported': reported})
|
|
|
|
else:
|
|
|
|
logging.warning("no bssid found?!")
|
2019-10-07 13:06:29 +02:00
|
|
|
else:
|
2019-10-08 14:54:03 +02:00
|
|
|
logging.debug("grid: reporting disabled")
|
2019-10-06 23:25:02 +02:00
|
|
|
|
|
|
|
except Exception as e:
|
2019-10-11 16:19:40 +02:00
|
|
|
logging.exception("grid api error")
|