- Table of contentShow
At the beginning of October I wrote a blog article called White Hacking: WeMos and SquirelCrawl!. I used the WeMos (ESP32) and the firmware provided by Hacker Arsenal to do a captive portal. As you known, a captive portal is a web page which is displayed to newly connected users before they are granted broader access to network resources [wiki]. This can be used in combination with evil portals to obtain login credentials. The firmware provided by Hacker Arsenal has multiple limitations, e.g. the web page has to be a single file, without external files, meaning that all images should be integrated in the html file using base64. Moreover, the maximal allowed file size is 150 kb. I wrote a Python script (SquirelCrawl) that copies and compresses an entire web page into a file.
This time, I've implemented the captive portal (system) using MicroPython on the ESP32. This implementation allows you to upload more than one file. This means, e.g. you can upload CSS and JavaScript files for better web page style and more interaction with the user (e.g. using jquery). However, you should not forget that the WiFi speed of the ESP32 as an access point is very limited. You should always optimize the web page!
Code: https://github.com/lemariva/uPyPortal Portal optimization is required! This is only a sample and a very beta code. The portal is far away from stable :S, but it works.
Disclaimer
I assume no responsibility for the usage of this code and post. I repeat again, the book "The Hacker Playbook 2: Practical Guide to Penetration Testing - Peter Kim" says
Just remember, ONLY test systems on which you have written permission. Just Google the term “hacker jailed” and you will see plenty of different examples where young teens have been sentenced to years in prison for what they thought was a “fun time.” There are many free platforms where legal hacking is allowed and will help you further educate yourself.
How does a Captive Portal work?
DNS implementation
There is more than one way to implement a captive portal. I used the "redirect by DNS". Every time a client requests a website, a DNS query is started. I implemented a DNS server that answers all the DNS lookups returning the IP address of the ESP32 and thus, as a result, the captive portal page.
How to get the "connect to a network" message?
Every time that you connect to a hotspot, you get usually the "connect to a network" message. This is triggered in different ways depending on the OS of your device. I used Wireshark to see the package communication (I connected an external WiFi interface to my computer and I configured the interface as an access point) and I saw the following:
Windows searches for the following web addresses and expects the answers with the described texts.
Address Answer Code Text * www.msftconnecttest.com/ncsi.txt HTTP/1.1 200 OK Microsoft NCSI * www.msftconnecttest.com/connecttest.txt HTTP/1.1 200 OK Microsoft Connect Test * www.msftconnecttest.com/redirect HTTP/1.1 302 Redirect
All other traffic should be redirected to the captive portal IP.
Android searches for the following web addresses, if the answer code is 204 (no content), there is no captive portal between the device and Internet. That means, if you want to have a "connect to a network" message, you can answer these requests with a code 200 (ok). The
gen_204
needs a 302 (redirect) to your captive portal web page.Address Answer Code connectivitycheck.gstatic.com/generate_204 (>6.0) HTTP/1.1 204 No Content clients3.google.com/generate_204 (4.4) HTTP/1.1 204 No Content connectivitycheck.gstatic.com/gen_204 (>6.0) HTTP/1.1 204 No Content
iOS works as Windows, it searches for a web address and expects the answer
Success
.Address Answer Code Text captive.apple.com/hotspot-detect.html HTTP/1.1 200 OK Success
Using picoweb, a web micro-framework that works on the ESP32, it is possible to respond to the described requests and simulate that the ESP32 is connected to the Internet and acts as a hotspot. The devices that connect to the ESP32 think that it is a normal Hotspot and the "connect to a network" message appears. The "evil" portal is then opened, when the user clicks on the message.
Hardware & Software Requirements
Installing packages: upip, picoweb & notes-pico
I wrote the captive portal code inspired and using code of the notes-pico package. This package is amazing! You need to test it on the ESP32. If you want to see it live, install MicroPython on the board and then, type the following lines on the PyMark console
import upip upip.install('notes-pico')
Installing
notes-pico
usingupip
installs also the following dependenciespicoweb utemplate micropython-logging micropython-pkg_resources micropython-btreedb
Using
upip
requires that you board has access to the Internet! That means, you need to connect the board to a WiFi node. That can be done using the following codeimport network ssid_ = <#your_ssid#> wp2_pass = <#your_wpa2_pass#> sta_if = [] def do_connect(): global sta_if sta_if = network.WLAN(network.STA_IF) if not sta_if.isconnected(): print('connecting to network...') sta_if.active(True) sta_if.connect(ssid_, wp2_pass) while not sta_if.isconnected(): pass print('network config:', sta_if.ifconfig()) # connecting to WiFi do_connect()
After the installation is finished, you can run the
notes-pico
application using the following linesimport notes_pico.__main__ notes_pico.__main__.main(host=sta_if.ifconfig()[0], port=80)
Then, you can access the note application using your browser and the IP and port that are reported on the console, e.g.
Running on http://192.168.178.79:80/
If you want to read more about this application, click here.
DIY: Captive Portal on ESP32
Get the required hardware.
Install MicroPython on the ESP32. You need a nightly version greater than esp32-20171031 (31 Oct. 2017)! Versions older than this one have a problem with the DNS address of the access point (see here). A tutorial to install MicroPython on the ESP32 can be found here.
Using the PyMark console, connect the WeMos to the Internet (code above or
setup_sta_upip.py
), and install the captive-portal dependencies (picoweb, micropython-logging, utemplate, micropython-pkg_resources, micropython-btreedb). I included the filesetup_sta_upip.py
. You need to change the<your_ssid>
, and the<wpa2_password>
to the corresponding of your network and execute the file on the PyMark console (click on the run button).Check the configuration variables in
config.py
and modified them if you want to.The configuration variables are located in this file. The logged data will be save on a file on the WeMos. To do that, you can choose between 3 possibilities (btree, filedb or sqlite). I tested only btree ;). This can be selected using the variable
DB_BACKEND
. The variableDB_PASSWORD
is the admin password. I included an admin section to read the database. The user is admin, the password is defined usingDB_PASSWORD
. The DNS service only responds to the requests that contain at least of the words from the arrayDNS_ANSWERS
. This reduces the CPU workload. The words listed per default are the required in order to get the "connect to a network" message (you should not remove any of them). You can add others to this array. The problems with sockets that I described in the Wemos-Alexa blog article has also consequences here. The number of opened sockets is limited. You can expect some fatal error from the picoweb service.Modify the captive portal webpage included in the
template
folder.The
homepage.html
is the web page that the users see after clicking on the "connect to a network" message. You can include some JavaScript files, images and CSS style files in the static folder too. The WiFi speed is slow. The portal should be not to big (I included one sample portal, but it should be a lighter one - optimization is required here!). If you are an advanced user, you can also modified theadmin.html
andlogin.html
pages. These two files are only for you to see the logged data (administrator section).Load the captive_portal folder using the FTP server included (
ftp.py
), or using theampy
.Configure the name of the access point in the file
boot.py
and load this file to the root folder.Reset the Wemos.
Connect to the access point network and wait for the "connect to a network" message. Click on it and wait for the portal.
Go to
http://<ip wemos>/admin.html
enter theadmin
as user and the password fromconfig.py
and you will see the logged data.
Credits
- For the logging data, I took some of the files from notes-pico and modified them.
- For the DNS fake code, I wrote a
dns.py
file using info from here (mirror: here).
We use cookies to improve our services. Read more about how we use cookies and how you can refuse them.
Empty