MX 2 лет назад
Родитель
Сommit
f4923e1208

+ 2 - 3
application.fam

@@ -7,9 +7,8 @@ App(
     requires=["gui"],
     stack_size=1 * 1024,
     order=90,
-	fap_author="bigbrodude6119",
-	fap_description="Create an evil captive portal Wi-Fi access point",
-    fap_libs=["assets"],
+    fap_author="bigbrodude6119",
+    fap_description="Create an evil captive portal Wi-Fi access point",
     fap_icon_assets="icons",
     fap_icon="icons/evil_portal_10px.png",
     fap_category="GPIO",

+ 20 - 11
evil_portal_app.c

@@ -25,12 +25,12 @@ static void evil_portal_app_tick_event_callback(void* context) {
 Evil_PortalApp* evil_portal_app_alloc() {
     Evil_PortalApp* app = malloc(sizeof(Evil_PortalApp));
 
-    app->sent_html = false;
-    app->sent_ap = false;
     app->sent_reset = false;
-    app->has_command_queue = false;
-    app->command_index = 0;
     app->portal_logs = furi_string_alloc();
+    app->portal_logs_mutex = furi_mutex_alloc(FuriMutexTypeRecursive);
+
+    app->capture_line = false;
+    app->captured_line = furi_string_alloc();
 
     app->dialogs = furi_record_open(RECORD_DIALOGS);
     app->file_path = furi_string_alloc();
@@ -82,12 +82,6 @@ Evil_PortalApp* evil_portal_app_alloc() {
 }
 
 void evil_portal_app_free(Evil_PortalApp* app) {
-    // save latest logs
-    if(furi_string_utf8_length(app->portal_logs) > 0) {
-        write_logs(app->portal_logs);
-        furi_string_free(app->portal_logs);
-    }
-
     // Send reset event to dev board
     evil_portal_uart_tx((uint8_t*)(RESET_CMD), strlen(RESET_CMD));
     evil_portal_uart_tx((uint8_t*)("\n"), 1);
@@ -111,6 +105,17 @@ void evil_portal_app_free(Evil_PortalApp* app) {
 
     evil_portal_uart_free(app->uart);
 
+    // save latest logs
+    furi_mutex_acquire(app->portal_logs_mutex, FuriWaitForever);
+    if(furi_string_size(app->portal_logs) > 0) {
+        write_logs(app->portal_logs);
+        furi_string_free(app->portal_logs);
+    }
+    furi_mutex_release(app->portal_logs_mutex);
+    furi_mutex_free(app->portal_logs_mutex);
+
+    furi_string_free(app->captured_line);
+
     // Close records
     furi_record_close(RECORD_GUI);
 
@@ -124,8 +129,12 @@ int32_t evil_portal_app(void* p) {
     UNUSED(p);
     Evil_PortalApp* evil_portal_app = evil_portal_app_alloc();
 
-    uint8_t attempts = 0;
     bool otg_was_enabled = furi_hal_power_is_otg_enabled();
+    // turn off 5v, so it gets reset on startup
+    if(otg_was_enabled) {
+        furi_hal_power_disable_otg();
+    }
+    uint8_t attempts = 0;
     while(!furi_hal_power_is_otg_enabled() && attempts++ < 5) {
         furi_hal_power_enable_otg();
         furi_delay_ms(10);

+ 4 - 8
evil_portal_app_i.h

@@ -25,18 +25,13 @@
 #define SET_AP_CMD "setap"
 #define RESET_CMD "reset"
 
-#define HTML_EXTENSION ".html"
-#define HTML_FOLDER ANY_PATH("apps_data/evil_portal/html")
-
 struct Evil_PortalApp {
     Gui* gui;
     ViewDispatcher* view_dispatcher;
     SceneManager* scene_manager;
 
     FuriString* portal_logs;
-    const char* command_queue[1];
-    int command_index;
-    bool has_command_queue;
+    FuriMutex* portal_logs_mutex;
 
     FuriString* text_box_store;
     size_t text_box_store_strlen;
@@ -57,12 +52,13 @@ struct Evil_PortalApp {
     bool is_custom_tx_string;
     bool focus_console_start;
     bool show_stopscan_tip;
-    bool sent_ap;
-    bool sent_html;
     bool sent_reset;
     int BAUDRATE;
     char text_store[2][128 + 1];
 
+    bool capture_line;
+    FuriString* captured_line;
+
     uint8_t* index_html;
     uint8_t* ap_name;
 };

+ 20 - 33
evil_portal_uart.c

@@ -48,57 +48,34 @@ static int32_t uart_worker(void* context) {
                 if(uart->handle_rx_data_cb) {
                     uart->handle_rx_data_cb(uart->rx_buf, len, uart->app);
 
-                    if(uart->app->has_command_queue) {
-                        if(uart->app->command_index < 1) {
-                            if(0 == strncmp(
-                                        SET_AP_CMD,
-                                        uart->app->command_queue[uart->app->command_index],
-                                        strlen(SET_AP_CMD))) {
-                                FuriString* out_data = furi_string_alloc();
-
-                                furi_string_cat(out_data, "setap=");
-                                furi_string_cat(out_data, (char*)uart->app->ap_name);
-
-                                evil_portal_uart_tx(
-                                    (uint8_t*)(furi_string_get_cstr(out_data)),
-                                    strlen(furi_string_get_cstr(out_data)));
-                                evil_portal_uart_tx((uint8_t*)("\n"), 1);
-
-                                uart->app->sent_ap = true;
-
-                                free(out_data);
-                                free(uart->app->ap_name);
-                            }
-
-                            uart->app->command_index = 0;
-                            uart->app->has_command_queue = false;
-                            uart->app->command_queue[0] = "";
-                        }
-                    }
-
+                    furi_mutex_acquire(uart->app->portal_logs_mutex, FuriWaitForever);
                     if(uart->app->sent_reset == false) {
                         furi_string_cat(uart->app->portal_logs, (char*)uart->rx_buf);
                     }
 
-                    if(furi_string_utf8_length(uart->app->portal_logs) > 4000) {
+                    if(furi_string_size(uart->app->portal_logs) > 4000) {
                         write_logs(uart->app->portal_logs);
                         furi_string_reset(uart->app->portal_logs);
                     }
+                    furi_mutex_release(uart->app->portal_logs_mutex);
                 } else {
                     uart->rx_buf[len] = '\0';
+                    furi_mutex_acquire(uart->app->portal_logs_mutex, FuriWaitForever);
                     if(uart->app->sent_reset == false) {
                         furi_string_cat(uart->app->portal_logs, (char*)uart->rx_buf);
                     }
 
-                    if(furi_string_utf8_length(uart->app->portal_logs) > 4000) {
+                    if(furi_string_size(uart->app->portal_logs) > 4000) {
                         write_logs(uart->app->portal_logs);
                         furi_string_reset(uart->app->portal_logs);
                     }
+                    furi_mutex_release(uart->app->portal_logs_mutex);
                 }
             }
         }
     }
 
+    furi_hal_uart_set_irq_cb(UART_CH, NULL, NULL);
     furi_stream_buffer_free(uart->rx_stream);
 
     return 0;
@@ -121,13 +98,20 @@ Evil_PortalUart* evil_portal_uart_init(Evil_PortalApp* app) {
 
     furi_thread_start(uart->rx_thread);
 
-    furi_hal_console_disable();
+    if(UART_CH == FuriHalUartIdUSART1) {
+        furi_hal_console_disable();
+    } else if(UART_CH == FuriHalUartIdLPUART1) {
+        furi_hal_uart_init(UART_CH, app->BAUDRATE);
+    }
+
     if(app->BAUDRATE == 0) {
         app->BAUDRATE = 115200;
     }
     furi_hal_uart_set_br(UART_CH, app->BAUDRATE);
     furi_hal_uart_set_irq_cb(UART_CH, evil_portal_uart_on_irq_cb, uart);
 
+    //evil_portal_uart_tx((uint8_t*)("XFW#EVILPORTAL=1\n"), strlen("XFW#EVILPORTAL=1\n"));
+
     return uart;
 }
 
@@ -138,8 +122,11 @@ void evil_portal_uart_free(Evil_PortalUart* uart) {
     furi_thread_join(uart->rx_thread);
     furi_thread_free(uart->rx_thread);
 
-    furi_hal_uart_set_irq_cb(UART_CH, NULL, NULL);
-    furi_hal_console_enable();
+    if(UART_CH == FuriHalUartIdLPUART1) {
+        furi_hal_uart_deinit(UART_CH);
+    } else {
+        furi_hal_console_enable();
+    }
 
     free(uart);
 }

+ 10 - 3
helpers/evil_portal_storage.c

@@ -13,6 +13,12 @@ void evil_portal_read_index_html(void* context) {
     Storage* storage = evil_portal_open_storage();
     FileInfo fi;
 
+    /*if(!storage_common_exists(storage, EVIL_PORTAL_INDEX_SAVE_PATH)) {
+        FuriString* tmp = furi_string_alloc_set(EVIL_PORTAL_INDEX_DEFAULT_PATH);
+        evil_portal_replace_index_html(tmp);
+        furi_string_free(tmp);
+    }*/
+
     if(storage_common_stat(storage, EVIL_PORTAL_INDEX_SAVE_PATH, &fi) == FSE_OK) {
         File* index_html = storage_file_alloc(storage);
         if(storage_file_open(
@@ -77,7 +83,7 @@ void evil_portal_read_ap_name(void* context) {
     if(storage_common_stat(storage, EVIL_PORTAL_AP_SAVE_PATH, &fi) == FSE_OK) {
         File* ap_name = storage_file_alloc(storage);
         if(storage_file_open(ap_name, EVIL_PORTAL_AP_SAVE_PATH, FSAM_READ, FSOM_OPEN_EXISTING)) {
-            app->ap_name = malloc((size_t)fi.size);
+            app->ap_name = malloc((size_t)fi.size + 1);
             uint8_t* buf_ptr = app->ap_name;
             size_t read = 0;
             while(read < fi.size) {
@@ -87,6 +93,8 @@ void evil_portal_read_ap_name(void* context) {
                 read += now_read;
                 buf_ptr += now_read;
             }
+            *buf_ptr = '\0';
+            buf_ptr++;
             free(buf_ptr);
         }
         storage_file_close(ap_name);
@@ -148,8 +156,7 @@ void write_logs(FuriString* portal_logs) {
     File* file = storage_file_alloc(storage);
 
     if(storage_file_open(file, seq_file_path, FSAM_WRITE, FSOM_CREATE_ALWAYS)) {
-        storage_file_write(
-            file, furi_string_get_cstr(portal_logs), furi_string_utf8_length(portal_logs));
+        storage_file_write(file, furi_string_get_cstr(portal_logs), furi_string_size(portal_logs));
     }
     storage_file_close(file);
     storage_file_free(file);

+ 3 - 0
helpers/evil_portal_storage.h

@@ -6,7 +6,10 @@
 #include <string.h>
 
 #define PORTAL_FILE_DIRECTORY_PATH EXT_PATH("apps_data/evil_portal")
+#define HTML_EXTENSION ".html"
+#define HTML_FOLDER PORTAL_FILE_DIRECTORY_PATH "/html"
 #define EVIL_PORTAL_INDEX_SAVE_PATH PORTAL_FILE_DIRECTORY_PATH "/index.html"
+//#define EVIL_PORTAL_INDEX_DEFAULT_PATH HTML_FOLDER "/xtreme.html"
 #define EVIL_PORTAL_AP_SAVE_PATH PORTAL_FILE_DIRECTORY_PATH "/ap.config.txt"
 #define EVIL_PORTAL_LOG_SAVE_PATH PORTAL_FILE_DIRECTORY_PATH "/logs"
 

BIN
icons/evil_portal_10px.png


+ 68 - 23
scenes/evil_portal_scene_console_output.c

@@ -1,10 +1,15 @@
 #include "../evil_portal_app_i.h"
 #include "../helpers/evil_portal_storage.h"
+#include <m-string.h>
 
 void evil_portal_console_output_handle_rx_data_cb(uint8_t* buf, size_t len, void* context) {
     furi_assert(context);
     Evil_PortalApp* app = context;
 
+    if(app->capture_line) {
+        furi_string_cat_printf(app->captured_line, "%s", buf);
+    }
+
     // If text box store gets too big, then truncate it
     app->text_box_store_strlen += len;
     if(app->text_box_store_strlen >= EVIL_PORTAL_TEXT_BOX_STORE_SIZE - 1) {
@@ -16,7 +21,11 @@ void evil_portal_console_output_handle_rx_data_cb(uint8_t* buf, size_t len, void
     buf[len] = '\0';
     furi_string_cat_printf(app->text_box_store, "%s", buf);
 
-    view_dispatcher_send_custom_event(app->view_dispatcher, Evil_PortalEventRefreshConsoleOutput);
+    text_box_set_text(app->text_box, furi_string_get_cstr(app->text_box_store));
+}
+
+static inline bool captured(Evil_PortalApp* app, const char* str) {
+    return furi_string_search_str(app->captured_line, str) != STRING_FAILURE;
 }
 
 void evil_portal_scene_console_output_on_enter(void* context) {
@@ -53,8 +62,10 @@ void evil_portal_scene_console_output_on_enter(void* context) {
             const char* help_msg = "Logs saved.\n\n";
             furi_string_cat_str(app->text_box_store, help_msg);
             app->text_box_store_strlen += strlen(help_msg);
+            furi_mutex_acquire(app->portal_logs_mutex, FuriWaitForever);
             write_logs(app->portal_logs);
             furi_string_reset(app->portal_logs);
+            furi_mutex_release(app->portal_logs_mutex);
             if(app->show_stopscan_tip) {
                 const char* msg = "Press BACK to return\n";
                 furi_string_cat_str(app->text_box_store, msg);
@@ -73,11 +84,9 @@ void evil_portal_scene_console_output_on_enter(void* context) {
         }
 
         if(0 == strncmp(SET_HTML_CMD, app->selected_tx_string, strlen(SET_HTML_CMD))) {
-            app->command_queue[0] = SET_AP_CMD;
-            app->has_command_queue = true;
-            app->command_index = 0;
             if(app->show_stopscan_tip) {
-                const char* msg = "Starting portal\nIf no response press\nBACK to return\n";
+                const char* msg =
+                    "Starting portal\nMarauder takes a few secs to start\nPress BACK to return\n";
                 furi_string_cat_str(app->text_box_store, msg);
                 app->text_box_store_strlen += strlen(msg);
             }
@@ -104,28 +113,67 @@ void evil_portal_scene_console_output_on_enter(void* context) {
 
     if(app->is_command && app->selected_tx_string) {
         if(0 == strncmp(SET_HTML_CMD, app->selected_tx_string, strlen(SET_HTML_CMD))) {
-            evil_portal_read_index_html(context);
-
             FuriString* data = furi_string_alloc();
-            furi_string_cat(data, "sethtml=");
-            furi_string_cat(data, (char*)app->index_html);
+            app->capture_line = true;
 
-            evil_portal_uart_tx(
-                (uint8_t*)(furi_string_get_cstr(data)), strlen(furi_string_get_cstr(data)));
-            evil_portal_uart_tx((uint8_t*)("\n"), 1);
+            evil_portal_read_ap_name(context);
+            // Test evil portal syntax and response, marauder ignores it
+            furi_string_printf(data, "setap=%s\n", (char*)app->ap_name);
+            furi_string_reset(app->captured_line);
+            evil_portal_uart_tx((uint8_t*)(furi_string_get_cstr(data)), furi_string_size(data));
+            // For some reason evil portal messes up "ap set" with newlines and random letters, "p set" works
+            for(uint8_t t = 0; t < 20 && !captured(app, "p set"); t++) furi_delay_ms(100);
+            bool icanhazmarauder = !captured(app, "p set"); // Evil portal didn't respond
+            // Not evil portal, set up marauder
+            if(icanhazmarauder) {
+                furi_string_printf(data, "clearlist -s\nssid -a -n '%s'\n", app->ap_name);
+                furi_string_reset(app->captured_line);
+                evil_portal_uart_tx(
+                    (uint8_t*)(furi_string_get_cstr(data)), furi_string_size(data));
+                // Marauder echoes the command, maybe still init so wait a while for echo
+                for(uint8_t t = 0; t < 42 && !captured(app, (char*)app->ap_name); t++)
+                    furi_delay_ms(100);
+            }
+            free(app->ap_name);
 
-            app->sent_html = true;
+            evil_portal_read_index_html(context);
+            if(icanhazmarauder) {
+                furi_string_reset(app->captured_line);
+                evil_portal_uart_tx(
+                    (uint8_t*)("evilportal -c sethtmlstr\n"),
+                    strlen("evilportal -c sethtmlstr\n"));
+                for(uint8_t t = 0; t < 5 && !captured(app, "Setting HTML from serial..."); t++)
+                    furi_delay_ms(100);
+                // Check for active attack
+                if(captured(app, ">") && !captured(app, "Setting HTML from serial...")) {
+                    furi_string_reset(app->captured_line);
+                } else {
+                    furi_string_reset(app->captured_line);
+                    evil_portal_uart_tx(app->index_html, strlen((char*)app->index_html));
+                    evil_portal_uart_tx((uint8_t*)("\n"), 1);
+                    for(uint8_t t = 0; t < 15 && !captured(app, "html set"); t++)
+                        furi_delay_ms(100);
+                    furi_delay_ms(100);
+                    evil_portal_uart_tx(
+                        (uint8_t*)("evilportal -c start\n"), strlen("evilportal -c start\n"));
+                }
+            } else {
+                furi_string_set(data, "sethtml=");
+                furi_string_cat(data, (char*)app->index_html);
+                evil_portal_uart_tx(
+                    (uint8_t*)(furi_string_get_cstr(data)), strlen(furi_string_get_cstr(data)));
+                evil_portal_uart_tx((uint8_t*)("\n"), 1);
+            }
 
-            free(data);
             free(app->index_html);
-
-            evil_portal_read_ap_name(context);
+            app->capture_line = false;
+            furi_string_reset(app->captured_line);
+            furi_string_free(data);
         } else if(0 == strncmp(RESET_CMD, app->selected_tx_string, strlen(RESET_CMD))) {
-            app->sent_html = false;
-            app->sent_ap = false;
             evil_portal_uart_tx(
                 (uint8_t*)(app->selected_tx_string), strlen(app->selected_tx_string));
             evil_portal_uart_tx((uint8_t*)("\n"), 1);
+            evil_portal_uart_tx((uint8_t*)("stopscan\n"), strlen("stopscan\n"));
         } else if(1 == strncmp("help", app->selected_tx_string, strlen("help"))) {
             evil_portal_uart_tx(
                 (uint8_t*)(app->selected_tx_string), strlen(app->selected_tx_string));
@@ -135,14 +183,11 @@ void evil_portal_scene_console_output_on_enter(void* context) {
 }
 
 bool evil_portal_scene_console_output_on_event(void* context, SceneManagerEvent event) {
-    Evil_PortalApp* app = context;
+    UNUSED(context);
 
     bool consumed = false;
 
-    if(event.type == SceneManagerEventTypeCustom) {
-        text_box_set_text(app->text_box, furi_string_get_cstr(app->text_box_store));
-        consumed = true;
-    } else if(event.type == SceneManagerEventTypeTick) {
+    if(event.type == SceneManagerEventTypeTick) {
         consumed = true;
     }