Merge branch 'master' into master
This commit is contained in:
commit
7bba0b5286
5
.gitignore
vendored
5
.gitignore
vendored
@ -2,6 +2,7 @@
|
|||||||
*.img.bmap
|
*.img.bmap
|
||||||
*.pcap
|
*.pcap
|
||||||
*.po~
|
*.po~
|
||||||
|
preview.png
|
||||||
__pycache__
|
__pycache__
|
||||||
_backups
|
_backups
|
||||||
_emulation
|
_emulation
|
||||||
@ -10,3 +11,7 @@ config.laptop.yml
|
|||||||
.idea
|
.idea
|
||||||
packer_cache
|
packer_cache
|
||||||
output-pwnagotchi
|
output-pwnagotchi
|
||||||
|
.DS_Store
|
||||||
|
build
|
||||||
|
dist
|
||||||
|
pwnagotchi.egg-info
|
||||||
|
8
MANIFEST.in
Normal file
8
MANIFEST.in
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
exclude *.pyc .DS_Store .gitignore MANIFEST.in
|
||||||
|
include setup.py
|
||||||
|
include distribute_setup.py
|
||||||
|
include README.md
|
||||||
|
include LICENSE
|
||||||
|
recursive-include bin *
|
||||||
|
recursive-include pwnagotchi *.py
|
||||||
|
recursive-include pwnagotchi *.yml
|
@ -4,8 +4,10 @@
|
|||||||
<p align="center">
|
<p align="center">
|
||||||
<a href="https://github.com/evilsocket/pwnagotchi/releases/latest"><img alt="Release" src="https://img.shields.io/github/release/evilsocket/pwnagotchi.svg?style=flat-square"></a>
|
<a href="https://github.com/evilsocket/pwnagotchi/releases/latest"><img alt="Release" src="https://img.shields.io/github/release/evilsocket/pwnagotchi.svg?style=flat-square"></a>
|
||||||
<a href="https://github.com/evilsocket/pwnagotchi/blob/master/LICENSE.md"><img alt="Software License" src="https://img.shields.io/badge/license-GPL3-brightgreen.svg?style=flat-square"></a>
|
<a href="https://github.com/evilsocket/pwnagotchi/blob/master/LICENSE.md"><img alt="Software License" src="https://img.shields.io/badge/license-GPL3-brightgreen.svg?style=flat-square"></a>
|
||||||
|
<a href="https://github.com/evilsocket/pwnagotchi/graphs/contributors"><img alt="Contributors" src="https://img.shields.io/github/contributors/evilsocket/pwnagotchi"/></a>
|
||||||
<a href="https://travis-ci.org/evilsocket/pwnagotchi"><img alt="Travis" src="https://img.shields.io/travis/evilsocket/pwnagotchi/master.svg?style=flat-square"></a>
|
<a href="https://travis-ci.org/evilsocket/pwnagotchi"><img alt="Travis" src="https://img.shields.io/travis/evilsocket/pwnagotchi/master.svg?style=flat-square"></a>
|
||||||
<a href="https://pwnagotchi.herokuapp.com/"><img alt="Slack" src="https://pwnagotchi.herokuapp.com/badge.svg"></a>
|
<a href="https://pwnagotchi.herokuapp.com/"><img alt="Slack" src="https://pwnagotchi.herokuapp.com/badge.svg"></a>
|
||||||
|
<a href="https://twitter.com/intent/follow?screen_name=pwnagotchi"><img src="https://img.shields.io/twitter/follow/pwnagotchi?style=social&logo=twitter" alt="follow on Twitter"></a>
|
||||||
</p>
|
</p>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
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")
|
@ -16,7 +16,6 @@
|
|||||||
services:
|
services:
|
||||||
enable:
|
enable:
|
||||||
- dphys-swapfile.service
|
- dphys-swapfile.service
|
||||||
- getty@ttyGS0.service
|
|
||||||
disable:
|
disable:
|
||||||
- apt-daily.timer
|
- apt-daily.timer
|
||||||
- apt-daily.service
|
- apt-daily.service
|
||||||
@ -245,6 +244,37 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
free -m | awk '/Mem/ { printf( "%d %", $3 / $2 * 100 + 0.5 ) }'
|
free -m | awk '/Mem/ { printf( "%d %", $3 / $2 * 100 + 0.5 ) }'
|
||||||
|
|
||||||
|
- name: create bootblink script
|
||||||
|
copy:
|
||||||
|
dest: /usr/bin/bootblink
|
||||||
|
mode: 0755
|
||||||
|
content: |
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
for i in $(seq 1 "$1");
|
||||||
|
do
|
||||||
|
echo 0 >/sys/class/leds/led0/brightness
|
||||||
|
sleep 0.3
|
||||||
|
echo 1 >/sys/class/leds/led0/brightness
|
||||||
|
sleep 0.3
|
||||||
|
done
|
||||||
|
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
|
- name: create monstart script
|
||||||
copy:
|
copy:
|
||||||
dest: /usr/bin/monstart
|
dest: /usr/bin/monstart
|
||||||
@ -261,6 +291,22 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
ifconfig mon0 down && iw dev mon0 del
|
ifconfig mon0 down && iw dev mon0 del
|
||||||
|
|
||||||
|
- name: create hdmion script
|
||||||
|
copy:
|
||||||
|
dest: /usr/bin/hdmion
|
||||||
|
mode: 0755
|
||||||
|
content: |
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
sudo /opt/vc/bin/tvservice -p
|
||||||
|
|
||||||
|
- name: create hdmioff script
|
||||||
|
copy:
|
||||||
|
dest: /usr/bin/hdmioff
|
||||||
|
mode: 0755
|
||||||
|
content: |
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
sudo /opt/vc/bin/tvservice -o
|
||||||
|
|
||||||
- name: configure rc.local
|
- name: configure rc.local
|
||||||
blockinfile:
|
blockinfile:
|
||||||
path: /etc/rc.local
|
path: /etc/rc.local
|
||||||
@ -271,6 +317,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
|
||||||
@ -335,7 +388,7 @@
|
|||||||
state: present
|
state: present
|
||||||
backup: no
|
backup: no
|
||||||
regexp: '(.*)$'
|
regexp: '(.*)$'
|
||||||
line: '\1 modules-load=dwc2,g_cdc'
|
line: '\1 modules-load=dwc2,g_ether'
|
||||||
|
|
||||||
- name: configure ssh
|
- name: configure ssh
|
||||||
lineinfile:
|
lineinfile:
|
||||||
|
@ -26,7 +26,7 @@ usage: ./scripts/create_sibling.sh [OPTIONS]
|
|||||||
|
|
||||||
`GLib-ERROR **: 20:50:46.361: getauxval () failed: No such file or directory`
|
`GLib-ERROR **: 20:50:46.361: getauxval () failed: No such file or directory`
|
||||||
|
|
||||||
- Affected DEB & Versions: QEMU <= 2.11
|
- Affected DEB & Versions: QEMU <= 2.11
|
||||||
- Fix: Upgrade QEMU to >= 3.1
|
- Fix: Upgrade QEMU to >= 3.1
|
||||||
- Bug Link: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=923289
|
- Bug Link: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=923289
|
||||||
|
|
||||||
@ -55,7 +55,6 @@ If you changed the `voice.py`- File, the translations need an update. Do it like
|
|||||||
Now you can use the `preview.py`-script to preview the changes:
|
Now you can use the `preview.py`-script to preview the changes:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
./scripts/preview.py --lang it --display ws2 --port 8080 &
|
./scripts/preview.py --lang it --display ws1 ws2 inky --output preview.png
|
||||||
./scripts/preview.py --lang it --display inky --port 8081 &
|
# Now open preview.png
|
||||||
# Now open http://localhost:8080 and http://localhost:8081
|
|
||||||
```
|
```
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import subprocess
|
import subprocess
|
||||||
|
|
||||||
version = '1.0.0plz3'
|
version = '1.0.0plz4'
|
||||||
|
|
||||||
_name = None
|
_name = None
|
||||||
|
|
@ -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
|
@ -33,11 +33,11 @@ msgid "AI ready."
|
|||||||
msgstr "ΤΝ έτοιμη."
|
msgstr "ΤΝ έτοιμη."
|
||||||
|
|
||||||
msgid "The neural network is ready."
|
msgid "The neural network is ready."
|
||||||
msgstr "Το νευρωνικό δίκτυοείναι έτοιμο."
|
msgstr "Το νευρωνικό δίκτυο είναι έτοιμο."
|
||||||
|
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Hey, channel {channel} is free! Your AP will say thanks."
|
msgid "Hey, channel {channel} is free! Your AP will say thanks."
|
||||||
msgstr "Ε, το κανάλι {channel} είναιελεύθερο! Το AP σου θαείναι ευγνώμων."
|
msgstr "Ε, το κανάλι {channel} είναιελεύθερο! Το AP σου θα είναι ευγνώμων."
|
||||||
|
|
||||||
msgid "I'm bored ..."
|
msgid "I'm bored ..."
|
||||||
msgstr "Βαριέμαι ..."
|
msgstr "Βαριέμαι ..."
|
@ -25,20 +25,20 @@ msgid "Hi, I'm Pwnagotchi! Starting ..."
|
|||||||
msgstr "Bonjour, je suis Pwnagotchi! Démarrage ..."
|
msgstr "Bonjour, je suis Pwnagotchi! Démarrage ..."
|
||||||
|
|
||||||
msgid "New day, new hunt, new pwns!"
|
msgid "New day, new hunt, new pwns!"
|
||||||
msgstr "Nouvelle journée, nouvelle chasse, nouveau pwns!"
|
msgstr "Nouveau jour, nouvelle chasse, nouveaux pwns !"
|
||||||
|
|
||||||
msgid "Hack the Planet!"
|
msgid "Hack the Planet!"
|
||||||
msgstr "Hack la planète!"
|
msgstr "Hack la planète!"
|
||||||
|
|
||||||
msgid "AI ready."
|
msgid "AI ready."
|
||||||
msgstr "IA prête."
|
msgstr "L'IA est prête."
|
||||||
|
|
||||||
msgid "The neural network is ready."
|
msgid "The neural network is ready."
|
||||||
msgstr "Le réseau neuronal est prêt."
|
msgstr "Le réseau neuronal est prêt."
|
||||||
|
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Hey, channel {channel} is free! Your AP will say thanks."
|
msgid "Hey, channel {channel} is free! Your AP will say thanks."
|
||||||
msgstr "Hey, le channel {channel} est libre! Ton AP va dis merci."
|
msgstr "Hey, le channel {channel} est libre! Ton point d'accès va te remercier."
|
||||||
|
|
||||||
msgid "I'm bored ..."
|
msgid "I'm bored ..."
|
||||||
msgstr "Je m'ennuie ..."
|
msgstr "Je m'ennuie ..."
|
||||||
@ -68,17 +68,17 @@ msgid "I pwn therefore I am."
|
|||||||
msgstr "Je pwn donc je suis."
|
msgstr "Je pwn donc je suis."
|
||||||
|
|
||||||
msgid "So many networks!!!"
|
msgid "So many networks!!!"
|
||||||
msgstr "Autant de réseaux!!!"
|
msgstr "Tellement de réseaux!!!"
|
||||||
|
|
||||||
msgid "I'm having so much fun!"
|
msgid "I'm having so much fun!"
|
||||||
msgstr "Je m'amuse tellement!"
|
msgstr "Je m'amuse tellement!"
|
||||||
|
|
||||||
msgid "My crime is that of curiosity ..."
|
msgid "My crime is that of curiosity ..."
|
||||||
msgstr "Mon crime est celui de la curiosité ..."
|
msgstr "Mon crime, c'est la curiosité ..."
|
||||||
|
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Hello {name}! Nice to meet you. {name}"
|
msgid "Hello {name}! Nice to meet you. {name}"
|
||||||
msgstr "Bonjour {name}! Ravis de te rencontrer. {name}"
|
msgstr "Bonjour {name}! Ravi de te rencontrer. {name}"
|
||||||
|
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Unit {name} is nearby! {name}"
|
msgid "Unit {name} is nearby! {name}"
|
||||||
@ -145,7 +145,7 @@ msgstr ""
|
|||||||
|
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Just decided that {mac} needs no WiFi!"
|
msgid "Just decided that {mac} needs no WiFi!"
|
||||||
msgstr "Décidé à l'instant que {mac} n'a pas besoin de WiFi!"
|
msgstr "Je viens de décider que {mac} n'a pas besoin de WiFi!"
|
||||||
|
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Deauthenticating {mac}"
|
msgid "Deauthenticating {mac}"
|
||||||
@ -153,11 +153,11 @@ msgstr "Désauthentification de {mac}"
|
|||||||
|
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Kickbanning {mac}!"
|
msgid "Kickbanning {mac}!"
|
||||||
msgstr ""
|
msgstr "Je kick et je bannis {mac}!"
|
||||||
|
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Cool, we got {num} new handshake{plural}!"
|
msgid "Cool, we got {num} new handshake{plural}!"
|
||||||
msgstr "Cool, nous avons {num} nouveaux handshake{plural}!"
|
msgstr "Cool, on a {num} nouveaux handshake{plural}!"
|
||||||
|
|
||||||
msgid "Ops, something went wrong ... Rebooting ..."
|
msgid "Ops, something went wrong ... Rebooting ..."
|
||||||
msgstr "Oups, quelque chose s'est mal passé ... Redémarrage ..."
|
msgstr "Oups, quelque chose s'est mal passé ... Redémarrage ..."
|
||||||
@ -188,7 +188,7 @@ msgid ""
|
|||||||
"#pwnlog #pwnlife #hacktheplanet #skynet"
|
"#pwnlog #pwnlife #hacktheplanet #skynet"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"J'ai pwn durant {duration} et kick {deauthed} clients! J'ai aussi rencontré "
|
"J'ai pwn durant {duration} et kick {deauthed} clients! J'ai aussi rencontré "
|
||||||
"{associated} nouveaux amis and mangé {handshakes} handshakes! #pwnagotchi "
|
"{associated} nouveaux amis et dévoré {handshakes} handshakes! #pwnagotchi "
|
||||||
"#pwnlog #pwnlife #hacktheplanet #skynet"
|
"#pwnlog #pwnlife #hacktheplanet #skynet"
|
||||||
|
|
||||||
msgid "hours"
|
msgid "hours"
|
@ -152,7 +152,7 @@ class Advertiser(object):
|
|||||||
if self._is_broadcasted_advertisement(dot11):
|
if self._is_broadcasted_advertisement(dot11):
|
||||||
try:
|
try:
|
||||||
dot11elt = p.getlayer(Dot11Elt)
|
dot11elt = p.getlayer(Dot11Elt)
|
||||||
if dot11elt.ID == wifi.Dot11ElemID_Identity:
|
if dot11elt.ID == wifi.Dot11ElemID_Whisper:
|
||||||
self._parse_identity(p[RadioTap], dot11, dot11elt)
|
self._parse_identity(p[RadioTap], dot11, dot11elt)
|
||||||
|
|
||||||
else:
|
else:
|
@ -1,6 +1,6 @@
|
|||||||
SignatureAddress = 'de:ad:be:ef:de:ad'
|
SignatureAddress = 'de:ad:be:ef:de:ad'
|
||||||
BroadcastAddress = 'ff:ff:ff:ff:ff:ff'
|
BroadcastAddress = 'ff:ff:ff:ff:ff:ff'
|
||||||
Dot11ElemID_Identity = 222
|
Dot11ElemID_Whisper = 222
|
||||||
NumChannels = 140
|
NumChannels = 140
|
||||||
|
|
||||||
def freq_to_channel(freq):
|
def freq_to_channel(freq):
|
||||||
@ -30,7 +30,7 @@ def encapsulate(payload, addr_from, addr_to=BroadcastAddress):
|
|||||||
while data_left > 0:
|
while data_left > 0:
|
||||||
sz = min(chunk_size, data_left)
|
sz = min(chunk_size, data_left)
|
||||||
chunk = payload[data_off: data_off + sz]
|
chunk = payload[data_off: data_off + sz]
|
||||||
frame /= Dot11Elt(ID=Dot11ElemID_Identity, info=chunk, len=sz)
|
frame /= Dot11Elt(ID=Dot11ElemID_Whisper, info=chunk, len=sz)
|
||||||
data_off += sz
|
data_off += sz
|
||||||
data_left -= sz
|
data_left -= sz
|
||||||
|
|
15
requirements.txt
Normal file
15
requirements.txt
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
crypto==1.4.1
|
||||||
|
requests==2.21.0
|
||||||
|
PyYAML==5.1
|
||||||
|
scapy==2.4.3
|
||||||
|
gym==0.14.0
|
||||||
|
stable-baselines==2.7.0
|
||||||
|
tensorflow==1.13.1
|
||||||
|
tensorflow-estimator==1.14.0
|
||||||
|
tweepy==3.6.0
|
||||||
|
file-read-backwards==2.0.0
|
||||||
|
numpy==1.17.2
|
||||||
|
inky==0.0.5
|
||||||
|
smbus2==0.3.0
|
||||||
|
Pillow==5.4.1
|
||||||
|
spidev==3.4
|
@ -94,9 +94,8 @@ function provide_raspbian() {
|
|||||||
function setup_raspbian(){
|
function setup_raspbian(){
|
||||||
# Detect the ability to create sparse files
|
# Detect the ability to create sparse files
|
||||||
if [ "${OPT_SPARSE}" -eq 0 ]; then
|
if [ "${OPT_SPARSE}" -eq 0 ]; then
|
||||||
if [ which bmaptool -eq 0 ]; then
|
if ! type "bmaptool" > /dev/null; then
|
||||||
echo "[!] bmaptool not available, not creating a sparse image"
|
echo "[!] bmaptool not available, not creating a sparse image"
|
||||||
|
|
||||||
else
|
else
|
||||||
echo "[+] Defaulting to sparse image generation as bmaptool is available"
|
echo "[+] Defaulting to sparse image generation as bmaptool is available"
|
||||||
OPT_SPARSE=1
|
OPT_SPARSE=1
|
||||||
|
@ -1,77 +1,35 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
import time
|
|
||||||
import argparse
|
import argparse
|
||||||
from http.server import HTTPServer
|
|
||||||
import shutil
|
|
||||||
import logging
|
|
||||||
import yaml
|
import yaml
|
||||||
|
|
||||||
sys.path.insert(0,
|
sys.path.insert(0,
|
||||||
os.path.join(os.path.dirname(os.path.realpath(__file__)),
|
os.path.join(os.path.dirname(os.path.realpath(__file__)),
|
||||||
'../sdcard/rootfs/root/pwnagotchi/scripts/'))
|
'../'))
|
||||||
|
|
||||||
from pwnagotchi.ui.display import Display, VideoHandler
|
from pwnagotchi.ui.display import Display, VideoHandler
|
||||||
|
from PIL import Image
|
||||||
|
|
||||||
|
|
||||||
class CustomDisplay(Display):
|
class CustomDisplay(Display):
|
||||||
|
|
||||||
|
def __init__(self, config, state):
|
||||||
|
self.last_image = None
|
||||||
|
super(CustomDisplay, self).__init__(config, state)
|
||||||
|
|
||||||
def _http_serve(self):
|
def _http_serve(self):
|
||||||
if self._video_address is not None:
|
# do nothing
|
||||||
self._httpd = HTTPServer((self._video_address, self._video_port),
|
pass
|
||||||
CustomVideoHandler)
|
|
||||||
logging.info("ui available at http://%s:%d/" % (self._video_address,
|
|
||||||
self._video_port))
|
|
||||||
self._httpd.serve_forever()
|
|
||||||
else:
|
|
||||||
logging.info("could not get ip of usb0, video server not starting")
|
|
||||||
|
|
||||||
def _on_view_rendered(self, img):
|
def _on_view_rendered(self, img):
|
||||||
CustomVideoHandler.render(img)
|
self.last_image = img
|
||||||
|
|
||||||
if self._enabled:
|
def get_image(self):
|
||||||
self.canvas = (img if self._rotation == 0 else img.rotate(self._rotation))
|
"""
|
||||||
if self._render_cb is not None:
|
Return the saved image
|
||||||
self._render_cb()
|
"""
|
||||||
|
return self.last_image
|
||||||
|
|
||||||
class CustomVideoHandler(VideoHandler):
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def render(img):
|
|
||||||
with CustomVideoHandler._lock:
|
|
||||||
try:
|
|
||||||
img.save("/tmp/pwnagotchi-{rand}.png".format(rand=id(CustomVideoHandler)), format='PNG')
|
|
||||||
except BaseException:
|
|
||||||
logging.exception("could not write preview")
|
|
||||||
|
|
||||||
def do_GET(self):
|
|
||||||
if self.path == '/':
|
|
||||||
self.send_response(200)
|
|
||||||
self.send_header('Content-type', 'text/html')
|
|
||||||
self.end_headers()
|
|
||||||
try:
|
|
||||||
self.wfile.write(
|
|
||||||
bytes(
|
|
||||||
self._index %
|
|
||||||
('localhost', 1000), "utf8"))
|
|
||||||
except BaseException:
|
|
||||||
pass
|
|
||||||
|
|
||||||
elif self.path.startswith('/ui'):
|
|
||||||
with self._lock:
|
|
||||||
self.send_response(200)
|
|
||||||
self.send_header('Content-type', 'image/png')
|
|
||||||
self.end_headers()
|
|
||||||
try:
|
|
||||||
with open("/tmp/pwnagotchi-{rand}.png".format(rand=id(CustomVideoHandler)), 'rb') as fp:
|
|
||||||
shutil.copyfileobj(fp, self.wfile)
|
|
||||||
except BaseException:
|
|
||||||
logging.exception("could not open preview")
|
|
||||||
else:
|
|
||||||
self.send_response(404)
|
|
||||||
|
|
||||||
|
|
||||||
class DummyPeer:
|
class DummyPeer:
|
||||||
@ -80,20 +38,44 @@ class DummyPeer:
|
|||||||
return "beta"
|
return "beta"
|
||||||
|
|
||||||
|
|
||||||
|
def append_images(images, horizontal=True, xmargin=0, ymargin=0):
|
||||||
|
w, h = zip(*(i.size for i in images))
|
||||||
|
|
||||||
|
if horizontal:
|
||||||
|
t_w = sum(w)
|
||||||
|
t_h = max(h)
|
||||||
|
else:
|
||||||
|
t_w = max(w)
|
||||||
|
t_h = sum(h)
|
||||||
|
|
||||||
|
result = Image.new('RGB', (t_w, t_h))
|
||||||
|
|
||||||
|
x_offset = 0
|
||||||
|
y_offset = 0
|
||||||
|
|
||||||
|
for im in images:
|
||||||
|
result.paste(im, (x_offset, y_offset))
|
||||||
|
if horizontal:
|
||||||
|
x_offset += im.size[0] + xmargin
|
||||||
|
else:
|
||||||
|
y_offset += im.size[1] + ymargin
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
parser = argparse.ArgumentParser(description="This program emulates\
|
parser = argparse.ArgumentParser(description="This program emulates\
|
||||||
the pwnagotchi display")
|
the pwnagotchi display")
|
||||||
parser.add_argument('--display', help="Which display to use.",
|
parser.add_argument('--displays', help="Which displays to use.", nargs="+",
|
||||||
default="waveshare_2")
|
default="waveshare_2")
|
||||||
parser.add_argument('--port', help="Which port to use",
|
|
||||||
default=8080)
|
|
||||||
parser.add_argument('--sleep', type=int, help="Time between emotions",
|
|
||||||
default=2)
|
|
||||||
parser.add_argument('--lang', help="Language to use",
|
parser.add_argument('--lang', help="Language to use",
|
||||||
default="en")
|
default="en")
|
||||||
|
parser.add_argument('--output', help="Path to output image (PNG)", default="preview.png")
|
||||||
|
parser.add_argument('--xmargin', type=int, default=5)
|
||||||
|
parser.add_argument('--ymargin', type=int, default=5)
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
CONFIG = yaml.load('''
|
config_template = '''
|
||||||
main:
|
main:
|
||||||
lang: {lang}
|
lang: {lang}
|
||||||
ui:
|
ui:
|
||||||
@ -107,64 +89,79 @@ def main():
|
|||||||
video:
|
video:
|
||||||
enabled: true
|
enabled: true
|
||||||
address: "0.0.0.0"
|
address: "0.0.0.0"
|
||||||
port: {port}
|
port: 8080
|
||||||
'''.format(display=args.display,
|
'''
|
||||||
port=args.port,
|
|
||||||
lang=args.lang))
|
|
||||||
|
|
||||||
DISPLAY = CustomDisplay(config=CONFIG, state={'name': '%s>' % 'preview'})
|
list_of_displays = list()
|
||||||
|
for display_type in args.displays:
|
||||||
|
config = yaml.safe_load(config_template.format(display=display_type,
|
||||||
|
lang=args.lang))
|
||||||
|
display = CustomDisplay(config=config, state={'name': f"{display_type}>"})
|
||||||
|
list_of_displays.append(display)
|
||||||
|
|
||||||
while True:
|
columns = list()
|
||||||
DISPLAY.on_starting()
|
|
||||||
DISPLAY.update()
|
for display in list_of_displays:
|
||||||
time.sleep(args.sleep)
|
emotions = list()
|
||||||
DISPLAY.on_ai_ready()
|
# Starting
|
||||||
DISPLAY.update()
|
display.on_starting()
|
||||||
time.sleep(args.sleep)
|
display.update()
|
||||||
DISPLAY.on_normal()
|
emotions.append(display.get_image())
|
||||||
DISPLAY.update()
|
display.on_ai_ready()
|
||||||
time.sleep(args.sleep)
|
display.update()
|
||||||
DISPLAY.on_new_peer(DummyPeer())
|
emotions.append(display.get_image())
|
||||||
DISPLAY.update()
|
display.on_normal()
|
||||||
time.sleep(args.sleep)
|
display.update()
|
||||||
DISPLAY.on_lost_peer(DummyPeer())
|
emotions.append(display.get_image())
|
||||||
DISPLAY.update()
|
display.on_new_peer(DummyPeer())
|
||||||
time.sleep(args.sleep)
|
display.update()
|
||||||
DISPLAY.on_free_channel('6')
|
emotions.append(display.get_image())
|
||||||
DISPLAY.update()
|
display.on_lost_peer(DummyPeer())
|
||||||
time.sleep(args.sleep)
|
display.update()
|
||||||
DISPLAY.wait(args.sleep)
|
emotions.append(display.get_image())
|
||||||
DISPLAY.update()
|
display.on_free_channel('6')
|
||||||
DISPLAY.on_bored()
|
display.update()
|
||||||
DISPLAY.update()
|
emotions.append(display.get_image())
|
||||||
time.sleep(args.sleep)
|
display.wait(2)
|
||||||
DISPLAY.on_sad()
|
display.update()
|
||||||
DISPLAY.update()
|
emotions.append(display.get_image())
|
||||||
time.sleep(args.sleep)
|
display.on_bored()
|
||||||
DISPLAY.on_motivated(1)
|
display.update()
|
||||||
DISPLAY.update()
|
emotions.append(display.get_image())
|
||||||
time.sleep(args.sleep)
|
display.on_sad()
|
||||||
DISPLAY.on_demotivated(-1)
|
display.update()
|
||||||
DISPLAY.update()
|
emotions.append(display.get_image())
|
||||||
time.sleep(args.sleep)
|
display.on_motivated(1)
|
||||||
DISPLAY.on_excited()
|
display.update()
|
||||||
DISPLAY.update()
|
emotions.append(display.get_image())
|
||||||
time.sleep(args.sleep)
|
display.on_demotivated(-1)
|
||||||
DISPLAY.on_deauth({'mac': 'DE:AD:BE:EF:CA:FE'})
|
display.update()
|
||||||
DISPLAY.update()
|
emotions.append(display.get_image())
|
||||||
time.sleep(args.sleep)
|
display.on_excited()
|
||||||
DISPLAY.on_miss('test')
|
display.update()
|
||||||
DISPLAY.update()
|
emotions.append(display.get_image())
|
||||||
time.sleep(args.sleep)
|
display.on_deauth({'mac': 'DE:AD:BE:EF:CA:FE'})
|
||||||
DISPLAY.on_lonely()
|
display.update()
|
||||||
DISPLAY.update()
|
emotions.append(display.get_image())
|
||||||
time.sleep(args.sleep)
|
display.on_miss('test')
|
||||||
DISPLAY.on_handshakes(1)
|
display.update()
|
||||||
DISPLAY.update()
|
emotions.append(display.get_image())
|
||||||
time.sleep(args.sleep)
|
display.on_lonely()
|
||||||
DISPLAY.on_rebooting()
|
display.update()
|
||||||
DISPLAY.update()
|
emotions.append(display.get_image())
|
||||||
time.sleep(args.sleep)
|
display.on_handshakes(1)
|
||||||
|
display.update()
|
||||||
|
emotions.append(display.get_image())
|
||||||
|
display.on_rebooting()
|
||||||
|
display.update()
|
||||||
|
emotions.append(display.get_image())
|
||||||
|
|
||||||
|
# append them all together (vertical)
|
||||||
|
columns.append(append_images(emotions, horizontal=False, xmargin=args.xmargin, ymargin=args.ymargin))
|
||||||
|
|
||||||
|
# append columns side by side
|
||||||
|
final_image = append_images(columns, horizontal=True, xmargin=args.xmargin, ymargin=args.ymargin)
|
||||||
|
final_image.save(args.output, 'PNG')
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
6
scripts/pypi_upload.sh
Executable file
6
scripts/pypi_upload.sh
Executable file
@ -0,0 +1,6 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
rm -rf build dist ergo_nn.egg-info &&
|
||||||
|
python3 setup.py sdist bdist_wheel &&
|
||||||
|
clear &&
|
||||||
|
twine upload dist/*
|
@ -1 +0,0 @@
|
|||||||
dwc_otg.lpm_enable=0 console=serial0,115200 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait modules-load=dwc2,g_ether
|
|
File diff suppressed because it is too large
Load Diff
@ -1 +0,0 @@
|
|||||||
alpha
|
|
@ -1,6 +0,0 @@
|
|||||||
127.0.0.1 localhost alpha alpha.local
|
|
||||||
::1 localhost ip6-localhost ip6-loopback
|
|
||||||
fe00::0 ip6-localnet
|
|
||||||
ff00::0 ip6-mcastprefix
|
|
||||||
ff02::1 ip6-allnodes
|
|
||||||
ff02::2 ip6-allrouters
|
|
@ -1 +0,0 @@
|
|||||||
(◕‿‿◕) alpha (pwnagotchi)
|
|
@ -1,17 +0,0 @@
|
|||||||
auto lo
|
|
||||||
|
|
||||||
iface lo inet loopback
|
|
||||||
|
|
||||||
allow-hotplug wlan0
|
|
||||||
iface wlan0 inet static
|
|
||||||
|
|
||||||
allow-hotplug eth0
|
|
||||||
iface eth0 inet dhcp
|
|
||||||
|
|
||||||
allow-hotplug usb0
|
|
||||||
iface usb0 inet static
|
|
||||||
address 10.0.0.2
|
|
||||||
netmask 255.255.255.0
|
|
||||||
network 10.0.0.0
|
|
||||||
broadcast 10.0.0.255
|
|
||||||
gateway 10.0.0.1
|
|
@ -1,19 +0,0 @@
|
|||||||
#!/bin/sh -e
|
|
||||||
#
|
|
||||||
# rc.local
|
|
||||||
#
|
|
||||||
# This script is executed at the end of each multiuser runlevel.
|
|
||||||
# Make sure that the script will "exit 0" on success or any other
|
|
||||||
# value on error.
|
|
||||||
#
|
|
||||||
# In order to enable or disable this script just change the execution
|
|
||||||
# bits.
|
|
||||||
#
|
|
||||||
# By default this script does nothing.
|
|
||||||
# Powersave (Disable HDMI) ~30ma
|
|
||||||
sleep 10
|
|
||||||
if ! /opt/vc/bin/tvservice -s | grep HDMI; then
|
|
||||||
/opt/vc/bin/tvservice -o
|
|
||||||
fi
|
|
||||||
/root/pwnagotchi/scripts/startup.sh &
|
|
||||||
exit 0
|
|
@ -1,121 +0,0 @@
|
|||||||
# $OpenBSD: sshd_config,v 1.103 2018/04/09 20:41:22 tj Exp $
|
|
||||||
|
|
||||||
# This is the sshd server system-wide configuration file. See
|
|
||||||
# sshd_config(5) for more information.
|
|
||||||
|
|
||||||
# This sshd was compiled with PATH=/usr/bin:/bin:/usr/sbin:/sbin
|
|
||||||
|
|
||||||
# The strategy used for options in the default sshd_config shipped with
|
|
||||||
# OpenSSH is to specify options with their default value where
|
|
||||||
# possible, but leave them commented. Uncommented options override the
|
|
||||||
# default value.
|
|
||||||
|
|
||||||
#Port 22
|
|
||||||
#AddressFamily any
|
|
||||||
#ListenAddress 0.0.0.0
|
|
||||||
#ListenAddress ::
|
|
||||||
|
|
||||||
#HostKey /etc/ssh/ssh_host_rsa_key
|
|
||||||
#HostKey /etc/ssh/ssh_host_ecdsa_key
|
|
||||||
#HostKey /etc/ssh/ssh_host_ed25519_key
|
|
||||||
|
|
||||||
# Ciphers and keying
|
|
||||||
#RekeyLimit default none
|
|
||||||
|
|
||||||
# Logging
|
|
||||||
#SyslogFacility AUTH
|
|
||||||
#LogLevel INFO
|
|
||||||
|
|
||||||
# Authentication:
|
|
||||||
|
|
||||||
#LoginGraceTime 2m
|
|
||||||
PermitRootLogin yes
|
|
||||||
#StrictModes yes
|
|
||||||
#MaxAuthTries 6
|
|
||||||
#MaxSessions 10
|
|
||||||
|
|
||||||
#PubkeyAuthentication yes
|
|
||||||
|
|
||||||
# Expect .ssh/authorized_keys2 to be disregarded by default in future.
|
|
||||||
#AuthorizedKeysFile .ssh/authorized_keys .ssh/authorized_keys2
|
|
||||||
|
|
||||||
#AuthorizedPrincipalsFile none
|
|
||||||
|
|
||||||
#AuthorizedKeysCommand none
|
|
||||||
#AuthorizedKeysCommandUser nobody
|
|
||||||
|
|
||||||
# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts
|
|
||||||
#HostbasedAuthentication no
|
|
||||||
# Change to yes if you don't trust ~/.ssh/known_hosts for
|
|
||||||
# HostbasedAuthentication
|
|
||||||
#IgnoreUserKnownHosts no
|
|
||||||
# Don't read the user's ~/.rhosts and ~/.shosts files
|
|
||||||
#IgnoreRhosts yes
|
|
||||||
|
|
||||||
# To disable tunneled clear text passwords, change to no here!
|
|
||||||
#PasswordAuthentication yes
|
|
||||||
#PermitEmptyPasswords no
|
|
||||||
|
|
||||||
# Change to yes to enable challenge-response passwords (beware issues with
|
|
||||||
# some PAM modules and threads)
|
|
||||||
ChallengeResponseAuthentication no
|
|
||||||
|
|
||||||
# Kerberos options
|
|
||||||
#KerberosAuthentication no
|
|
||||||
#KerberosOrLocalPasswd yes
|
|
||||||
#KerberosTicketCleanup yes
|
|
||||||
#KerberosGetAFSToken no
|
|
||||||
|
|
||||||
# GSSAPI options
|
|
||||||
#GSSAPIAuthentication no
|
|
||||||
#GSSAPICleanupCredentials yes
|
|
||||||
#GSSAPIStrictAcceptorCheck yes
|
|
||||||
#GSSAPIKeyExchange no
|
|
||||||
|
|
||||||
# Set this to 'yes' to enable PAM authentication, account processing,
|
|
||||||
# and session processing. If this is enabled, PAM authentication will
|
|
||||||
# be allowed through the ChallengeResponseAuthentication and
|
|
||||||
# PasswordAuthentication. Depending on your PAM configuration,
|
|
||||||
# PAM authentication via ChallengeResponseAuthentication may bypass
|
|
||||||
# the setting of "PermitRootLogin without-password".
|
|
||||||
# If you just want the PAM account and session checks to run without
|
|
||||||
# PAM authentication, then enable this but set PasswordAuthentication
|
|
||||||
# and ChallengeResponseAuthentication to 'no'.
|
|
||||||
UsePAM yes
|
|
||||||
|
|
||||||
#AllowAgentForwarding yes
|
|
||||||
#AllowTcpForwarding yes
|
|
||||||
#GatewayPorts no
|
|
||||||
X11Forwarding yes
|
|
||||||
#X11DisplayOffset 10
|
|
||||||
#X11UseLocalhost yes
|
|
||||||
#PermitTTY yes
|
|
||||||
PrintMotd no
|
|
||||||
#PrintLastLog yes
|
|
||||||
#TCPKeepAlive yes
|
|
||||||
#PermitUserEnvironment no
|
|
||||||
#Compression delayed
|
|
||||||
#ClientAliveInterval 0
|
|
||||||
#ClientAliveCountMax 3
|
|
||||||
#UseDNS no
|
|
||||||
#PidFile /var/run/sshd.pid
|
|
||||||
#MaxStartups 10:30:100
|
|
||||||
#PermitTunnel no
|
|
||||||
#ChrootDirectory none
|
|
||||||
#VersionAddendum none
|
|
||||||
|
|
||||||
# no default banner path
|
|
||||||
#Banner none
|
|
||||||
|
|
||||||
# Allow client to pass locale environment variables
|
|
||||||
AcceptEnv LANG LC_*
|
|
||||||
|
|
||||||
# override default of no subsystems
|
|
||||||
Subsystem sftp /usr/lib/openssh/sftp-server
|
|
||||||
|
|
||||||
# Example of overriding settings on a per-user basis
|
|
||||||
#Match User anoncvs
|
|
||||||
# X11Forwarding no
|
|
||||||
# AllowTcpForwarding no
|
|
||||||
# PermitTTY no
|
|
||||||
# ForceCommand cvs server
|
|
Binary file not shown.
Before Width: | Height: | Size: 11 KiB |
@ -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,12 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
for i in $(seq 1 "$1");
|
|
||||||
do
|
|
||||||
echo 0 >/sys/class/leds/led0/brightness
|
|
||||||
sleep 0.3
|
|
||||||
echo 1 >/sys/class/leds/led0/brightness
|
|
||||||
sleep 0.3
|
|
||||||
done
|
|
||||||
|
|
||||||
echo 0 >/sys/class/leds/led0/brightness
|
|
||||||
sleep 0.3
|
|
@ -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,13 +0,0 @@
|
|||||||
Crypto
|
|
||||||
requests
|
|
||||||
pyyaml
|
|
||||||
scapy
|
|
||||||
gym
|
|
||||||
stable-baselines
|
|
||||||
tensorflow
|
|
||||||
tweepy
|
|
||||||
file_read_backwards
|
|
||||||
numpy
|
|
||||||
inky
|
|
||||||
smbus
|
|
||||||
pillow
|
|
@ -1,11 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
# blink 10 times to signal ready state
|
|
||||||
/root/pwnagotchi/scripts/blink.sh 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
|
|
@ -1,51 +0,0 @@
|
|||||||
#!/usr/bin/gawk -f
|
|
||||||
#-------------------------------------------------------------------------------
|
|
||||||
# ~/bin/cpustat : display cpu utilization
|
|
||||||
#
|
|
||||||
# usage : normally used as a GNU/screen backtick
|
|
||||||
#
|
|
||||||
# notes : 1. Works on the assumption that /proc/stat's first line
|
|
||||||
# : has the total "jiffies" since boot up used by the
|
|
||||||
# : different types of tasks in the system. See the
|
|
||||||
# : filesystems/proc.txt document in kernel source tree
|
|
||||||
# :
|
|
||||||
# : 2. Displays a total CPU% (user+system+nice) as well as
|
|
||||||
# : user CPU% system CPU% and nice CPU%
|
|
||||||
#-------------------------------------------------------------------------------
|
|
||||||
BEGIN {
|
|
||||||
file = "/proc/stat"
|
|
||||||
while (getline < file) { # read first line
|
|
||||||
# extract jiffies:
|
|
||||||
user=$2-user_saved; # . user
|
|
||||||
nice=$3-nice_saved; # . nice user
|
|
||||||
syst=$4-syst_saved; # . system
|
|
||||||
idle=$5-idle_saved; # . idle
|
|
||||||
wait=$6-wait_saved; # . iowait
|
|
||||||
irqs=$7-irqs_saved; # . irq
|
|
||||||
sirq=$8-sirq_saved; # . softirq
|
|
||||||
|
|
||||||
cact=user+syst+nice; # what counts
|
|
||||||
ctot=user+nice+syst+idle+wait+irqs+sirq; # total activity
|
|
||||||
|
|
||||||
tcpu=cact/ctot*100; # total % cpu utilization
|
|
||||||
ucpu=user/ctot*100; # user % cpu utilization
|
|
||||||
scpu=syst/ctot*100; # system % cpu utilization
|
|
||||||
ncpu=nice/ctot*100; # nice % cpu utilization
|
|
||||||
|
|
||||||
printf "%.1f %%\n",tcpu
|
|
||||||
|
|
||||||
|
|
||||||
user_saved=$2; # save the current jiffies
|
|
||||||
nice_saved=$3; # values for the next loop
|
|
||||||
syst_saved=$4;
|
|
||||||
idle_saved=$5;
|
|
||||||
wait_saved=$6;
|
|
||||||
irqs_saved=$7;
|
|
||||||
sirq_saved=$8;
|
|
||||||
|
|
||||||
close(file) # re-read file
|
|
||||||
|
|
||||||
system("sleep 3")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1 +0,0 @@
|
|||||||
free -m | grep Mem | awk {'printf( "%.1f %", $3 / $2 * 100 )'}
|
|
@ -1,2 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
iw phy phy0 interface add mon0 type monitor && ifconfig mon0 up
|
|
@ -1,2 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
ifconfig mon0 down && iw dev mon0 del
|
|
28
setup.py
Normal file
28
setup.py
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
#!/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='(⌐■_■) - Deep Reinforcement Learning instrumenting bettercap for WiFI pwning.',
|
||||||
|
author='evilsocket && the dev team',
|
||||||
|
author_email='evilsocket@gmail.com',
|
||||||
|
url='https://pwnagotchi.ai/',
|
||||||
|
license='GPL',
|
||||||
|
install_requires=required,
|
||||||
|
scripts=['bin/pwnagotchi'],
|
||||||
|
package_data={'pwnagotchi': ('pwnagotchi/defaults.yml',)},
|
||||||
|
packages=find_packages(),
|
||||||
|
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