pull and merge conflict

This commit is contained in:
Justin-p 2019-10-03 23:54:18 +02:00
commit bdda2072cf
18 changed files with 77 additions and 80 deletions

@ -1,23 +1,23 @@
## About the Project
# About the Project
[Pwnagotchi](https://twitter.com/pwnagotchi) is an "AI" that learns from the WiFi environment and instruments
[bettercap](https://www.bettercap.org/) in order to maximize the WPA key material that's being captured either passively
or by performing deauthentication and association attakcs. This material is collected as pcap files containing any form
of handshake supported by [hashcat](https://hashcat.net/hashcat/), including [PMKIDs](https://www.evilsocket.net/2019/02/13/Pwning-WiFi-networks-with-bettercap-and-the-PMKID-client-less-attack/),
[Pwnagotchi](https://twitter.com/pwnagotchi) is an [A2C](https://hackernoon.com/intuitive-rl-intro-to-advantage-actor-critic-a2c-4ff545978752)-based "AI" leveraging [bettercap](https://www.bettercap.org/) that learns from its surrounding WiFi environment in order to maximize the WPA key material it captures (either passively, or by performing deauthentication and association attacks). This material is collected as PCAP files containing any form of handshake supported by [hashcat](https://hashcat.net/hashcat/), including [PMKIDs](https://www.evilsocket.net/2019/02/13/Pwning-WiFi-networks-with-bettercap-and-the-PMKID-client-less-attack/),
full and half WPA handshakes.
![handshake](https://i.imgur.com/pdA4vCZ.png)
Instead of playing [Super Mario or Atari games](https://becominghuman.ai/getting-mario-back-into-the-gym-setting-up-super-mario-bros-in-openais-gym-8e39a96c1e41?gi=c4b66c3d5ced), pwnagotchi will tune over time [its own parameters](https://github.com/evilsocket/pwnagotchi/blob/master/sdcard/rootfs/root/pwnagotchi/config.yml#L54), effectively learning to get better at pwning WiFi things. **Keep in mind:** unlike the usual RL simulations, pwnagotchi learns over time (where a single epoch can last from a few seconds to minutes, depending on how many access points and client stations are visible), do not expect it to perform amazingly well at the beginning, as it'll be exploring several combinations of parameters ... but listen to it when it's bored, bring it with you and have it observe new networks and capture new handshakes and you'll see :)
Instead of merely playing [Super Mario or Atari games](https://becominghuman.ai/getting-mario-back-into-the-gym-setting-up-super-mario-bros-in-openais-gym-8e39a96c1e41?gi=c4b66c3d5ced) like most reinforcement learning based "AI" *(yawn)*, Pwnagotchi tunes [its own parameters](https://github.com/evilsocket/pwnagotchi/blob/master/sdcard/rootfs/root/pwnagotchi/config.yml#L54) over time to **get better at pwning WiFi things** in the environments you expose it to.
Multiple units can talk to each other, advertising their own presence using a parasite protocol I've built on top of the existing dot11 standard, by broadcasting custom information elements. Over time, two or more units learn to cooperate if they detect each other's presence, by dividing the available channels among them.
**Keep in mind:** Unlike the usual RL simulations, Pwnagotchi actually learns over time. Time for a Pwnagotchi is measured in epochs; a single epoch can last from a few seconds to minutes, depending on how many access points and client stations are visible. Do not expect your Pwnagotchi to perform amazingly well at the very beginning, as it will be [exploring](https://hackernoon.com/intuitive-rl-intro-to-advantage-actor-critic-a2c-4ff545978752) several combinations of [key parameters](https://github.com/evilsocket/pwnagotchi/blob/master/docs/usage.md#training-the-ai) to determine ideal adjustments for pwning the particular environment you are exposing it to during its beginning epochs ... but **definitely listen to your pwnagotchi when it tells you it's bored!** Bring it into novel WiFi environments with you and have it observe new networks and capture new handshakes—and you'll see. :)
Multiple units within close physical proximity can "talk" to each other, advertising their own presence to each other by broadcasting custom information elements using a parasite protocol I've built on top of the existing dot11 standard. Over time, two or more units trained together will learn to cooperate upon detecting each other's presence by dividing the available channels among them for optimal pwnage.
![peers](https://i.imgur.com/Ywr5aqx.png)
Depending on the status of the unit, several states and states transitions are configurable and represented on the display as different moods, expressions and sentences.
[Depending on the status of the unit](), several states and states transitions are configurable and represented on the display as different moods, expressions and sentences. Pwnagotchi speaks [many languages](https://github.com/evilsocket/pwnagotchi/blob/master/docs/configure.md#configuration), too!
Of course, it is possible to run your Pwnagotchi with the AI disabled (configurable in `config.yml`). Why might you want to do this? Perhaps you simply want to use your own fixed parameters (instead of letting the AI decide for you), or maybe you want to save battery and CPU cycles, or maybe it's just you have strong concerns about aiding and abetting baby Skynet. Whatever your particular reasons may be: an AI-disabled Pwnagotchi is still a simple and very effective automated deauther, WPA handshake sniffer, and portable [bettercap](https://www.bettercap.org/) + [webui](https://github.com/evilsocket/pwnagotchi/blob/master/docs/usage.md#bettercaps-web-ui) dedicated hardware.
If instead you just want to use your own parameters and save battery and CPU cycles, you can disable the AI in `config.yml` and enjoy an automated deauther, WPA handshake sniffer and portable bettercap + webui dedicated hardware.
## License
`pwnagotchi` is made with ♥ by [@evilsocket](https://twitter.com/evilsocket) and the [amazing dev team](https://github.com/evilsocket/pwnagotchi/graphs/contributors). It's released under the GPL3 license.
`pwnagotchi` is made with ♥ by [@evilsocket](https://twitter.com/evilsocket) and the [amazing dev team](https://github.com/evilsocket/pwnagotchi/graphs/contributors). It's released under the GPL3 license.

@ -1,7 +1,6 @@
### Connecting to your Pwnagotchi
# Connecting to your Pwnagotchi
Once you wrote the image file on the SD card, there're a few steps you'll have to follow in order to configure your unit properly, first, start with connecting the USB cable to the
data port of the Raspberry Pi and the RPi to your computer. After a few seconds the board will boot and you will see a new Ethernet interface on your host computer.
Once you wrote the image file on the SD card, there're a few steps you'll have to follow in order to configure your unit properly, first, start with connecting the USB cable to the data port of the Raspberry Pi and the RPi to your computer. After a few seconds the board will boot and you will see a new Ethernet interface on your host computer.
You'll need to configure it with a static IP address:
@ -26,26 +25,32 @@ Moreover, it is recommended that you copy your SSH public key among the unit's a
ssh-copy-id -i ~/.ssh/id_rsa.pub pi@10.0.0.2
```
### Configuration
## Configuration
You can now set a new name for your unit by [changing the hostname](https://geek-university.com/raspberry-pi/change-raspberry-pis-hostname/). Create the `/root/custom.yml` file (either via SSH or by direclty editing the SD card contents from a computer) that will override
the [default configuration](https://github.com/evilsocket/pwnagotchi/blob/master/sdcard/rootfs/root/pwnagotchi/config.yml) with your custom values.
You can now set a new name for your unit by [changing the hostname](https://geek-university.com/raspberry-pi/change-raspberry-pis-hostname/). Create the `/root/custom.yml` file (either via SSH or by direclty editing the SD card contents from a computer) that will override the [default configuration](https://github.com/evilsocket/pwnagotchi/blob/master/sdcard/rootfs/root/pwnagotchi/config.yml) with your custom values.
## Language Selection
For instance, you can change `main.lang` to one of the supported languages:
* **english** (default)
* german
* dutch
* greek
* macedonian
* italian
* french
- **english** (default)
- german
- dutch
- greek
- macedonian
- italian
- french
The set the type of display you want to use via `ui.display.type` (if your display does not work after changing this setting, you might need to complete remove power from the Raspberry and make a clean boot).
## Display Selection
Set the type of display you want to use via `ui.display.type` (if your display does not work after changing this setting, you might need to completely remove power from the Raspberry and make a clean boot).
You can configure the refresh interval of the display via `ui.fps`, we advise to use a slow refresh to not shorten the lifetime of your display. The default value is 0, which will only refresh when changes are made to the screen.
### Host Connection Share
## Host Connection Share
If you connect to the unit via `usb0` (thus using the data port), you might want to use the `scripts/linux_connection_share.sh` ,
`scripts/macos_connection_share.sh` or `scripts/win_connection_share.ps1` script to bring the interface up on your end and share internet connectivity from another interface, so you can update the unit and generally download things from the internet on it.
If you connect to the unit via `usb0` (thus using the data port), you might want to use the `scripts/linux_connection_share.sh`, `scripts/macos_connection_share.sh` or `scripts/win_connection_share.ps1` script to bring the interface up on your end and share internet connectivity from another interface, so you can update the unit and generally download things from the internet on it.
## Troubleshooting
If your network connection keeps flapping on your device connecting to your pwnagotchi, check if `usb0` (or equivalent) device is being controlled by NetworkManager. You can check this via `nmcli dev status`.

@ -1,4 +1,4 @@
## Software
# Software
- Raspbian + [nexmon patches](https://re4son-kernel.com/re4son-pi-kernel/) for monitor mode, or any Linux with a monitor mode enabled interface (if you tune config.yml).
@ -21,6 +21,7 @@ usage: ./scripts/create_sibling.sh [OPTIONS]
-d # Only run dependencies checks
-h # Show this help
```
## Adding a Language
If you want to add a language use the `language.sh` script. If you want to add for example the language **italian** you would type:

@ -10,4 +10,4 @@ Because Python sucks and TF is huge.
## Why ...?
Because!
Because!

@ -16,4 +16,4 @@
## License
`pwnagotchi` is made with ♥ by [@evilsocket](https://twitter.com/evilsocket) and the [amazing dev team](https://github.com/evilsocket/pwnagotchi/graphs/contributors). It's released under the GPL3 license.
`pwnagotchi` is made with ♥ by [@evilsocket](https://twitter.com/evilsocket) and the [amazing dev team](https://github.com/evilsocket/pwnagotchi/graphs/contributors). It's released under the GPL3 license.

@ -1,7 +1,6 @@
# Installation
The project has been developed to run on a Raspberry Pi 0 W configured as an [USB Ethernet gadget](https://learn.adafruit.com/turning-your-raspberry-pi-zero-into-a-usb-gadget/ethernet-gadget) device in order to connect to it via USB.
However, given the proper configuration tweaks, any GNU/Linux computer with a WiFi interface that supports monitor mode could be used.
The project has been developed to run on a Raspberry Pi 0 W configured as an [USB Ethernet gadget](https://learn.adafruit.com/turning-your-raspberry-pi-zero-into-a-usb-gadget/ethernet-gadget) device in order to connect to it via USB. However, given the proper configuration tweaks, any GNU/Linux computer with a WiFi interface that supports monitor mode could be used.
## Required Hardware
@ -34,9 +33,7 @@ Color displays have a much slower refresh rate, in some cases it can take up to
The easiest way to create a new Pwnagotchi is downloading the latest stable image from [our release page](https://github.com/evilsocket/pwnagotchi/releases) and write it to your SD card. You will need to use an image writing tool to install the image you have downloaded on your SD card.
[balenaEtcher](https://www.balena.io/etcher/) is a graphical SD card writing tool that works on Mac OS, Linux and Windows,
and is the easiest option for most users. balenaEtcher also supports writing images directly from the zip file,
without any unzipping required. To write your image with balenaEtcher:
[balenaEtcher](https://www.balena.io/etcher/) is a graphical SD card writing tool that works on Mac OS, Linux and Windows, and is the easiest option for most users. balenaEtcher also supports writing images directly from the zip file, without any unzipping required. To write your image with balenaEtcher:
- Download the latest [Pwnagotchi .img file](https://github.com/evilsocket/pwnagotchi/releases).
- Download [balenaEtcher](https://www.balena.io/etcher/) and install it.
@ -45,4 +42,4 @@ without any unzipping required. To write your image with balenaEtcher:
- Select the SD card you wish to write your image to.
- Review your selections and click 'Flash!' to begin writing data to the SD card.
Your SD card is now ready for the first boot!
Your SD card is now ready for the first boot!

@ -1,8 +1,7 @@
# Plugins
Pwnagotchi has a simple plugins system that you can use to customize your unit and its behaviour. You can place your plugins anywhere
as python files and then edit the `config.yml` file (`main.plugins` value) to point to their containing folder. Check the [plugins folder](https://github.com/evilsocket/pwnagotchi/tree/master/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/plugins/default/) for a list of default
plugins and all the callbacks that you can define for your own customizations.
as python files and then edit the `config.yml` file (`main.plugins` value) to point to their containing folder. Check the [plugins folder](https://github.com/evilsocket/pwnagotchi/tree/master/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/plugins/default/) for a list of default plugins and all the callbacks that you can define for your own customizations.
Here's as an example the GPS plugin:

@ -1,4 +1,6 @@
### User Interface
# Usage
## User Interface
The UI is available either via display if installed, or via http://pwnagotchi.local:8080/ if you connect to the unit via `usb0` and set a static address on the network interface (change `pwnagotchi` with the hostname of your unit).
@ -10,7 +12,7 @@ The UI is available either via display if installed, or via http://pwnagotchi.lo
* **PWND**: Number of handshakes captured in this session and number of unique networks we own at least one handshake of, from the beginning.
* **AUTO**: This indicates that the algorithm is running with AI disabled (or still loading), it disappears once the AI dependencies have been bootrapped and the neural network loaded.
### Training the AI
## Training the AI
At its core Pwnagotchi is a very simple creature: we could summarize its main algorithm as:
@ -27,7 +29,7 @@ while True:
for client in ap.clients:
# deauthenticate the client to get its half or full handshake
deauthenticate(client)
wait_for_loot()
```
@ -73,14 +75,11 @@ personality:
sad_num_epochs: 25
```
There is no optimal set of parameters for every situation: when the unit is moving (during a walk for instance) smaller timeouts and RSSI thresholds might be preferred
in order to quickly remove routers that are not in range anymore, while when stationary in high density areas (like an office) other parameters might be better.
The role of the AI is to observe what's going on at the WiFi level, and adjust those parameters in order to maximize the cumulative reward of that loop / epoch.
There is no optimal set of parameters for every situation: when the unit is moving (during a walk for instance) smaller timeouts and RSSI thresholds might be preferred in order to quickly remove routers that are not in range anymore, while when stationary in high density areas (like an office) other parameters might be better. The role of the AI is to observe what's going on at the WiFi level, and adjust those parameters in order to maximize the cumulative reward of that loop / epoch.
#### Reward Function
## Reward Function
After each iteration of the main loop (an `epoch`), the reward, a score that represents how well the parameters performed, is computed as
(an excerpt from `pwnagotchi/ai/reward.py`):
After each iteration of the main loop (an `epoch`), the reward, a score that represents how well the parameters performed, is computed as (an excerpt from `pwnagotchi/ai/reward.py`):
```python
# state contains the information of the last epoch
@ -107,15 +106,13 @@ reward = h + a + c + b + i + m
By maximizing this reward value, the AI learns over time to find the set of parameters that better perform with the current environmental conditions.
## BetterCAP's Web UI
### BetterCAP's Web UI
Moreover, given that the unit is running bettercap with API and Web UI, you'll be able to use the unit as a WiFi penetration testing portable station
by accessing `http://pwnagotchi.local/`.
Moreover, given that the unit is running bettercap with API and Web UI, you'll be able to use the unit as a WiFi penetration testing portable station by accessing `http://pwnagotchi.local/`.
![webui](https://raw.githubusercontent.com/bettercap/media/master/ui-events.png)
### Update your Pwnagotchi
## Update your Pwnagotchi
You can use the `scripts/update_pwnagotchi.sh` script to update to the most recent version of pwnagotchi.
@ -132,7 +129,7 @@ usage: ./update_pwnagitchi.sh [OPTIONS]
```
### Backup your Pwnagotchi
## Backup your Pwnagotchi
You can use the `scripts/backup.sh` script to backup the important files of your unit.
@ -140,12 +137,10 @@ You can use the `scripts/backup.sh` script to backup the important files of your
usage: ./scripts/backup.sh HOSTNAME backup.zip
```
### Random Info
- **On a rpi0w, it'll take approximately 30 minutes to load the AI**.
- `/var/log/pwnagotchi.log` is your friend.
- if connected to a laptop via usb data port, with internet connectivity shared, magic things will happen.
- checkout the `ui.video` section of the `config.yml` - if you don't want to use a display, you can connect to it with the browser and a cable.
- If you get `[FAILED] Failed to start Remount Root and Kernel File Systems.` while booting pwnagotchi, make sure
the `PARTUUID`s for `rootfs` and `boot` partitions are the same in `/etc/fstab`. Use `sudo blkid` to find those values when you are using `create_sibling.sh`.
## Random Info
* **On a rpi0w, it'll take approximately 30 minutes to load the AI**.
* `/var/log/pwnagotchi.log` is your friend.
* if connected to a laptop via usb data port, with internet connectivity shared, magic things will happen.
* checkout the `ui.video` section of the `config.yml` - if you don't want to use a display, you can connect to it with the browser and a cable.
* If you get `[FAILED] Failed to start Remount Root and Kernel File Systems.` while booting pwnagotchi, make sure the `PARTUUID`s for `rootfs` and `boot` partitions are the same in `/etc/fstab`. Use `sudo blkid` to find those values when you are using `create_sibling.sh`.

@ -3,7 +3,11 @@ main:
# currently implemented: en (default), de, nl, it
lang: en
# custom plugins path, if null only default plugins with be loaded
plugins: null
custom_plugins:
# which plugins to load and enable
plugins:
- gps
- twitter
# monitor interface to use
iface: mon0
# command to run to bring the mon interface up in case it's not up already
@ -15,7 +19,9 @@ main:
# if true, will not restart the wifi module
no_restart: false
# access points to ignore
whitelist: []
whitelist:
- EXAMPLE_NETWORK
- ANOTHER_EXAMPLE_NETWORK
# if not null, filter access points by this regular expression
filter: null
# cryptographic key for identity

@ -1,5 +1,4 @@
#!/usr/bin/python3
import os
import argparse
import time
import logging
@ -33,9 +32,9 @@ args = parser.parse_args()
config = utils.load_config(args)
utils.setup_logging(args, config)
plugins.load_from_path(plugins.default_path)
if 'plugins' in config['main'] and config['main']['plugins'] is not None:
plugins.load_from_path(config['main']['plugins'])
plugins.load_from_path(plugins.default_path, enabled=config['main']['plugins'])
if 'custom_plugins' in config['main'] and config['main']['custom_plugins'] is not None:
plugins.load_from_path(config['main']['custom_plugins'], enabled=config['main']['plugins'])
plugins.on('loaded')

@ -27,14 +27,13 @@ def load_from_file(filename):
return plugin_name, instance
def load_from_path(path):
def load_from_path(path, enabled=()):
global loaded
for filename in glob.glob(os.path.join(path, "*.py")):
name, plugin = load_from_file(filename)
if name in loaded:
raise Exception("plugin %s already loaded from %s" % (name, plugin.__file__))
elif not plugin.__enabled__:
elif name not in enabled:
# print("plugin %s is not enabled" % name)
pass
else:

@ -3,7 +3,6 @@ __version__ = '1.0.0'
__name__ = 'hello_world'
__license__ = 'GPL3'
__description__ = 'An example plugin for pwnagotchi that implements all the available callbacks.'
__enabled__ = False # IMPORTANT: set this to True to enable your plugin.
import logging

@ -3,7 +3,6 @@ __version__ = '1.0.0'
__name__ = 'gps'
__license__ = 'GPL3'
__description__ = 'Save GPS coordinates whenever an handshake is captured.'
__enabled__ = True # set to false if you just don't use GPS
import logging
import json

@ -7,7 +7,6 @@ __version__ = '1.0.0'
__name__ = 'memtemp'
__license__ = 'GPL3'
__description__ = 'A plugin that will add a memory and temperature indicator'
__enabled__ = False
import struct

@ -3,7 +3,6 @@ __version__ = '1.0.0'
__name__ = 'twitter'
__license__ = 'GPL3'
__description__ = 'This plugin creates tweets about the recent activity of pwnagotchi'
__enabled__ = True
import logging
from pwnagotchi.voice import Voice

@ -12,7 +12,6 @@ __version__ = '1.0.0'
__name__ = 'ups_lite'
__license__ = 'GPL3'
__description__ = 'A plugin that will add a voltage indicator for the UPS Lite v1.1'
__enabled__ = False
import struct

@ -3,7 +3,6 @@ __version__ = '1.0.0'
__name__ = 'wpa_sec'
__license__ = 'GPL3'
__description__ = 'This plugin automatically uploades handshakes to https://wpa-sec.stanev.org'
__enabled__ = False
import os
import logging
@ -13,6 +12,7 @@ READY = False
API_KEY = None
ALREADY_UPLOADED = None
# INSTALLATION:
## apt-get install libcurl4-openssl-dev
## https://github.com/ZerBea/hcxtools.git
@ -51,6 +51,7 @@ def _upload_to_wpasec(path):
logging.error(f"WPA_SEC: Error while uploading {path}")
raise os_e
# called in manual mode when there's internet connectivity
def on_internet_available(display, config, log):
if READY:
@ -60,12 +61,12 @@ def on_internet_available(display, config, log):
handshake_paths = [os.path.join(handshake_dir, filename) for filename in handshake_filenames]
handshake_new = set(handshake_paths) - set(ALREADY_UPLOADED)
if handhake_new:
if handshake_new:
logging.info("Internet connectivity detected.\
Uploading new handshakes to wpa-sec.stanev.org")
for idx, handshake in enumerate(handshake_new):
display.set('status', f"Uploading handshake to wpa-sec.stanev.org ({idx + 1}/{len(handshake_new})")
display.set('status', "Uploading handshake to wpa-sec.stanev.org ({idx + 1}/{len(handshake_new})")
display.update(force=True)
try:
_upload_to_wpasec(handshake)

@ -86,8 +86,8 @@ class View(object):
'face': Text(value=faces.SLEEP, position=face_pos, color=BLACK, font=fonts.Huge),
'friend_face': Text(value=None, position=(0, 90), font=fonts.Bold, color=BLACK),
'friend_name': Text(value=None, position=(40, 93), font=fonts.BoldSmall, color=BLACK),
'friend_face': Text(value=None, position=(0, (self._height * 0.88) - 15 ), font=fonts.Bold, color=BLACK),
'friend_name': Text(value=None, position=(40,(self._height * 0.88) - 13 ), font=fonts.BoldSmall, color=BLACK),
'name': Text(value='%s>' % 'pwnagotchi', position=name_pos, color=BLACK, font=fonts.Bold),