### Initialize and Start Pwnagotchi Agent Source: https://context7.com/jayofelony/pwnagotchi/llms.txt This snippet shows how to load configuration, initialize the Display, KeyPair, and Agent, and then start the agent. The agent handles setup, event handling, and monitor mode activation. ```python config = { 'main': {'iface': 'wlan0mon', 'no_restart': False, 'whitelist': [], 'mon_start_cmd': '/usr/bin/monstart', 'mon_max_blind_epochs': 5, 'plugins': {}}, 'bettercap': {'hostname': '127.0.0.1', 'scheme': 'http', 'port': 8081, 'username': 'pwnagotchi', 'password': 'pwnagotchi', 'handshakes': '/etc/pwnagotchi/handshakes', 'silence': ['wifi.ap.new', 'wifi.ap.lost']}, 'personality': {'associate': True, 'deauth': True, 'channels': [], 'min_rssi': -200, 'recon_time': 30, 'hop_recon_time': 10, 'min_recon_time': 5, 'max_interactions': 3, 'max_misses_for_recon': 5, 'ap_ttl': 120, 'sta_ttl': 300, 'max_inactive_scale': 2, 'recon_inactive_multiplier': 2, 'throttle_a': 0.4, 'throttle_d': 0.9, 'excited_num_epochs': 10, 'bored_num_epochs': 15, 'sad_num_epochs': 25, 'bond_encounters_factor': 20000}, 'ui': {'web': {'enabled': True, 'address': '::', 'port': 8080, 'auth': False, 'on_frame': ''}, 'display': {'enabled': False, 'rotation': 180, 'type': 'waveshare_4'}, 'fps': 0.0, 'faces': {}} } display = Display(config=config, state={'name': 'pwnagotchi>' agent = Agent(view=display, config=config, keypair=KeyPair(view=display)) # Start the agent (waits for bettercap, sets up events, starts monitor mode) agent.start() ``` -------------------------------- ### Enable and Start Pwnagotchi Services Source: https://github.com/jayofelony/pwnagotchi/wiki/Step-1-Installation-for-other-boards Enables the Pwnagotchi, Bettercap, and Pwngrid services to start on boot and starts them immediately. ```bash sudo systemctl enable --now bettercap pwngrid-peer pwnagotchi ``` -------------------------------- ### Install pwngrid Source: https://github.com/jayofelony/pwnagotchi/wiki/Step-1-Installation-for-other-boards Downloads and installs the pwngrid utility, a peer-to-peer discovery and communication tool. ```bash wget "https://github.com/evilsocket/pwngrid/releases/download/v1.10.3/pwngrid_linux_aarch64_v1.10.3.zip" ``` ```bash unzip pwngrid_linux_aarch64_v1.10.3.zip ``` ```bash sudo mv pwngrid /usr/bin/ ``` -------------------------------- ### Pwnagotchi Custom Plugin Example Source: https://context7.com/jayofelony/pwnagotchi/llms.txt A comprehensive example of a custom Pwnagotchi plugin demonstrating various callback functions for different events like loading, UI setup, and data updates. Access plugin configuration from /etc/pwnagotchi/config.toml. ```python import logging import pwnagotchi.plugins as plugins from pwnagotchi.ui.components import LabeledValue from pwnagotchi.ui.view import BLACK import pwnagotchi.ui.fonts as fonts class MyPlugin(plugins.Plugin): __author__ = 'you@example.com' __version__ = '1.0.0' __license__ = 'GPL3' __description__ = 'Example custom plugin.' def __init__(self): self.options = dict() def on_loaded(self): # Access plugin config from /etc/pwnagotchi/config.toml: # [main.plugins.myplugin] # enabled = true # my_option = "hello" logging.info("myplugin loaded, options: %s" % self.options) def on_ui_setup(self, ui): ui.add_element('myplugin', LabeledValue( color=BLACK, label='MP', value='--', position=(0, 95), label_font=fonts.Bold, text_font=fonts.Medium )) def on_ui_update(self, ui): ui.set('myplugin', 'ok') def on_unload(self, ui): with ui._lock: ui.remove_element('myplugin') def on_ready(self, agent): # Run a bettercap command on startup agent.run('set wifi.rssi.min -80') def on_handshake(self, agent, filename, access_point, client_station): # access_point and client_station are dicts with mac, hostname, vendor, # channel, rssi (if matched) or plain MAC strings logging.info("New handshake: %s -> %s saved to %s" % ( client_station['mac'] if isinstance(client_station, dict) else client_station, access_point['hostname'] if isinstance(access_point, dict) else access_point, filename )) def on_wifi_update(self, agent, access_points): # access_points: list of dicts with keys: # mac, hostname, vendor, channel, rssi, encryption, clients for ap in access_points: logging.debug("AP: %s (%s) ch=%d rssi=%d enc=%s clients=%d" % ( ap['hostname'], ap['mac'], ap['channel'], ap['rssi'], ap['encryption'], len(ap['clients']) )) def on_epoch(self, agent, epoch, epoch_data): # epoch_data keys: epoch, duration, missed, assoc, deauth, # handshakes, hops, peers, sleep logging.info("Epoch %d: %d handshakes, %d assoc, %d deauth" % ( epoch, epoch_data.get('handshakes', 0), epoch_data.get('assoc', 0), epoch_data.get('deauth', 0) )) def on_internet_available(self, agent): # Called when pwngrid confirms internet connectivity pass def on_peer_detected(self, agent, peer): logging.info("Peer detected: %s" % peer) def on_peer_lost(self, agent, peer): logging.info("Peer lost: %s" % peer) def on_webhook(self, path, request): # Accessible at http://:8080/plugins/myplugin/ from flask import render_template_string return render_template_string('

MyPlugin Webhook

path={{ path }}

', path=path) ``` -------------------------------- ### Install bettercap from Source Source: https://github.com/jayofelony/pwnagotchi/wiki/Step-1-Installation-for-other-boards Downloads, unzips, compiles, and installs the bettercap network analysis tool from its source code. ```bash wget https://github.com/bettercap/bettercap/archive/refs/tags/v2.32.0.zip ``` ```bash unzip v2.32.0.zip ``` ```bash cd better* ``` ```bash make build ``` ```bash sudo mv bettercap /usr/bin/ ``` -------------------------------- ### Setup pwnlib Script Source: https://github.com/jayofelony/pwnagotchi/wiki/Step-1-Installation-for-other-boards Downloads the pwnlib script from a GitHub URL and saves it to /usr/bin/pwnlib. This script contains helper functions for managing monitor interfaces. ```bash sudo wget https://raw.githubusercontent.com/evilsocket/pwnagotchi/refs/heads/master/builder/data/usr/bin/pwnlib -O /usr/bin/pwnlib ``` -------------------------------- ### Install PwnDroid Plugin Source: https://github.com/jayofelony/pwnagotchi/wiki/Step-4-Customization Use these commands to install the PwnDroid plugin for sharing GPS data with your Pwnagotchi. ```bash sudo pwnagotchi plugins update sudo pwnagotchi plugins install pwndroid ``` -------------------------------- ### Install Go Programming Language Source: https://github.com/jayofelony/pwnagotchi/wiki/Step-1-Installation-for-other-boards Downloads and installs the Go programming language (version 1.20.2 for arm64). It also adds the Go binary directory to the system's PATH. ```bash wget https://go.dev/dl/go1.20.2.linux-arm64.tar.gz ``` ```bash sudo tar -C /usr/local -xzf go1.20.2.linux-arm64.tar.gz ``` ```bash export PATH=$PATH:/usr/local/go/bin/ ``` ```bash source .bashrc ``` -------------------------------- ### Install usb-modeswitch for Dual State Adapters Source: https://github.com/jayofelony/pwnagotchi/wiki/Step-1-Installation-for-other-boards Installs the usb-modeswitch utility, which is necessary for certain dual-state Wi-Fi adapters to function correctly. It may require manual mode switching. ```bash sudo apt install usb-modeswitch ``` ```bash sudo usb_modeswitch -K -W -v 0e8d -p 2870 ``` -------------------------------- ### Install Pwnagotchi Package Source: https://github.com/jayofelony/pwnagotchi/wiki/Step-1-Installation-for-other-boards Clone the Pwnagotchi repository and install it using pip. The `--break-system-packages` flag is used to install packages outside of the system's default package manager. ```bash git clone https://github.com/jayofelony/pwnagotchi cd pwnagotchi sudo pip install . --break-system-packages ``` -------------------------------- ### Install Avahi Daemon on Linux Source: https://github.com/jayofelony/pwnagotchi/wiki/Step-2-Connecting Install necessary packages for Avahi daemon and discovery on your host Linux PC to enable hostname resolution. ```bash sudo apt update && sudo apt install avahi-daemon avahi-discover ``` -------------------------------- ### Create Monitor Mode Start Script Source: https://github.com/jayofelony/pwnagotchi/wiki/Step-1-Installation-for-other-boards Creates a bash script named 'monstart' that sources the 'pwnlib' script and calls the 'start_monitor_interface' function to enable monitor mode on a Wi-Fi interface. ```bash sudo bash -c 'cat > /usr/bin/monstart' << EOF #!/bin/bash source /usr/bin/pwnlib start_monitor_interface EOF ``` -------------------------------- ### Configure pwngrid Systemd Service Source: https://github.com/jayofelony/pwnagotchi/wiki/Step-1-Installation-for-other-boards Sets up the pwngrid systemd service, enabling it to start on boot. It also conditionally disables the service and its dependency in the bettercap service if PWN_GRID is not set. ```bash if ! $PWN_GRID then sudo systemctl stop pwngrid-peer.service sudo systemctl disable pwngrid-peer.service ## disable dependency in bettercap service launch script sudo bash -c "sed -i 's/^After=pwngrid.service/#After=pwngrid.service/g' /etc/systemd/system/bettercap.service" else sudo systemctl enable pwngrid-peer.service fi ``` -------------------------------- ### Start and Stop Monitor Interface using airmon-ng Source: https://github.com/jayofelony/pwnagotchi/wiki/Step-1-Installation-for-other-boards Use these commands to start and stop the monitor interface with airmon-ng. Ensure you replace 'wlx40a5ef2f05b7' and 'wlan1mon' with your actual interface names. ```bash start_monitor_interface() { airmon-ng start wlx40a5ef2f05b7 } stop_monitor_interface() { airmon-ng stop wlan1mon } ``` -------------------------------- ### Install Pwnagotchi Core Dependencies Source: https://github.com/jayofelony/pwnagotchi/wiki/Step-1-Installation-for-other-boards Installs essential packages required for Pwnagotchi, including git, Python 3, build tools, and networking utilities. ```bash sudo apt install -y git python3-pip python3-smbus libusb-1.0-0-dev build-essential dkms tcpdump unzip lsof python3-pil fonts-dejavu-core libnetfilter-queue-dev aircrack-ng python3-prctl ``` -------------------------------- ### Quick Font Download Setup (Linux/macOS) Source: https://github.com/jayofelony/pwnagotchi/blob/noai/pwnagotchi/ui/web/static/fonts/README.md This command-line snippet downloads the TrueType font file directly from a GitHub repository using wget. It assumes you are in the correct directory. ```bash cd static/fonts wget https://github.com/google/fonts/raw/main/ofl/vt323/VT323-Regular.ttf ``` -------------------------------- ### Install Mediatek Firmware Source: https://github.com/jayofelony/pwnagotchi/wiki/Step-1-Installation-for-other-boards Installs the necessary firmware for Mediatek Wi-Fi chipsets. This is often required for proper operation of these adapters. ```bash sudo apt install firmware-mediatek ``` -------------------------------- ### Pwnagotchi Auto-Update Plugin Functions Source: https://context7.com/jayofelony/pwnagotchi/llms.txt Utilize functions from the auto-update plugin to check for new releases and install them. The 'check' function returns information about available updates, while 'install' handles the download, verification, and installation process. ```python from pwnagotchi.plugins.default.auto_update import check, install # Check for a newer release on GitHub info = check( version="2.9.5.5", repo="jayofelony/pwnagotchi", native=False, # False = Python package (pip), True = native binary token="" # optional GitHub token ) # Returns: # {'repo': 'jayofelony/pwnagotchi', 'current': '2.9.5.5', # 'available': '2.9.6.0', 'url': 'https://github.com/.../v2.9.6.0.zip', # 'native': False, 'arch': 'aarch64'} # url is None if no update is available # Check native bettercap binary (architecture-aware asset selection) info = check( version="2.32.0", repo="jayofelony/bettercap", native=True ) # Selects the correct .zip asset for armhf or aarch64 # Install an update (download → SHA256 verify → pip install / service swap) info['service'] = 'pwnagotchi' success = install(display=agent.view(), update=info) # For native=True: stops service, replaces binary at `which bettercap`, restarts service # For native=False: activates venv and runs pip install on the extracted source # Parse version string from a CLI command from pwnagotchi.plugins.default.auto_update import parse_version ver = parse_version('bettercap -version') # e.g. "2.32.0" ``` -------------------------------- ### Install Older libpcap Version Source: https://github.com/jayofelony/pwnagotchi/wiki/Step-1-Installation-for-other-boards Downloads and installs an older version of libpcap (1.9.1) to avoid compatibility issues with newer versions (1.10.x) that may be present in some repositories. ```bash wget http://old.kali.org/kali/pool/main/libp/libpcap/libpcap0.8_1.9.1-4_arm64.deb ``` ```bash sudo dpkg -i libpcap0.8_1.9.1-4_arm64.deb ``` -------------------------------- ### Configure Auto-Update Plugin in TOML Source: https://context7.com/jayofelony/pwnagotchi/llms.txt Enable and configure the auto-update plugin in the Pwnagotchi TOML configuration file. Set 'install' to false to only receive notifications. ```toml # /etc/pwnagotchi/config.toml [main.plugins.auto-update] enabled = true install = true # set false to only notify without installing interval = 1 # check every N hours token = "" # optional GitHub personal access token (avoids rate limits) ``` -------------------------------- ### Update System Packages Source: https://github.com/jayofelony/pwnagotchi/wiki/Step-1-Installation-for-other-boards Ensures your system's package list is up-to-date and all installed packages are upgraded to their latest versions. ```bash sudo apt update && sudo apt upgrade -y ``` -------------------------------- ### WPA-SEC Plugin Download Results Source: https://context7.com/jayofelony/pwnagotchi/llms.txt Demonstrates how the WPA-SEC plugin fetches cracked password results from wpa-sec.stanev.org using a GET request. The results are saved to a local .potfile. ```python import requests result = requests.get( "https://wpa-sec.stanev.org/?api&dl=1", cookies={'key': 'YOUR_API_KEY'}, timeout=30 ) # Saved to /etc/pwnagotchi/handshakes/wpa-sec.cracked.potfile # Format: bssid:station_mac:ssid:password # With single_files=true, also writes: # /etc/pwnagotchi/handshakes/NetworkName_BSSID.pcap.cracked (contains password) ``` -------------------------------- ### Manual Git Commit Sign-off Example Source: https://github.com/jayofelony/pwnagotchi/blob/noai/CONTRIBUTING.md Append this line to your git commit message to manually sign off your contribution. This certifies that you have the right to submit the work under the project's open source license. ```text Signed-off-by: Joe Smith ``` -------------------------------- ### Create Pwngrid Systemd Service Source: https://github.com/jayofelony/pwnagotchi/wiki/Step-1-Installation-for-other-boards This configuration file sets up the Pwngrid peer service using systemd. It specifies the command to run, logging, and restart behavior. Replace 'wlan1mon' with your monitor interface. ```bash sudo bash -c 'cat > /etc/systemd/system/pwngrid-peer.service' << EOF [Unit] Description=pwngrid peer service. Documentation=https://pwnagotchi.ai Wants=network.target [Service] Type=simple PermissionsStartOnly=true ExecStart=/usr/bin/pwngrid -keys /etc/pwnagotchi -address 127.0.0.1:8666 -client-token /root/.api-enrollment.json -wait -log /var/log/pwngrid-peer.log -iface wlan1mon Restart=always RestartSec=30 [Install] WantedBy=multi-user.target EOF ``` -------------------------------- ### Create Bettercap Launcher Script Source: https://github.com/jayofelony/pwnagotchi/wiki/Step-1-Installation-for-other-boards This script launches Bettercap, checking for network interfaces and determining whether to run in auto or manual mode based on the presence of a specific override file. Replace 'wlan1mon' with your monitor interface. ```bash sudo bash -c 'cat > /usr/bin/bettercap-launcher' << EOF #!/usr/bin/env bash /usr/bin/monstart if [[ \".$(ifconfig | grep usb0 | grep RUNNING)\" != "." ]] || [[ \".$(cat /sys/class/net/eth0/carrier)\" != "." ]]; then # if override file exists, go into auto mode if [ -f /root/.pwnagotchi-auto ]; then /usr/bin/bettercap -no-colors -caplet pwnagotchi-auto -iface wlan1mon else /usr/bin/bettercap -no-colors -caplet pwnagotchi-manual -iface wlan1mon fi else /usr/bin/bettercap -no-colors -caplet pwnagotchi-auto -iface wlan1mon fi EOF ``` -------------------------------- ### Configure PwnDroid Plugin Source: https://github.com/jayofelony/pwnagotchi/wiki/Step-4-Customization Enable and configure the PwnDroid plugin in your Pwnagotchi configuration file. ```toml [main.plugins.pwndroid] enabled = true display = false # show coords on display display_altitude = false # show altitude on display gateway = "" # defaults to 192.168.44.1 ``` -------------------------------- ### Upgrade PwnDroid Plugin Source: https://github.com/jayofelony/pwnagotchi/wiki/Step-4-Customization Run these commands to update the PwnDroid plugin to the latest version. ```bash sudo pwnagotchi plugins update sudo pwnagotchi plugins upgrade pwndroid ``` -------------------------------- ### Create Pwnagotchi Systemd Service Source: https://github.com/jayofelony/pwnagotchi/wiki/Step-1-Installation-for-other-boards This configuration file sets up Pwnagotchi as a systemd service, defining its description, dependencies, execution parameters, and restart behavior. ```bash sudo bash -c 'cat > /etc/systemd/system/pwnagotchi.service' << EOF [Unit] Description=pwnagotchi Deep Reinforcement Learning instrumenting bettercap for WiFI pwning. Documentation=https://pwnagotchi.ai Wants=network.target After=pwngrid-peer.service [Service] Type=simple WorkingDirectory=/tmp PermissionsStartOnly=true ExecStart=/usr/bin/pwnagotchi-launcher Restart=always RestartSec=30 TasksMax=infinity LimitNPROC=infinity StandardOutput=null StandardError=null [Install] WantedBy=multi-user.target EOF ``` -------------------------------- ### Make Bettercap Launcher Executable Source: https://github.com/jayofelony/pwnagotchi/wiki/Step-1-Installation-for-other-boards Grants execute permissions to the Bettercap launcher script. ```bash sudo chmod u+x /usr/bin/bettercap-launcher ``` -------------------------------- ### Manage Pwnagotchi Agent Modules Source: https://context7.com/jayofelony/pwnagotchi/llms.txt This snippet demonstrates how to manage modules within the Pwnagotchi agent. You can check if a module is running, start a new module, or restart an existing one. ```python # Module management running = agent.is_module_running('wifi') # bool agent.start_module('wifi.recon') agent.restart_module('wifi.recon') ``` -------------------------------- ### Pwnagotchi Web UI Configuration Source: https://context7.com/jayofelony/pwnagotchi/llms.txt Enable and configure the Pwnagotchi web interface, including the listening address, port, and authentication credentials. ```toml [ui.web] enabled = true address = "::" # "::" = IPv4+IPv6; "0.0.0.0" = IPv4 only port = 8080 auth = true username = "admin" password = "s3cr3t" ``` -------------------------------- ### Copy Default Configuration Source: https://github.com/jayofelony/pwnagotchi/wiki/Step-1-Installation-for-other-boards Copies the default Pwnagotchi configuration file to the system's configuration directory. Remember to edit this file to set your monitor interface. ```bash sudo cp /usr/local/lib/python3.11/dist-packages/pwnagotchi/defaults.toml /etc/pwnagotchi/config.toml ``` -------------------------------- ### Custom Plugin: Manual Mood Transitions and Activity Checks Source: https://context7.com/jayofelony/pwnagotchi/llms.txt This Python code demonstrates how to create a custom Pwnagotchi plugin. It shows how to manually trigger mood transitions based on handshake counts and how to check for agent activity like staleness or any new associations/deauths. ```python # Automata methods are called automatically by Agent.next_epoch() # but can also be called directly from plugins: class MyPlugin(plugins.Plugin): def on_epoch(self, agent, epoch, epoch_data): # Manually trigger mood transitions if needed if epoch_data.get('handshakes', 0) > 10: agent.set_excited() # Check current activity if agent.is_stale(): # Too many missed interactions, recon may be failing pass if agent.any_activity(): # At least one association or deauth happened this epoch pass # Wait (fires on_wait / on_sleep plugin events + view update) agent.wait_for(5, sleeping=False) # waiting (not sleeping) agent.wait_for(30, sleeping=True) # sleeping ``` -------------------------------- ### Configure BT-Tether Plugin Source: https://github.com/jayofelony/pwnagotchi/wiki/Step-4-Customization Enable and customize the BT-Tether plugin for on-the-go internet connectivity via Bluetooth. ```toml [main.plugins.bt-tether] enabled = true # Enable the plugin # Display Settings show_on_screen = true # Master switch: enable/disable all on-screen display (default: true) show_mini_status = true # Show compact mini status indicator (single letter) (default: true) mini_status_position = [110, 0] # Position [x, y] for mini status (default: [110, 0]) show_detailed_status = true # Show detailed status line with IP (default: true) detailed_status_position = [0, 82] # Position for detailed status (default: [0, 82]) # Auto-Reconnect Settings auto_reconnect = true # Automatically reconnect when connection drops (default: true) reconnect_interval = 60 # Check connection every N seconds (default: 60) reconnect_failure_cooldown = 300 # Cooldown after max failures in seconds (default: 300 = 5 minutes) ``` -------------------------------- ### Initialize Leaflet Map and Layers Source: https://github.com/jayofelony/pwnagotchi/blob/noai/pwnagotchi/plugins/default/webgpsmap.html Sets up the Leaflet map instance with two base layers (Esri World Imagery and CartoDB Dark Matter) for a dark visual theme. It also includes controls for scale and user location, and a button for downloading the map offline. ```javascript function firstMapLoad() { // Create the map map = L.map('mapdiv', {attributionControl:false}); // Set the map base theme (from https://leaflet-extras.github.io/leaflet-providers/preview/) // Use 2 layers with alpha for a nice dark style var Esri_WorldImagery = L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', { attribution: 'Tiles © Esri — Source: Esri, i-cubed, USDA, USGS, AEX, GeoEye, Getmapping, Aerogrid, IGN, IGP, UPR-EGP, and the GIS User Community', maxNativeZoom: 19, maxZoom: 21, }); var CartoDB_DarkMatter = L.tileLayer('https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}{r}.png', { attribution: '© OpenStreetMap contributors © CARTO', subdomains: 'abcd', opacity:0.7, maxNativeZoom: 19, maxZoom: 21, }); Esri_WorldImagery.addTo(map); CartoDB_DarkMatter.addTo(map); // Draw positions on the map drawPositions(); // Add the scale to the map L.control.scale().addTo(map); // Add current user location to the map (only if the current page is a considered a secure origin by the browser) if ("isSecureContext" in window && window.isSecureContext) { L.control.locate({ icon: "fa fa-solid fa-location-arrow", locateOptions: { enableHighAccuracy: true } }).addTo(map); } // Add "download map for offline usage" button to the map (only if not already offline) if (!offlinePositions) { L.easyButton('fa-solid fa-download', function(btn, map){ window.open("/plugins/webgpsmap/offlinemap", '\_blank'); }).addTo(map); } // Handle search (filter) events if ("onsearch" in window) { document.getElementById("search").addEventListener("search", function(e) { drawPositions(); }); } else { document.getElementById("search").addEventListener("keyup", function(e) { if (e.key === "Enter") { drawPositions(); } }); } // Handle map popup open events map.on('popupopen', function(e) { var key = e.popup.markerKey; // Draw an accuracy circle around the AP if (typeof key !== "undefined" && "acc" in positions[key] && positions[key].acc) { var radius = Math.round(Math.min(positions[key].acc, 500)); var markerColor = 'red'; var markerColorCode = '#f03'; if (positions[key].pass) { markerColor = 'green'; markerColorCode = '#1aff00'; } var markerPos ``` -------------------------------- ### Read System State and Control Device Lifecycle with pwnagotchi Source: https://context7.com/jayofelony/pwnagotchi/llms.txt Utilities for reading system statistics like name, version, uptime, memory, CPU load, and temperature. Also includes functions for graceful device lifecycle control such as restart, reboot, and shutdown. ```python import pwnagotchi # Read device identity and system stats print(pwnagotchi.name()) # e.g. "pwnagotchi" print(pwnagotchi.__version__) # e.g. "2.9.5.5" print(pwnagotchi.uptime()) # seconds since boot, e.g. 3742 print(pwnagotchi.mem_usage()) # float 0.0–1.0, e.g. 0.4 print(pwnagotchi.cpu_load()) # float 0.0–1.0, sampled over 100ms print(pwnagotchi.cpu_load(tag="my_plugin")) # differential reading with named tag print(pwnagotchi.temperature()) # Celsius int, e.g. 52 print(pwnagotchi.temperature(celsius=False)) # Fahrenheit # Rename the unit (rewrites /etc/hostname, /etc/hosts, reboots) # Name must be 2–25 chars, a-zA-Z0-9- pwnagotchi.set_name("mypwny") # Graceful lifecycle control pwnagotchi.restart(mode='AUTO') # restart bettercap + pwnagotchi in auto mode pwnagotchi.restart(mode='MANU') # restart in manual mode pwnagotchi.reboot() # sync filesystems and hard reboot pwnagotchi.reboot(mode='AUTO') # reboot and boot into auto mode pwnagotchi.shutdown() # sync and halt ``` -------------------------------- ### Create Monitor Mode Stop Script Source: https://github.com/jayofelony/pwnagotchi/wiki/Step-1-Installation-for-other-boards Creates a bash script named 'monstop' that sources the 'pwnlib' script and calls the 'stop_monitor_interface' function to disable monitor mode. ```bash sudo bash -c 'cat > /usr/bin/monstop' << EOF #!/bin/bash source /usr/bin/pwnlib stop_monitor_interface EOF ``` -------------------------------- ### Create Pwnagotchi Launcher Script Source: https://github.com/jayofelony/pwnagotchi/wiki/Step-1-Installation-for-other-boards This script is responsible for launching the Pwnagotchi application, handling encrypted modes, and determining whether to run in manual or automatic mode. ```bash sudo bash -c 'cat > /usr/bin/pwnagotchi-launcher' << EOF #!/usr/bin/env bash source /usr/bin/pwnlib # we need to decrypt something if is_crypted_mode; then while ! is_decrypted; do echo "Waiting for decryption..." sleep 1 done fi # blink 10 times to signal ready state blink_led 10 & if is_auto_mode; then /usr/local/bin/pwnagotchi else /usr/local/bin/pwnagotchi --manual fi EOF ``` -------------------------------- ### Modify pwnlib start_monitor_interface Function Source: https://github.com/jayofelony/pwnagotchi/wiki/Step-1-Installation-for-other-boards Edits the 'start_monitor_interface' function within the '/usr/bin/pwnlib' script to correctly set up a monitor interface named 'mon0'. ```bash # starts mon0 start_monitor_interface() { iw phy "$(iw phy | head -1 | cut -d" " -f2)" interface add mon0 type monitor && ifconfig mon0 up } ``` -------------------------------- ### Pwnagotchi Main Configuration Source: https://context7.com/jayofelony/pwnagotchi/llms.txt Configure the main settings for Pwnagotchi, including hostname, language, Wi-Fi interface, and a whitelist of SSIDs or MAC addresses to ignore. ```toml [main] name = "mypwny" # unit hostname (2–25 chars, a-zA-Z0-9-) lang = "en" iface = "wlan0mon" # monitor mode interface whitelist = [ # SSIDs, partial MACs, or full MACs to never attack "HomeNetwork", "de:ad:be:ef", "aa:bb:cc:dd:ee:ff" ] custom_plugins = "/usr/local/share/pwnagotchi/custom-plugins/" ``` -------------------------------- ### Configure WPA-SEC Plugin Source: https://context7.com/jayofelony/pwnagotchi/llms.txt Enable and configure the WPA-SEC plugin in config.toml to automatically upload handshakes for cracking. Set your API key, URL, and preferences for downloading results and displaying passwords. ```toml # /etc/pwnagotchi/config.toml [main.plugins.wpa-sec] enabled = true api_key = "your_wpa_sec_key" api_url = "https://wpa-sec.stanev.org" download_results = true # download cracked passwords show_pwd = true # display latest cracked password on screen single_files = true # write per-handshake .pcap.cracked files download_interval = 3600 # seconds between result downloads ``` -------------------------------- ### Pwnagotchi Display Configuration Source: https://context7.com/jayofelony/pwnagotchi/llms.txt Configure the Pwnagotchi display settings, including enabling the display and specifying the driver type and rotation. ```toml [ui.display] enabled = true type = "waveshare_4" # display driver to use rotation = 180 ``` -------------------------------- ### Configure GPS Plugin Source: https://context7.com/jayofelony/pwnagotchi/llms.txt Set up the GPS plugin in pwnagotchi's config.toml to save GPS coordinates with handshake files. Configure the serial device, baud rate, and optional display settings. ```toml # /etc/pwnagotchi/config.toml [main.plugins.gps] enabled = true speed = 19200 device = "/dev/ttyUSB0" # or "localhost:2947" for GPSD position = "127, 74" # optional: custom lat display position linespacing = 10 # optional: pixel spacing between lat/lon/alt lines ``` -------------------------------- ### Core Module: pwnagotchi Source: https://context7.com/jayofelony/pwnagotchi/llms.txt Provides utilities for reading system state and controlling the device lifecycle. These functions are useful for monitoring and managing the Pwnagotchi device. ```APIDOC ## Core Module: `pwnagotchi` ### Description Top-level utilities for reading system state (hostname, uptime, memory, CPU, temperature) and controlling the device lifecycle (shutdown, restart, reboot). ### Functions - `pwnagotchi.name()`: Returns the device hostname. - `pwnagotchi.__version__()`: Returns the Pwnagotchi version. - `pwnagotchi.uptime()`: Returns the system uptime in seconds. - `pwnagotchi.mem_usage()`: Returns the memory usage as a float between 0.0 and 1.0. - `pwnagotchi.cpu_load(tag=None)`: Returns the CPU load as a float between 0.0 and 1.0. An optional tag can be provided for differential readings. - `pwnagotchi.temperature(celsius=True)`: Returns the CPU temperature in Celsius (default) or Fahrenheit. - `pwnagotchi.set_name(name)`: Renames the unit by rewriting system configuration files and rebooting. The name must be 2-25 characters long and contain only a-zA-Z0-9-. - `pwnagotchi.restart(mode)`: Restarts bettercap and pwnagotchi in the specified mode ('AUTO' or 'MANU'). - `pwnagotchi.reboot(mode=None)`: Syncs filesystems and performs a hard reboot. An optional mode ('AUTO') can be specified to boot into auto mode. - `pwnagotchi.shutdown()`: Syncs filesystems and halts the system. An optional mode ('AUTO') can be specified to boot into auto mode. ``` -------------------------------- ### Pwnagotchi WPA-Sec Plugin Configuration Source: https://context7.com/jayofelony/pwnagotchi/llms.txt Enable and configure the WPA-Sec plugin for Pwnagotchi, providing your API key and options for downloading results and showing passwords. ```toml [main.plugins.wpa-sec] enabled = true api_key = "your-wpa-sec-key" download_results = true show_pwd = true ``` -------------------------------- ### Pwnagotchi Wigle Plugin Configuration Source: https://context7.com/jayofelony/pwnagotchi/llms.txt Enable and configure the Wigle.net plugin for Pwnagotchi, providing your API key for uploading wardriving data. ```toml [main.plugins.wigle] enabled = true api_key = "AID_base64key==" ``` -------------------------------- ### Bettercap Handshake Configuration Source: https://context7.com/jayofelony/pwnagotchi/llms.txt Specify the directory where Bettercap should store captured handshakes. ```toml [bettercap] handshakes = "/etc/pwnagotchi/handshakes" ``` -------------------------------- ### Configure Wigle Plugin in TOML Source: https://context7.com/jayofelony/pwnagotchi/llms.txt Enable and configure the Wigle plugin in the Pwnagotchi TOML configuration file. Ensure your API key is correctly formatted. ```toml # /etc/pwnagotchi/config.toml [main.plugins.wigle] enabled = true api_key = "AID_base64encodedkey" # Base64-encoded wigle API key (mandatory) donated = false # donate uploads to wigle community cvs_dir = "/tmp" # optional: save CSV copies locally timeout = 30 position = [7, 85] # screen position for stats display ``` -------------------------------- ### Initialize Pwnagotchi Agent Source: https://context7.com/jayofelony/pwnagotchi/llms.txt The Agent class is the central controller for Pwnagotchi, integrating bettercap client, mood system, and mesh advertising. It manages reconnaissance, handshake tracking, and the web UI. This snippet shows basic instantiation. ```python from pwnagotchi.agent import Agent from pwnagotchi.ui.display import Display from pwnagotchi.identity import KeyPair import pwnagotchi.plugins as plugins import pwnagotchi ``` -------------------------------- ### Draw Graphics with Pwnagotchi Primitives Source: https://context7.com/jayofelony/pwnagotchi/llms.txt Demonstrates drawing basic shapes like lines and rectangles on a canvas using PIL and Pwnagotchi's drawing utilities. Ensure PIL and ImageDraw are imported. ```python from PIL import Image, ImageDraw canvas = Image.new('1', (200, 100), 'white') drawer = ImageDraw.Draw(canvas) line.draw(canvas, drawer) rect.draw(canvas, drawer) filled.draw(canvas, drawer) ``` -------------------------------- ### Interact with Pwngrid Mesh API Source: https://context7.com/jayofelony/pwnagotchi/llms.txt Utilize the pwnagotchi.grid module to interact with the local pwngrid-peer daemon for connectivity checks, mesh operations, and messaging. Requires the grid module to be imported. ```python from pwnagotchi import grid # Check internet connectivity via opwngrid.xyz uptime endpoint if grid.is_connected(): print("Internet available") # Low-level API call helper result = grid.call("/mesh/peers") # GET result = grid.call("/data", {'key': 'val'}) # POST JSON result = grid.call("/unit/PEERNAME/inbox", b"hello") # POST raw bytes # Peer mesh all_peers = grid.peers() # list of peer dicts nearest = grid.closest_peer() # first peer or None mem = grid.memory() # mesh memory state # Advertisement data (broadcast via dot11 custom IEs) grid.advertise(enabled=True) grid.set_advertisement_data({'version': '2.9.5.5', 'name': 'mypwny'}) data = grid.get_advertisement_data() # Update session data on the pwngrid network grid.update_data(agent.last_session) # Broadcasts: version, plugins, language, bettercap/pwngrid versions, session stats # Report a suspicious AP to the grid grid.report_ap(essid="FreeWifi", bssid="AA:BB:CC:DD:EE:FF") # Inbox messaging between units messages = grid.inbox(page=1) # list of messages messages, pager = grid.inbox(with_pager=True) # with pagination info msg = grid.inbox_message(id=42) # single message grid.mark_message(id=42, mark="seen") grid.send_message(to="otherpwny", message="hi from mypwny") ``` -------------------------------- ### Wigle API Interaction with Python Source: https://context7.com/jayofelony/pwnagotchi/llms.txt Demonstrates how to upload CSV data and retrieve user statistics from the Wigle API using Python's requests library. Requires an API key for authorization. ```python # Wigle upload request (done internally via on_internet_available): import requests csv_content = """WigleWifi-1.6,appRelease=4.1.0,model=pwnagotchi,... MAC,SSID,AuthMode,FirstSeen,Channel,Frequency,RSSI,... AA:BB:CC:DD:EE:FF,MyNetwork,[WPA2],[WPA2],2024-01-15 14:30:00,6,2437,-65,...""" response = requests.post( "https://api.wigle.net/api/v2/file/upload", headers={\"Authorization\": \"Basic AID_base64encodedkey\"}, data={\"donate\": \"false\"}, files={\"file\": (\"pwnagotchi_20240115_143000.csv\", csv_content, \"text/csv\")}, timeout=30 ).json() # {\"success\": true, \"message\": \"...\"} # Get user statistics (shown cycling on display): stats = requests.get( "https://api.wigle.net/api/v2/stats/user", headers={\"Authorization\": \"Basic AID_base64encodedkey\"} ).json() # {\"user\": \"myuser\", \"rank\": 1234, \"monthRank\": 56, # \"statistics\": {\"discoveredWiFi\": 9876, \"last\": \"20240115\"}} ``` -------------------------------- ### WPA-SEC Plugin Source: https://context7.com/jayofelony/pwnagotchi/llms.txt Automatically uploads captured handshakes to wpa-sec.stanev.org for cracking when internet is available. Tracks upload state in a local SQLite database. ```APIDOC ## Built-in Plugin: WPA-SEC (`pwnagotchi/plugins/default/wpa-sec.py`) ### Description Automatically uploads captured handshakes to [wpa-sec.stanev.org](https://wpa-sec.stanev.org) for cracking when internet is available. Tracks upload state in a local SQLite database. ### Configuration (`/etc/pwnagotchi/config.toml`) ```toml [main.plugins.wpa-sec] enabled = true api_key = "your_wpa_sec_key" api_url = "https://wpa-sec.stanev.org" download_results = true # download cracked passwords show_pwd = true # display latest cracked password on screen single_files = true # write per-handshake .pcap.cracked files download_interval = 3600 # seconds between result downloads ``` ### Behavior - **`on_handshake`**: Marks the `.pcap` file as `TOUPLOAD` in the SQLite database. - **`on_internet_available`**: Uploads all pending `.pcap` files one by one. ### Upload Request Example (Internal) ```python import requests with open('/etc/pwnagotchi/handshakes/Network_AP.pcap', 'rb') as f: result = requests.post( "https://wpa-sec.stanev.org", cookies={'key': 'YOUR_API_KEY'}, files={'file': f}, timeout=30 ) # Success response starts with "hcxpcapngtool" ``` ### Download Cracked Results Example (Internal) ```python import requests result = requests.get( "https://wpa-sec.stanev.org/?api&dl=1", cookies={'key': 'YOUR_API_KEY'}, timeout=30 ) # Saved to /etc/pwnagotchi/handshakes/wpa-sec.cracked.potfile # Format: bssid:station_mac:ssid:password # With single_files=true, also writes: # /etc/pwnagotchi/handshakes/NetworkName_BSSID.pcap.cracked (contains password) ``` ``` -------------------------------- ### SSH Connection to Pwnagotchi (Linux/macOS) Source: https://github.com/jayofelony/pwnagotchi/wiki/Step-2-Connecting Connect to your Pwnagotchi via SSH using its hostname. Confirm the security prompt and enter the default password. ```bash ssh pi@.local ``` -------------------------------- ### Define Navigation Links in Jinja2 Source: https://github.com/jayofelony/pwnagotchi/blob/noai/pwnagotchi/ui/web/templates/base.html Sets up a list of navigation links for the web interface using Jinja2 templating. Each item includes the URL, an ID, and a display caption. This list is used to dynamically generate the navigation menu. ```jinja2 {% set navigation = [ ( '/', 'home', 'Home' ), ( '/inbox', 'inbox', 'Inbox' ), ( '/inbox/new', 'new', 'New' ), ( '/inbox/profile', 'profile', 'Profile' ), ( '/inbox/peers', 'peers', 'Peers' ), ( '/plugins', 'plugins', 'Plugins' ), ] %} ``` -------------------------------- ### Configure bettercap HTTP UI Credentials Source: https://github.com/jayofelony/pwnagotchi/wiki/Step-1-Installation-for-other-boards Modifies the bettercap http-ui caplet to set a custom username and password for its REST API. ```bash sudo sed -i 's/set api.rest.username user/set api.rest.username pwnagotchi/' /usr/local/share/bettercap/caplets/http-ui.cap ``` ```bash sudo sed -i 's/set api.rest.password pass/set api.rest.password pwnagotchi/' /usr/local/share/bettercap/caplets/http-ui.cap ``` -------------------------------- ### Create bettercap Systemd Service Source: https://github.com/jayofelony/pwnagotchi/wiki/Step-1-Installation-for-other-boards Defines a systemd service unit for bettercap, allowing it to run as a background service with automatic restarts. ```bash sudo bash -c 'cat > /etc/systemd/system/bettercap.service' << EOF [Unit] Description=bettercap api.rest service. Documentation=https://bettercap.org Wants=network.target #After=pwngrid.service [Service] Type=simple PermissionsStartOnly=true ExecStart=/usr/bin/bettercap-launcher Restart=always RestartSec=30 [Install] WantedBy=multi-user.target EOF ```