diff --git a/netgotchi/buttons.ino b/netgotchi/buttons.ino index c56f176..44a309a 100644 --- a/netgotchi/buttons.ino +++ b/netgotchi/buttons.ino @@ -6,22 +6,21 @@ Button2 buttonA; Button2 buttonB; -void buttonsInit() -{ - //change your pins configurations - buttonA.begin(BTN_A); - buttonA.setID(BTN_A); - buttonB.begin(BTN_B); - buttonB.setID(BTN_B); - buttonLeft.begin(BTN_LEFT); - buttonLeft.setID(BTN_LEFT); - buttonRight.begin(BTN_RIGHT); - buttonRight.setID(BTN_RIGHT); +void buttonsInit() { + //change your pins configurations + buttonA.begin(BTN_A); + buttonA.setID(BTN_A); + buttonB.begin(BTN_B); + buttonB.setID(BTN_B); + buttonLeft.begin(BTN_LEFT); + buttonLeft.setID(BTN_LEFT); + buttonRight.begin(BTN_RIGHT); + buttonRight.setID(BTN_RIGHT); - buttonA.setPressedHandler(buttonPressed); - buttonB.setPressedHandler(buttonPressed); - buttonLeft.setPressedHandler(buttonPressed); - buttonRight.setPressedHandler(buttonPressed); + buttonA.setPressedHandler(buttonPressed); + buttonB.setPressedHandler(buttonPressed); + buttonLeft.setPressedHandler(buttonPressed); + buttonRight.setPressedHandler(buttonPressed); } void buttonLoops() { @@ -33,8 +32,17 @@ void buttonLoops() { } } -void resetSettings() -{ +void checkOfflineMode() { + + if (digitalRead(BTN_A) == LOW) { + delay(50); + if (digitalRead(BTN_A) == LOW) { + enableNetworkMode = false; + } + } +} + +void resetSettings() { displayClearDisplay(); displayPrintln("Flash button pressed. WiFiManager settings..."); wifiManager.resetSettings(); @@ -44,8 +52,7 @@ void resetSettings() ESP.restart(); } -void controlsButtonLoop() -{ +void controlsButtonLoop() { buttonA.loop(); buttonB.loop(); buttonLeft.loop(); @@ -59,32 +66,30 @@ void buttonPressed(Button2 &btn) { handleButtons(btn.getID()); } -void handleButtons(int btnID) -{ - switch (btnID){ - case BTN_A: - //A - if(settingMode)settingConfirm(); - break; +void handleButtons(int btnID) { + switch (btnID) { + case BTN_A: + //A + if (settingMode) settingConfirm(); + break; case BTN_B: - //B - if(settingMode)settingCancel(); - break; + //B + if (settingMode) settingCancel(); + break; case BTN_LEFT: - //RIGHT - nextScreen(); - break; + //RIGHT + nextScreen(); + break; case BTN_RIGHT: - //DOWN - settingMode = true; - if(settingMode) - { - selectedSetting++; - if(selectedSetting> settingLength )selectedSetting=0; - } - break; + //DOWN + settingMode = true; + if (settingMode) { + selectedSetting++; + if (selectedSetting > settingLength) selectedSetting = 0; + } + break; } } diff --git a/netgotchi/ctrlgotchi.ino b/netgotchi/ctrlgotchi.ino new file mode 100644 index 0000000..d57a579 --- /dev/null +++ b/netgotchi/ctrlgotchi.ino @@ -0,0 +1,246 @@ +#include + +String command[] = {"< ESPNOW RECEIVER >","< ESPNOW SENDER >", "< ON >", "< OFF >" , "< TIME 1min >", "< TIME 15min >", "< TIME 1h >", "< TIME 8h >", }; +String ctrlmessage = ""; +int commandLength=7; +int ctrlselectedMode = 0; + +String ctrlface = "(éwè)"; +unsigned long ctrlpreviousMillis = 0; +const long ctrlinterval = 3000; // timer at which to change the face +String ctrlstatus = "__"; +bool remote_controlled_status=false; +unsigned long previousMillisctrl = 0; +bool ctrltimerstarted=false; + +struct_message ctrlmyData; + +Button2 ctrlloaderButtonLeft; +Button2 ctrlloaderButtonRight; +Button2 ctrlloaderButtonA; +Button2 ctrlloaderButtonB; + +long ctrltimer = 0; + +void ctrlLeftButtonPressed(Button2 &btn) { + ctrlselectedMode--; + if(ctrlselectedMode< 0 )ctrlselectedMode=commandLength-1; +} + +void ctrlRightButtonPressed(Button2 &btn) { + ctrlselectedMode++; + if(ctrlselectedMode>=commandLength)ctrlselectedMode=0; +} + +void ctrlAButtonPressed(Button2 &btn) { + playTone(); + if(ctrlselectedMode == 0) + { + //display.println("Press A to control"); + } + if(ctrlselectedMode == 1) + { + //display.println("Press A to send ON"); + crtlgotchi_sendMessage("CTRL:TRIGGER"); + } + if(ctrlselectedMode == 2) + { + raisePinVoltage(); + ctrlstatus="TRG"; + } + if(ctrlselectedMode == 3) + { + lowerPinVoltage(); + ctrlstatus="LWR"; + + } + if(ctrlselectedMode == 4) + { + ctrltimer=60 * 1000; + } + if(ctrlselectedMode == 5) + { + ctrltimer=5 *60 * 1000; + } + if(ctrlselectedMode == 6) + { + ctrltimer=60 *60 * 1000; + } + if(ctrlselectedMode == 7) + { + ctrltimer=8*60 *60 * 1000; + } +} +void ctrlBButtonPressed(Button2 &btn) { + playTone(); + +} + + +void ctrlgotchi_setup() +{ + WiFi.mode(WIFI_STA); + + if (esp_now_init() != ERR_OK) { + Serial.println("Error initializing ESP-NOW"); + return; + } + + esp_now_set_self_role(ESP_NOW_ROLE_COMBO); + esp_now_add_peer(broadcastAddress, ESP_NOW_ROLE_COMBO, 1, NULL, 0); + esp_now_register_recv_cb(crtlgotchi_OnDataRecv); + + displayClearDisplay(); + + ctrlloaderButtonLeft.begin(BTN_LEFT); + ctrlloaderButtonRight.begin(BTN_RIGHT); + ctrlloaderButtonA.begin(BTN_A); + ctrlloaderButtonB.begin(BTN_B); + ctrlloaderButtonLeft.setPressedHandler(ctrlLeftButtonPressed); + ctrlloaderButtonRight.setPressedHandler(ctrlRightButtonPressed); + ctrlloaderButtonA.setPressedHandler(ctrlAButtonPressed); + ctrlloaderButtonB.setPressedHandler(ctrlBButtonPressed); +} + +void ctrlgotchi_loop() +{ + crtlgotchi_updateDisplay(); + crtlgotchi_loopFace(); + + ctrlloaderButtonLeft.loop(); + ctrlloaderButtonRight.loop(); + ctrlloaderButtonA.loop(); + ctrlloaderButtonB.loop(); + + if(ctrltimer > 0 ){ + unsigned long currentMillisctrl = millis(); + if(!ctrltimerstarted) { + ctrltimerstarted = true; + previousMillisctrl=millis(); + } + if (currentMillisctrl - previousMillisctrl >= ctrltimer) { + // Enable pin 0 after the interval + raisePinVoltage(); + ctrltimer=0; + ctrlstatus="TRG"; + ctrltimerstarted=false; + + } + } + + if(remote_controlled_status && ctrlselectedMode == 0) + { + raisePinVoltage(); + ctrlstatus="TRG"; + + } + if(!remote_controlled_status && ctrlselectedMode == 0) + { + lowerPinVoltage(); + ctrlstatus="LWR"; + + } +} + +void crtlgotchi_loopFace() { + unsigned long currentMillis = millis(); + if (currentMillis - ctrlpreviousMillis >= ctrlinterval) { + ctrlpreviousMillis = currentMillis; + crtlgotchi_changeFace(); + } +} + +void crtlgotchi_changeFace() { + static int index = 0; + // Array of different emoticons + const String ctrlfaces[] = { + " (v^v) ", + " (^-^) ", + "(-_-) ", + "(.__.) ", + " (p_p) ", + " (._.)", + "(,_,) ", + " (o_o) " + }; + // Update the face variable + ctrlface = ctrlfaces[index]; + // Move to the next ctrlface in the array + index = (index + 1) % (sizeof(ctrlfaces) / sizeof(ctrlfaces[0])); // Loop back to the start when reaching the end +} + + + + +void crtlgotchi_sendMessage(const String &msg) { + + msg.toCharArray(ctrlmyData.text, sizeof(ctrlmyData.text)); + + ctrlstatus = esp_now_send(broadcastAddress, (uint8_t *)&ctrlmyData, sizeof(ctrlmyData)) == 0 ? "OK" : "ER"; + Serial.println("status:"); + Serial.println(ctrlstatus); +} + +void crtlgotchi_OnDataRecv(uint8_t *mac, uint8_t *incomingData, uint8_t len) { + display.clearDisplay(); // Clear the display + ctrlmessage = ""; // Reset the received message + memcpy(&ctrlmyData, incomingData, sizeof(ctrlmyData)); + ctrlmessage = String(ctrlmyData.text); + if(ctrlmessage=="CTRL:TRIGGER" && ctrlselectedMode == 0) + { + playTone(); // Play tone when a new message is received + remote_controlled_status = !remote_controlled_status; + } +} + +void crtlgotchi_updateDisplay() { + display.clearDisplay(); + // Display received and sent messages at the top + display.setTextSize(1); + display.setCursor(0, 5); + display.print("CTRLGOTCHI " + ctrlface + "" + ctrlstatus); + display.setCursor(0, 15); + display.print("PIN D0 CONTROL :"); + display.println(ctrlmessage); + display.println(" "); + displayPrintln(command[ctrlselectedMode]); + display.println(" "); + + if(ctrlselectedMode == 0) + { + display.println("D0 Control enabled "); + } + if(ctrlselectedMode == 1) + { + display.println("Press A to send ON/OFF"); + } + if(ctrlselectedMode == 2) + { + display.println("Press A to enable D0"); + } + if(ctrlselectedMode == 3) + { + display.println("Press A to disable D0"); + } + if(ctrlselectedMode == 4) + { + display.println("D0 timer - 1min"); + } + if(ctrlselectedMode == 5) + { + display.println("D0 timer - 15min"); + } + if(ctrlselectedMode == 6) + { + display.println("D0 timer - 1h"); + } + if(ctrlselectedMode == 7) + { + display.println("D0 timer - 8h"); + } + + display.display(); +} + + + diff --git a/netgotchi/deauthergotchi.ino b/netgotchi/deauthergotchi.ino new file mode 100644 index 0000000..ea8f4c5 --- /dev/null +++ b/netgotchi/deauthergotchi.ino @@ -0,0 +1,20 @@ +//work in progress! + +void deauthergotchi_setup() +{ + displayClearDisplay(); + delay(500); + display.setTextSize(1); + display.setCursor(0, 5); + display.println("DEAUTHERGOTCHI"); + display.println(""); + display.println("Work in progress.."); + display.println("Restarting..."); + display.display(); +} + +void deauthergotchi_loop() +{ + delay(5000); + ESP.restart(); +} \ No newline at end of file diff --git a/netgotchi/loader.ino b/netgotchi/loader.ino new file mode 100644 index 0000000..60571ab --- /dev/null +++ b/netgotchi/loader.ino @@ -0,0 +1,121 @@ + +//loader vars +int selectedMode = 0; +int availableModeLength=4; +String availableMode[] = {"NETGOTCHI", "TEXTGOTCHI", "CTRLGOTCHI", "DEAUTHERGOTCHI"}; +bool loaderSetupSuccess =false; +bool displayLoaderComplete=false; +bool loaderSuccess = false; +long closingSec = 1000; + +Button2 loaderButtonLeft; +Button2 loaderButtonRight; +Button2 loaderButtonA; +Button2 loaderButtonB; + + +void loaderSetup() +{ + loaderButtonLeft.begin(BTN_LEFT); + loaderButtonRight.begin(BTN_RIGHT); + loaderButtonA.begin(BTN_A); + loaderButtonB.begin(BTN_B); + loaderButtonLeft.setPressedHandler(leftButtonPressed); + loaderButtonRight.setPressedHandler(rightButtonPressed); + loaderButtonA.setPressedHandler(AButtonPressed); + loaderButtonB.setPressedHandler(BButtonPressed); + if(skipLoader)SkipLoader(); + +} + +void rightButtonPressed(Button2 &btn) { + selectedMode++; + if(selectedMode>=availableModeLength)selectedMode=0; +} + +void leftButtonPressed(Button2 &btn) { + selectedMode--; + if(selectedMode < 0)selectedMode=availableModeLength-1; +} + +void AButtonPressed(Button2 &btn) { + closingSec=10; +} +void BButtonPressed(Button2 &btn) { + closingSec=1000; +} + +void loader() +{ + if(!displayLoaderComplete ) + { + bool debounce =true; + displayClearDisplay(); + displaySetSize(1); + displaySetTextColor(1); //white color + displaySetCursor(0, 0); + displayPrintln("Gotchi Loader [0_0]"); + displayPrintln(" "); + + for(int i=0; i< availableModeLength ; i++) + { + if(selectedMode == i) + displayPrintln(">"+availableMode[i]); + else + displayPrintln(" "+availableMode[i]); + } + displayPrintln(" "); + displayPrint("Closing in .."); + displayPrintln(String(closingSec)); + displayDisplay(); + delay(20); + + closingSec -= 4; + if(closingSec <=0 ) + { + loadedSetup(); + displayLoaderComplete=true; + } + loaderButtonLeft.loop(); + loaderButtonRight.loop(); + loaderButtonA.loop(); + loaderButtonB.loop(); + } + else loadedLoop(); +} + + +void loadedSetup() +{ + + //all modes + if(selectedMode == 0){ + netgotchi_setup(); + } + if(selectedMode == 1){ + textgotchi_setup(); + } + if(selectedMode == 2){ + ctrlgotchi_setup(); + } + if(selectedMode == 3){ + deauthergotchi_setup(); + } + //close the setup + loaderSetupSuccess=true; +} + +void loadedLoop() +{ + //run normal loops + if(selectedMode == 0 ) netgotchi_loop(); + if(selectedMode == 1 ) textgotchi_loop(); + if(selectedMode == 2 ) ctrlgotchi_loop(); + if(selectedMode == 3 ) deauthergotchi_loop(); +} + +void SkipLoader() +{ + //closing loader very fast + closingSec=5; +} \ No newline at end of file diff --git a/netgotchi/netgotchi.ino b/netgotchi/netgotchi.ino index a1124cd..0079e0d 100644 --- a/netgotchi/netgotchi.ino +++ b/netgotchi/netgotchi.ino @@ -24,7 +24,7 @@ #include // Include the WiFiManager library #include -const float VERSION = 1.5; +const float VERSION = 1.62; //Oled Screen Selectors #define SCREEN_WIDTH 128 @@ -159,6 +159,7 @@ bool hasDisplay = true; bool carouselMode = true; bool scheduledRestart = false; bool settingMode = false; +bool skipLoader=true; bool securityScanActive = true; bool skipFTPScan = true; @@ -166,15 +167,18 @@ int vulnerabilitiesFound = 0; int selectedSetting = 0; int settingLength = 6; -String settings[] = { "Start AP", "Online Mode", "Airplane Mode", "Start WebInterface", "Stop WebInterface", "Reset Settings" }; +String settings[] = { "Start AP", "Online Mode", "Airplane Mode", "Start WebInterface", "Restart", "Reset Settings" }; struct Service { const char* name; uint16_t port; }; + + + Service dangerousServices[] = { - { "Telnet", 23 }, + { "Telnet", 23 }, { "FTP", 21 }, { "SSH", 22 }, { "VNC", 5900 }, @@ -196,6 +200,15 @@ bool evilTwinDetected = false; bool webInterface = true; String headlessStatus = ""; + +// Broadcast MAC address +uint8_t broadcastAddress[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; + +typedef struct struct_message { + char text[250]; +} struct_message; + + static const char PROGMEM pagehtml[] = R"rawliteral( @@ -347,8 +360,28 @@ void SerialPrintLn(int message) { void setup() { Serial.begin(115200); + displayInit(); + loaderSetup(); +} +void loop() { + loader(); +} + +void headlessInfo() { + if (seconds - serial_info_seconds > 1) { + serial_info_seconds = seconds; + headlessStatus = netgotchiCurrentFace + " Honeypot:" + (honeypotTriggered ? "breached" : "OK") + " EvilTwin:" + (evilTwinDetected ? "detected" : "OK") + " Host-Found:" + String(ipnum) + " Vulnerabilities:" + String(vulnerabilitiesFound); + SerialPrintLn(headlessStatus); + } +} + + +void netgotchi_setup() +{ + displayInit(); + if(hasControlsButtons)checkOfflineMode(); netgotchiIntro(); if (enableNetworkMode) { @@ -361,8 +394,9 @@ void setup() { initStars(); } -void loop() { - currentMillis = millis(); +void netgotchi_loop() +{ + currentMillis = millis(); seconds = currentMillis / 1000; //main netgotchi network functionalities @@ -392,18 +426,5 @@ void loop() { //headless infos if (headless) headlessInfo(); - - - delay(15); } - -void headlessInfo() { - if (seconds - serial_info_seconds > 1) { - serial_info_seconds = seconds; - headlessStatus = netgotchiCurrentFace + " Honeypot:" + (honeypotTriggered ? "breached" : "OK") + " EvilTwin:" + (evilTwinDetected ? "detected" : "OK") + " Host-Found:" + String(ipnum) + " Vulnerabilities:" + String(vulnerabilitiesFound); - SerialPrintLn(headlessStatus); - } -} - - diff --git a/netgotchi/settings.ino b/netgotchi/settings.ino index 5550f91..c49b7b1 100644 --- a/netgotchi/settings.ino +++ b/netgotchi/settings.ino @@ -19,7 +19,7 @@ void settingConfirm() } if(selectedSetting == 4) { - //webinterface code -- stop + ESP.restart(); } if(selectedSetting == 5) { diff --git a/netgotchi/sounds.ino b/netgotchi/sounds.ino index c7b0177..1e5b386 100644 --- a/netgotchi/sounds.ino +++ b/netgotchi/sounds.ino @@ -13,4 +13,8 @@ void playAlert() { delay(500); noTone(BUZZER_PIN); #endif +} + +void playTone() { + tone(BUZZER_PIN,1000 ,100 ); // Play a tone at frequency of1000 Hz for200 ms } \ No newline at end of file diff --git a/netgotchi/textgotchi.ino b/netgotchi/textgotchi.ino new file mode 100644 index 0000000..463ea0b --- /dev/null +++ b/netgotchi/textgotchi.ino @@ -0,0 +1,162 @@ +#include + +const char keyboard_chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 "; +int selected_keyboard_index = 0; +String textmessage = ""; +String textreceivedMessage = ""; +String face = "(=*w*=)"; +unsigned long textgotchipreviousMillis = 0; +const long textgotchinterval = 3000; // textgotchinterval at which to change the face +String textgotchistatus = "__"; + +struct_message myData; + +Button2 textgotchiloaderButtonLeft; +Button2 textgotchiloaderButtonRight; +Button2 textgotchiloaderButtonA; +Button2 textgotchiloaderButtonB; + +void textgotchiLeftButtonPressed(Button2 &btn) { + selected_keyboard_index = (selected_keyboard_index - 1 + sizeof(keyboard_chars) - 1) % (sizeof(keyboard_chars) - 1); +} + +void textgotchiRightButtonPressed(Button2 &btn) { + selected_keyboard_index = (selected_keyboard_index + 1) % (sizeof(keyboard_chars) - 1); +} + +void textgotchiAButtonPressed(Button2 &btn) { + textmessage += keyboard_chars[selected_keyboard_index]; + +} +void textgotchiBButtonPressed(Button2 &btn) { + sendMessage(textmessage); + textmessage = ""; // Clear message after sending + playTone(); // Play tone when message is sent +} + + +void textgotchi_setup() +{ + WiFi.mode(WIFI_STA); + + if (esp_now_init() != ERR_OK) { + Serial.println("Error initializing ESP-NOW"); + return; + } + + esp_now_set_self_role(ESP_NOW_ROLE_COMBO); + esp_now_add_peer(broadcastAddress, ESP_NOW_ROLE_COMBO, 1, NULL, 0); + esp_now_register_recv_cb(OnDataRecv); + + displayClearDisplay(); + + textgotchiloaderButtonLeft.begin(BTN_LEFT); + textgotchiloaderButtonRight.begin(BTN_RIGHT); + textgotchiloaderButtonA.begin(BTN_A); + textgotchiloaderButtonB.begin(BTN_B); + textgotchiloaderButtonLeft.setPressedHandler(textgotchiLeftButtonPressed); + textgotchiloaderButtonRight.setPressedHandler(textgotchiRightButtonPressed); + textgotchiloaderButtonA.setPressedHandler(textgotchiAButtonPressed); + textgotchiloaderButtonB.setPressedHandler(textgotchiBButtonPressed); +} + +void textgotchi_loop() +{ + updateDisplay(); + loopFace(); + handleSerialInput(); + + textgotchiloaderButtonLeft.loop(); + textgotchiloaderButtonRight.loop(); + textgotchiloaderButtonA.loop(); + textgotchiloaderButtonB.loop(); +} + +void loopFace() { + unsigned long currentMillis = millis(); + if (currentMillis - textgotchipreviousMillis >= textgotchinterval) { + textgotchipreviousMillis = currentMillis; + changeFace(); + } +} + +void changeFace() { + static int index = 0; + // Array of different emoticons + const String faces[] = { + "(=*w*=)", + " (^_^) ", + "(o_O) ", + "(>__<) ", + " (^o^) ", + " (-_-)", + "(T_T) ", + " (^_~) " + }; + // Update the face variable + face = faces[index]; + // Move to the next face in the array + index = (index + 1) % (sizeof(faces) / sizeof(faces[0])); // Loop back to the start when reaching the end +} + + + + +void sendMessage(const String &msg) { + + msg.toCharArray(myData.text, sizeof(myData.text)); + + textgotchistatus = esp_now_send(broadcastAddress, (uint8_t *)&myData, sizeof(myData)) == 0 ? "OK" : "ER"; + Serial.println("message sent: " + textreceivedMessage); + Serial.println("status:"); + Serial.println(textgotchistatus); +} + +void OnDataRecv(uint8_t *mac, uint8_t *incomingData, uint8_t len) { + display.clearDisplay(); // Clear the display + textreceivedMessage = ""; // Reset the received message + memcpy(&myData, incomingData, sizeof(myData)); + textreceivedMessage = String(myData.text); + Serial.println("Serial message received: " + textreceivedMessage); + playTone(); // Play tone when a new message is received +} + +void updateDisplay() { + display.clearDisplay(); + // Display received and sent messages at the top + display.setTextSize(1); + display.setCursor(5, 5); + display.print("TEXTGOTCHI " + face + "" + textgotchistatus); + display.setCursor(0, 15); + display.print("Recv: "); + display.println(textreceivedMessage); + display.print("Sent: "); + display.println(textmessage); + + // Display keyboard at the bottom + + for (int i = 0; i < sizeof(keyboard_chars) - 1; i++) { + if (i == selected_keyboard_index) { + display.setTextColor(0, 1); // Highlight selected character + } else { + display.setTextColor(1); + } + int yOffset = (i < 26) ? SCREEN_HEIGHT - 20 : SCREEN_HEIGHT - 10; // Adjust y position for second line + int xOffset = (i % 26) * 5; // Adjust x position based on character index + display.setCursor(xOffset, yOffset); + display.print(keyboard_chars[i]); + } + display.display(); +} + +void handleSerialInput() { + if (Serial.available()) { + String serialMessage = Serial.readStringUntil('\n'); + serialMessage.trim(); // Remove any trailing newline or spaces + if (serialMessage.length() > 0) { + sendMessage(serialMessage); + Serial.println("Serial message sent: " + serialMessage); + playTone(); // Play tone when message is sent via serial + } + } +}