misc: refactored code to work as a setup.py based package
Signed-off-by: Simone Margaritelli <evilsocket@gmail.com>
This commit is contained in:
parent
6b4bfb6992
commit
cbf7511e17
4
.gitignore
vendored
4
.gitignore
vendored
@ -10,3 +10,7 @@ config.laptop.yml
|
||||
.idea
|
||||
packer_cache
|
||||
output-pwnagotchi
|
||||
.DS_Store
|
||||
build
|
||||
dist
|
||||
pwnagotchi.egg-info
|
||||
|
106
bin/pwnagotchi
Executable file
106
bin/pwnagotchi
Executable file
@ -0,0 +1,106 @@
|
||||
#!/usr/bin/python3
|
||||
if __name__ == '__main__':
|
||||
import argparse
|
||||
import time
|
||||
import os
|
||||
import logging
|
||||
|
||||
import pwnagotchi
|
||||
import pwnagotchi.utils as utils
|
||||
import pwnagotchi.plugins as plugins
|
||||
|
||||
from pwnagotchi.log import SessionParser
|
||||
from pwnagotchi.agent import Agent
|
||||
from pwnagotchi.ui.display import Display
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
|
||||
parser.add_argument('-C', '--config', action='store', dest='config',
|
||||
default=os.path.join(os.path.abspath(os.path.dirname(pwnagotchi.__file__)), '/defaults.yml'),
|
||||
help='Main configuration file.')
|
||||
parser.add_argument('-U', '--user-config', action='store', dest='user_config', default='/etc/pwnagotchi/config.yml',
|
||||
help='If this file exists, configuration will be merged and this will override default values.')
|
||||
|
||||
parser.add_argument('--manual', dest="do_manual", action="store_true", default=False, help="Manual mode.")
|
||||
parser.add_argument('--clear', dest="do_clear", action="store_true", default=False,
|
||||
help="Clear the ePaper display and exit.")
|
||||
|
||||
parser.add_argument('--debug', dest="debug", action="store_true", default=False,
|
||||
help="Enable debug logs.")
|
||||
|
||||
args = parser.parse_args()
|
||||
config = utils.load_config(args)
|
||||
utils.setup_logging(args, config)
|
||||
|
||||
plugins.load(config)
|
||||
|
||||
display = Display(config=config, state={'name': '%s>' % pwnagotchi.name()})
|
||||
agent = Agent(view=display, config=config)
|
||||
|
||||
logging.info("%s@%s (v%s)" % (pwnagotchi.name(), agent._identity, pwnagotchi.version))
|
||||
|
||||
for _, plugin in plugins.loaded.items():
|
||||
logging.debug("plugin '%s' v%s loaded from %s" % (plugin.__name__, plugin.__version__, plugin.__file__))
|
||||
|
||||
if args.do_clear:
|
||||
logging.info("clearing the display ...")
|
||||
display.clear()
|
||||
|
||||
elif args.do_manual:
|
||||
logging.info("entering manual mode ...")
|
||||
|
||||
log = SessionParser(config)
|
||||
logging.info(
|
||||
"the last session lasted %s (%d completed epochs, trained for %d), average reward:%s (min:%s max:%s)" % (
|
||||
log.duration_human,
|
||||
log.epochs,
|
||||
log.train_epochs,
|
||||
log.avg_reward,
|
||||
log.min_reward,
|
||||
log.max_reward))
|
||||
|
||||
while True:
|
||||
display.on_manual_mode(log)
|
||||
time.sleep(1)
|
||||
|
||||
if Agent.is_connected():
|
||||
plugins.on('internet_available', display, config, log)
|
||||
|
||||
else:
|
||||
logging.info("entering auto mode ...")
|
||||
|
||||
agent.start()
|
||||
|
||||
while True:
|
||||
try:
|
||||
# recon on all channels
|
||||
agent.recon()
|
||||
# get nearby access points grouped by channel
|
||||
channels = agent.get_access_points_by_channel()
|
||||
# check for free channels to use
|
||||
agent.check_channels(channels)
|
||||
# for each channel
|
||||
for ch, aps in channels:
|
||||
agent.set_channel(ch)
|
||||
|
||||
if not agent.is_stale() and agent.any_activity():
|
||||
logging.info("%d access points on channel %d" % (len(aps), ch))
|
||||
|
||||
# for each ap on this channel
|
||||
for ap in aps:
|
||||
# send an association frame in order to get for a PMKID
|
||||
agent.associate(ap)
|
||||
# deauth all client stations in order to get a full handshake
|
||||
for sta in ap['clients']:
|
||||
agent.deauth(ap, sta)
|
||||
|
||||
# An interesting effect of this:
|
||||
#
|
||||
# From Pwnagotchi's perspective, the more new access points
|
||||
# and / or client stations nearby, the longer one epoch of
|
||||
# its relative time will take ... basically, in Pwnagotchi's universe,
|
||||
# WiFi electromagnetic fields affect time like gravitational fields
|
||||
# affect ours ... neat ^_^
|
||||
agent.next_epoch()
|
||||
except Exception as e:
|
||||
logging.exception("main loop exception")
|
@ -260,6 +260,21 @@
|
||||
echo 0 >/sys/class/leds/led0/brightness
|
||||
sleep 0.3
|
||||
|
||||
- name: create pwnagotchi-launcher script
|
||||
copy:
|
||||
dest: /usr/bin/pwnagotchi-launcher
|
||||
mode: 0755
|
||||
content: |
|
||||
#!/usr/bin/env bash
|
||||
# blink 10 times to signal ready state
|
||||
/usr/bin/bootblink 10 &
|
||||
# start a detached screen session with bettercap
|
||||
if ifconfig | grep usb0 | grep RUNNING; then
|
||||
/usr/bin/pwnagotchi --manual
|
||||
else
|
||||
/usr/bin/pwnagotchi
|
||||
fi
|
||||
|
||||
- name: create monstart script
|
||||
copy:
|
||||
dest: /usr/bin/monstart
|
||||
@ -286,6 +301,13 @@
|
||||
fi
|
||||
/root/pwnagotchi/scripts/startup.sh &
|
||||
|
||||
- name: create /etc/pwnagotchi/config.yml
|
||||
blockinfile:
|
||||
path: /etc/pwnagotchi/config.yml
|
||||
create: yes
|
||||
block: |
|
||||
# put here your custom configuration overrides
|
||||
|
||||
- name: configure lo interface
|
||||
blockinfile:
|
||||
path: /etc/network/interfaces.d/lo-cfg
|
||||
|
@ -153,8 +153,8 @@ bettercap:
|
||||
scheme: http
|
||||
hostname: localhost
|
||||
port: 8081
|
||||
username: user
|
||||
password: pass
|
||||
username: pwnagotchi
|
||||
password: pwnagotchi
|
||||
# folder where bettercap stores the WPA handshakes, given that
|
||||
# wifi.handshakes.aggregate will be set to false and individual
|
||||
# pcap files will be created in order to minimize the chances
|
@ -1,49 +0,0 @@
|
||||
defutf8 on
|
||||
|
||||
shell -${SHELL}
|
||||
defscrollback 1024
|
||||
startup_message off
|
||||
altscreen on
|
||||
autodetach on
|
||||
zombie kr
|
||||
|
||||
activity "activity in %n (%t)"
|
||||
bell_msg "bell in %n (%t)"
|
||||
|
||||
vbell on
|
||||
vbell_msg "WTF DUDE ??!!"
|
||||
vbellwait 1
|
||||
|
||||
# set terminal emulator to xterm mode
|
||||
term xterm
|
||||
# Make the output buffer large for (fast) xterms.
|
||||
termcapinfo xterm* ti@:te@
|
||||
# tell screen how to set colors
|
||||
termcapinfo xterm 'Co#256:AB=\E[48;5;%dm:AF=\E[38;5;%dm'
|
||||
# allow bold colors
|
||||
attrcolor b ".I"
|
||||
# erase background with current bg color
|
||||
defbce "on"
|
||||
|
||||
# ctrl + { left, right }
|
||||
bindkey ^[[1;5D prev
|
||||
bindkey ^[[1;5C next
|
||||
bindkey ^[[5D prev
|
||||
bindkey ^[[5C next
|
||||
bindkey ^[b prev
|
||||
bindkey ^[f next
|
||||
bindkey ^[[D prev
|
||||
bindkey ^[[C next
|
||||
|
||||
screen -t shell
|
||||
screen -t auto-mode /bin/bash -c "/root/pwnagotchi/scripts/main.py"
|
||||
screen -t bettercap /usr/bin/bettercap -caplet http-ui -eval "!/usr/bin/monstart; set wifi.interface mon0"
|
||||
|
||||
select log
|
||||
|
||||
backtick 1 0 0 cpuusage
|
||||
backtick 2 5 5 memusage
|
||||
|
||||
hardstatus alwayslastline
|
||||
hardstatus string '%{= kG}[ %{G}%H %{g}][%= %{= kw}%?%-Lw%?%{r}(%{W}%n*%f%t%?(%u)%?%{r})%{w}%?%+Lw%?%?%= %{g}][cpu %1`][mem %2`][%{B} %m-%d %{W}%c %{g}]'
|
||||
|
@ -1,49 +0,0 @@
|
||||
defutf8 on
|
||||
|
||||
shell -${SHELL}
|
||||
defscrollback 1024
|
||||
startup_message off
|
||||
altscreen on
|
||||
autodetach on
|
||||
zombie kr
|
||||
|
||||
activity "activity in %n (%t)"
|
||||
bell_msg "bell in %n (%t)"
|
||||
|
||||
vbell on
|
||||
vbell_msg "WTF DUDE ??!!"
|
||||
vbellwait 1
|
||||
|
||||
# set terminal emulator to xterm mode
|
||||
term xterm
|
||||
# Make the output buffer large for (fast) xterms.
|
||||
termcapinfo xterm* ti@:te@
|
||||
# tell screen how to set colors
|
||||
termcapinfo xterm 'Co#256:AB=\E[48;5;%dm:AF=\E[38;5;%dm'
|
||||
# allow bold colors
|
||||
attrcolor b ".I"
|
||||
# erase background with current bg color
|
||||
defbce "on"
|
||||
|
||||
# ctrl + { left, right }
|
||||
bindkey ^[[1;5D prev
|
||||
bindkey ^[[1;5C next
|
||||
bindkey ^[[5D prev
|
||||
bindkey ^[[5C next
|
||||
bindkey ^[b prev
|
||||
bindkey ^[f next
|
||||
bindkey ^[[D prev
|
||||
bindkey ^[[C next
|
||||
|
||||
screen -t shell
|
||||
screen -t manual-mode /bin/bash -c "/root/pwnagotchi/scripts/main.py --manual"
|
||||
screen -t bettercap /usr/bin/bettercap -caplet http-ui -eval "!/usr/bin/monstart; set wifi.interface mon0"
|
||||
|
||||
select log
|
||||
|
||||
backtick 1 0 0 cpuusage
|
||||
backtick 2 5 5 memusage
|
||||
|
||||
hardstatus alwayslastline
|
||||
hardstatus string '%{= kG}[ %{G}%H %{g}][%= %{= kw}%?%-Lw%?%{r}(%{W}%n*%f%t%?(%u)%?%{r})%{w}%?%+Lw%?%?%= %{g}][cpu %1`][mem %2`][%{B} %m-%d %{W}%c %{g}]'
|
||||
|
@ -1,103 +0,0 @@
|
||||
#!/usr/bin/python3
|
||||
import argparse
|
||||
import time
|
||||
import logging
|
||||
|
||||
import pwnagotchi
|
||||
import pwnagotchi.utils as utils
|
||||
import pwnagotchi.plugins as plugins
|
||||
|
||||
from pwnagotchi.log import SessionParser
|
||||
from pwnagotchi.agent import Agent
|
||||
from pwnagotchi.ui.display import Display
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
|
||||
parser.add_argument('-C', '--config', action='store', dest='config', default='/root/pwnagotchi/config.yml',
|
||||
help='Main configuration file.')
|
||||
parser.add_argument('-U', '--user-config', action='store', dest='user_config', default='/root/custom.yml',
|
||||
help='If this file exists, configuration will be merged and this will override default values.')
|
||||
|
||||
parser.add_argument('--manual', dest="do_manual", action="store_true", default=False, help="Manual mode.")
|
||||
parser.add_argument('--clear', dest="do_clear", action="store_true", default=False,
|
||||
help="Clear the ePaper display and exit.")
|
||||
|
||||
parser.add_argument('--debug', dest="debug", action="store_true", default=False,
|
||||
help="Enable debug logs.")
|
||||
|
||||
args = parser.parse_args()
|
||||
config = utils.load_config(args)
|
||||
utils.setup_logging(args, config)
|
||||
|
||||
plugins.load(config)
|
||||
|
||||
display = Display(config=config, state={'name': '%s>' % pwnagotchi.name()})
|
||||
agent = Agent(view=display, config=config)
|
||||
|
||||
logging.info("%s@%s (v%s)" % (pwnagotchi.name(), agent._identity, pwnagotchi.version))
|
||||
|
||||
for _, plugin in plugins.loaded.items():
|
||||
logging.debug("plugin '%s' v%s loaded from %s" % (plugin.__name__, plugin.__version__, plugin.__file__))
|
||||
|
||||
if args.do_clear:
|
||||
logging.info("clearing the display ...")
|
||||
display.clear()
|
||||
|
||||
elif args.do_manual:
|
||||
logging.info("entering manual mode ...")
|
||||
|
||||
log = SessionParser(config)
|
||||
logging.info(
|
||||
"the last session lasted %s (%d completed epochs, trained for %d), average reward:%s (min:%s max:%s)" % (
|
||||
log.duration_human,
|
||||
log.epochs,
|
||||
log.train_epochs,
|
||||
log.avg_reward,
|
||||
log.min_reward,
|
||||
log.max_reward))
|
||||
|
||||
while True:
|
||||
display.on_manual_mode(log)
|
||||
time.sleep(1)
|
||||
|
||||
if Agent.is_connected():
|
||||
plugins.on('internet_available', display, config, log)
|
||||
|
||||
else:
|
||||
logging.info("entering auto mode ...")
|
||||
|
||||
agent.start()
|
||||
|
||||
while True:
|
||||
try:
|
||||
# recon on all channels
|
||||
agent.recon()
|
||||
# get nearby access points grouped by channel
|
||||
channels = agent.get_access_points_by_channel()
|
||||
# check for free channels to use
|
||||
agent.check_channels(channels)
|
||||
# for each channel
|
||||
for ch, aps in channels:
|
||||
agent.set_channel(ch)
|
||||
|
||||
if not agent.is_stale() and agent.any_activity():
|
||||
logging.info("%d access points on channel %d" % (len(aps), ch))
|
||||
|
||||
# for each ap on this channel
|
||||
for ap in aps:
|
||||
# send an association frame in order to get for a PMKID
|
||||
agent.associate(ap)
|
||||
# deauth all client stations in order to get a full handshake
|
||||
for sta in ap['clients']:
|
||||
agent.deauth(ap, sta)
|
||||
|
||||
# An interesting effect of this:
|
||||
#
|
||||
# From Pwnagotchi's perspective, the more new access points
|
||||
# and / or client stations nearby, the longer one epoch of
|
||||
# its relative time will take ... basically, in Pwnagotchi's universe,
|
||||
# WiFi electromagnetic fields affect time like gravitational fields
|
||||
# affect ours ... neat ^_^
|
||||
agent.next_epoch()
|
||||
except Exception as e:
|
||||
logging.exception("main loop exception")
|
@ -1,11 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# blink 10 times to signal ready state
|
||||
/usr/bin/bootblink 10 &
|
||||
|
||||
# start a detached screen session with bettercap
|
||||
if ifconfig | grep usb0 | grep RUNNING; then
|
||||
sudo -H -u root /usr/bin/screen -dmS pwnagotchi -c /root/pwnagotchi/data/screenrc.manual
|
||||
else
|
||||
sudo -H -u root /usr/bin/screen -dmS pwnagotchi -c /root/pwnagotchi/data/screenrc.auto
|
||||
fi
|
26
setup.py
Normal file
26
setup.py
Normal file
@ -0,0 +1,26 @@
|
||||
#!/usr/bin/env python3
|
||||
from setuptools import setup, find_packages
|
||||
import pwnagotchi
|
||||
|
||||
required = []
|
||||
with open('requirements.txt') as fp:
|
||||
for line in fp:
|
||||
line = line.strip()
|
||||
if line != "":
|
||||
required.append(line)
|
||||
|
||||
setup(name='pwnagotchi',
|
||||
version=pwnagotchi.version,
|
||||
description='Pwnagotchi is a cute AI that eats WPA handshakes.',
|
||||
author='evilsocket && the dev team',
|
||||
author_email='evilsocket@gmail.com',
|
||||
url='https://pwnagotchi.ai/',
|
||||
install_requires=required,
|
||||
scripts=['bin/pwnagotchi'],
|
||||
license='GPL',
|
||||
classifiers=[
|
||||
'Programming Language :: Python :: 3',
|
||||
'Development Status :: 5 - Production/Stable',
|
||||
'License :: OSI Approved :: GNU General Public License (GPL)',
|
||||
'Environment :: Console',
|
||||
])
|
Loading…
x
Reference in New Issue
Block a user