etc.git


etc

~ scripts and random things
git clone https://github.com/djnnvx/etc.git
log | files | refs | archive

commit 50ece89659bfd3d1f99f2cb84cb2b7164f2b0327
parent 9a7e60ea84b3a5445f171478ec2f773c6dbf2547
Author: djnn <[email protected]>
Date: Wed, 16 Jul 2025 23:17:09 +0900

Merge branch 'main' of github.com:djnnvx/etc

Diffstat:
Aembedded/arduino-packet-sniffer/lila.ino | 527+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

1 file changed, 527 insertions(+), 0 deletions(-)

diff --git a/embedded/arduino-packet-sniffer/lila.ino b/embedded/arduino-packet-sniffer/lila.ino
@@ -0,0 +1,527 @@
+/*
+   lila ~ https://djnn.sh/posts/why-fi/
+
+   esp8266 packet-sniffer. relays packets count over mqtt & informs you in case of
+   deauth attack.
+
+PLEASE NOTE:
+
+  since it uses the same WiFi stack to run analysis & communicate, this really fucking
+  sucks. ive attempted to do this just to do something funny. please dont actually use
+  this or attempt to replicate. its fucking stupid.
+
+Dependencies:
+
+- arduinojson
+- arduino pubsub client
+- base64
+- time
+
+ */
+
+
+#include "base64.hpp"
+#include <SPI.h>
+#include <ArduinoJson.h>
+#include <PubSubClient.h>
+#include <WiFiClientSecure.h>
+#include <Arduino.h>
+#include <TimeLib.h>
+
+
+#ifdef ESP8266
+#include <ESP8266WiFi.h>
+#else
+#include <WiFi.h>
+#endif
+
+extern "C" {
+  #include "user_interface.h"
+}
+
+// ignore stupid warnings
+#pragma GCC diagnostic ignored "-Wwrite-strings"
+
+/* CONSTANTS */
+
+#define LED             2           /* LED pin (2=built-in LED) */
+#define SERIAL_BAUD     9600        /* Baudrate for serial communication */
+#define CH_TIME         140         /* Scan time (in ms) per channel */
+
+#define DELAY_TIME              1000
+#define QUICK_DELAY_TIME        500
+#define VERY_QUICK_DELAY_TIME   10
+
+
+#define MQTT_TOPIC_INPUT    "lila_output"
+#define MQTT_TOPIC_OUTPUT   "lila_input" /* name is confusing because the chip output is the server input */
+#define MQTT_USERNAME       "lila-sniffer"
+#define MQTT_PASSWORD       ""
+#define MQTT_SERVER_URL     "broker.hivemq.com"
+#define MQTT_CLIENT_ID      "djnn.sh"
+#define MQTT_PORT           1883
+
+#define STATE_ASLEEP            0
+#define STATE_MONITOR_MODE      1
+#define STATE_SOFT_AP_MODE      2
+
+#define COMMAND_SET_ASLEEP    "ASLEEP"
+#define COMMAND_SET_MONITOR   "MONITOR_DEAUTH"
+#define COMMAND_SET_SOFTAP    "SOFTAP"
+
+#define MSG_OK "OK"
+#define MSG_KO "KO"
+
+/* VARIABLES */
+
+#define MQTT_MSG_SIZE 512
+
+// program things
+unsigned int program_state = STATE_SOFT_AP_MODE;
+char mqtt_msg_to_send[MQTT_MSG_SIZE];
+
+WiFiClient net_client;
+PubSubClient ps_client(net_client);
+
+int nb_packets = 0;
+char ip_address[256];
+
+char saved_ssid[256];
+char saved_pass[256];
+
+
+/* FUNCTIONS */
+
+// Connects to local WiFi hotspot
+void __wifi_local_connect(char const *ssid, char const *pass) {
+    WiFi.mode(WIFI_STA);
+    WiFi.begin(ssid, pass);
+    while (WiFi.status() != WL_CONNECTED) {
+        delay(VERY_QUICK_DELAY_TIME);
+    }
+}
+
+
+// sets up soft access point on setup
+void __wifi_setup_soft_ap() {
+
+    delay(QUICK_DELAY_TIME);
+    Serial.println("Setting up soft-AP with credentials: lila1337:lila1337.......");
+    if (WiFi.softAP("lila1337", "lila1337")) {
+        __blink_success();
+
+        program_state = STATE_SOFT_AP_MODE;
+
+        // ensure we can scan & use AP mode
+        WiFi.mode(WIFI_AP_STA);
+
+        IPAddress myIP = WiFi.softAPIP();
+        Serial.print("[+] AP IP address: http://");
+        Serial.println(myIP);
+    } else {
+        __blink_failure();
+        Serial.println("[!] Could not set up webserver........");
+        return;
+    }
+
+    Serial.println("Booting up webserver...");
+
+    WiFiClient net_client;
+    WiFiServer configWebServer(80);
+    configWebServer.begin();
+
+    // run webserver until we have wifi credentials
+    while (program_state == STATE_SOFT_AP_MODE) {
+
+        // either scan for Wifi hotspots or connect to them...
+        net_client = configWebServer.available();
+        if (net_client) {
+
+            char line[64];
+            int l = net_client.readBytesUntil('\n', line, sizeof(line));
+            line[l] = 0;
+
+            net_client.find((char*) "\r\n\r\n");
+            if (strncmp_P(line, PSTR("POST"), strlen("POST")) == 0) {
+                l = net_client.readBytes(line, sizeof(line));
+                line[l] = 0;
+
+                // parse the parameters sent by the html form
+                const char* delims = "=&";
+                strtok(line, delims);
+
+                const char* ssid = strtok(NULL, delims);
+                strtok(NULL, delims);
+
+                const char* pass = strtok(NULL, delims);
+
+                memset(saved_ssid, 0, 256);
+                memset(saved_pass, 0, 256);
+                strncpy(saved_ssid, ssid, 256);
+                strncpy(saved_pass, pass, 256);
+
+                // send a response before attemting to connect to the WiFi network
+                // because it will reset the SoftAP and disconnect the client station
+                net_client.println(F("HTTP/1.1 200 OK"));
+                net_client.println(F("Connection: close"));
+                net_client.println(F("Refresh: 10")); // send a request after 10 seconds
+                net_client.println();
+                net_client.println(F("<html><body><h3>Configuration AP</h3><br>connecting...</body></html>"));
+                net_client.stop();
+
+                Serial.println();
+                Serial.print("Attempting to connect to WPA SSID: ");
+                Serial.println(ssid);
+
+                WiFi.persistent(true);
+                WiFi.setAutoConnect(true);
+                WiFi.begin(ssid, pass);
+                WiFi.waitForConnectResult();
+
+            } {
+
+                net_client.println(F("HTTP/1.1 200 OK"));
+                net_client.println(F("Connection: close"));
+                net_client.println();
+                net_client.println(F("<html><body><h3>Configuration AP</h3><br>"));
+
+                int status = WiFi.status();
+                if (status == WL_CONNECTED) {
+
+                    net_client.println(F("</body></html>"));
+
+                    program_state = STATE_ASLEEP;
+                    net_client.println(F("Connection successful. Ending AP."));
+                    net_client.stop();
+
+                    delay(1000);
+                    Serial.println("Connection successful. Ending AP.");
+                    configWebServer.stop();
+
+                    WiFi.mode(WIFI_STA);
+                    Serial.print("WiFi status = ");
+                    Serial.println(WiFi.status());
+
+                    Serial.print("Local IP address:");
+                    Serial.println(WiFi.localIP());
+
+
+                    return;
+
+                } else {
+                    net_client.println(F("<form action='/' method='POST'>WiFi connection failed. Enter valid parameters, please.<br><br>"));
+                    net_client.println(F("SSID:<br><input type='text' name='i'><br>"));
+                    net_client.println(F("Password:<br><input type='password' name='p'><br><br>"));
+                    net_client.println(F("<input type='submit' value='Submit'></form>"));
+                    net_client.println(F("</body></html>"));
+                }
+            }
+        }
+    }
+}
+
+// Reconnects to MQTT server
+PubSubClient __mqtt_reconnect(PubSubClient ps_client, WiFiClient net_client, char ip[256]) {
+
+    Serial.printf(
+      "[+] Attempting MQTT connection to %s: [username = %s, client id: %s]\n",
+      MQTT_SERVER_URL,
+      MQTT_USERNAME,
+      MQTT_CLIENT_ID
+    );
+
+    if (ps_client.connect(MQTT_CLIENT_ID, MQTT_USERNAME, MQTT_PASSWORD)) {
+      __blink_success();
+      ps_client.subscribe(MQTT_TOPIC_INPUT);
+      Serial.printf("Subscribed to topic %s\n", MQTT_TOPIC_INPUT);
+
+    } else {
+      __blink_failure();
+      Serial.print("error: ");
+      Serial.println(ps_client.state());
+      return ps_client;
+   }
+
+    char mqtt_message[512];
+    DynamicJsonDocument js = __get_net_information(net_client, ip);
+
+    serializeJson(js, mqtt_message);
+    ps_client.publish(MQTT_TOPIC_OUTPUT, mqtt_message, true);
+    Serial.printf("[+] net info: %s\n", mqtt_message);
+    return ps_client;
+}
+
+// returns public ip address by querying various "what's my IP" services
+void __net_get_public_ip(WiFiClient net_client, char *output, size_t output_size) {
+
+    char return_value[256];
+
+    memset(output, 0, output_size);
+
+    strncpy(return_value, "0.0.0.0", 256);
+    strncpy(output, return_value, output_size - 1);
+    output[output_size - 1] = '\0';
+
+    Serial.println("Attempting to retrieve Public IP address...");
+
+    delay(QUICK_DELAY_TIME);
+
+    // check if service is up & we can connect
+    if (!net_client.connect("ipecho.net", 80)) {
+        Serial.print("could not connect. status = ");
+        Serial.println(net_client.status());
+        __blink_failure();
+        return;
+    }
+
+    // hand-write the request
+    net_client.println(F("GET /plain HTTP/1.0"));
+    net_client.println(F("Host: ipecho.net"));
+    net_client.println(F("User-Agent: lila (ESP8266 packet sniffer)"));
+    net_client.println(F("Accept: */*"));
+    net_client.println(F("Connection: close"));
+    net_client.println();
+
+    delay(5000);
+
+    // skip all lines until last one
+    String line;
+    do {
+        line = net_client.readStringUntil('\n');
+    } while (net_client.available());
+
+    // Copy the last line to return_value
+    strncpy(output, line.c_str(), output_size - 1);
+
+    Serial.printf("IP Address: %s\n", output);
+}
+
+
+// returns wifi security type (WEP, WPA, etc) as a string to be serialized
+char *__wifi_get_security() {
+    char *security_descriptors[] = {
+        "UNKNOWN",
+        "UNKNOWN",
+        "TKIP (WPA)",
+        "UNKNOWN",
+        "CCMP (WPA)",
+        "WEP",
+        "UNKNOWN",
+        "NONE",
+        "AUTO",
+    };
+
+    return security_descriptors[8];
+}
+
+// Retrieves network information related to current SSID
+DynamicJsonDocument __get_net_information(WiFiClient net_client, char ip[256]) {
+
+    /*
+       Retrieve following information and return it in a JSON-formatted string:
+
+       - SSID
+       - signal strength
+       - public IP address
+       - Security (WPA/WPA2)
+       - channel number
+       - number of packets
+     */
+
+    DynamicJsonDocument js(MQTT_MSG_SIZE);
+
+    js["ssid"] = WiFi.SSID();
+    js["mac"] = WiFi.macAddress();
+    js["channel"] = WiFi.channel();
+    js["strength"] = WiFi.RSSI();
+    js["ip-address"] = ip;
+    js["security"] = __wifi_get_security();
+    js["nb_packets"] = nb_packets;
+
+    return js;
+}
+
+
+// MQTT callback on message read
+void __mqtt_read_callback(char* topic, byte* payload, unsigned int length) {
+
+    String msg = "";
+    for (int i = 0; i < length; i++)
+      msg += (char)payload[i];
+
+    Serial.println("[MQTT] received [" + String(topic) + "]: " + msg);
+    if (!strcmp(msg.c_str(), COMMAND_SET_ASLEEP) && program_state != STATE_ASLEEP) {
+      Serial.println("SET MODE ASLEEP");
+      program_state = STATE_ASLEEP;
+
+      wifi_promiscuous_enable(0);
+      wifi_set_promiscuous_rx_cb(__sniffer_asleep);
+      wifi_set_channel(WiFi.channel());
+      wifi_promiscuous_enable(1);
+      goto CALLBACK_SEND_OK;
+    }
+
+    if (!strcmp(msg.c_str(), COMMAND_SET_MONITOR) && program_state != STATE_MONITOR_MODE) {
+      Serial.println("SET MODE MONITOR");
+      program_state = STATE_MONITOR_MODE;
+
+      wifi_promiscuous_enable(0);
+      wifi_set_promiscuous_rx_cb(__sniffer_monitor);
+      wifi_promiscuous_enable(1);
+      goto CALLBACK_SEND_OK;
+    }
+
+
+    if (!strcmp(msg.c_str(), COMMAND_SET_SOFTAP)) { // cannot interact once softap mode enabled
+      Serial.println("SET MODE SOFT_AP");
+      program_state = STATE_SOFT_AP_MODE;
+
+      wifi_promiscuous_enable(0);
+      goto CALLBACK_SEND_OK;
+    }
+
+    strncpy(mqtt_msg_to_send, MSG_KO, sizeof(MSG_KO));
+    return;
+
+CALLBACK_SEND_OK:
+    strncpy(mqtt_msg_to_send, MSG_OK, sizeof(MSG_OK));
+    return;
+}
+
+
+// blink for a long time in case of error
+void __blink_failure() {
+    digitalWrite(LED, LOW);
+    delay(DELAY_TIME);
+    digitalWrite(LED, HIGH);
+}
+
+// blink for a short time in case of success
+void __blink_success() {
+    digitalWrite(LED, LOW);
+    delay(QUICK_DELAY_TIME);
+    digitalWrite(LED, HIGH);
+}
+
+void __sniffer_relay(uint8_t *buf, uint16_t len) {
+
+  char mqtt_message[512];
+  DynamicJsonDocument js(512);
+
+  char pcap[64];
+  encode_base64(buf, len, (unsigned char *)pcap);
+
+  js["mac"] = WiFi.macAddress();
+  js["strength"] = WiFi.RSSI();
+  js["pcap"] = pcap;
+
+  serializeJson(js, mqtt_message);
+
+  Serial.println(mqtt_message);
+}
+
+
+void __sniffer_monitor(uint8_t *buf, uint16_t len) {
+  if (buf && len >= 27) {
+    byte pkt_type = buf[12];
+
+    // If captured packet is a deauthentication or dissassociaten frame
+    if (pkt_type == 0xA0 || pkt_type == 0xC0) {
+      ps_client.publish(MQTT_TOPIC_OUTPUT, "ALERT DEAUTH", true);
+      Serial.println("Spotted DEAUTH attack!");
+    }
+  }
+}
+
+void __sniffer_asleep(uint8_t *buf, uint16_t len) {
+   if (buf && len >= 27)
+      nb_packets += 1;
+}
+
+void __switch_promiscuous_mode(int mode) {
+  if (mode == 1) {
+
+    WiFi.disconnect();
+
+    if (program_state == STATE_ASLEEP) {
+      wifi_set_promiscuous_rx_cb(__sniffer_asleep);
+    } else if (program_state == STATE_MONITOR_MODE) {
+      wifi_set_promiscuous_rx_cb(__sniffer_monitor);
+    }
+
+    wifi_promiscuous_enable(1);
+    delay(VERY_QUICK_DELAY_TIME);
+
+  } else {
+
+    wifi_promiscuous_enable(0);
+    __wifi_local_connect(saved_ssid, saved_pass);
+    ps_client.setServer(MQTT_SERVER_URL, MQTT_PORT);
+    ps_client.setCallback(__mqtt_read_callback);
+
+    if (ps_client.connect(MQTT_CLIENT_ID, MQTT_USERNAME, MQTT_PASSWORD)) {
+      ps_client.subscribe(MQTT_TOPIC_INPUT);
+    }
+  }
+
+}
+
+/*
+ * Main routines for arduino things
+ *
+ * setup -> constructor, will set up the environment for the esp to do it thing
+ * loop -> main execution loop. manages state etc
+ */
+
+
+void setup() {
+
+    // init led
+    pinMode(LED, OUTPUT);
+    randomSeed(millis());
+
+    // init serial output
+    Serial.begin(SERIAL_BAUD);
+    while (!Serial) delay(QUICK_DELAY_TIME);
+
+    delay(QUICK_DELAY_TIME);
+
+    Serial.println("waking up.......");
+    __wifi_setup_soft_ap();
+    __blink_success();
+   __net_get_public_ip(net_client, ip_address, 256);
+   __switch_promiscuous_mode(1);
+}
+
+
+void loop() {
+    Serial.println("[+] Looping...");
+
+    delay(DELAY_TIME * 3);
+    __switch_promiscuous_mode(0);
+    delay(DELAY_TIME);
+    ps_client.loop();
+    __switch_promiscuous_mode(1);
+
+
+    if (program_state == STATE_SOFT_AP_MODE) {
+      __wifi_setup_soft_ap();
+      goto endloop;
+    }
+
+    if (program_state == STATE_ASLEEP) {
+      memset(mqtt_msg_to_send, 0, MQTT_MSG_SIZE);
+
+      __switch_promiscuous_mode(0);
+      DynamicJsonDocument js = __get_net_information(net_client, ip_address);
+      serializeJson(js, mqtt_msg_to_send);
+      Serial.printf("[MQTT] sending: %s\n", mqtt_msg_to_send);
+      ps_client.publish(MQTT_TOPIC_OUTPUT, mqtt_msg_to_send, true);
+      nb_packets = 0;
+      __switch_promiscuous_mode(1);
+    }
+
+endloop:
+    delay(DELAY_TIME);
+
+}