RaspPi Auto-Enumerator Part 2: Setup and Provisioning
Last Updated: 2018-12-30
Last time, we discussed the overall process of figuring out how to build the Enumpi - predefining the scope of a project, limiting the amount of fresh development we'll have to do, and coming up with a roadmap for implementation. This time, we're taking a look at the actual implementation. While the last guide was a good general guide for working on projects at all, this guide will be a little more specific.
Fundamentally, we can break the process down into three phases: initial setup and provisioning of the hardware, installing the necessary software, and then developing, "installing", and scheduling the actual enumeration logic. Lastly, we'll have a look at what improvements could be made to the project as a whole for a future re-implementation.
As usual, I did a lot of learning by failing, so I'll make sure to point out my failures so that you can avoid repeating my mistakes!
Setting Up the Raspberry Pi 3
While the RP3 is a beautiful piece of hardware for its price point, it isn't exactly fully functioned out of the box. As we discussed before, I wanted to create this product using the device's stock OS, Raspbian. Specifically, we used the November 2018 version of Raspbian Stretch Lite. In order to install the OS, I downloaded the image, verified the hash, and wrote it to a 16gb MicroSD card I had lying around from a previous project using gnome-disks.
Here we reached our first mistake. I noticed that the rootfs partion was quite small, which is to be expected because of the size of the OS image. I tried to rectify this manually using gparted. This ultimately caused the final image to be unbootable, which was undesirable.
The correct solution is to first prepare card to allow the OS to boot in a mode suitable for headless operation, and then allow it to go through an initial boot. Raspbian will resize the partition manually. Since modern versions of raspbian have SSH disabled by default, create a file called "ssh" in the root of the "boot" partition.
From here, my process was to connect the device to my LAN - if you want to use wifi, you must also create another file called "wpa_supplicant.cfg" and feed it the corresponding information - guides for this are abundant. I also installed the SD card, and then powered the device up with a 2A5V microUSB wall-adapter.
The rest of the configuration was pretty simple. You can ssh in as the default user "pi" - I recommend changing the password immediately once you have. The only major changes I had to make to configuration were to change the sshd-config to allow the public key method and disallow password login, and of course to add my SSH key to pi's home directory.
Installing the Software
There was, however, some significant installations to do. We already have the most important components - apt and python3. We also needed the openvpn, git, nmap, and golang packages, which installed fairly straight-forward. Gobuster, our dirbuster alternative, is built in go and available in source from, so I can compile it for ARM, which is the architecture underlying the RPi. There were some tricks to installing it.
First, we had to git clone the relevant repo. Specific instructions for compiling and installing the program using go are included in the repo's readme.md function, but we also have to remember as part of go's installation we need to add the go path to our environment variables.
Gobuster does need a wordlist to function. I used the wordlist from here, which is the same wordlist I use on manual runs of dirbuster in Kali.
Designing the "Brains"
At this point, what we have is technically sufficient as a start-and-walk-away enumeration platform. If you forward your ports, or have a jumpbox on your lan, you could log into this pi from anywhere and do some basic enumeration. That's not what we're trying to build, though. We're trying to build a device we can switch on, and just periodically pull down reasonably-current information on demand. In order to do that, we need some automation. And since I am who I am, that means we need some Python.
As usual, in my head, I started with an overly simplistic model of the process in question. What we need to do is first a broad, basic scan of which hosts are "up" on the target subnet. Then we have to injest the results of that scan, keep some sort of state about it, and then iterate over the list of "up" hosts taking full-range TCP, UDP Top-100, and Web Directories.
The final result was pretty simplistic. It did exactly as I described, and as we'll see in a little bit, it has some problems. I keep that repo current - changes to the enumeration script are pushed up to github pretty much as soon as I make them.
Of course, just having the script is also kind of enough. We could just SSH in and call it. However... that's not nearly as fun as being able to plug the pi in and walk away.
What I did was add the script to root's chron jobs using the command "sudo chron -u root -e". I chose to have it run "@midnight". I also included two as "@reboot": the first connects to openvpn using my htb credentials. The second sleeps for 300 seconds (to allow openvpn to complete), and then executes the enumeration script.
Improvements Going Forward
All development is iterative. I've left out several days of launching scripts and having them not quite work right. Additionally, the current state of the script is horrifically inefficient. Time-to-complete wasn't one of my primary objectives, but the current state (several days for the 10.10.10.0/24 subnet) is excessive, even in a set-and-forget solution.
Right now, the principle improvements I'd like to add to this system are:
- Switching to a multiprocess model which can execute tasks in parellel to save time.
- Evaluating the information I actually need and using either a shorter wordlist or enumerating fewer ports (I don't need, necessarily, all 65k TCP ports, for example), and;
- Adding a notification-of-completeness of some kind, possibly via email or some kind of ARP hack, so that I don't have to keep SSHing into the pi to check things out.
While you're waiting for more information about the EnumPi, or indeed, if you want to check out our other projects, I'd encourage you to check out our actual projects page using the links above. Additionally, if you're interested in a similar project and you'd like our input, check out the services tab. If you liked this guide, and want to see more like it, please share with your friends or consider donating to our Coffee Fund!