fix: using pwngrid-peer service from the grid plugin
This commit is contained in:
parent
3ddc717009
commit
8210c0bb71
@ -34,7 +34,7 @@
|
|||||||
url: "https://github.com/bettercap/bettercap/releases/download/v2.25/bettercap_linux_armv6l_2.25.zip"
|
url: "https://github.com/bettercap/bettercap/releases/download/v2.25/bettercap_linux_armv6l_2.25.zip"
|
||||||
ui: "https://github.com/bettercap/ui/releases/download/v1.3.0/ui.zip"
|
ui: "https://github.com/bettercap/ui/releases/download/v1.3.0/ui.zip"
|
||||||
pwngrid:
|
pwngrid:
|
||||||
url: "https://github.com/evilsocket/pwngrid/releases/download/v1.5.3/pwngrid_linux_armv6l_v1.5.3.zip"
|
url: "https://github.com/evilsocket/pwngrid/releases/download/v1.5.4/pwngrid_linux_armv6l_v1.5.4.zip"
|
||||||
apt:
|
apt:
|
||||||
hold:
|
hold:
|
||||||
- firmware-atheros
|
- firmware-atheros
|
||||||
@ -502,7 +502,7 @@
|
|||||||
[Service]
|
[Service]
|
||||||
Type=simple
|
Type=simple
|
||||||
PermissionsStartOnly=true
|
PermissionsStartOnly=true
|
||||||
ExecStart=/usr/bin/pwngrid -keys /etc/pwnagotchi -address 127.0.0.1:8666 -wait
|
ExecStart=/usr/bin/pwngrid -keys /etc/pwnagotchi -address 127.0.0.1:8666 -wait -log /var/log/pwngrid-peer.log
|
||||||
Restart=always
|
Restart=always
|
||||||
RestartSec=30
|
RestartSec=30
|
||||||
|
|
||||||
|
@ -15,7 +15,6 @@ import pwnagotchi.utils as utils
|
|||||||
from pwnagotchi.utils import WifiInfo, extract_from_pcap
|
from pwnagotchi.utils import WifiInfo, extract_from_pcap
|
||||||
|
|
||||||
OPTIONS = dict()
|
OPTIONS = dict()
|
||||||
AUTH = utils.StatusFile('/root/.api-enrollment.json', data_format='json')
|
|
||||||
REPORT = utils.StatusFile('/root/.api-report.json', data_format='json')
|
REPORT = utils.StatusFile('/root/.api-report.json', data_format='json')
|
||||||
|
|
||||||
|
|
||||||
@ -23,61 +22,6 @@ def on_loaded():
|
|||||||
logging.info("grid plugin loaded.")
|
logging.info("grid plugin loaded.")
|
||||||
|
|
||||||
|
|
||||||
def get_api_token(last_session, keys):
|
|
||||||
global AUTH
|
|
||||||
|
|
||||||
if AUTH.newer_then_minutes(25) and AUTH.data is not None and 'token' in AUTH.data:
|
|
||||||
return AUTH.data['token']
|
|
||||||
|
|
||||||
if AUTH.data is None:
|
|
||||||
logging.info("grid: enrolling unit ...")
|
|
||||||
else:
|
|
||||||
logging.info("grid: refreshing token ...")
|
|
||||||
|
|
||||||
identity = "%s@%s" % (pwnagotchi.name(), keys.fingerprint)
|
|
||||||
# sign the identity string to prove we own both keys
|
|
||||||
_, signature_b64 = keys.sign(identity)
|
|
||||||
|
|
||||||
brain = {}
|
|
||||||
try:
|
|
||||||
with open('/root/brain.json') as fp:
|
|
||||||
brain = json.load(fp)
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
api_address = 'https://api.pwnagotchi.ai/api/v1/unit/enroll'
|
|
||||||
enrollment = {
|
|
||||||
'identity': identity,
|
|
||||||
'public_key': keys.pub_key_pem_b64,
|
|
||||||
'signature': signature_b64,
|
|
||||||
'data': {
|
|
||||||
'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,
|
|
||||||
'uname': subprocess.getoutput("uname -a"),
|
|
||||||
'brain': brain,
|
|
||||||
'version': pwnagotchi.version
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
r = requests.post(api_address, json=enrollment)
|
|
||||||
if r.status_code != 200:
|
|
||||||
raise Exception("(status %d) %s" % (r.status_code, r.json()))
|
|
||||||
|
|
||||||
AUTH.update(data=r.json())
|
|
||||||
|
|
||||||
logging.info("grid: done")
|
|
||||||
|
|
||||||
return AUTH.data["token"]
|
|
||||||
|
|
||||||
|
|
||||||
def parse_pcap(filename):
|
def parse_pcap(filename):
|
||||||
logging.info("grid: parsing %s ..." % filename)
|
logging.info("grid: parsing %s ..." % filename)
|
||||||
|
|
||||||
@ -106,32 +50,6 @@ def parse_pcap(filename):
|
|||||||
return info[WifiInfo.ESSID], info[WifiInfo.BSSID]
|
return info[WifiInfo.ESSID], info[WifiInfo.BSSID]
|
||||||
|
|
||||||
|
|
||||||
def api_report_ap(last_session, keys, token, essid, bssid):
|
|
||||||
while True:
|
|
||||||
token = AUTH.data['token']
|
|
||||||
logging.info("grid: reporting %s (%s)" % (essid, bssid))
|
|
||||||
try:
|
|
||||||
api_address = 'https://api.pwnagotchi.ai/api/v1/unit/report/ap'
|
|
||||||
headers = {'Authorization': 'access_token %s' % token}
|
|
||||||
report = {
|
|
||||||
'essid': essid,
|
|
||||||
'bssid': bssid,
|
|
||||||
}
|
|
||||||
r = requests.post(api_address, headers=headers, json=report)
|
|
||||||
if r.status_code != 200:
|
|
||||||
if r.status_code == 401:
|
|
||||||
logging.warning("token expired")
|
|
||||||
token = get_api_token(last_session, keys)
|
|
||||||
continue
|
|
||||||
else:
|
|
||||||
raise Exception("(status %d) %s" % (r.status_code, r.text))
|
|
||||||
else:
|
|
||||||
return True
|
|
||||||
except Exception as e:
|
|
||||||
logging.error("grid: %s" % e)
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
def is_excluded(what):
|
def is_excluded(what):
|
||||||
for skip in OPTIONS['exclude']:
|
for skip in OPTIONS['exclude']:
|
||||||
skip = skip.lower()
|
skip = skip.lower()
|
||||||
@ -141,24 +59,76 @@ def is_excluded(what):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
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 = {
|
||||||
|
'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,
|
||||||
|
'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
|
||||||
|
|
||||||
|
|
||||||
def on_internet_available(agent):
|
def on_internet_available(agent):
|
||||||
global REPORT
|
global REPORT
|
||||||
|
|
||||||
|
logging.debug("internet available")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
logging.debug("internet available")
|
grid_update_data(agent.last_session)
|
||||||
|
except Exception as e:
|
||||||
config = agent.config()
|
logging.error("error connecting to the pwngrid-peer service: %s" % e)
|
||||||
keys = agent.keypair()
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
logging.debug("checking pcaps")
|
logging.debug("checking pcaps")
|
||||||
|
|
||||||
pcap_files = glob.glob(os.path.join(config['bettercap']['handshakes'], "*.pcap"))
|
pcap_files = glob.glob(os.path.join(agent.config()['bettercap']['handshakes'], "*.pcap"))
|
||||||
num_networks = len(pcap_files)
|
num_networks = len(pcap_files)
|
||||||
reported = REPORT.data_field_or('reported', default=[])
|
reported = REPORT.data_field_or('reported', default=[])
|
||||||
num_reported = len(reported)
|
num_reported = len(reported)
|
||||||
num_new = num_networks - num_reported
|
num_new = num_networks - num_reported
|
||||||
|
|
||||||
token = get_api_token(agent.last_session, agent.keypair())
|
|
||||||
if num_new > 0:
|
if num_new > 0:
|
||||||
if OPTIONS['report']:
|
if OPTIONS['report']:
|
||||||
logging.info("grid: %d new networks to report" % num_new)
|
logging.info("grid: %d new networks to report" % num_new)
|
||||||
@ -177,11 +147,13 @@ def on_internet_available(agent):
|
|||||||
if is_excluded(essid) or is_excluded(bssid):
|
if is_excluded(essid) or is_excluded(bssid):
|
||||||
logging.debug("not reporting %s due to exclusion filter" % pcap_file)
|
logging.debug("not reporting %s due to exclusion filter" % pcap_file)
|
||||||
|
|
||||||
elif api_report_ap(agent.last_session, keys, token, essid, bssid):
|
elif grid_report_ap(essid, bssid):
|
||||||
reported.append(net_id)
|
reported.append(net_id)
|
||||||
REPORT.update(data={'reported': reported})
|
REPORT.update(data={'reported': reported})
|
||||||
|
else:
|
||||||
|
logging.warning("no bssid found?!")
|
||||||
else:
|
else:
|
||||||
logging.debug("grid: reporting disabled")
|
logging.debug("grid: reporting disabled")
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logging.exception("error while enrolling the unit")
|
logging.exception("grid api error")
|
||||||
|
Loading…
x
Reference in New Issue
Block a user