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
|
.idea
|
||||||
packer_cache
|
packer_cache
|
||||||
output-pwnagotchi
|
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
|
echo 0 >/sys/class/leds/led0/brightness
|
||||||
sleep 0.3
|
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
|
- name: create monstart script
|
||||||
copy:
|
copy:
|
||||||
dest: /usr/bin/monstart
|
dest: /usr/bin/monstart
|
||||||
@ -286,6 +301,13 @@
|
|||||||
fi
|
fi
|
||||||
/root/pwnagotchi/scripts/startup.sh &
|
/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
|
- name: configure lo interface
|
||||||
blockinfile:
|
blockinfile:
|
||||||
path: /etc/network/interfaces.d/lo-cfg
|
path: /etc/network/interfaces.d/lo-cfg
|
||||||
|
@ -153,8 +153,8 @@ bettercap:
|
|||||||
scheme: http
|
scheme: http
|
||||||
hostname: localhost
|
hostname: localhost
|
||||||
port: 8081
|
port: 8081
|
||||||
username: user
|
username: pwnagotchi
|
||||||
password: pass
|
password: pwnagotchi
|
||||||
# folder where bettercap stores the WPA handshakes, given that
|
# folder where bettercap stores the WPA handshakes, given that
|
||||||
# wifi.handshakes.aggregate will be set to false and individual
|
# wifi.handshakes.aggregate will be set to false and individual
|
||||||
# pcap files will be created in order to minimize the chances
|
# 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