How to Create Rogue APs with MicroPython on an ESP8266 Microcontroller

May 12, 2020 09:36 PM
637248902306550649.jpg

For a hacker, there are a lot of advantages to creating a fake network. One advantage forces nearby devices to use their real MAC address if you happen upon a network that's stored in their preferred network list.

There are a lot of tools out there for creating fake access points. Spacehuhn has designed one called the Beacon Spammer that's based in Arduino and allows you to create hundreds of artificial networks, all spammed out regularly using different MAC addresses. We can even create fake access points that have passwords, which can trick smartphones that have encrypted networks stored on the OS.

In this article, we're going to create an elementary version of the Beacon Spammer in MicroPython. The advantage of doing so is that a beginner can get started with creating a fake access point with just a couple of lines of code, and it works against both encrypted and unencrypted networks stored in nearby users' phones. The big difference here is that we'll be creating real fake networks, whereas the Beacon Spammer doesn't, so it can only operate so quickly.

However, we can have precise control right out of the box without needing to do a whole bunch of Arduino code. We can have control over the MAC address, the name of the network, the channel that it's operating on, whether it's hidden, and even access authentication modes like WEP, which isn't supported in Arduino IDE.

For a hacker, something like the Beacon Spammer could be used to find a bunch of different networks for devices nearby to connect to, then create the best possible fake networks to take over people's devices, perform phishing attacks, or whatever else the hacker desires.

What You'll Need

To follow along, you'll need an ESP8266-based microcontroller, such as the D1 Mini or NodeMCU. These boards are cheap and easy to find on websites like AliExpress and Amazon.

You'll also need a computer with Python3 installed and a Micro-USB cable to connect to the board, as well as an internet connection to download the MicroPython firmware binary.

Step 1: Install MicroPython on the ESP8266

To get MicroPython on your ESP8266-based board, you'll need Python 3 and ESPtool installed. Then, you'll need to connect your board to your computer, identify its serial port, erase the board, download the firmware binary, and flash the firmware to your board.

We've gone over all of this in detail in our previous guide on getting started with MicroPython on ESP8266 microcontrollers. Visit that guide, specifically Steps 1 through 5, to get everything ready, then come back here to continue.

Step 2: Enter MicroPython REPL

Once your ready, it's time to connect to the REPL command-line interface for MicroPython on the ESP8266 board. Use the following screen + serial port + baud rate format in a terminal window, making sure to replace the serial port number with the one for your device.

~$ screen SERIAL_PORT 115200

MicroPython v1.11-8-g48dcbbe60 on 2020-05-11; ESP module with ESP8266
Type "help()" for more information.
>>>

To make sure you're communicating correctly with your board, you can test it out with some simple code like:

>>> x = "Hello World"
>>> print(x)

Hello World

Step 3: Install Adafruit Ampy

Before continuing, we need a way to upload MicroPython files to the ESP8266-based microcontroller. Here, we're going to use Adafruit Ampy, which you can install on your computer using:

~$ pip3 install adafruit-ampy

Collecting adafruit-ampy
  Downloading https://files.pythonhosted.org/packages/59/99/f8635577c9a11962ec43714b3fc3d4583070e8f292789b4683979c4abfec/adafruit_ampy-1.0.7-py2.py3-none-any.whl
Requirement already satisfied: click in /usr/lib/python3/dist-packages (from adafruit-ampy) (7.0)
Collecting python-dotenv (from adafruit-ampy)
  Downloading https://files.pythonhosted.org/packages/57/c8/5b14d5cffe7bb06bedf9d66c4562bf90330d3d35e7f0266928c370d9dd6d/python_dotenv-0.10.3-py2.py3-none-any.whl
Requirement already satisfied: pyserial in /usr/lib/python3/dist-packages (from adafruit-ampy) (3.4)
Installing collected packages: python-dotenv, adafruit-ampy
Successfully installed adafruit-ampy-1.0.7 python-dotenv-0.10.3
Once Ampy is installed, we can use the format ampy --port /serial/port run

You could use Jupyter Notebook, which is the way we do it in our Cyber Weapons Lab video above. We've also shown how to use MicroPython in Jupyter Notebook with an ESP8266 device in our NeoPixel holiday lights project, so you can refer to that for help. Also, we highly recommend checking out Marcello's post on Towards Data Science that goes over getting MicroPython running on Jupyter Notebook, which lays everything out in an easy-to-understand way.

Step 4: Create the MicroPython Program

Making the code that creates a fake access point, in our case, "Null Byte Wi-Fi," is pretty simple. You can copy and paste the code below to work with it in a blank document, which you can create using nano. We called the file "fakeap.py" (you can call it whatever you'd like).

from time import sleep
import network

def newConnect(ssid):
    ap = network.WLAN(network.AP_IF)
    ap.active(True)
    ap.config(essid=ssid)
    ap.config(authmode=0, channel=1)

ssidList = ["Null Byte Wi-Fi"]

while True:
    for i in range (0, len(ssidList)):
        newConnect(ssidList[i])
        sleep(.5)

In the script, we've created a function where, when we pass in the name of a network, it creates a station; it sets it to "True"; it sets the ESSID, or the network named, to the SSID that we've specified; and then it sets the authentication mode. For the authentication code, we used "0" (zero) for open and "1" for the channel so that it's only broadcasting on channel 1.

from time import sleep
import network

def newConnect(ssid):
    ap = network.WLAN(network.AP_IF)
    ap.active(True)
    ap.config(essid=ssid)
    ap.config(authmode=0, channel=1)

In our code, the "ssidList" defines the names of the names we want to appear as fake APs. We are just using "Null Byte Wi-Fi" as an example, but you can add others as well; just separate them with a comma, like so:

ssidList = ["Null Byte Wi-Fi","Google Starbucks","TWCWIFI"]

Then, we created a loop that says "while True" (which is forever). In it, we use "for i in range (0, len(ssidList)):" where the 0 (zero) is the start of our ssidList and "len" is the length. For the length, you just need to list "ssidList" which will determine the length. If you have one fake name in there, it'll be from 0 to 1, but if you have a hundred, it will be form 0 to 100.

Next, runs "newConnect" for the "i" we specified, which runs through all of the fake names. It passes this on to the "newConnect" command we created earlier, and it runs each one of our fake names through that loop over and over and over with a delay of 0.5 seconds.

while True:
    for i in range (0, len(ssidList)):
        newConnect(ssidList[i])
        sleep(.5)

In the end, what it looks like is an infinite loop that is going through our fake names and creating a phony network for each one. After 0.5 seconds, it moves on to the next name. The result is:

from time import sleep
import network

def newConnect(ssid):
    ap = network.WLAN(network.AP_IF)
    ap.active(True)
    ap.config(essid=ssid)
    ap.config(authmode=0, channel=1)

ssidList = ["Null Byte Wi-Fi"]

while True:
    for i in range (0, len(ssidList)):
        newConnect(ssidList[i])
        sleep(.5)

Save the file by typing Control-X and Y to confirm.

Step 5: Run the File on Your Board

After saving the file on our computer, we can run it on our ESP8266 board. Again, replace the serial port number with the one for your device. You should see the code start to run on your board.

~$ ampy --port SERIAL__PORT run fakeap.py

If you want your code to run at boot, you need to replace the "main.py" file on the board. You can upload your Python file and replace the main.py file on the board with the following command.

~$ ampy --port SERIAL__PORT put fakeap.py /main.py

With this command, our board will run the program we just uploaded. It won't do so as a loop, like an Arduino, unless it was specified as an endless loop in the code. In our case, we did. The infinite loop runs forever and doesn't give the board a chance to boot, but you can stop the program in the serial REPL by pressing Control-C and then erasing the board.

Step 6: Observe Traffic in Wireshark

To see what's going on, you can use Wireshark. In it, you can create a filter to see only the packets from all the names of your fake APs, so it only looks for those.

When you run the MicroPython code on the ESP8266, it'll try to lure nearby devices into connecting to one of your fake APs. You'll be able to see different things, such as activities coming from the MCU and others directed toward it. If you see the latter, nearby devices have recognized a fake AP name and are trying to connect.

For more on viewing the data, check out the Cyber Weapons Lab video above.

It Doesn't Take More Than a Few Lines of MicroPython!

This was just a brief introduction to how to get started manipulating Wi-Fi networks and MicroPython. In general, if you want to start creating phony networks that reveal nearby devices' real MAC addresses, then it doesn't take much more than a couple of lines of MicroPython code. The ability to do so in a browser is super nifty, so you should check out how to use it in Jupyter Notebook.

Now, there are some limitations to the fake networks we create with MicroPython. For example, we're actually popping up real networks, unlike Spacehuhn's Beacon Spammer. So instead of just sending a bunch of packets that suggest there's a network there, we're creating real ones, and that limits the amount of speed we can use to create a lot of them.

If we wanted to make this even eviler, we could pop up a phishing page or try to get people to submit credentials to get access to free public Wi-Fi that doesn't exist. However, we just wanted to show you how easy it is to get started messing with Wi-Fi using MicroPython.

Cover image by georgejmclittle/123RF

Comments

No Comments Exist

Be the first, drop a comment!