Tamagotchi gone Pi-wild! Kicking networks with Pwnagotchi


(last time edited: 2021-04-11)

tags: networks, security, raspi, pwnagotchi

This month was strangely nostalgic and japanese-based. Remembering all kinds of old japanese hardware, video games, and racing cars. After looking at some old Tamagotchi to buy I ended up remembering there was a project called Pwnagotchi made by evilsocket. A year ago this project was still very new and hard to setup but it's very robust now.



Pwnagotchi is an A2C-based “AI” powered by BetterCAP and running on a Raspberry Pi Zero W that learns from its surrounding WiFi environment in order to maximize the crackable WPA key material it captures (either through passive sniffing or by performing deauthentication and association attacks). This material is collected on disk as PCAP files containing any form of handshake supported by hashcat, including full and half WPA handshakes as well as PMKIDs.


Pwnagotchi is a fun front-end to BetterCAP and an optional data location server API called PwnGRID. Pwnagotchi is written in JavaScript and Python and the front-end uses Flask to display the cute character on screen rendering it via web as well as some other menus for plugins, inbox, config, etc. PwnGRID and BetterCAP are written in Go. This software can be run in any kind of system but the recommended way is to run it in portable hardware like the Raspberry Pi Zero W or in any laptop / rooted smartphone as an alternative but that is way harder to do.

In simple words Pwnagotchi captures Wi-Fi data automatically so you can do things with it later. The program has its own reinforcement learning algorithm (most commonly known as AI for normies; humans are fucking stupid) and settings to help it get better at capturing data. There is a similar project called Flipper Zero but it's more commercial, I do not recommend it.

Anyways I ended up buying in a rush the minimal requirements needed to run this software. No display at all. The tiny display is optional since you can see the BetterCAP web-UI and the smiley character from any web browser using Bluetooth.

Minimal requirements:

Notice: Power bank needs to be at least 5V and 1.5A~2A.



Pwnagotchi on Raspberry Pi Zero W

Download the latest Pwnagotchi .zip file image from GitHub releases page.

Extract it.

$ unzip /path/to/pwnagotchiimage.zip

Plug in your micro SD card (minimum size 16GB) in a laptop or a smartphone and burn the image using using the command line. With a smartphone you may probably need Termux to run the dd commands and possibly smartphone root permissions.

# dd if=pwnagotchiimage.img of=/dev/mmcblk0 status=progress

Once the image is written, mount the boot partition in your system, we need to add a custom Pwnagotchi config.

# mkdir /mnt/mypwna

Mount the boot partition.

# mount /dev/mmcblk0p1 /mnt/mypwna

Create a new file called config.toml and place it inside the boot partition just mounted, along all other files.

The config.toml file should override, at boot level, all the settings found in defaults.toml.

This file will be later deleted from boot partition automatically and then Pwnagotchi configurations will be then stored in /etc/pwnagotchi/config.toml. You can later change the configuration via SSH manually, or using the webcfg plugin.

Example of a random config.toml file:

# ...
# ...

# Choose a nice name for your Pwnagotchi.
main.name = "somethingsomething"
main.lang = "en"

# You must get each home device MAC address you have and write it down here.
main.whitelist = [
  "your router's wireless mac address",
  "your phone's mac address",
  "your friend's mac address",

# OPTIONAL. This is the PwnGRID plugin, will send information to the pwnagotchi.ai servers to collect data.
main.plugins.grid.enabled = false 

# I don't have a display.
ui.display.enabled = false

# These options will make our system write less information on the SD card for longer life expectancy.
fs.memory.enabled = true
fs.memory.mounts.log.enabled = true
fs.memory.mounts.data.enabled = true

personality.deauth = true # if you want your Pwnagotchi to be more friendly then disable this option
# if you don't know what are deauthentication attacks please read this https://en.wikipedia.org/wiki/Wi-Fi_deauthentication_attack

# ...
# ...

There are many other options you can add and tweak to override defaults. It's not necessary to list all of them, only the ones necessary. Perhaps you might want to backup a personal config.toml too.

In my personal configuration I disabled the Pwnagotchi UI display because I will connect to my Pwnagotchi from a smartphone / computer using Low Power Bluetooth rather than using a LED display to read all the data while consuming battery. Sometimes I use the USB to connect.

However, now put the micro SD card into the Raspberry Pi Zero W and once you plug in the power bank into the power input micro B USB the system will instantly boot and run without any user intervention.

Hurrah! Your Pwnagotchi is alive. You will see a LED blinking and stabilizing in your Raspberry Pi Zero W.



Connection via USB

Connect the data micro B USB from the Raspiberry Pi Zero W to the your personal computer.

Hook your USB to your computer and list all current interfaces.

$ ip a

Start up the Raspberry network interface device.

# ip link set dev usb0 up

Add IP and netmask to the interface.

# ip addr add brd + dev usb0

Now you can connect via SSH to it. Default password is raspberry.

$ ssh pi@

Pwnagotchi has 2 modes, MANU and AUTO.

Notice! Crucial step. To use the BetterCAP web UI from your host machine you may need to add a new address in your /etc/hosts file. pwnagotchi.local

Save it and you will be able to connect to http://pwnagotchi.local:8081 instantly. No need to refresh anything.

Notice! The BetterCAP web UI only works in MANUAL mode! I know it's very redundant to say this, but the connection to http://pwnagotchi.local:8081 won't be sucessful in AUTO mode and without the /etc/hosts edited file.


Also inside SSH you can look at what's happening in the background

# tail -f /var/log/pwnagotchi.log


# tail -f -n300 /var/log/pwn* | sed --unbuffered "s/,[[:digit:]]\{3\}\]//g" | cut -d " " -f 2-'

Share your host internet with the Pwnagotchi via USB

You can find the linux connection share BASH script in the /path/to/pwnagotchi/scripts directory.

But first edit it with your current network interfaces. In my case usb0 is the Raspberry Pi connected to my host. eth0 is my network ethernet card.

Remember! You must run the script in your host machine, not in the Raspberry Pi.

Inside your Raspberry Pi Zero W login to root.

$ sudo su or $ sudo -i or $sudo su root

And add new DNS to the resolv.conf file. There are multiple DNS you can choose from, some are more privacy oriented, some not. In this example I will add the Google DNS which I DON'T recommend to do so for obvious reasons. Use a safe one instead or build your own DNS server.

# echo nameserver > /etc/resolv.conf

# echo nameserver >> /etc/resolv.conf

Use chattr on the resolv.conf file to make it immutable. Systemd will be unable to overwrite it no matter what.

# chattr +i /etc/resolv.conf

If everything is working correctly you will be able to ping any domain from inside the Raspberry Pi Zero W.

# ping unblogmas.ar

If you want to return to default values in your host machine, just flush your iptables.

# iptables --flush

And disable IP forwarding.

# echo 0 > /proc/sys/net/ipv4/ip_forward

Hot-plug your rpi0w USB network interface with udev rules

I don't recommend using dhcpcd or ndhc to set up your network interfaces. Don't relay on daemons to do everything for you automatically. They can bring lot of trouble at the moment of assigning IP addresses. Those are good programs for people who don't wanna waste their precious time, which is totally fine I guess.

Relay on udev instead. Simple, fast, concise. Here is a good explanation on how to write udev rules.

Connect the data USB from the Raspberry Pi Zero W to the computer and get udev info on the device.

# udevadm info -ap /sys/class/net/usb0 | less

We will now make a custom udev rule with the specific information we got.

# touch /etc/udev/rules.d/80-usb0.rules

The file should look like this:

ACTION=="add",·SUBSYSTEM=="net",·KERNEL=="usb0", RUN+="/bin/sh -c 'ip link set dev usb0 up && ip addr brd + dev usb0"

This is completely optional but you can also activate Internet connection sharing via USB automatically from our udev custom rule.

The file should look like this:

ACTION=="add", SUBSYSTEM=="net", KERNEL=="usb0", RUN+="/bin/sh -c 'ip link set dev usb0 up && ip addr add brd + dev usb0 && iptables -A FORWARD -o eth0 -i usb0 -s -m conntrack --ctstate NEW -j ACCEPT && iptables -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT && iptables -t nat -F POSTROUTING && iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE && echo 1 > /proc/sys/net/ipv4/ip_forward'"
ACTION=="remove", SUBSYSTEM=="net", KERNEL=="usb0", RUN+="/bin/sh -c 'iptables --flush && echo 0 > /proc/sys/net/ipv4/ip_forward'"

Reload udev rules.

# udevadm control --reload-rules && udevadm trigger

Now disconnect your USB and monitor your connections just in case.

# udevadm monitor


$ watch -n1 ip a


$ watch -n1 ifconfig

Plug the USB again.

If everything went correctly you should see the usb0 interface up and running with assigned netmask and IP address.

Connection via Bluetooth

We can opt to connect to our Pwnagotchi via USB but we can also do it via Bluetooth and use tethering to share our internet connection (from the smartphone) to the Pwnagotchi.

First activate Bluetooth in your smartphone.


And then activate Hotspot & tethering (Bluetooth tethering). Both are separate programs in your Android device. Only tethering depends on Bluetooth being enabled.


Then go to Pwnagotchi's web UI while connected via USB and go to plugins tab. If you don't have webcfg enabled please enable it, at least for now. It's not necessary to have it enabled all the time.

Inside webcfg you must have these settings to make it work.

main.plugins.bt-tether.enabled = true # enables the bluetooth plugin
main.plugins.bt-tether.devices.android-phone.enabled = true # enables connection to android-phone
main.plugins.bt-tether.devices.android-phone.max_tries = 0 # 0 tries, instead of 10, keep trying until it connects
main.plugins.bt-tether.devices.android-phone.mac = "B2:B2:B2:B2:B2:B2" # your phone Bluetooth MAC address
main.plugins.bt-tether.devices.android-phone.ip = ""
main.plugins.bt-tether.devices.android-phone.netmask = 24
main.plugins.bt-tether.devices.android-phone.interval = 1 # scan between 1 minute intervals
main.plugins.bt-tether.devices.android-phone.priority = 999 # big priority
main.plugins.bt-tether.devices.android-phone.share_internet = true # we can share internet via USB but this is very handy too

Now use SSH to get into the Raspberry. Default password is raspberry.

$ ssh pi@

Get into the root account.

$ sudo su or $ sudo -i or $ sudo su root

Now let's pair to bluetooth, we need to enter the bluetooth shell.

# bluetoothctl

Agent registered

[bluetooth]# scan on

Wait a few seconds until your smartphone device appears.

Discovery started
[CHG] Controller A1:A1:A1:A1:A1:A1 Discovering: yes
[NEW] Device B2:B2:B2:B2:B2:B2 moto g(7) play

Now you're safe to stop the scanning.

[bluetooth]# scan off

[CHG] Controller A1:A1:A1:A1:A1:A1 Discovering: no
Discovery stopped

Now pair to your cellphone using the MAC address you just found.

[bluetooth]# pair B2:B2:B2:B2:B2:B2

Attempting to pair with B2:B2:B2:B2:B2:B2
[CHG] Device A1:A1:A1:A1:A1:A1 Connected: yes
Request confirmation
[agent] Confirm passkey 51234 [yes/no]: yes

Pay attention to your smartphone and accept the pairing.

[agent] Confirm passkey 875154 (yes/no): yes
[CHG] Device B2:B2:B2:B2:B2:B2 Modalias: bluetooth:v001bp1300d1136
[CHG] Device B2:B2:B2:B2:B2:B2 UUIDs: 00001105-0000-1000-8000-00805f9b34fb
[CHG] Device B2:B2:B2:B2:B2:B2 UUIDs: 0000110a-0000-1000-8000-00805f9b34fb
[CHG] Device B2:B2:B2:B2:B2:B2 UUIDs: 0000110c-0000-1000-8000-00805f9b34fb
[CHG] Device B2:B2:B2:B2:B2:B2 ServicesResolved: yes
[CHG] Device B2:B2:B2:B2:B2:B2 Paired: yes
Pairing successful
[CHG] Device B2:B2:B2:B2:B2:B2 ServicesResolved: no
[CHG] Device B2:B2:B2:B2:B2:B2 Connected: no

Trust the new phone bluetooth MAC address.

[bluetooth]# trust B2:B2:B2:B2:B2:B2

[CHG] Device B2:B2:B2:B2:B2:B2 Trusted: yes
Changing B2:B2:B2:B2:B2:B2 trust succeded

Exit from bluetoothctl shell.

[bluetooth]# exit

Now reboot the Pwnagotchi at hardware level.

# reboot

With Bluetooth enabled I can leave home with my Pwnagotchi and look at the screen via smartphone.

Now you will be able to log in to your Pwnagotchi web UI via, default login ID is changeme, default password is changeme.

You can even download Termux and SSH into it via Bluetooth.

$ ssh pi@

The only problem I've encountered with Bluetooth is that I can't reconnect after a disconnection.



Backup your Pwnagotchi via USB

In your host machine first clone the repository.

$ git clone https://github.com/evilsocket/pwnagotchi

And then run the backup script to retrieve all the data, handshakes included. Make sure your pwnagotchi is connected via USB, the interface is up and configured and you have SSH access to it.

$ sh /path/to/pwnagotchi/backup.sh

You will be prompted to enter the SSH password to pi@

@ backing up to ...
pi@'s password:

All data will be saved inside /path/to/pwnagotchi/backup directory in a .tgz tarball file.

This is my current mobile rpi0w unit called chobi. Feel free to send me a message via PwnMAIL. I'll be very happy to hear that this guide helped you.

Happy pwning!