Просмотр исходного кода

add deauthentication option (req FlipperHTTP v2.0)

jblanked 8 месяцев назад
Родитель
Сommit
8e53e1302f
7 измененных файлов с 240 добавлено и 6 удалено
  1. 2 1
      alloc/flip_wifi_alloc.c
  2. 36 1
      callback/alloc.c
  3. 128 1
      callback/callback.c
  4. 3 0
      callback/callback.h
  5. 7 3
      flip_wifi.h
  6. 48 0
      flipper_http/flipper_http.c
  7. 16 0
      flipper_http/flipper_http.h

+ 2 - 1
alloc/flip_wifi_alloc.c

@@ -19,7 +19,8 @@ FlipWiFiApp *flip_wifi_app_alloc()
         return NULL;
     }
     submenu_add_item(app->submenu_main, "Scan", FlipWiFiSubmenuIndexWiFiScan, callback_submenu_choices, app);
-    submenu_add_item(app->submenu_main, "AP Mode", FlipWiFiSubmenuIndexWiFiAP, callback_submenu_choices, app);
+    submenu_add_item(app->submenu_main, "Deauthentication", FlipWiFiSubmenuIndexWiFiDeauth, callback_submenu_choices, app);
+    submenu_add_item(app->submenu_main, "Captive Portal", FlipWiFiSubmenuIndexWiFiAP, callback_submenu_choices, app);
     submenu_add_item(app->submenu_main, "Saved APs", FlipWiFiSubmenuIndexWiFiSaved, callback_submenu_choices, app);
     submenu_add_item(app->submenu_main, "Commands", FlipWiFiSubmenuIndexCommands, callback_submenu_choices, app);
     submenu_add_item(app->submenu_main, "Info", FlipWiFiSubmenuIndexAbout, callback_submenu_choices, app);

+ 36 - 1
callback/alloc.c

@@ -254,7 +254,7 @@ bool alloc_text_inputs(void *context, uint32_t view)
     case FlipWiFiSubmenuIndexWiFiAPSetSSID:
         if (!app->uart_text_input)
         {
-            if (!easy_flipper_set_uart_text_input(&app->uart_text_input, FlipWiFiViewTextInput, "Enter AP SSID", app->uart_text_input_temp_buffer, app->uart_text_input_buffer_size, callback_ap_ssid_updated, callback_to_submenu_saved, &app->view_dispatcher, app))
+            if (!easy_flipper_set_uart_text_input(&app->uart_text_input, FlipWiFiViewTextInput, "Enter AP SSID", app->uart_text_input_temp_buffer, app->uart_text_input_buffer_size, callback_ap_ssid_updated, callback_to_submenu_main, &app->view_dispatcher, app))
             {
                 FURI_LOG_E(TAG, "Failed to allocate text input for Fast Command");
                 return false;
@@ -266,6 +266,27 @@ bool alloc_text_inputs(void *context, uint32_t view)
             }
         }
         return true;
+    case FlipWiFiViewTextInputDeauth:
+        if (!app->uart_text_input)
+        {
+            if (!easy_flipper_set_uart_text_input(&app->uart_text_input, FlipWiFiViewTextInput, "Enter SSID", app->uart_text_input_temp_buffer, app->uart_text_input_buffer_size, callback_text_updated_deauth, callback_to_submenu_scan, &app->view_dispatcher, app))
+            {
+                FURI_LOG_E(TAG, "Failed to allocate text input for WiFi Deauth");
+                return false;
+            }
+            if (!app->uart_text_input)
+            {
+                FURI_LOG_E(TAG, "Failed to allocate text input for WiFi Deauth");
+                return false;
+            }
+            char deauth_ssid[64];
+            if (load_char("deauth_ssid", deauth_ssid, sizeof(deauth_ssid)))
+            {
+                strncpy(app->uart_text_input_temp_buffer, deauth_ssid, app->uart_text_input_buffer_size);
+                app->uart_text_input_temp_buffer[app->uart_text_input_buffer_size - 1] = '\0';
+            }
+        }
+        return true;
     }
     return false;
 }
@@ -304,6 +325,20 @@ bool alloc_views(void *context, uint32_t view)
             }
         }
         return true;
+    case FlipWiFiViewWiFiDeauth:
+        if (!app->view_wifi)
+        {
+            if (!easy_flipper_set_view(&app->view_wifi, FlipWiFiViewGeneric, callback_view_draw_callback_deauth, callback_view_input_callback_deauth, callback_to_submenu_main, &app->view_dispatcher, app))
+            {
+                return false;
+            }
+            if (!app->view_wifi)
+            {
+                FURI_LOG_E(TAG, "Failed to allocate view for WiFi Deauth");
+                return false;
+            }
+        }
+        return true;
     default:
         return false;
     }

+ 128 - 1
callback/callback.c

@@ -86,6 +86,93 @@ void callback_ap_ssid_updated(void *context)
     save_char("ap_ssid", app->uart_text_input_temp_buffer);
     view_dispatcher_switch_to_view(app->view_dispatcher, FlipWiFiViewSubmenu);
 }
+void callback_text_updated_deauth(void *context)
+{
+    FlipWiFiApp *app = (FlipWiFiApp *)context;
+    furi_check(app);
+    if (!app->uart_text_input_temp_buffer)
+    {
+        FURI_LOG_E(TAG, "Text input buffer is NULL");
+        return;
+    }
+    if (!app->uart_text_input_temp_buffer[0])
+    {
+        FURI_LOG_E(TAG, "Text input buffer is empty");
+        return;
+    }
+    save_char("deauth_ssid", app->uart_text_input_temp_buffer);
+    if (!app->fhttp)
+    {
+        app->fhttp = flipper_http_alloc();
+        if (!app->fhttp)
+        {
+            easy_flipper_dialog("[ERROR]", "Failed to initialize flipper http");
+            return;
+        }
+    }
+    Loading *loading = loading_alloc();
+    int32_t loading_view_id = 87654321; // Random ID
+    view_dispatcher_add_view(app->view_dispatcher, loading_view_id, loading_get_view(loading));
+    view_dispatcher_switch_to_view(app->view_dispatcher, loading_view_id);
+    if (!flipper_http_deauth_start(app->fhttp, app->uart_text_input_temp_buffer))
+    {
+        easy_flipper_dialog("[ERROR]", "Failed to start deauth attack");
+        flipper_http_free(app->fhttp);
+        view_dispatcher_switch_to_view(app->view_dispatcher, FlipWiFiViewTextInput);
+        view_dispatcher_remove_view(app->view_dispatcher, loading_view_id);
+        loading_free(loading);
+        loading = NULL;
+        return;
+    }
+    while (app->fhttp->last_response == NULL || strlen(app->fhttp->last_response) == 0)
+    {
+        furi_delay_ms(100);
+    }
+    if (strstr(app->fhttp->last_response, "[DEAUTH/STARTING]") == NULL)
+    {
+        char response[256];
+        snprintf(response, sizeof(response), "Failed to start deauth attack:\n%s", app->fhttp->last_response);
+        easy_flipper_dialog("[ERROR]", response);
+        flipper_http_free(app->fhttp);
+        view_dispatcher_switch_to_view(app->view_dispatcher, FlipWiFiViewTextInput);
+        view_dispatcher_remove_view(app->view_dispatcher, loading_view_id);
+        loading_free(loading);
+        loading = NULL;
+        return;
+    }
+    while (strstr(app->fhttp->last_response, "[DEAUTH/STARTING]") != NULL)
+    {
+        furi_delay_ms(100);
+    }
+    if (strstr(app->fhttp->last_response, "[ERROR]") != NULL)
+    {
+        char response[256];
+        snprintf(response, sizeof(response), "Failed to start deauth attack:\n%s", app->fhttp->last_response);
+        easy_flipper_dialog("[ERROR]", response);
+        flipper_http_free(app->fhttp);
+        view_dispatcher_switch_to_view(app->view_dispatcher, FlipWiFiViewTextInput);
+        view_dispatcher_remove_view(app->view_dispatcher, loading_view_id);
+        loading_free(loading);
+        loading = NULL;
+        return;
+    }
+
+    if (!alloc_views(app, FlipWiFiViewWiFiDeauth))
+    {
+        FURI_LOG_E(TAG, "Failed to allocate view for WiFi Deauth");
+        view_dispatcher_switch_to_view(app->view_dispatcher, FlipWiFiViewTextInput);
+        view_dispatcher_remove_view(app->view_dispatcher, loading_view_id);
+        loading_free(loading);
+        loading = NULL;
+        return;
+    }
+
+    // switch to a canvas view
+    view_dispatcher_switch_to_view(app->view_dispatcher, FlipWiFiViewGeneric);
+    view_dispatcher_remove_view(app->view_dispatcher, loading_view_id);
+    loading_free(loading);
+    loading = NULL;
+}
 
 void callback_redraw_submenu_saved(void *context)
 {
@@ -143,6 +230,17 @@ void callback_view_draw_callback_saved(Canvas *canvas, void *model)
     canvas_draw_str_aligned(canvas, 107, 54, AlignLeft, AlignTop, "Edit");
 }
 
+// Callback for drawing the deauth screen
+void callback_view_draw_callback_deauth(Canvas *canvas, void *model)
+{
+    UNUSED(model);
+    canvas_clear(canvas);
+    canvas_set_font(canvas, FontPrimary);
+    canvas_draw_str(canvas, 0, 10, "Deauthing...");
+    canvas_draw_icon(canvas, 0, 53, &I_ButtonBACK_10x8);
+    canvas_draw_str_aligned(canvas, 12, 54, AlignLeft, AlignTop, "Hit Back to stop");
+}
+
 // Input callback for the view (async input handling)
 bool callback_view_input_callback_scan(InputEvent *event, void *context)
 {
@@ -161,6 +259,26 @@ bool callback_view_input_callback_scan(InputEvent *event, void *context)
     }
     return false;
 }
+
+// Input callback for the view (async input handling)
+bool callback_view_input_callback_deauth(InputEvent *event, void *context)
+{
+    FlipWiFiApp *app = (FlipWiFiApp *)context;
+    if (event->type == InputTypePress && event->key == InputKeyBack)
+    {
+        if (app->fhttp)
+        {
+            flipper_http_deauth_stop(app->fhttp);
+            furi_delay_ms(200);
+            flipper_http_free(app->fhttp);
+            app->fhttp = NULL;
+        }
+        view_dispatcher_switch_to_view(app->view_dispatcher, FlipWiFiViewSubmenuMain);
+        return true;
+    }
+    return false;
+}
+
 // Input callback for the view (async input handling)
 bool callback_view_input_callback_saved(InputEvent *event, void *context)
 {
@@ -391,7 +509,7 @@ static void update_text_box(FlipWiFiApp *app)
             text_box_reset(app->textbox);
             text_box_set_focus(app->textbox, TextBoxFocusEnd);
             text_box_set_font(app->textbox, TextBoxFontText);
-            text_box_set_text(app->textbox, "AP Connected... please wait");
+            text_box_set_text(app->textbox, "Connected... please wait");
         }
         else if (furi_string_size(app->fhttp->last_response_str) != last_response_len)
         {
@@ -568,6 +686,15 @@ void callback_submenu_choices(void *context, uint32_t index)
             return;
         }
         break;
+    case FlipWiFiSubmenuIndexWiFiDeauth:
+        free_all(app);
+        if (!alloc_text_inputs(app, FlipWiFiViewTextInputDeauth))
+        {
+            FURI_LOG_E(TAG, "Failed to allocate text input for WiFi Saved Add Password");
+            return;
+        }
+        view_dispatcher_switch_to_view(app->view_dispatcher, FlipWiFiViewTextInput);
+        break;
     case FlipWiFiSubmenuIndexWiFiSaved:
         free_all(app);
         if (!alloc_submenus(app, FlipWiFiViewSubmenuSaved))

+ 3 - 0
callback/callback.h

@@ -10,10 +10,13 @@ uint32_t callback_to_submenu_scan(void *context);
 uint32_t callback_to_submenu_saved(void *context);
 void callback_custom_command_updated(void *context);
 void callback_ap_ssid_updated(void *context);
+void callback_text_updated_deauth(void *context);
 void callback_redraw_submenu_saved(void *context);
 void callback_view_draw_callback_scan(Canvas *canvas, void *model);
 void callback_view_draw_callback_saved(Canvas *canvas, void *model);
+void callback_view_draw_callback_deauth(Canvas *canvas, void *model);
 bool callback_view_input_callback_scan(InputEvent *event, void *context);
+bool callback_view_input_callback_deauth(InputEvent *event, void *context);
 bool callback_view_input_callback_saved(InputEvent *event, void *context);
 void callback_timer_callback(void *context);
 void callback_submenu_choices(void *context, uint32_t index);

+ 7 - 3
flip_wifi.h

@@ -18,6 +18,7 @@ typedef enum
     FlipWiFiSubmenuIndexAbout,
     //
     FlipWiFiSubmenuIndexWiFiScan,
+    FlipWiFiSubmenuIndexWiFiDeauth,
     FlipWiFiSubmenuIndexWiFiAP,
     FlipWiFiSubmenuIndexWiFiSaved,
     FlipWiFiSubmenuIndexCommands,
@@ -37,9 +38,11 @@ typedef enum
 // Define a single view for our FlipWiFi application
 typedef enum
 {
-    FlipWiFiViewWiFiScan,  // The view for the wifi scan screen
-    FlipWiFiViewWiFiAP,    // The view for the wifi AP screen
-    FlipWiFiViewWiFiSaved, // The view for the wifi scan screen
+    FlipWiFiViewWiFiScan,       // The view for the wifi scan screen
+    FlipWiFiViewWiFiDeauth,     // The view for the wifi scan screen
+    FlipWiFiViewWiFiDeauthWait, // The view for the wifi scan screen
+    FlipWiFiViewWiFiAP,         // The view for the wifi AP screen
+    FlipWiFiViewWiFiSaved,      // The view for the wifi scan screen
     //
     FlipWiFiViewSubmenuMain,     // The submenu for the main screen
     FlipWiFiViewSubmenuScan,     // The submenu for the wifi scan screen
@@ -48,6 +51,7 @@ typedef enum
     FlipWiFiViewSubmenuCommands, // The submenu for the fast commands screen
     FlipWiFiViewAbout,           // The about screen
     FlipWiFiViewTextInputScan,   // The text input screen for the wifi scan screen
+    FlipWiFiViewTextInputDeauth, // The text input screen for the wifi scan screen
     FlipWiFiViewTextInputSaved,  // The text input screen for the wifi saved screen
     //
     FlipWiFiViewTextInputSavedAddSSID,     // The text input screen for the wifi saved screen

+ 48 - 0
flipper_http/flipper_http.c

@@ -392,6 +392,54 @@ bool flipper_http_append_to_file(
     return true;
 }
 
+/**
+ * @brief      Send a command to deauthenticate a WiFi network.
+ * @return     true if the request was successful, false otherwise.
+ * @param fhttp The FlipperHTTP context
+ * @note       The received data will be handled asynchronously via the callback.
+ */
+bool flipper_http_deauth_start(FlipperHTTP *fhttp, const char *ssid)
+{
+    if (!fhttp)
+    {
+        FURI_LOG_E(HTTP_TAG, "flipper_http_deauth_start: Failed to get context.");
+        return false;
+    }
+    if (!ssid)
+    {
+        FURI_LOG_E("FlipperHTTP", "Invalid arguments provided to flipper_http_deauth_start.");
+        return false;
+    }
+
+    char buffer[256];
+
+    int ret = snprintf(buffer, sizeof(buffer), "[DEAUTH]{\"ssid\":\"%s\"}", ssid);
+
+    if (ret < 0 || ret >= (int)sizeof(buffer))
+    {
+        FURI_LOG_E("FlipperHTTP", "Failed to format WiFi deauth command.");
+        return false;
+    }
+
+    return flipper_http_send_data(fhttp, buffer);
+}
+
+/**
+ * @brief      Send a request to stop the deauth
+ * @return     true if the request was successful, false otherwise.
+ * @param fhttp The FlipperHTTP context
+ * @note       The received data will be handled asynchronously via the callback.
+ */
+bool flipper_http_deauth_stop(FlipperHTTP *fhttp)
+{
+    if (!fhttp)
+    {
+        FURI_LOG_E(HTTP_TAG, "flipper_http_deauth_stop: Failed to get context.");
+        return false;
+    }
+    return flipper_http_send_data(fhttp, "[DEAUTH/STOP]");
+}
+
 /**
  * @brief      Load data from a file.
  * @return     The loaded data as a FuriString.

+ 16 - 0
flipper_http/flipper_http.h

@@ -124,6 +124,22 @@ void flipper_http_free(FlipperHTTP *fhttp);
  */
 bool flipper_http_append_to_file(const void *data, size_t data_size, bool start_new_file, char *file_path);
 
+/**
+ * @brief      Send a command to deauthenticate a WiFi network.
+ * @return     true if the request was successful, false otherwise.
+ * @param fhttp The FlipperHTTP context
+ * @note       The received data will be handled asynchronously via the callback.
+ */
+bool flipper_http_deauth_start(FlipperHTTP *fhttp, const char *ssid);
+
+/**
+ * @brief      Send a request to stop the deauth
+ * @return     true if the request was successful, false otherwise.
+ * @param fhttp The FlipperHTTP context
+ * @note       The received data will be handled asynchronously via the callback.
+ */
+bool flipper_http_deauth_stop(FlipperHTTP *fhttp);
+
 /**
  * @brief      Load data from a file.
  * @return     The loaded data as a FuriString.