WarBerry Pi: The Complete Guide



*The Complete Guide *

Author: @sec_groundzero

Sponsored by:

[_Help Peerlyst sponsor more books by sharing your knowledge on Peerlyst.com! _]

  • *

*Table of Contents *


CHAPTER 1 – WarBerryPi History

CHAPTER 2 – Hardware Elements

CHAPTER 3 – Setting up Your WarBerryPi

CHAPTER 4 – Covert Channel

CHAPTER 5 – Usage

CHAPTER 6 – The WarBerryPi Back End

CHAPTER 7 – Reporting

CHAPTER 8 – Building Your Own Scanner

CHAPTER 9 – Adding a Switch

CHAPTER 10 – Adding an LCD



The development of the WarBerryPi wasn’t the targeted creation of a tool, it was built out of necessity. I got my hands on the Raspberry Pi 1 Model B back in 2012, when it was given to me by a good friend and colleague (@zrenos) who is an avid fan of Kickstarter and gadgets in general. Back then I was in the process of building my desktop PC and jamming as much power as I could into it. So I was surprised how a small device running Linux with 256 MB

of RAM could be of any help to me.

I have to admit that I put any ideas for the Raspberry Pi on ice for a year before I started to experiment with it and see what that cheap solution might offer me. Being in information security, the first idea that popped in my mind was using it for wardriving. Fortunately, there were a lot of tutorials online on how to do the setup. In a way, though, that was unfortunate, because prepping the device didn’t take long—and didn’t fulfill my hacker hunger. I continued experimenting with the setup and ended up using a GPS dongle to record GPS

positions along with the wireless networks captured. Finding the right drivers and making the dongle work was a hassle, but it gave me a sense of achievement. That was the point when I started seeing the potential of the device and what it could offer me. Since then, I’m hooked!

I owe the satisfaction I get from these devices to the Raspberry Pi Foundation, which makes these little devices and provides them at an affordable cost. The Raspberry Pi was also my ticket to be part of great conferences—another reason I’m grateful to the Raspberry PI Foundation.

CHAPTER 1 – WarBerryPi History

The WarBerryPi refers to a hardware device hosting a set of scripts that run on a slightly customized Raspberry Pi. The customization has nothing to do with the hardware aspect of the Raspberry Pi, but rather with the installation of additional tools and utilities that allow the WarBerryPi scripts to run.

The main purpose of the WarBerryPi is to be useful during Red Team operations. Since the whole Red Team/Blue Team terminology stems from the military, I wanted to baptize my project with a military-related term, hence the name “WarBerryPi.”

As I mentioned in the introduction, the WarBerryPi was developed out of necessity, not because I was actively searching for and thinking of a tool to develop. Working in information security, I often need to social engineer my way into companies. After running a few of those engagements, you realize that it is not very practical to social engineer your way through and plug a laptop into the network and start typing commands. These sorts of engagements are usually hectic and you need to get in and out quickly. It was through these difficulties as a physical security penetration tester that I realized that I needed a device I could plug it to give me remote connectivity so that I could continue my penetration test from the comfort of my office. And on top of that, it’d be even better if the device could handle some of the workload for me.

A rule that I set from the beginning—and still abide by—is that whatever device I build will not do any automatic exploitation. I didn’t want to build a device that would destroy networks if it fell into the wrong or inexperienced hands. I wanted to develop a device that would be beneficial only to an experienced penetration tester.

Since I had a couple of Raspberry Pi’s laying around, those were the obvious option to start experimenting on.

As my background did not include much programming, I only have basic knowledge of a few programming/scripting languages, so I went out and researched my options in order to start writing some code.

My first attempt was with Bash.

Bash was working great—up to a point. When I wanted to leverage some lower level functionality such as scapy (http://www.secdev.org/projects/scapy/), I had some trouble, and it looked as if the solution to my problems was Python. Although I’d never programmed in Python, I had a somewhat working model in Bash. I made the decision to learn Python so I could rewrite the entire code in it.

As you can imagine, this was a roller coaster ride because of the difficulties I had with writing somewhat advanced code in Python while I was still learning. It wasn’t until 2016

(and a year of painful development) that I was feeling confident enough to put my code on GitHub. A few days later, I saw one of the accounts I follow on Twitter had posted a link to my GitHub page. Just a few days after the public release of the WarBerryPi, it had 500 stars on GitHub, which gave me the motivation I needed to develop more modules and perfect the ones already released.

Another important payoff for me was the fact that I was finally giving back to the great InfoSec community. For years, I’ve been watching from the wings, benefitting from all the great stuff that people took the time to write, develop, and share. This was my chance to give back.

This book is going to be a deep dive into the inner workings of the WarBerryPi. I will cover all the important code—in many cases, line by line—in order to give you an understanding of how it works. I also want to make it easier for you to add new modules or remove modules you don’t need, effectively making your own version of the WarBerryPi, one that will suit you better.

CHAPTER 2 – Hardware Elements

The Raspberry Pi Foundation does a great job perfecting their devices. The newest and most powerful model at the moment is Raspberry Pi 3 Model B, and that’s the model I would suggest you build the WarBerryPi on, for a few reasons. Two of the most important reasons are the fact that this model has Bluetooth and Wi-Fi embedded modules that are compatible with the WarBerryPi. That also removes clutter, as you will not have to plug in additional antennas or dongles. This model has also an impressive 1 GB of RAM, which is more than enough for handling the WarBerryPi. If you still want to go for a cheaper older model, you can. During operation, the WarBerryPi will detect the model and disable certain modules that rely on the newest model.

I use both the Pibow Ninja (https://www.adafruit.com/product/1124) and the Pibow Coupe (https://www.adafruit.com/products/2083) cases depending on my setup. For example, if I am using an LCD screen, I prefer the Ninja case and when I want access to the GPIO pins, I use the Coupe case—but any kind of case will work. Another accessory I make use of is a three-port USB hub with Ethernet (https://shop.pimoroni.com/products/usb-multi-function-lan-adaptor ), which serves a couple of purposes. First, it allows me to have more USB ports.

And it also provides me which a second Ethernet interface, which comes in very handy when you want to use the WarBerryPi with another device.

When it comes to 3G/4G connectivity, I almost always rely on Huawei dongles, specifically E303 and E173, mostly because the drivers are readily available. Though I am sure others are compatible with the Raspberry Pi as well.

The 3G/4G dongle use is a two-fold. First, it allows you to connect to the device remotely, the same as if you were physically connected with your laptop. Second, if for any reason the scripts fail to run, you can connect in remotely and troubleshoot the problem.

On one of my WarBerryPi’s, I use a Display-O-Tron 3000 LCD

(https://shop.pimoroni.com/products/displayotron-3000) which shows some basic

information, such as the Ethernet and wireless IP address, as well as the current module the script is running. This is completely optional, and it only adds a l33t effect to your WarBerryPi.

For portability purposes, you can use any type of battery pack with 5000mA or more in order for the device to remain operational for a couple of hours.

Finally, if you are planning to use a switch to control the execution of the scripts, any toggle switch for Arduino or Raspberry Pi will work.

It goes without saying that you will need an SD card of at least 8 GB capacity to store the operating system.

CHAPTER 3 – Setting up Your WarBerryPi

Setting up the WarBerryPi is a straightforward process. At least it is for me, because I have already done it multiple times. This chapter will guide you through the transformation of a vanilla Raspberry Pi to a WarBerryPi.

First things first: You need to download the appropriate operating system, which comes in the form of an image file provided by the Raspberry Pi Foundation.

Everything you need can be found at https://www.raspberrypi.org/downloads/raspbian/.

Through that link, you can download the Raspbian image, which is stable and the

WarBerryPi runs on it without any compatibility issues.

Download the image and burn it to the SD card. If you are a Windows user,

Win32DiskImager is a great option, and can be found here

https://sourceforge.net/projects/win32diskimager/. MacOS users can use Etcher, which can be found here https://etcher.io/.

The next step is to boot up your device and find its IP address. When I am on my home network and don’t know the IP address of the Raspberry Pi, I use Nmap to locate it.

nmap –sV –p22 --open

Otherwise, connecting the device to an external monitor to perform the setup would work, but would also require a keyboard and a mouse.

After you locate your device, connect to it via SSH to get the fun started.

ssh [email protected] and the default password is raspberry.

Changing the hostname

You can change the hostname from the default _raspberrypi _ to anything you like.I prefer using the name _WarBerryPi. _ In order to change your hostname, you need to edit the hostname value in two files.

1) /etc/hosts

2) /etc/hostname

Replace the current hostname value in both files with the name you would like to use and reboot for the changes to take effect.


At this point you should see your prompt saying something like [email protected] and you should be in the /home/pi directory. The easiest way to verify the location you are currently in is to type pwd which should return /home/pi. If not, change into that directory by typing _cd _

[_/home/pi, _] as _ _ we need to be in the correct directory for the rest of the installation to run smoothly.

OK, so now we are ready to begin the actual installation.

The first step is to download all the code for the WarBerryPi through the following command.

sudo git clone https://github.com/secgroundzero/warberry.git

This downloads the entire WarBerryPi repository, which can be easily updated in the future by running git pull when inside the directory.

Next cd into the newly created warberry directory.

cd warberry

At this stage, you have two options to choose from. Either proceed with a fully automated installation or proceed with the manual installation. Whatever you choose will have the same effect.

Automated installation

sudo bash bootstrap.sh

The automated setup will begin by creating the necessary directories, updating the operating system, and installing the dependencies.

Manual installation

This process is a bit more tedious and could lead to some errors if the steps are not followed correctly.

• Create a directory under /home/pi

o sudo mkdir WarBerry

• Create the Results subdirectory in home/pi/WarBerry

o sudo mkdir Results

• Create the Results subdirectory in home/pi/WarBerry

o sudo mkdir Tools

• Update the operating system by typing

o sudo apt-get update

Now the long process of installing the necessary tools begins. These are all tools and utilities required by the WarBerryPi to run.

sudo apt-get install nbtscan

sudo apt-get install python-scapy

sudo apt-get install tcpdump

sudo apt-get install nmap

sudo pip install python-nmap

sudo apt-get install python-bluez

sudo pip install optparse-pretty

sudo pip install netaddr

sudo pip install ipaddress

sudo apt-get install ppp

sudo apt-get install xprobe2

sudo apt-get install sg3-utils

sudo apt-get install netdiscover

sudo apt-get install macchanger

sudo apt-get install unzip

sudo wget http://seclists.org/nmap-dev/2016/q2/att-201/clamav-exec.nse -O


Most of these tools should make sense to you if you are in information security. Tools like tcpdump and Nmap are widely used tools for network packet monitoring and port scanning, respectively. If you are unsure about any of these tools, the Linux Man pages and Google are your best friends.

Now cd into the Tools directory in order to download some additional tools for post exploitation and network poisoning.

sudo git clone https://github.com/DanMcInerney/net-creds.git

sudo apt-get install onesixtyone

sudo apt-get install nikto

sudo apt-get install hydra

sudo apt-get install john

sudo apt-get install bridge-utils

sudo apt-get install w3af-console

sudo apt-get install ettercap-text-only

sudo apt-get install cryptcat

sudo apt-get install ike-scan

sudo git clone https://github.com/sqlmapproject/sqlmap.git

sudo git clone https://github.com/CoreSecurity/impacket.git

sudo git clone https://github.com/samratashok/nishang.git

sudo git clone https://github.com/SpiderLabs/Responder.git

sudo git clone https://github.com/PowerShellMafia/PowerSploit.git

sudo git clone https://github.com/offensive-security/exploit-database.git

sudo wget https://download.sysinternals.com/files/SysinternalsSuite.zip

wget https://labs.portcullis.co.uk/download/enum4linux-0.8.9.tar.gz -O


tar -zxvf enum4linux-0.8.9.tar.gz

mv enum4linux-0.8.9 enum4linux

Hopefully, you have installed the tools without any errors and the WarBerryPi is now ready to run.

CHAPTER 4 – Covert Channel

Imagine you have placed your WarBerryPi inside a network, but are not planning to retrieve it in the future or you want to control it remotely. Since the WarBerryPi will not be reachable from the Web directly, your best bet is for the WarBerryPi to connect back to you through a process called reverse SSH. This, though, will depend on the egress rules of the network, as attempting an HTTP connection from inside a network to a third-party server controlled by you may be prohibited, and the device will be flagged immediately. In order to bypass this issue, we can have the WarBerryPi connect back to us via a 3G/4G connection, which will not be picked up by the firewall, as it’s a different channel, which is not part of the network.

You can use this channel even if you decide not to use a 3G/4G dongle, as the WarBerryPi will attempt to initiate an outgoing connection through its Ethernet connection if no dongle is found.

You can set up your own server for accepting and managing these connections, but personally, I like to use a third-party service. Keep in mind, though, that when using a third-party service, it means that all of your communication—potentially including client sensitive information—goes through this service.

What happens in this process is that there is a service running on the WarBerryPi that’s responsible for connecting to a third-party service on the Web. That service in turn provides us with a public IP that we can connect to the WarberryPi, and it will forward our connection to the WarBerryPi so we don’t have to deal with setting up our own servers and configuring the port forwarding.

While I was searching for a solution, I came across Weaved, which is now called remot3.it.

Before jumping into the configuration of the service, let’s first go through the setup of the dongle on the WarBerryPi.

During the setup process you have installed two out of the three tools needed for the dongle setup. Those were ppp and sg3-utils. A third script is needed, named sakis3G.

Go inside the /home/pi/WarBerry/Tools directory and type the following commands.

1. sudo wget “http://downloads.sourceforge.net/project/vim-


n4n0%2Ffiles%2F&ts=1363537696&use_mirror=tene~t" -O sakis3g.tar.gz

2. sudo tar -xzvf sakis36.tar.gz

3. sudo apt-get install sg3-utils

4. sudo chmod +x sakis3g

5. sudo ./sakis3g --interactive

Follow the on-screen instructions and you should have an additional network interface called eth1 which will have a valid IP if everything worked fine. This was a slightly painful process for me, as I had to do a lot of debugging for the dongle to be recognized as a 3G device and not a USB storage device, but if you run into trouble yourself, again, Google is your best friend.

Back to the third-party service configuration. Install the necessary service on your WarBerryPi.

sudo apt-get install weavedconnectd

sudo weavedinstaller

Go through the installation and make sure no errors are shown.

Next log in to your account of https://www.remot3.it/ and click on “Manage Devices.”

Clicking on your device will give you the SSH command to run to connect to the device remotely.

That is all. Now every time your device goes online, it will appear in the “Manage Devices”

section, and you can connect to and control it remotely.

Since I am not affiliated with or endorsed by https://www.remot3.it/, I will not go into further detail on their service offering, but I will say that this worked flawlessly for me in the past.

CHAPTER 5 – Usage

Now I’ll take you through the various switches available to the WarBerryPi so you can run your customized scripts.

First switch into the /home/pi/WarBerry/warberry directory. The warberry.py script is the main script, and it is what you will be running at all times.

Then run sudo python warberry.py –h

It is important that you run all warberry.py related commands with _sudo, _ as most of the tools require root privileges to run.

Invoking the help flag will present the following output:

Starting with the first option, which is -a or –attack, *] this is where you define what kind of enumeration you would like to do. By default, the warberry.py script will use the [*—attack mode, which is basically going to perform the enumeration based on the port list included in the /src/core/scanners/port_list file.

In order to specify a different attack type, you need to use the –A flag alongside with the –T,

-B or –F flags.

-T or —toptcp will enumerate the top tcp ports

example: sudo python warberry.py –a -T

-B or —topudp will enumerate the top udp ports

example: sudo python warberry.py --attack --topudp

-F or —fulltcp will enumerate all TCP ports

Of course, enumerating all TCP ports during a Red Team engagement will not be very covert, and will create a lot of network noise. Keep in mind that if you enable this flag you will be scanning 65535 ports per host. All other scanning types except the default one are basically useful in cases when you want to scan your own network or a network you are performing a penetration test on. I never use this option during any of my engagements, and they have been added after I received numerous requests on GitHub.

Moving on, the next flag is the –p or —packets flag. During the initial stages of the warberry.py script, a network packet capture takes place. This is useful to gain some understanding of the network, such as endpoint names and the kind of technologies are used.

You might even get lucky and find a misconfigured switch, which will allow you to capture traffic from all endpoints. By default, the script instructs the network capture mechanism to capture 20 packets, which is a very low number. You can change the number of packets that will be captured by using the –p flag.

As an example, the following will capture 100 packets:

sudo python warberry.py –p 100

If we get stuck inside a network or a subnet that does not have any packets flowing, our script will not proceed, as it will wait to capture the number of packets we indicated using the –p flag or the default 20 packets.

This is where the –x or —expire flag comes in handy, as it instructs the script to skip this phase after a predefined period of time. By default, that time is 20 seconds, but you can increase it according to your needs.

As an example, the following will capture 100 packets and exit if no packets are received in 10 seconds:

sudo python warberry.py –p 100 –x 10

The warberry.py script can be executed on multiple network interfaces, including the Ethernet one and the wireless one. Of course, in 99% of the cases you will be running it on the Ethernet interface.

It is good practice to always specify the interface you want to use for your scanning. This can be achieved via the –I or —interface flag.

As an example, the following will execute the default script on the eth0 interface: sudo python warberry.py –I eth0

_ _

And the following example will execute the default script on the eth0 interface and capture 50 packets with a timeout of 30 seconds:

sudo python warberry.py –I eth0 –p 50 –x 30

Next up is the hostname you would like to use during the execution of the script. If you have intelligence about the network you are attacking beforehand (say, for example, you know that endpoints follow a specific naming convention such as “USER_PC1,” “USER_PC2,” and so on), you may decide to specify a hostname for your WarBerryPi that will follow that naming convention, making the device harder for administrators to identify.

Using the –N or —name flag, you can do that. The following example changes the name of the WarBerryPi to PC1 and captures 100 packets on the eth0 interface:

_ _

sudo python warberry.py –I eth0 –p 100 –N PC1

As you can see, up to now, multiple flags can be combined. Later on we will see some flags that cannot be used with others.

Digging deeper into the functionality of the WarBerryPi, we come to the intensity flag.

Throughout the warberry.py script, we make heavy use of Nmap. Nmap is one my favorite tools, and I don’t know any security professionals who don’t use it. The –i or —intensity flag specifies how fast should the scanning phase take place. Here we follow the Nmap timing parameters, which go from T1 to T5, and basically translate as paranoid, sneaky, polite, normal, aggressive, and insane.

The slowest one is paranoid or T1, and the fastest one is insane or T5. The WarBerryPi supports up to T4 because I don’t think anyone would ever run a T5 scan during an engagement (or T4 for that matter).

The following example shows how you can specify the timing parameter through the –i or the

—intensity flag—in this case, executing the default script on the eth0 interface using the T3

timing option:

sudo python warberry.py –I eth0 --intensity –T3

Remember that a – (dash) is required in front of the timing option.

The final phase of the warberry.py script is to run a network poisoning tool in order to capture NTLM hashes to crack them later on. This is possible through a tool called Responder. By default, the script will run at the end of all other scripts for 15 minutes (900


If for any reason you want to disable this tool from running, you can do so with the –P or

poison flag. Additionally, you can set a timeout limit for the script to stop running after a period of time with the –t or —time flag. Of course, these two flags cannot be combined, and doing so would lead to the script producing errors.

The following example will execute the default script on the eth0 interface using the T3

timing option and stop running Responder after 10 minutes:

sudo python warberry.py –I eth0 --intensity –T3 –t 600

When I am in a network that I know doesn’t have many security mechanisms, so I don’t mind being a bit loud, I like to use threaded scanning, so the script finishes earlier. This functionality can be enabled through the –Q or —quick flag, which enables threads. This means that we will be using 100 threads for our scans. Combining this with T4, you are being as loud as possible, and the device will probably be picked up immediately.

During the early stages of execution, the warberry.py will sniff network names and attempt to see if any interesting ones can be found. If any interesting names are found, then it changes its hostname to one of those names in order to blend in, so it’s harder to identify.

But what do I mean by interesting names?

If you go to the /src/core/utils file, you will see at Line 175 there’s a small array of words: You can add or delete any words you want on this list, depending on the environment you are attacking. During execution, if any of these names are encountered, the WarBerryPi will change its hostname to that name. If you don’t want to do that, you can invoke the –H or

hostname flag, which will skip this phase. This is useful in cases where you want to assess the defensive mechanisms inside an organization or the response time of the IT department, as it will be obvious that a rogue device was placed inside their network. This flag cannot be combined with the –N flag.

The malicious mode is defined by –M or —malicious. By malicious, we mean that only the poisoning phase is performed. In other words, if you only want to gather credentials and would like to skip all other phases, this is the flag to use. This flag can be combined with the

-t or —time flag, but no other flags.

Next up are two interesting flags, the –B or —bluetooth and –W or —wifi. The Bluetooth flag makes use of the embedded Bluetooth module of the Raspberry Pi 3 and the Wi-Fi flag the embedded Wi-Fi module. The Bluetooth module gathers all nearby Bluetooth device names, and the Wi-Fi module captures all the nearby wireless network names. What is interesting about these two flags is that the information they gather has nothing to do with the network we are attacking. The sole purpose of the information that is gathered is to be used later on, during the social engineering attacks.

Depending on your engagement, you may want to just use a passive device and not perform any scans. The WarBerryPi can provide a network sniffer for you that does nothing except

sniff the number of packets you specify. By default, this is going to be 20 packets. The flag responsible for this functionality is –S or —sniffer.

All results and output from the script is saved inside the /WarBerry/Results directory.

Although each time you run the script previous files are overwritten, it is good practice to delete previous results to avoid confusion. This can be done through the –C or —clear flag.

This flag cannot be combined with any other flags.

As you can see, I skipped the enumeration and reconnaissance flags. This is because they are still experimental and their functionality is currently covered by other phases. So don’t worry, you’re not missing anything.

CHAPTER 6 – The WarBerryPi Back End

This chapter is only useful to people who want to understand what happens in the background when you run the warberry.py script. Understanding the inner workings can be beneficial if you want to modify the script to your liking. Going through the entire code would not be possible, so I chose only what I believe are the most important areas. The remaining parts that are left out should be pretty easy for any Python developer to fill in.

Project structure

The project is divided into the main WarBerry directory, which holds the Tools and Results folders. It also holds the _warberry _ directory, which is further explained below.

The warberry directory is where all the action takes place. Besides the warberry.py Python script, which is the main script the warberry directory holds, there’s the _src, _ which refers to the source of the script.

The src in turn is broken down into the utils and core directories. Think about utils as being all the scripts that take place for finding if we have a valid IP and any other scripts responsible mostly for preparation before running the main script. The core is where all the scanning and enumeration scripts are located. The structure looks like the image below: Going into the warberry.py script might look daunting at first, as there are a lot of imports taking place. This is just standard procedure to import all of the scripts and utilities needed for the operation of the WarBerryPi. The real action begins at Line 114:

This chunk of code is responsible for checking that we are running the script with “sudo”

rights. If not, the script will exit, as running the script with limited access rights will affect further scripts, which will not be able to run. The chunk of code starting at Line 126 just checks to see which interface has a valid IP in order to run the scripts on that one. In cases when we have both an Ethernet and a wireless IP, we can specify which one to use with the –

I flag, as I explained before. It is good practice to always specify the interface. At Line 135

we call the iprecon function and we send it the interface name. The iprecon function is located in /src/core/enumeration/ip_enum and it is explained below:

This module is where we extract the internal IP on the interface we specified. We validated that the IP is valid by calling the int_ip function, which is located in /src/core/utils.

The purpose of this function is to check that the internal IP we obtained is not private, loopback, reserved, or hostmask. In other words, it verifies that we have a valid IP, so we can continue with the script.

The next part is to generate the netmask for the IP we have obtained, and that is also in the

[_/src/core/utils. _] The netmask is required later on, for the creation of the CIDR.

_ _

The next step is to see if the WarBerryPi can reach the Web. This is done by requesting our external IP address from a third-party website. Keep in mind that if you do multiple requests in a short period of time, you may not get any results. This is a protection from the third-party website, so that people don’t query them non-stop.

The final part of the ip_enum function is to create the CIDR. This is very useful, as the CIDR

will be used later on in our scanning scripts. In order to create the CIDR, we need to send the IP and the netmask to the /src/core/utils

Here, a little of bit of Python kung fu takes place to break down the netmask and generate the CIDR based on that.

Up to now, we followed the process when a valid IP is obtained. But what happens if a non-valid IP is obtained? This is what line 53 in [_/src/core/enumeration/ip_enum _] does.

Here we will make a series of assumptions, including that we could not obtain a valid IP

because of some kind of filtering. If the network port is not activated, we cannot do anything of course.

Nevertheless, let’s assume that the port is activated and the reason we did not obtain an IP

address is some kind of filtering blocking us. The first step to overcoming this problem is to assume that the network is protected by static IP addresses. That means we need a valid IP

belonging to the network to be hard coded.

Static IP Filtering Bypass

This process takes place in the /src/core/bypass/static file.

Here we leverage one of the tools installed during the installation process, and that is none other than Netdiscover. With Netdiscover, we aim to find IP addresses in the network and save them in a list. That list is then verified to ensure that the IPs we gathered are valid.

As long as we have a valid IP captured, we will move to the [_/src/core/utils/ _] and specifically to the _set_static _ function.

The concept behind this is simple: Review the IP addresses we saw in the network and create the CIDR based on those, excluding the IPs that are in use from the list. Then change the IPs of the WarBerryPi one by one, and ping one of the IPs that are in use. If we get a response, that means we have a valid IP that can communicate inside the network. We follow the same process for all IPs in our list, and if we still don’t get a valid response, then we make the assumption that MAC address filtering may be in place. Otherwise, we proceed with the rest of the script as normal.

The process is shown below:

MAC Address Filtering Bypass

The MAC address filtering bypass is a bit different. The code for attempting the bypass is located at /src/core/bypass/mac and it goes like this:

Run Netdiscover, but this time capture MAC addresses. Change the MAC address of the WarBerryPi manually, and also set a random IP from the list of IPs obtained before. Once again, ping any of the IPs that are currently in use, and check if a valid response is obtained.

The process is diagrammed below:

If no MAC addresses are captured or we don’t have a valid IP, then we make the assumption that there is port filtering or NAC, and we move on to the respective bypassing function.

NAC Filtering Bypass

The NAC bypass function works under the assumption that NAC filtering is in place, but some devices have an exception because they don’t support NAC. In real life, some devices such as printers are often excepted, and that is what we aim for.

The responsible function for performing these steps is located at [_ /src/core/bypass/nac_] What is important to note here is the array at Line 29. The current array that ships with the WarBerryPi is for demo purposes and does not have real value in the corporate world. If you have prior intelligence about the network, you should change the values of the devices you believe they will have an exception in this array. It is also a good idea to enter the specific names of the printer models and so on that may be present inside the network.

The rest of the process basically is a combination of the static IP bypass and the MAC bypass functions, but here we also leverage the hostnames enumeration. If we get a bit lucky, we may find a device that has an exception and duplicate its MAC and IP. Keep in mind, though, that duplicate IPs may also cause problems inside the network.

The process is diagrammed below:

If no MAC addresses are captured or we don’t have a valid IP, we simply exit. At this stage, we can take control of the WarBerryPi remote and troubleshoot.

Main Execution

At this point, I assume that you have a valid IP and we can continue with the execution of the warberry.py script.

Before jumping into the port scanning section of the script, we first need to define a scope.

The scope is simply the IP list that we will use for any subsequent scans. Rather than scanning the entire subnet and creating unnecessary noise in the network, we will attempt to include only IPs that appear as live in the network. During this process, we may miss some hosts that either were not active or do not respond to ping, but nevertheless during a Red Team operation you try to be as quiet as possible, so the risk of missing a couple of IPs is worth it.

As you can see from the code extract above, we use the interface name that was defined at start-up time and also the CIDR, which was created in the next step. Whenever we sniff a packet with an IP belonging to our subnet, we include it in a list called live_ips. The code of this script is located at [_/src/core/enumeration/ip_enum. _]

_ _

The next important phase of the execution is the port scanning phase. During this phase we will identify the open ports, which we will do further enumeration on.

As explained in the previous section, the WarBerryPi supports different numbers of scans.

The initial design (and what I currently use) is the targeted port one, which will scan only selected ports. All scanners can be found under [_/src/core/scanners, _] and as you will see, there are two variants for each scanner. The difference between these scanners is that one version uses threads and the other doesn’t. _ _

_ _

The port scanning phase is supplemented by the enumeration phase. An example would be that we found a number of Windows hosts, and we identified that based on the fact that ports 445 and 139 were open. Based on the operating system, the warberry.py script will attempt to enumerate shares and users via SMB.

Another example would be finding an FTP port open and attempt to anonymously log in.

The final phase of the script is to launch Responder to begin poisoning the network with the goal of capturing some user credentials. The GitHub repository for Responder can be found here:


Responder is a great tool and can be extremely helpful in any penetration test or Red Team engagement. As with all tools though, use with caution.

CHAPTER 7 – Reporting

The reporting module was built to assist in visualizing the results and planning your next actions. The entire reporting module is located under the /REPORTING folder and is not dependent on any other files.

The reporting module requires an Apache Web server, which can be easily installed with XAMPP.


As mentioned in previous chapters, all output generated during the execution of the warberry.py script is saved in various files in [_/home/pi/WarBerry/Results/. _]

The reporting module requires nothing more than those results files in order to generate a report. In simple words, the only requirement is to transfer the Results folder from the WarBerryPi to the Reporting folder on your workstation.

When I am using Windows, I use Putty

(http://www.chiark.greenend.org.uk/~sgtatham/putty/) to transfer the folder, and when I am on my Mac, I use CyberDuck (https://cyberduck.io/?l=en).

When you visit localhost/warberry/reporting.html in your browser, you should be presented with the following page:

The reporting module is dynamic and the content is created based on the results so that we are not presented with unnecessary information.

The reporting module is straightforward: You just click what information you want to see and that’s all.

_ _

CHAPTER 8 – Building Your own Scanner

If you want to change the current port list that ships with the WarBerryPi, you only need to change one file, which is located at [_/src/core/scanners/port_list. _]

The file is broken down into six lists:

1. Path File – The path of the file that will hold the output

2. Result File – Where results should be saved

3. Message – This is simply an output message that is shown to the user if the specific port is found to be open. This is helpful in case you want to remember the exact command or tool to use.

4. Name – The name of the service we are scanning for.

5. Port – This denotes the port number to scan. If you want to scan multiple ports for one service, then you need to enclose them in quotes like ’8611,8612,5222,5223’

6. Scan Type – This field specifies if the port scan should take place over TCP, UDP, or both. The “n” character denotes a TCP scan, the “y” character a UDP scan.

The order you insert the information in the above lists is of paramount importance. Since the lists will be read sequentially, this means that the port number at location 3 should correspond to the correct file at location 3, and so on.

CHAPTER 9 -‐ Adding a Switch

On one of my devices, I installed a toggle switch to control the script execution. This allows me to first check on the LCD that the WarBerryPi has obtained a valid IP address before starting the execution. Installing the switch is an easy job, but it does require you to drill a hole in the case.

The connection schematic is shown below. Of course, you can connect to another pin of your preference, but in my setup, I used PIN16, which corresponds to BCM23 on the Raspberry Pi.

Depending on the toggle switch you purchased, you need to identify which pin is the ground pin.

Then create the switch controller script. Change the pins and script location according to your setup. On the RPi3, I have the switch connected to PIN6 and PIN16, which correspond to GND and BCM23 respectively.

Once you have installed the switch correctly, you need a way to control it. The controller script is a Python script, which in essence waits for a change on the GPIO PIN 23. As soon as it detects that, it will execute whatever command we want.

Create a file using nano/vi/vim/gedit and name it switch.py. Place the following code inside the file and save it inside the /home/pi/WarBerry/warberry directory:

1. #!/usr/bin/env python2.7

2. import RPi.GPIO as GPIO

3. import subprocess

4. GPIO.setmode(GPIO.BCM)

5. import os


7. GPIO.setup(23, GPIO.IN, pull_up_down=GPIO.PUD_UP)


9. try:

10. GPIO.wait_for_edge(23, GPIO.FALLING)

11. subprocess.call(“sudo python warberry.py”, shell = True)


13. except KeyboardInterrupt:

14. GPIO.cleanup()

15. GPIO.cleanup()

Make any amendments you would like at Line 11, which is the part that controls which code will be executed. My example above will simply execute the warberry.py script without any additional parameters.

In order for the Python script to run, we need another controller script to call our Python script. This will be a very short Bash script.

1. #!/bin/sh

2. cd /home/pi/WarBerry/warberry/

3. sudo python switch.py

Now for the start.sh script to be called at boot time, so our system is waiting for a change on the pin. We need to put an entry inside the rc.local file as follows:

sudo nano /etc/rc.loca

Scroll to the end and add the line

sudo bash /home/pi/WarBerry/start.sh &

If you have named your files differently or saved inside different categories, now is the time to make the necessary changes.

And that’s it. Reboot your WarBerryPi and toggle the switch. Nothing will appear on the command line, because the process is running in the background. But if you run the command ps aux | grep warberry you should see a process running.

CHAPTER 10 -‐ Adding an LCD

I mentioned in the hardware requirement section that I use an LCD to display some basic information. My personal preference is the Display-O-Tron 3000, but you can use anything you like. What I like about this LCD is that it is a shield, meaning that it snaps on the Raspberry Pi pins, avoiding the need for any soldering.

If you want to duplicate this setup, it is not difficult at all.

I have created a folder inside the /WarBerry directory called /init_scripts and inside I place whatever scripts I want to execute at boot time.

Create a new file called lcd_init.sh and paste the following code:

1. #!/bin/sh

2. cd /home/pi/WarBerry/init_scripts/

3. sudo python lcd_on.py

Now create a new file called lcd_on.py and paste the following code:

1. import dothat.lcd as lcd

2. import dothat.backlight as backlight

3. import math

4. import os, subprocess

5. import time


7. time.sleep(0.05)


9. backlight.off()

10. backlight.set_graph(0)

11. lcd.clear()

12. backlight.rgb(100, 255, 255)

13. lcd.set_contrast(50)

14. lcd.set_cursor_position(3, 0)

15. lcd.write(“WarBerryPi”)

16. subprocess.call("sudo /sbin/ifconfig eth0 | grep 'inet addr:' | cut -‐d: -‐

f2 | awk ‘{ print $1}’ > eth_ip_ad”, shell = True)

17. subprocess.call("sudo /sbin/ifconfig wlan0 | grep 'inet addr:' | cut -‐d: -‐

f2 | awk ‘{ print $1}’ > wlan_ip_ad”, shell = True)

18. subprocess.call("sudo /sbin/ifconfig eth1 | grep 'inet addr:' | cut -‐d: -‐

f2 | awk ‘{ print $1}’ > eth1_ip_ad”, shell = True)



21. lcd.set_cursor_position(0, 1)

22. lcd.write(“E: “)

23. with open(‘eth_ip_ad’, ‘r’) as eth_ip:

24. eth = eth_ip.readline()

25. if eth == “”:

26. lcd.set_cursor_position(2, 1)

27. lcd.write(“N/A”)

28. else:

29. e = eth.strip()

30. lcd.set_cursor_position(2, 1)

31. lcd.write(e)


33. lcd.set_cursor_position(0, 2)

34. lcd.write(“W: “)

35. with open(‘wlan_ip_ad’, ‘r’) as wlan_ip:

36. wlan = wlan_ip.readline()

37. if wlan == “”:

38. lcd.set_cursor_position(2, 2)

39. lcd.write(“N/A”)

40. else:

41. w = wlan.strip()

42. lcd.set_cursor_position(2, 2)

43. lcd.write(w)

The lcd_on.py script is the script responsible for putting the information on screen. Basically what the script does is extract the IP addresses of eth0, eth1, and wlan0, saving them in text files that are then read by the script to display the information at the right location on the LCD.

Now we need to instruct the lcd_init.sh to start at boot time:

sudo nano /etc/rc.local

Scroll to the end and add the line

sudo bash /home/pi/WarBerry/init_scripts/lcd_init.sh &

And that’s it. If you have downloaded the correct libraries for the LCD, it should work like a charm.


I’d like to thank the people that helped me during the development of the WarBerryPi.

First and foremost, I’d like to thank my good friend Renos (@zrenos), who introduced me to the concept of microdevices and gave me my first RaspberryPi. He also went to BSides Athens with me to offer his support. BSides Athens was the first conference that gave me the opportunity to present the WarBerryPi, and that was the beginning of a great journey for me.

Preparing for Blackhat and other conferences, I needed to put it a lot of hours, and my team member Stella (stconstanti) was always there with me, debugging and most important, building the reporting module.

I have also created a Hall of Fame page in my GitHub wiki page for all the people that contributed to the project. You can find them all here:


And I could not leave out my good friends at ToolsWatch (@toolswatch) for giving me the opportunity to present at Blackhat USA and Blackhat Europe.

Last I wanted to close by thanking Peerlyst for building a more transparent information security culture, allowing everybody to be a part of this great InfoSec community.

[*Thanks for reading! Let me know how things work out for you—and keep in touch. *]

[email protected]


WarBerry Pi: The Complete Guide

This is a comprehensive introduction from the inventor of WarBerry Pi. This short volume teaches you what WarBerryPi is—and how you can use it. The main purpose of the WarBerryPi is to be useful during Red Team operations. Since the whole Red Team/Blue Team terminology stems from the military, @sec_groundzero wanted to baptize his project with a military-related term, hence the name “WarBerryPi.”

  • ISBN: 9781370773251
  • Author: @sec groundzero
  • Published: 2017-02-16 01:20:18
  • Words: 7794
WarBerry Pi: The Complete Guide WarBerry Pi: The Complete Guide