├── .github
├── FUNDING.yml
└── workflows
│ └── build.yml
├── LICENSE
├── ReadMe.md
├── application.fam
├── assets
├── DolphinCommon_56x48.png
├── KeyBackspaceSelected_16x9.png
├── KeyBackspace_16x9.png
├── KeyKeyboardSelected_10x11.png
├── KeyKeyboard_10x11.png
├── KeySaveSelected_24x11.png
├── KeySave_24x11.png
├── Text_10x10.png
└── WarningDolphin_45x42.png
├── docs
├── README.md
└── changelog.md
├── file
├── sequential_file.c
└── sequential_file.h
├── scenes
├── wifi_marauder_scene.c
├── wifi_marauder_scene.h
├── wifi_marauder_scene_config.h
├── wifi_marauder_scene_console_output.c
├── wifi_marauder_scene_log_viewer.c
├── wifi_marauder_scene_script_confirm_delete.c
├── wifi_marauder_scene_script_edit.c
├── wifi_marauder_scene_script_edit_list.c
├── wifi_marauder_scene_script_options.c
├── wifi_marauder_scene_script_select.c
├── wifi_marauder_scene_script_settings.c
├── wifi_marauder_scene_script_stage_add.c
├── wifi_marauder_scene_script_stage_edit.c
├── wifi_marauder_scene_settings_init.c
├── wifi_marauder_scene_sniffpmkid_options.c
├── wifi_marauder_scene_start.c
├── wifi_marauder_scene_text_input.c
└── wifi_marauder_scene_user_input.c
├── screenshots
├── marauder-save-pcaps.png
├── marauder-script-demo.png
└── marauder-topmenu.png
├── script
├── cJSON.c
├── cJSON.h
├── menu
│ ├── wifi_marauder_script_stage_menu.c
│ ├── wifi_marauder_script_stage_menu.h
│ ├── wifi_marauder_script_stage_menu_beaconap.c
│ ├── wifi_marauder_script_stage_menu_beaconlist.c
│ ├── wifi_marauder_script_stage_menu_config.h
│ ├── wifi_marauder_script_stage_menu_deauth.c
│ ├── wifi_marauder_script_stage_menu_delay.c
│ ├── wifi_marauder_script_stage_menu_exec.c
│ ├── wifi_marauder_script_stage_menu_probe.c
│ ├── wifi_marauder_script_stage_menu_scan.c
│ ├── wifi_marauder_script_stage_menu_select.c
│ ├── wifi_marauder_script_stage_menu_sniffbeacon.c
│ ├── wifi_marauder_script_stage_menu_sniffdeauth.c
│ ├── wifi_marauder_script_stage_menu_sniffesp.c
│ ├── wifi_marauder_script_stage_menu_sniffpmkid.c
│ ├── wifi_marauder_script_stage_menu_sniffpwn.c
│ └── wifi_marauder_script_stage_menu_sniffraw.c
├── wifi_marauder_script.c
├── wifi_marauder_script.h
├── wifi_marauder_script_executor.c
├── wifi_marauder_script_executor.h
├── wifi_marauder_script_worker.c
└── wifi_marauder_script_worker.h
├── wifi_10px.png
├── wifi_marauder_app.c
├── wifi_marauder_app.h
├── wifi_marauder_app_i.h
├── wifi_marauder_custom_event.h
├── wifi_marauder_ep.c
├── wifi_marauder_ep.h
├── wifi_marauder_text_input.c
├── wifi_marauder_text_input.h
├── wifi_marauder_uart.c
├── wifi_marauder_uart.h
├── wifi_marauder_validators.c
└── wifi_marauder_validators.h
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
4 | patreon: # Replace with a single Patreon username
5 | open_collective: # Replace with a single Open Collective username
6 | ko_fi: cococode
7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
9 | liberapay: # Replace with a single Liberapay username
10 | issuehunt: # Replace with a single IssueHunt username
11 | otechie: # Replace with a single Otechie username
12 | lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
13 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
14 |
--------------------------------------------------------------------------------
/.github/workflows/build.yml:
--------------------------------------------------------------------------------
1 | name: "FAP Build"
2 | on:
3 | push:
4 | branches:
5 | - feature_wifi_marauder_app
6 | pull_request:
7 | schedule:
8 | # do a build every day
9 | - cron: "1 1 * * *"
10 | jobs:
11 | ufbt-build-action:
12 | runs-on: ubuntu-latest
13 | strategy:
14 | matrix:
15 | include:
16 | - name: dev channel
17 | sdk-channel: dev
18 | - name: release channel
19 | sdk-channel: release
20 | - name: Unleashed dev
21 | sdk-index-url: https://up.unleashedflip.com/directory.json
22 | sdk-channel: dev
23 | - name: Unleashed release
24 | sdk-index-url: https://up.unleashedflip.com/directory.json
25 | sdk-channel: release
26 | name: 'ufbt: Build for ${{ matrix.name }}'
27 | steps:
28 | - name: Checkout
29 | uses: actions/checkout@v3
30 | with:
31 | submodules: recursive
32 | - name: Build with ufbt
33 | uses: flipperdevices/flipperzero-ufbt-action@v0.1.2
34 | id: build-app
35 | with:
36 | sdk-channel: ${{ matrix.sdk-channel }}
37 | sdk-index-url: ${{ matrix.sdk-index-url }}
38 | - name: Upload app artifacts
39 | uses: actions/upload-artifact@v4
40 | with:
41 | name: ${{ github.event.repository.name }}-${{ steps.build-app.outputs.suffix }}
42 | path: ${{ steps.build-app.outputs.fap-artifacts }}
43 |
--------------------------------------------------------------------------------
/ReadMe.md:
--------------------------------------------------------------------------------
1 | [](https://github.com/0xchocolate/flipperzero-wifi-marauder/actions/workflows/build.yml)
2 |
3 | # WiFi Marauder companion app for Flipper Zero
4 |
5 | Requires a connected dev board running Marauder FW. [See install instructions from UberGuidoZ here.](https://github.com/UberGuidoZ/Flipper/tree/main/Wifi_DevBoard#marauder-install-information)
6 |
7 |
8 |
9 | ## Get the app
10 | 1. Make sure you're logged in with a github account (otherwise the downloads in step 2 won't work)
11 | 2. Navigate to the [FAP Build](https://github.com/0xchocolate/flipperzero-wifi-marauder/actions/workflows/build.yml)
12 | GitHub action workflow, and select the most recent run, scroll down to artifacts.
13 | 3. The FAP is built for the `dev` and `release` channels of both official and unleashed
14 | firmware. Download the artifact corresponding to your firmware version.
15 | 4. (Optional step to avoid confusion) Go to "Apps/GPIO" on the Flipper SD Card, delete any existing Marauder app, on some firmwares there will be a `ESP32CAM_Marauder.fap` or similar.
16 | 5. Extract `esp32_wifi_marauder.fap` from the ZIP file downloaded in step 3 to your Flipper Zero SD card, preferably under Apps/GPIO along with the rest of the GPIO apps. (If you're using qFlipper to transfer files you need to extract the content of the ZIP file to your computer before you drag it to qFlipper, as qFlipper does not support direct dragging from a ZIP file (at least on Windows)).
17 |
18 | From a local clone of this repo, you can also build the app yourself using ufbt.
19 |
20 | ### FYI - the ESP flasher is now its own app: https://github.com/0xchocolate/flipperzero-esp-flasher
21 |
22 |
23 | ## Support
24 |
25 | For app feedback, bugs, and feature requests, please [create an issue here](https://github.com/0xchocolate/flipperzero-firmware-with-wifi-marauder-companion/issues).
26 |
27 | You can find me (0xchocolate) on discord as @cococode.
28 |
29 | If you'd like to donate to the app development effort:
30 |
31 | [](https://ko-fi.com/O4O1R7X6K)
32 |
33 | **ETH**: `0xf32A1F0CD6122C97d8953183E53cB889cc087C9b`
34 | **BTC**: `bc1qtw7s25cwdkuaups22yna8sttfxn0usm2f35wc3`
35 |
36 | Find more info about Marauder and support its developer (justcallmekoko aka WillStunForFood) here: https://github.com/justcallmekoko/ESP32Marauder
37 |
38 | If you found the app preinstalled in a firmware release, consider supporting the maintainers!
39 |
--------------------------------------------------------------------------------
/application.fam:
--------------------------------------------------------------------------------
1 | App(
2 | appid="esp32_wifi_marauder",
3 | name="[ESP32] WiFi Marauder",
4 | fap_version=(7, 2),
5 | apptype=FlipperAppType.EXTERNAL,
6 | entry_point="wifi_marauder_app",
7 | requires=["gui"],
8 | stack_size=4 * 1024,
9 | order=90,
10 | fap_icon="wifi_10px.png",
11 | fap_category="GPIO",
12 | fap_icon_assets="assets",
13 | )
14 |
--------------------------------------------------------------------------------
/assets/DolphinCommon_56x48.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/justcallmekoko/flipperzero-wifi-marauder/316258b8c708c1f2a67a2c087aa6d16348ed76f5/assets/DolphinCommon_56x48.png
--------------------------------------------------------------------------------
/assets/KeyBackspaceSelected_16x9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/justcallmekoko/flipperzero-wifi-marauder/316258b8c708c1f2a67a2c087aa6d16348ed76f5/assets/KeyBackspaceSelected_16x9.png
--------------------------------------------------------------------------------
/assets/KeyBackspace_16x9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/justcallmekoko/flipperzero-wifi-marauder/316258b8c708c1f2a67a2c087aa6d16348ed76f5/assets/KeyBackspace_16x9.png
--------------------------------------------------------------------------------
/assets/KeyKeyboardSelected_10x11.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/justcallmekoko/flipperzero-wifi-marauder/316258b8c708c1f2a67a2c087aa6d16348ed76f5/assets/KeyKeyboardSelected_10x11.png
--------------------------------------------------------------------------------
/assets/KeyKeyboard_10x11.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/justcallmekoko/flipperzero-wifi-marauder/316258b8c708c1f2a67a2c087aa6d16348ed76f5/assets/KeyKeyboard_10x11.png
--------------------------------------------------------------------------------
/assets/KeySaveSelected_24x11.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/justcallmekoko/flipperzero-wifi-marauder/316258b8c708c1f2a67a2c087aa6d16348ed76f5/assets/KeySaveSelected_24x11.png
--------------------------------------------------------------------------------
/assets/KeySave_24x11.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/justcallmekoko/flipperzero-wifi-marauder/316258b8c708c1f2a67a2c087aa6d16348ed76f5/assets/KeySave_24x11.png
--------------------------------------------------------------------------------
/assets/Text_10x10.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/justcallmekoko/flipperzero-wifi-marauder/316258b8c708c1f2a67a2c087aa6d16348ed76f5/assets/Text_10x10.png
--------------------------------------------------------------------------------
/assets/WarningDolphin_45x42.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/justcallmekoko/flipperzero-wifi-marauder/316258b8c708c1f2a67a2c087aa6d16348ed76f5/assets/WarningDolphin_45x42.png
--------------------------------------------------------------------------------
/docs/README.md:
--------------------------------------------------------------------------------
1 | ## WiFi Marauder companion app for Flipper Zero
2 |
3 | Requires a connected dev board running Marauder FW. See install instructions from UberGuidoZ here: https://github.com/UberGuidoZ/Flipper/tree/main/Wifi_DevBoard#marauder-install-information
4 |
5 | ## Support
6 |
7 | For app feedback, bugs, and feature requests, please create an issue here: https://github.com/0xchocolate/flipperzero-wifi-marauder/issues
8 |
9 | You can find me (0xchocolate) on discord as @cococode.
10 |
--------------------------------------------------------------------------------
/docs/changelog.md:
--------------------------------------------------------------------------------
1 | ## v0.7.2
2 |
3 | Thanks to @justcallmekoko for adding app support for the new features in Marauder firmware v1.1.0! See the additions and grab the firmware for your wifi board here: https://github.com/justcallmekoko/ESP32Marauder/releases/tag/v1.1.0
4 |
5 | <3 @0xchocolate (cococode)
6 |
7 |
8 | ## v0.7.1
9 |
10 | Bug fixes and improvements!
11 |
12 | - Back to working on latest official firmware ( @GeorgeBotsev )
13 | - Now the Evil Portal and wardrive dumps will be saved to a new directory apps_data/marauder/dumps, and the "-serial" argument for all commands will respect your "save pcaps" app setting ( @Willy-JL )
14 | - You'll also notice an apps_data/marauder/html directory, to support migrating from the standalone Evil Portal ( @RogueMaster )
15 | - Fixes an issue with loading scripts due to upstream toolchain changes ( @Willy-JL , @vollukas )
16 |
17 | As always, make sure you're running the latest version of Marauder FW on your wifi board: https://github.com/justcallmekoko/ESP32Marauder/releases/latest
18 |
19 | <3 @0xchocolate (cococode)
20 |
21 |
22 | ## v0.7.0
23 |
24 | Unified serial update! No more complicated wiring of 2x UART connections - all your boards are supported now, with PCAPs and text both going over just ONE, SINGLE serial channel! Thanks to @Willy-JL for adding this amazing feature and fixing up the app for the new APIs.
25 |
26 | Requires Marauder **FW v0.13.7** (or newer) flashed to your wifi board: https://github.com/justcallmekoko/ESP32Marauder/releases/latest
27 |
28 | <3 @0xchocolate (cococode)
29 |
30 |
31 | ## v0.6.6
32 |
33 | Bug fixes and new BLE spam commands! Thanks to @justcallmekoko for adding the new commands! I also fixed the script user input bug where it would hang after selecting "save".
34 |
35 | The BLE spam command format has changed and requires at least **FW v0.13.6**. Make sure you flash the latest release of Marauder FW to your wifi board: https://github.com/justcallmekoko/ESP32Marauder/releases/latest
36 |
37 | Note: if you're flashing directly from your flipper using the [ESP Flasher app](https://github.com/0xchocolate/flipperzero-esp-flasher), grab the bin that corresponds to your hardware and only reflash the Firmware partition. (If you have dual boot set up, then choose the slot where you want to install it. Otherwise, reflash FirmwareA only.)
38 |
39 | By the way, want to support app development by buying me a coffee? You finally have that option! https://ko-fi.com/cococode
40 |
41 | <3 @0xchocolate (cococode)
42 |
43 |
44 | ## v0.6.5
45 |
46 | New option to load Evil Portal HTML files from the flipper sd card!
47 |
48 |
49 | ## v0.6.4
50 |
51 | swiftpair spam and ESP32 sd card commands: sethtml, ls. Requires a board with BT and sd card support. Thanks to @justcallmekoko for adding the new commands!
52 |
53 |
54 | ## v0.6.3
55 |
56 | BT wardriving and Sour Apple! Requires a board with BT support. Thanks to @justcallmekoko for adding the new commands!
57 |
58 |
59 | ## v0.6.2
60 |
61 | Happy wardriving! Thanks to @justcallmekoko for adding the gps and wardrive commands!
62 |
63 | Instructions to install a GPS module: https://github.com/justcallmekoko/ESP32Marauder/wiki/gps-modification
64 |
65 |
66 | ## v0.6.1
67 |
68 | Thanks to @superhedge22 for adding a channel hop option to the sniffpmkid script stage!
69 |
70 |
71 | ## v0.6.0
72 |
73 | Evil Portal and LED control! Thanks @justcallmekoko for adding the commands! See Evil Portal workflow here: https://github.com/justcallmekoko/ESP32Marauder/wiki/evil-portal-workflow
74 |
75 | This version also removes the in-app ESP flasher, but don't worry! It's grown up into its own app, where development will continue separately: https://github.com/0xchocolate/flipperzero-esp-flasher
76 |
77 |
78 | ## v0.4.0
79 |
80 | Added Signal Monitor (thanks @justcallmekoko!) to support new sigmon command in Marauder v0.10.5: https://github.com/justcallmekoko/ESP32Marauder/releases
81 |
82 | Added keyboard and +5V support from unleashed (thanks @xMasterX!)
83 |
--------------------------------------------------------------------------------
/file/sequential_file.c:
--------------------------------------------------------------------------------
1 | #include "sequential_file.h"
2 |
3 | char* sequential_file_resolve_path(
4 | Storage* storage,
5 | const char* dir,
6 | const char* prefix,
7 | const char* extension) {
8 | if(storage == NULL || dir == NULL || prefix == NULL || extension == NULL) {
9 | return NULL;
10 | }
11 |
12 | char file_path[256];
13 | int file_index = 0;
14 |
15 | do {
16 | if(snprintf(
17 | file_path, sizeof(file_path), "%s/%s_%d.%s", dir, prefix, file_index, extension) <
18 | 0) {
19 | return NULL;
20 | }
21 | file_index++;
22 | } while(storage_file_exists(storage, file_path));
23 |
24 | return strdup(file_path);
25 | }
26 |
27 | bool sequential_file_open(
28 | Storage* storage,
29 | File* file,
30 | const char* dir,
31 | const char* prefix,
32 | const char* extension) {
33 | if(storage == NULL || file == NULL || dir == NULL || prefix == NULL || extension == NULL) {
34 | return false;
35 | }
36 |
37 | char* file_path = sequential_file_resolve_path(storage, dir, prefix, extension);
38 | if(file_path == NULL) {
39 | return false;
40 | }
41 |
42 | bool success = storage_file_open(file, file_path, FSAM_WRITE, FSOM_CREATE_ALWAYS);
43 | free(file_path);
44 |
45 | return success;
46 | }
--------------------------------------------------------------------------------
/file/sequential_file.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
5 | char* sequential_file_resolve_path(
6 | Storage* storage,
7 | const char* dir,
8 | const char* prefix,
9 | const char* extension);
10 | bool sequential_file_open(
11 | Storage* storage,
12 | File* file,
13 | const char* dir,
14 | const char* prefix,
15 | const char* extension);
--------------------------------------------------------------------------------
/scenes/wifi_marauder_scene.c:
--------------------------------------------------------------------------------
1 | #include "wifi_marauder_scene.h"
2 |
3 | // Generate scene on_enter handlers array
4 | #define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_enter,
5 | void (*const wifi_marauder_scene_on_enter_handlers[])(void*) = {
6 | #include "wifi_marauder_scene_config.h"
7 | };
8 | #undef ADD_SCENE
9 |
10 | // Generate scene on_event handlers array
11 | #define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_event,
12 | bool (*const wifi_marauder_scene_on_event_handlers[])(void* context, SceneManagerEvent event) = {
13 | #include "wifi_marauder_scene_config.h"
14 | };
15 | #undef ADD_SCENE
16 |
17 | // Generate scene on_exit handlers array
18 | #define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_exit,
19 | void (*const wifi_marauder_scene_on_exit_handlers[])(void* context) = {
20 | #include "wifi_marauder_scene_config.h"
21 | };
22 | #undef ADD_SCENE
23 |
24 | // Initialize scene handlers configuration structure
25 | const SceneManagerHandlers wifi_marauder_scene_handlers = {
26 | .on_enter_handlers = wifi_marauder_scene_on_enter_handlers,
27 | .on_event_handlers = wifi_marauder_scene_on_event_handlers,
28 | .on_exit_handlers = wifi_marauder_scene_on_exit_handlers,
29 | .scene_num = WifiMarauderSceneNum,
30 | };
31 |
--------------------------------------------------------------------------------
/scenes/wifi_marauder_scene.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
5 | // Generate scene id and total number
6 | #define ADD_SCENE(prefix, name, id) WifiMarauderScene##id,
7 | typedef enum {
8 | #include "wifi_marauder_scene_config.h"
9 | WifiMarauderSceneNum,
10 | } WifiMarauderScene;
11 | #undef ADD_SCENE
12 |
13 | extern const SceneManagerHandlers wifi_marauder_scene_handlers;
14 |
15 | // Generate scene on_enter handlers declaration
16 | #define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_enter(void*);
17 | #include "wifi_marauder_scene_config.h"
18 | #undef ADD_SCENE
19 |
20 | // Generate scene on_event handlers declaration
21 | #define ADD_SCENE(prefix, name, id) \
22 | bool prefix##_scene_##name##_on_event(void* context, SceneManagerEvent event);
23 | #include "wifi_marauder_scene_config.h"
24 | #undef ADD_SCENE
25 |
26 | // Generate scene on_exit handlers declaration
27 | #define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_exit(void* context);
28 | #include "wifi_marauder_scene_config.h"
29 | #undef ADD_SCENE
30 |
--------------------------------------------------------------------------------
/scenes/wifi_marauder_scene_config.h:
--------------------------------------------------------------------------------
1 | ADD_SCENE(wifi_marauder, start, Start)
2 | ADD_SCENE(wifi_marauder, console_output, ConsoleOutput)
3 | ADD_SCENE(wifi_marauder, text_input, TextInput)
4 | ADD_SCENE(wifi_marauder, settings_init, SettingsInit)
5 | ADD_SCENE(wifi_marauder, log_viewer, LogViewer)
6 | ADD_SCENE(wifi_marauder, user_input, UserInput)
7 | ADD_SCENE(wifi_marauder, script_select, ScriptSelect)
8 | ADD_SCENE(wifi_marauder, script_options, ScriptOptions)
9 | ADD_SCENE(wifi_marauder, script_edit, ScriptEdit)
10 | ADD_SCENE(wifi_marauder, script_settings, ScriptSettings)
11 | ADD_SCENE(wifi_marauder, script_confirm_delete, ScriptConfirmDelete)
12 | ADD_SCENE(wifi_marauder, script_stage_edit, ScriptStageEdit)
13 | ADD_SCENE(wifi_marauder, script_stage_add, ScriptStageAdd)
14 | ADD_SCENE(wifi_marauder, script_stage_edit_list, ScriptStageEditList)
15 | ADD_SCENE(wifi_marauder, sniffpmkid_options, SniffPmkidOptions)
16 |
--------------------------------------------------------------------------------
/scenes/wifi_marauder_scene_console_output.c:
--------------------------------------------------------------------------------
1 | #include "../wifi_marauder_app_i.h"
2 |
3 | char* _wifi_marauder_get_prefix_from_cmd(const char* command) {
4 | int end = strcspn(command, " ");
5 | char* prefix = (char*)malloc(sizeof(char) * (end + 1));
6 | strncpy(prefix, command, end);
7 | prefix[end] = '\0';
8 | return prefix;
9 | }
10 |
11 | bool _wifi_marauder_is_saving_enabled(WifiMarauderApp* app) {
12 | // If it is a script that contains a sniff function
13 | if(app->script != NULL) {
14 | if(app->script->save_pcap == WifiMarauderScriptBooleanFalse) {
15 | return false;
16 | }
17 | if(app->script->save_pcap == WifiMarauderScriptBooleanUndefined) {
18 | if(!app->ok_to_save_pcaps) {
19 | return false;
20 | }
21 | }
22 | return wifi_marauder_script_has_stage(app->script, WifiMarauderScriptStageTypeSniffRaw) ||
23 | wifi_marauder_script_has_stage(
24 | app->script, WifiMarauderScriptStageTypeSniffBeacon) ||
25 | wifi_marauder_script_has_stage(
26 | app->script, WifiMarauderScriptStageTypeSniffDeauth) ||
27 | wifi_marauder_script_has_stage(app->script, WifiMarauderScriptStageTypeSniffEsp) ||
28 | wifi_marauder_script_has_stage(
29 | app->script, WifiMarauderScriptStageTypeSniffPmkid) ||
30 | wifi_marauder_script_has_stage(app->script, WifiMarauderScriptStageTypeSniffPwn);
31 | }
32 | if(!app->ok_to_save_pcaps) {
33 | return false;
34 | }
35 | // If it is a sniff/wardrive/btwardrive/evilportal function
36 | return app->is_command && app->selected_tx_string &&
37 | (strncmp("sniff", app->selected_tx_string, strlen("sniff")) == 0 ||
38 | strncmp("wardrive", app->selected_tx_string, strlen("wardrive")) == 0 ||
39 | strncmp("btwardrive", app->selected_tx_string, strlen("btwardrive")) == 0 ||
40 | strncmp("evilportal", app->selected_tx_string, strlen("evilportal")) == 0);
41 | }
42 |
43 | void wifi_marauder_console_output_handle_rx_data_cb(uint8_t* buf, size_t len, void* context) {
44 | furi_assert(context);
45 | WifiMarauderApp* app = context;
46 |
47 | if(app->is_writing_log) {
48 | app->has_saved_logs_this_session = true;
49 | storage_file_write(app->log_file, buf, len);
50 | }
51 |
52 | // If text box store gets too big, then truncate it
53 | app->text_box_store_strlen += len;
54 | if(app->text_box_store_strlen >= WIFI_MARAUDER_TEXT_BOX_STORE_SIZE - 1) {
55 | furi_string_right(app->text_box_store, app->text_box_store_strlen / 2);
56 | app->text_box_store_strlen = furi_string_size(app->text_box_store) + len;
57 | }
58 |
59 | // Null-terminate buf and append to text box store
60 | buf[len] = '\0';
61 | furi_string_cat_printf(app->text_box_store, "%s", buf);
62 | view_dispatcher_send_custom_event(app->view_dispatcher, WifiMarauderEventRefreshConsoleOutput);
63 | }
64 |
65 | void wifi_marauder_console_output_handle_rx_packets_cb(uint8_t* buf, size_t len, void* context) {
66 | furi_assert(context);
67 | WifiMarauderApp* app = context;
68 |
69 | if(app->is_writing_pcap) {
70 | storage_file_write(app->capture_file, buf, len);
71 | }
72 | }
73 |
74 | void wifi_marauder_scene_console_output_on_enter(void* context) {
75 | WifiMarauderApp* app = context;
76 |
77 | // Reset text box and set font
78 | TextBox* text_box = app->text_box;
79 | text_box_reset(text_box);
80 | text_box_set_font(text_box, TextBoxFontText);
81 |
82 | // Set focus on start or end
83 | if(app->focus_console_start) {
84 | text_box_set_focus(text_box, TextBoxFocusStart);
85 | } else {
86 | text_box_set_focus(text_box, TextBoxFocusEnd);
87 | }
88 |
89 | // Set command-related messages
90 | if(app->is_command) {
91 | furi_string_reset(app->text_box_store);
92 | app->text_box_store_strlen = 0;
93 | // Help message
94 | if(0 == strncmp("help", app->selected_tx_string, strlen("help"))) {
95 | const char* help_msg = "Marauder companion " WIFI_MARAUDER_APP_VERSION "\n";
96 | furi_string_cat_str(app->text_box_store, help_msg);
97 | app->text_box_store_strlen += strlen(help_msg);
98 | }
99 | // Stopscan message
100 | if(app->show_stopscan_tip) {
101 | const char* help_msg = "Press BACK to send stopscan\n";
102 | furi_string_cat_str(app->text_box_store, help_msg);
103 | app->text_box_store_strlen += strlen(help_msg);
104 | }
105 | }
106 |
107 | // Set starting text
108 | text_box_set_text(app->text_box, furi_string_get_cstr(app->text_box_store));
109 |
110 | // Set scene state and switch view
111 | scene_manager_set_scene_state(app->scene_manager, WifiMarauderSceneConsoleOutput, 0);
112 | view_dispatcher_switch_to_view(app->view_dispatcher, WifiMarauderAppViewConsoleOutput);
113 |
114 | // Register callbacks to receive data
115 | wifi_marauder_uart_set_handle_rx_data_cb(
116 | app->uart,
117 | wifi_marauder_console_output_handle_rx_data_cb); // setup callback for general log rx thread
118 | wifi_marauder_uart_set_handle_rx_pcap_cb(
119 | app->uart,
120 | wifi_marauder_console_output_handle_rx_packets_cb); // setup callback for packets rx thread
121 |
122 | // Get ready to send command
123 | if((app->is_command && app->selected_tx_string) || app->script) {
124 | char* prefix_buf = NULL;
125 | if(strlen(app->selected_tx_string) > 0) {
126 | prefix_buf = _wifi_marauder_get_prefix_from_cmd(app->selected_tx_string);
127 | }
128 | const char* prefix = prefix_buf ? prefix_buf : // Function name
129 | app->script->name; // Script name
130 |
131 | // Create files *before* sending command
132 | // (it takes time to iterate through the directory)
133 | if(app->ok_to_save_logs) {
134 | char* resolved_path = sequential_file_resolve_path(
135 | app->storage, MARAUDER_APP_FOLDER_LOGS, prefix, "log");
136 | if(resolved_path != NULL) {
137 | strcpy(app->log_file_path, resolved_path);
138 | free(resolved_path);
139 | if(storage_file_open(
140 | app->log_file, app->log_file_path, FSAM_WRITE, FSOM_CREATE_ALWAYS)) {
141 | app->is_writing_log = true;
142 | } else {
143 | dialog_message_show_storage_error(app->dialogs, "Cannot open log file");
144 | }
145 | } else {
146 | dialog_message_show_storage_error(app->dialogs, "Cannot resolve log path");
147 | }
148 | }
149 |
150 | // If it is a sniff/wardrive/btwardrive/evilportal function or script, open the capture file for recording
151 | if(_wifi_marauder_is_saving_enabled(app)) {
152 | const char* folder = NULL;
153 | const char* extension = NULL;
154 | if(app->script || // Scripts only support sniff functions, but selected_tx_string is empty
155 | strncmp("sniff", app->selected_tx_string, strlen("sniff")) == 0) {
156 | folder = MARAUDER_APP_FOLDER_PCAPS;
157 | extension = "pcap";
158 | } else {
159 | folder = MARAUDER_APP_FOLDER_DUMPS;
160 | extension = "txt";
161 | }
162 | if(sequential_file_open(app->storage, app->capture_file, folder, prefix, extension)) {
163 | app->is_writing_pcap = true;
164 | } else {
165 | dialog_message_show_storage_error(app->dialogs, "Cannot open capture file");
166 | }
167 | }
168 |
169 | bool send_html = false;
170 | uint8_t* the_html = NULL;
171 | size_t html_size = 0;
172 | if(app->selected_tx_string && strncmp(
173 | "evilportal -c sethtmlstr",
174 | app->selected_tx_string,
175 | strlen("evilportal -c sethtmlstr")) == 0) {
176 | send_html = wifi_marauder_ep_read_html_file(app, &the_html, &html_size);
177 | }
178 |
179 | // Send command with newline '\n'
180 | if(app->selected_tx_string) {
181 | if(app->script == NULL) {
182 | wifi_marauder_uart_tx(
183 | app->uart,
184 | (uint8_t*)(app->selected_tx_string),
185 | strlen(app->selected_tx_string));
186 | if(app->is_writing_pcap) {
187 | wifi_marauder_uart_tx(
188 | app->uart, (uint8_t*)(" -serial\n"), strlen(" -serial\n"));
189 | } else {
190 | wifi_marauder_uart_tx(app->uart, (uint8_t*)("\n"), 1);
191 | }
192 | }
193 | if(send_html && the_html) {
194 | wifi_marauder_uart_tx(app->uart, the_html, html_size);
195 | wifi_marauder_uart_tx(app->uart, (uint8_t*)("\n"), 1);
196 | free(the_html);
197 | send_html = false;
198 | }
199 | }
200 |
201 | // Run the script if the file with the script has been opened
202 | if(app->script != NULL) {
203 | app->script_worker = wifi_marauder_script_worker_alloc(app->uart);
204 | wifi_marauder_script_worker_start(app->script_worker, app->script);
205 | }
206 |
207 | if(prefix_buf) {
208 | free(prefix_buf);
209 | }
210 | }
211 | }
212 |
213 | bool wifi_marauder_scene_console_output_on_event(void* context, SceneManagerEvent event) {
214 | WifiMarauderApp* app = context;
215 |
216 | bool consumed = false;
217 |
218 | if(event.type == SceneManagerEventTypeCustom) {
219 | text_box_set_text(app->text_box, furi_string_get_cstr(app->text_box_store));
220 | consumed = true;
221 | } else if(event.type == SceneManagerEventTypeTick) {
222 | consumed = true;
223 | }
224 |
225 | return consumed;
226 | }
227 |
228 | void wifi_marauder_scene_console_output_on_exit(void* context) {
229 | WifiMarauderApp* app = context;
230 |
231 | // Automatically stop the scan when exiting view
232 | if(app->is_command) {
233 | wifi_marauder_uart_tx(app->uart, (uint8_t*)("stopscan\n"), strlen("stopscan\n"));
234 | furi_delay_ms(50);
235 | }
236 |
237 | // Unregister rx callback
238 | wifi_marauder_uart_set_handle_rx_data_cb(app->uart, NULL);
239 | wifi_marauder_uart_set_handle_rx_pcap_cb(app->uart, NULL);
240 |
241 | if(app->script_worker) {
242 | wifi_marauder_script_worker_free(app->script_worker);
243 | app->script_worker = NULL;
244 | }
245 |
246 | app->is_writing_pcap = false;
247 | if(app->capture_file && storage_file_is_open(app->capture_file)) {
248 | storage_file_close(app->capture_file);
249 | }
250 |
251 | app->is_writing_log = false;
252 | if(app->log_file && storage_file_is_open(app->log_file)) {
253 | storage_file_close(app->log_file);
254 | }
255 | }
256 |
--------------------------------------------------------------------------------
/scenes/wifi_marauder_scene_log_viewer.c:
--------------------------------------------------------------------------------
1 | #include "../wifi_marauder_app_i.h"
2 |
3 | void wifi_marauder_scene_log_viewer_widget_callback(
4 | GuiButtonType result,
5 | InputType type,
6 | void* context) {
7 | WifiMarauderApp* app = context;
8 | if(type == InputTypeShort) {
9 | view_dispatcher_send_custom_event(app->view_dispatcher, result);
10 | }
11 | }
12 |
13 | static void _read_log_page_into_text_store(WifiMarauderApp* app) {
14 | char temp[64 + 1];
15 | storage_file_seek(
16 | app->log_file, WIFI_MARAUDER_TEXT_BOX_STORE_SIZE * (app->open_log_file_page - 1), true);
17 | furi_string_reset(app->text_box_store);
18 | for(uint16_t i = 0; i < (WIFI_MARAUDER_TEXT_BOX_STORE_SIZE / (sizeof(temp) - 1)); i++) {
19 | uint16_t num_bytes = storage_file_read(app->log_file, temp, sizeof(temp) - 1);
20 | if(num_bytes == 0) {
21 | break;
22 | }
23 | temp[num_bytes] = '\0';
24 | furi_string_cat_str(app->text_box_store, temp);
25 | }
26 | }
27 |
28 | void wifi_marauder_scene_log_viewer_setup_widget(WifiMarauderApp* app, bool called_from_browse) {
29 | Widget* widget = app->widget;
30 | bool is_open = storage_file_is_open(app->log_file);
31 | bool should_open_log = (app->has_saved_logs_this_session || called_from_browse);
32 | if(is_open) {
33 | _read_log_page_into_text_store(app);
34 | } else if(
35 | should_open_log &&
36 | storage_file_open(app->log_file, app->log_file_path, FSAM_READ, FSOM_OPEN_EXISTING)) {
37 | uint64_t filesize = storage_file_size(app->log_file);
38 | app->open_log_file_num_pages = filesize / WIFI_MARAUDER_TEXT_BOX_STORE_SIZE;
39 | int extra_page = (filesize % WIFI_MARAUDER_TEXT_BOX_STORE_SIZE != 0) ? 1 : 0;
40 | app->open_log_file_num_pages = (filesize / WIFI_MARAUDER_TEXT_BOX_STORE_SIZE) + extra_page;
41 | app->open_log_file_page = 1;
42 | _read_log_page_into_text_store(app);
43 | } else {
44 | app->open_log_file_page = 0;
45 | app->open_log_file_num_pages = 0;
46 | }
47 |
48 | widget_reset(widget);
49 |
50 | if(furi_string_empty(app->text_box_store)) {
51 | char help_msg[256];
52 | snprintf(
53 | help_msg,
54 | sizeof(help_msg),
55 | "The log is empty! :(\nTry sending a command?\n\nSaving pcaps to flipper sdcard: %s\nSaving logs to flipper sdcard: %s",
56 | app->ok_to_save_pcaps ? "ON" : "OFF",
57 | app->ok_to_save_logs ? "ON" : "OFF");
58 | furi_string_set_str(app->text_box_store, help_msg);
59 | }
60 |
61 | widget_add_text_scroll_element(
62 | widget, 0, 0, 128, 53, furi_string_get_cstr(app->text_box_store));
63 |
64 | if(1 < app->open_log_file_page && app->open_log_file_page < app->open_log_file_num_pages) {
65 | // hide "Browse" text for middle pages
66 | widget_add_button_element(
67 | widget, GuiButtonTypeCenter, "", wifi_marauder_scene_log_viewer_widget_callback, app);
68 | } else {
69 | // only show "Browse" text on first and last page
70 | widget_add_button_element(
71 | widget,
72 | GuiButtonTypeCenter,
73 | "Browse",
74 | wifi_marauder_scene_log_viewer_widget_callback,
75 | app);
76 | }
77 |
78 | char pagecounter[100];
79 | snprintf(
80 | pagecounter,
81 | sizeof(pagecounter),
82 | "%d/%d",
83 | app->open_log_file_page,
84 | app->open_log_file_num_pages);
85 | if(app->open_log_file_page > 1) {
86 | if(app->open_log_file_page == app->open_log_file_num_pages) {
87 | // only show left side page-count on last page
88 | widget_add_button_element(
89 | widget,
90 | GuiButtonTypeLeft,
91 | pagecounter,
92 | wifi_marauder_scene_log_viewer_widget_callback,
93 | app);
94 | } else {
95 | widget_add_button_element(
96 | widget, GuiButtonTypeLeft, "", wifi_marauder_scene_log_viewer_widget_callback, app);
97 | }
98 | }
99 | if(app->open_log_file_page < app->open_log_file_num_pages) {
100 | widget_add_button_element(
101 | widget,
102 | GuiButtonTypeRight,
103 | pagecounter,
104 | wifi_marauder_scene_log_viewer_widget_callback,
105 | app);
106 | }
107 | }
108 |
109 | void wifi_marauder_scene_log_viewer_on_enter(void* context) {
110 | WifiMarauderApp* app = context;
111 |
112 | app->open_log_file_page = 0;
113 | app->open_log_file_num_pages = 0;
114 | bool saved_logs_exist = false;
115 | if(!app->has_saved_logs_this_session && furi_string_empty(app->text_box_store)) {
116 | // no commands sent yet this session, find last saved log
117 | if(storage_dir_open(app->log_file, MARAUDER_APP_FOLDER_LOGS)) {
118 | char name[70];
119 | char lastname[70];
120 | while(storage_dir_read(app->log_file, NULL, name, sizeof(name))) {
121 | // keep reading directory until last file is reached
122 | strlcpy(lastname, name, sizeof(lastname));
123 | saved_logs_exist = true;
124 | }
125 | if(saved_logs_exist) {
126 | snprintf(
127 | app->log_file_path,
128 | sizeof(app->log_file_path),
129 | "%s/%s",
130 | MARAUDER_APP_FOLDER_LOGS,
131 | lastname);
132 | }
133 | }
134 | storage_dir_close(app->log_file);
135 | }
136 |
137 | wifi_marauder_scene_log_viewer_setup_widget(app, saved_logs_exist);
138 |
139 | view_dispatcher_switch_to_view(app->view_dispatcher, WifiMarauderAppViewWidget);
140 | }
141 |
142 | bool wifi_marauder_scene_log_viewer_on_event(void* context, SceneManagerEvent event) {
143 | WifiMarauderApp* app = context;
144 | bool consumed = false;
145 |
146 | if(event.type == SceneManagerEventTypeCustom) {
147 | if(event.event == GuiButtonTypeCenter) {
148 | // Browse
149 | FuriString* predefined_filepath = furi_string_alloc_set_str(MARAUDER_APP_FOLDER_LOGS);
150 | FuriString* selected_filepath = furi_string_alloc();
151 | DialogsFileBrowserOptions browser_options;
152 | dialog_file_browser_set_basic_options(&browser_options, ".log", &I_Text_10x10);
153 | if(dialog_file_browser_show(
154 | app->dialogs, selected_filepath, predefined_filepath, &browser_options)) {
155 | strncpy(
156 | app->log_file_path,
157 | furi_string_get_cstr(selected_filepath),
158 | sizeof(app->log_file_path));
159 | if(storage_file_is_open(app->log_file)) {
160 | storage_file_close(app->log_file);
161 | }
162 | wifi_marauder_scene_log_viewer_setup_widget(app, true);
163 | }
164 | furi_string_free(selected_filepath);
165 | furi_string_free(predefined_filepath);
166 | consumed = true;
167 | } else if(event.event == GuiButtonTypeRight) {
168 | // Advance page
169 | ++app->open_log_file_page;
170 | wifi_marauder_scene_log_viewer_setup_widget(app, false);
171 | } else if(event.event == GuiButtonTypeLeft) {
172 | // Previous page
173 | --app->open_log_file_page;
174 | wifi_marauder_scene_log_viewer_setup_widget(app, false);
175 | }
176 | }
177 |
178 | return consumed;
179 | }
180 |
181 | void wifi_marauder_scene_log_viewer_on_exit(void* context) {
182 | WifiMarauderApp* app = context;
183 | widget_reset(app->widget);
184 | if(storage_file_is_open(app->log_file)) {
185 | storage_file_close(app->log_file);
186 | }
187 | }
188 |
--------------------------------------------------------------------------------
/scenes/wifi_marauder_scene_script_confirm_delete.c:
--------------------------------------------------------------------------------
1 | #include "../wifi_marauder_app_i.h"
2 |
3 | void wifi_marauder_scene_script_confirm_delete_widget_callback(
4 | GuiButtonType result,
5 | InputType type,
6 | void* context) {
7 | WifiMarauderApp* app = context;
8 | if(type == InputTypeShort) {
9 | view_dispatcher_send_custom_event(app->view_dispatcher, result);
10 | }
11 | }
12 |
13 | void wifi_marauder_scene_script_confirm_delete_on_enter(void* context) {
14 | WifiMarauderApp* app = context;
15 |
16 | widget_add_button_element(
17 | app->widget,
18 | GuiButtonTypeLeft,
19 | "No",
20 | wifi_marauder_scene_script_confirm_delete_widget_callback,
21 | app);
22 | widget_add_button_element(
23 | app->widget,
24 | GuiButtonTypeRight,
25 | "Yes",
26 | wifi_marauder_scene_script_confirm_delete_widget_callback,
27 | app);
28 |
29 | widget_add_string_element(
30 | app->widget, 0, 0, AlignLeft, AlignTop, FontPrimary, "Are you sure?");
31 | widget_add_text_box_element(
32 | app->widget,
33 | 0,
34 | 12,
35 | 128,
36 | 38,
37 | AlignCenter,
38 | AlignCenter,
39 | "The script will be\npermanently deleted",
40 | false);
41 |
42 | view_dispatcher_switch_to_view(app->view_dispatcher, WifiMarauderAppViewWidget);
43 | }
44 |
45 | bool wifi_marauder_scene_script_confirm_delete_on_event(void* context, SceneManagerEvent event) {
46 | WifiMarauderApp* app = context;
47 | bool consumed = false;
48 |
49 | if(event.type == SceneManagerEventTypeCustom) {
50 | // get which button press: "Yes" or "No"
51 | if(event.event == GuiButtonTypeRight) {
52 | // Yes
53 | if(app->script != NULL) {
54 | char script_path[256];
55 | snprintf(
56 | script_path,
57 | sizeof(script_path),
58 | "%s/%s.json",
59 | MARAUDER_APP_FOLDER_SCRIPTS,
60 | app->script->name);
61 | storage_simply_remove(app->storage, script_path);
62 | wifi_marauder_script_free(app->script);
63 | app->script = NULL;
64 |
65 | DialogMessage* message = dialog_message_alloc();
66 | dialog_message_set_text(message, "Deleted!", 88, 32, AlignCenter, AlignCenter);
67 | dialog_message_set_icon(message, &I_DolphinCommon_56x48, 5, 6);
68 | dialog_message_set_buttons(message, NULL, "Ok", NULL);
69 | dialog_message_show(app->dialogs, message);
70 | dialog_message_free(message);
71 | }
72 | }
73 | scene_manager_previous_scene(app->scene_manager);
74 | consumed = true;
75 | }
76 |
77 | return consumed;
78 | }
79 |
80 | void wifi_marauder_scene_script_confirm_delete_on_exit(void* context) {
81 | WifiMarauderApp* app = context;
82 | widget_reset(app->widget);
83 | }
84 |
--------------------------------------------------------------------------------
/scenes/wifi_marauder_scene_script_edit.c:
--------------------------------------------------------------------------------
1 | #include "../wifi_marauder_app_i.h"
2 |
3 | static void wifi_marauder_scene_script_edit_callback(void* context, uint32_t index) {
4 | WifiMarauderApp* app = context;
5 | WifiMarauderScriptStage* current_stage = app->script->first_stage;
6 | uint32_t stage_index = 0;
7 |
8 | while(current_stage != NULL && stage_index < index) {
9 | current_stage = current_stage->next_stage;
10 | stage_index++;
11 | }
12 | app->script_edit_selected_stage = current_stage;
13 |
14 | if(app->script_edit_selected_stage != NULL) {
15 | scene_manager_set_scene_state(app->scene_manager, WifiMarauderSceneScriptEdit, index);
16 | scene_manager_next_scene(app->scene_manager, WifiMarauderSceneScriptStageEdit);
17 | }
18 | }
19 |
20 | static void wifi_marauder_scene_script_edit_add_callback(void* context, uint32_t index) {
21 | WifiMarauderApp* app = context;
22 | scene_manager_set_scene_state(app->scene_manager, WifiMarauderSceneScriptEdit, index);
23 | scene_manager_next_scene(app->scene_manager, WifiMarauderSceneScriptStageAdd);
24 | }
25 |
26 | void wifi_marauder_scene_script_edit_on_enter(void* context) {
27 | WifiMarauderApp* app = context;
28 | Submenu* submenu = app->submenu;
29 | WifiMarauderScript* script = app->script;
30 | submenu_set_header(submenu, script->name);
31 |
32 | WifiMarauderScriptStage* current_stage = script->first_stage;
33 | int stage_index = 0;
34 | while(current_stage != NULL) {
35 | switch(current_stage->type) {
36 | case WifiMarauderScriptStageTypeScan:
37 | submenu_add_item(
38 | submenu, "Scan", stage_index, wifi_marauder_scene_script_edit_callback, app);
39 | break;
40 | case WifiMarauderScriptStageTypeSelect:
41 | submenu_add_item(
42 | submenu, "Select", stage_index, wifi_marauder_scene_script_edit_callback, app);
43 | break;
44 | case WifiMarauderScriptStageTypeDeauth:
45 | submenu_add_item(
46 | submenu, "Deauth", stage_index, wifi_marauder_scene_script_edit_callback, app);
47 | break;
48 | case WifiMarauderScriptStageTypeProbe:
49 | submenu_add_item(
50 | submenu, "Probe", stage_index, wifi_marauder_scene_script_edit_callback, app);
51 | break;
52 | case WifiMarauderScriptStageTypeSniffRaw:
53 | submenu_add_item(
54 | submenu, "Sniff raw", stage_index, wifi_marauder_scene_script_edit_callback, app);
55 | break;
56 | case WifiMarauderScriptStageTypeSniffBeacon:
57 | submenu_add_item(
58 | submenu,
59 | "Sniff beacon",
60 | stage_index,
61 | wifi_marauder_scene_script_edit_callback,
62 | app);
63 | break;
64 | case WifiMarauderScriptStageTypeSniffDeauth:
65 | submenu_add_item(
66 | submenu,
67 | "Sniff deauth",
68 | stage_index,
69 | wifi_marauder_scene_script_edit_callback,
70 | app);
71 | break;
72 | case WifiMarauderScriptStageTypeSniffEsp:
73 | submenu_add_item(
74 | submenu, "Sniff esp", stage_index, wifi_marauder_scene_script_edit_callback, app);
75 | break;
76 | case WifiMarauderScriptStageTypeSniffPmkid:
77 | submenu_add_item(
78 | submenu, "Sniff PMKID", stage_index, wifi_marauder_scene_script_edit_callback, app);
79 | break;
80 | case WifiMarauderScriptStageTypeSniffPwn:
81 | submenu_add_item(
82 | submenu, "Sniff pwn", stage_index, wifi_marauder_scene_script_edit_callback, app);
83 | break;
84 | case WifiMarauderScriptStageTypeBeaconList:
85 | submenu_add_item(
86 | submenu, "Beacon list", stage_index, wifi_marauder_scene_script_edit_callback, app);
87 | break;
88 | case WifiMarauderScriptStageTypeBeaconAp:
89 | submenu_add_item(
90 | submenu, "Beacon AP", stage_index, wifi_marauder_scene_script_edit_callback, app);
91 | break;
92 | case WifiMarauderScriptStageTypeExec:
93 | submenu_add_item(
94 | submenu,
95 | "Custom command",
96 | stage_index,
97 | wifi_marauder_scene_script_edit_callback,
98 | app);
99 | break;
100 | case WifiMarauderScriptStageTypeDelay:
101 | submenu_add_item(
102 | submenu, "Delay", stage_index, wifi_marauder_scene_script_edit_callback, app);
103 | break;
104 | }
105 | current_stage = current_stage->next_stage;
106 | stage_index++;
107 | }
108 |
109 | submenu_add_item(
110 | submenu, "[+] ADD STAGE", stage_index++, wifi_marauder_scene_script_edit_add_callback, app);
111 | submenu_set_selected_item(
112 | submenu, scene_manager_get_scene_state(app->scene_manager, WifiMarauderSceneScriptEdit));
113 | view_dispatcher_switch_to_view(app->view_dispatcher, WifiMarauderAppViewSubmenu);
114 | }
115 |
116 | bool wifi_marauder_scene_script_edit_on_event(void* context, SceneManagerEvent event) {
117 | UNUSED(context);
118 | UNUSED(event);
119 | return false;
120 | }
121 |
122 | void wifi_marauder_scene_script_edit_on_exit(void* context) {
123 | WifiMarauderApp* app = context;
124 | submenu_reset(app->submenu);
125 | }
126 |
--------------------------------------------------------------------------------
/scenes/wifi_marauder_scene_script_edit_list.c:
--------------------------------------------------------------------------------
1 | #include "../wifi_marauder_app_i.h"
2 |
3 | static void
4 | wifi_marauder_scene_script_stage_edit_list_add_callback(void* context, uint32_t index) {
5 | WifiMarauderApp* app = context;
6 |
7 | // Creates new item
8 | WifiMarauderScriptStageListItem* new_item =
9 | (WifiMarauderScriptStageListItem*)malloc(sizeof(WifiMarauderScriptStageListItem));
10 | new_item->value = malloc(64);
11 | new_item->next_item = NULL;
12 |
13 | if(app->script_stage_edit_first_item == NULL) {
14 | app->script_stage_edit_first_item = new_item;
15 | } else {
16 | WifiMarauderScriptStageListItem* last_item = app->script_stage_edit_first_item;
17 | while(last_item->next_item != NULL) {
18 | last_item = last_item->next_item;
19 | }
20 | last_item->next_item = new_item;
21 | }
22 |
23 | scene_manager_set_scene_state(app->scene_manager, WifiMarauderSceneScriptStageEditList, index);
24 | app->user_input_type = WifiMarauderUserInputTypeString;
25 | app->user_input_string_reference = &new_item->value;
26 | scene_manager_next_scene(app->scene_manager, WifiMarauderSceneUserInput);
27 | }
28 |
29 | static void wifi_marauder_scene_script_stage_edit_list_deallocate_items(WifiMarauderApp* app) {
30 | WifiMarauderScriptStageListItem* current_item = app->script_stage_edit_first_item;
31 | while(current_item != NULL) {
32 | WifiMarauderScriptStageListItem* next_item = current_item->next_item;
33 | free(current_item->value);
34 | free(current_item);
35 | current_item = next_item;
36 | }
37 | app->script_stage_edit_first_item = NULL;
38 | }
39 |
40 | static void wifi_marauder_scene_script_stage_edit_list_save_strings(WifiMarauderApp* app) {
41 | WifiMarauderScriptStageListItem* current_item = app->script_stage_edit_first_item;
42 | int array_size = 0;
43 |
44 | // Calculates the required array size
45 | while(current_item != NULL) {
46 | array_size++;
47 | current_item = current_item->next_item;
48 | }
49 |
50 | // Reallocate the array of strings if necessary
51 | if(*app->script_stage_edit_string_count_reference < array_size) {
52 | *app->script_stage_edit_strings_reference =
53 | realloc(*app->script_stage_edit_strings_reference, array_size * sizeof(char*));
54 | }
55 |
56 | // Fills the array of strings
57 | current_item = app->script_stage_edit_first_item;
58 | int i = 0;
59 | while(current_item != NULL) {
60 | char* current_str = malloc(strlen(current_item->value) + 1);
61 | strncpy(current_str, current_item->value, strlen(current_item->value) + 1);
62 | (*app->script_stage_edit_strings_reference)[i] = current_str;
63 | current_item = current_item->next_item;
64 | i++;
65 | }
66 |
67 | *app->script_stage_edit_string_count_reference = array_size;
68 | }
69 |
70 | static void wifi_marauder_scene_script_stage_edit_list_save_numbers(WifiMarauderApp* app) {
71 | WifiMarauderScriptStageListItem* current_item = app->script_stage_edit_first_item;
72 | int array_size = 0;
73 |
74 | // Calculates the required array size
75 | while(current_item != NULL) {
76 | array_size++;
77 | current_item = current_item->next_item;
78 | }
79 |
80 | // Reallocate the array of integers if necessary
81 | if(*app->script_stage_edit_number_count_reference < array_size) {
82 | *app->script_stage_edit_numbers_reference =
83 | realloc(*app->script_stage_edit_numbers_reference, array_size * sizeof(int));
84 | }
85 |
86 | // Fills the array of integers
87 | current_item = app->script_stage_edit_first_item;
88 | int i = 0;
89 | while(current_item != NULL) {
90 | (*app->script_stage_edit_numbers_reference)[i] = atoi(current_item->value);
91 | current_item = current_item->next_item;
92 | i++;
93 | }
94 |
95 | *app->script_stage_edit_number_count_reference = array_size;
96 | }
97 |
98 | static void
99 | wifi_marauder_scene_script_stage_edit_list_save_callback(void* context, uint32_t index) {
100 | UNUSED(index);
101 | WifiMarauderApp* app = context;
102 |
103 | if(app->script_stage_edit_strings_reference != NULL &&
104 | app->script_stage_edit_string_count_reference != NULL) {
105 | wifi_marauder_scene_script_stage_edit_list_save_strings(app);
106 | }
107 |
108 | if(app->script_stage_edit_numbers_reference != NULL &&
109 | app->script_stage_edit_number_count_reference != NULL) {
110 | wifi_marauder_scene_script_stage_edit_list_save_numbers(app);
111 | }
112 |
113 | wifi_marauder_scene_script_stage_edit_list_deallocate_items(app);
114 | scene_manager_previous_scene(app->scene_manager);
115 | }
116 |
117 | static void
118 | wifi_marauder_scene_script_stage_edit_list_clear_callback(void* context, uint32_t index) {
119 | UNUSED(index);
120 | WifiMarauderApp* app = context;
121 |
122 | wifi_marauder_scene_script_stage_edit_list_deallocate_items(app);
123 |
124 | submenu_reset(app->submenu);
125 | submenu_add_item(
126 | app->submenu,
127 | "[+] ADD ITEM",
128 | 99,
129 | wifi_marauder_scene_script_stage_edit_list_add_callback,
130 | app);
131 | submenu_add_item(
132 | app->submenu,
133 | "[*] SAVE ITEMS",
134 | 99,
135 | wifi_marauder_scene_script_stage_edit_list_save_callback,
136 | app);
137 | submenu_add_item(
138 | app->submenu,
139 | "[-] CLEAR LIST",
140 | 99,
141 | wifi_marauder_scene_script_stage_edit_list_clear_callback,
142 | app);
143 | }
144 |
145 | void wifi_marauder_scene_script_stage_edit_list_on_enter(void* context) {
146 | WifiMarauderApp* app = context;
147 | int item_index = 0;
148 | WifiMarauderScriptStageListItem* current_item = app->script_stage_edit_first_item;
149 |
150 | while(current_item != NULL) {
151 | submenu_add_item(app->submenu, current_item->value, item_index++, NULL, app);
152 | current_item = current_item->next_item;
153 | }
154 | submenu_add_item(
155 | app->submenu,
156 | "[+] ADD ITEM",
157 | 99,
158 | wifi_marauder_scene_script_stage_edit_list_add_callback,
159 | app);
160 | submenu_add_item(
161 | app->submenu,
162 | "[*] SAVE ITEMS",
163 | 99,
164 | wifi_marauder_scene_script_stage_edit_list_save_callback,
165 | app);
166 | submenu_add_item(
167 | app->submenu,
168 | "[-] CLEAR LIST",
169 | 99,
170 | wifi_marauder_scene_script_stage_edit_list_clear_callback,
171 | app);
172 |
173 | submenu_set_selected_item(
174 | app->submenu,
175 | scene_manager_get_scene_state(app->scene_manager, WifiMarauderSceneScriptStageEditList));
176 | view_dispatcher_switch_to_view(app->view_dispatcher, WifiMarauderAppViewSubmenu);
177 | }
178 |
179 | bool wifi_marauder_scene_script_stage_edit_list_on_event(void* context, SceneManagerEvent event) {
180 | UNUSED(context);
181 | UNUSED(event);
182 | return false;
183 | }
184 |
185 | void wifi_marauder_scene_script_stage_edit_list_on_exit(void* context) {
186 | WifiMarauderApp* app = context;
187 | submenu_reset(app->submenu);
188 | }
189 |
--------------------------------------------------------------------------------
/scenes/wifi_marauder_scene_script_options.c:
--------------------------------------------------------------------------------
1 | #include "../wifi_marauder_app_i.h"
2 |
3 | enum SubmenuIndex {
4 | SubmenuIndexRun,
5 | SubmenuIndexSettings,
6 | SubmenuIndexEditStages,
7 | SubmenuIndexSave,
8 | SubmenuIndexDelete
9 | };
10 |
11 | void wifi_marauder_scene_script_options_save_script(WifiMarauderApp* app) {
12 | char script_path[256];
13 | snprintf(
14 | script_path,
15 | sizeof(script_path),
16 | "%s/%s.json",
17 | MARAUDER_APP_FOLDER_SCRIPTS,
18 | app->script->name);
19 | wifi_marauder_script_save_json(app->storage, script_path, app->script);
20 |
21 | DialogMessage* message = dialog_message_alloc();
22 | dialog_message_set_text(message, "Saved!", 88, 32, AlignCenter, AlignCenter);
23 | dialog_message_set_icon(message, &I_DolphinCommon_56x48, 5, 6);
24 | dialog_message_set_buttons(message, NULL, "Ok", NULL);
25 | dialog_message_show(app->dialogs, message);
26 | dialog_message_free(message);
27 | }
28 |
29 | static void wifi_marauder_scene_script_options_callback(void* context, uint32_t index) {
30 | WifiMarauderApp* app = context;
31 |
32 | switch(index) {
33 | case SubmenuIndexRun:
34 | scene_manager_set_scene_state(app->scene_manager, WifiMarauderSceneScriptOptions, index);
35 | scene_manager_next_scene(app->scene_manager, WifiMarauderSceneConsoleOutput);
36 | break;
37 | case SubmenuIndexSettings:
38 | scene_manager_set_scene_state(app->scene_manager, WifiMarauderSceneScriptOptions, index);
39 | scene_manager_next_scene(app->scene_manager, WifiMarauderSceneScriptSettings);
40 | break;
41 | case SubmenuIndexEditStages:
42 | scene_manager_set_scene_state(app->scene_manager, WifiMarauderSceneScriptOptions, index);
43 | scene_manager_next_scene(app->scene_manager, WifiMarauderSceneScriptEdit);
44 | break;
45 | case SubmenuIndexSave:
46 | wifi_marauder_scene_script_options_save_script(app);
47 | break;
48 | case SubmenuIndexDelete:
49 | scene_manager_set_scene_state(app->scene_manager, WifiMarauderSceneScriptOptions, index);
50 | scene_manager_next_scene(app->scene_manager, WifiMarauderSceneScriptConfirmDelete);
51 | break;
52 | }
53 | }
54 |
55 | void wifi_marauder_scene_script_options_on_enter(void* context) {
56 | WifiMarauderApp* app = context;
57 |
58 | // If returning after confirming script deletion
59 | if(app->script == NULL) {
60 | scene_manager_previous_scene(app->scene_manager);
61 | return;
62 | }
63 |
64 | Submenu* submenu = app->submenu;
65 |
66 | submenu_set_header(submenu, app->script->name);
67 | submenu_add_item(
68 | submenu, "[>] RUN", SubmenuIndexRun, wifi_marauder_scene_script_options_callback, app);
69 | submenu_add_item(
70 | submenu,
71 | "[S] SETTINGS",
72 | SubmenuIndexSettings,
73 | wifi_marauder_scene_script_options_callback,
74 | app);
75 | submenu_add_item(
76 | submenu,
77 | "[+] EDIT STAGES",
78 | SubmenuIndexEditStages,
79 | wifi_marauder_scene_script_options_callback,
80 | app);
81 | submenu_add_item(
82 | submenu, "[*] SAVE", SubmenuIndexSave, wifi_marauder_scene_script_options_callback, app);
83 | submenu_add_item(
84 | submenu,
85 | "[X] DELETE",
86 | SubmenuIndexDelete,
87 | wifi_marauder_scene_script_options_callback,
88 | app);
89 |
90 | submenu_set_selected_item(
91 | submenu,
92 | scene_manager_get_scene_state(app->scene_manager, WifiMarauderSceneScriptOptions));
93 | view_dispatcher_switch_to_view(app->view_dispatcher, WifiMarauderAppViewSubmenu);
94 | }
95 |
96 | bool wifi_marauder_scene_script_options_on_event(void* context, SceneManagerEvent event) {
97 | WifiMarauderApp* app = context;
98 | bool consumed = false;
99 |
100 | if(event.type == SceneManagerEventTypeBack) {
101 | wifi_marauder_script_free(app->script);
102 | app->script = NULL;
103 | }
104 |
105 | return consumed;
106 | }
107 |
108 | void wifi_marauder_scene_script_options_on_exit(void* context) {
109 | WifiMarauderApp* app = context;
110 | submenu_reset(app->submenu);
111 | }
112 |
--------------------------------------------------------------------------------
/scenes/wifi_marauder_scene_script_select.c:
--------------------------------------------------------------------------------
1 | #include "../wifi_marauder_app_i.h"
2 |
3 | static void wifi_marauder_scene_script_select_callback(void* context, uint32_t index) {
4 | WifiMarauderApp* app = context;
5 |
6 | char script_path[256];
7 | snprintf(
8 | script_path,
9 | sizeof(script_path),
10 | "%s/%s.json",
11 | MARAUDER_APP_FOLDER_SCRIPTS,
12 | furi_string_get_cstr(app->script_list[index]));
13 |
14 | app->script = wifi_marauder_script_parse_json(app->storage, script_path);
15 | if(app->script) {
16 | scene_manager_set_scene_state(app->scene_manager, WifiMarauderSceneScriptSelect, index);
17 | scene_manager_next_scene(app->scene_manager, WifiMarauderSceneScriptOptions);
18 | }
19 | }
20 |
21 | static void wifi_marauder_scene_script_select_add_callback(void* context, uint32_t index) {
22 | WifiMarauderApp* app = context;
23 | scene_manager_set_scene_state(app->scene_manager, WifiMarauderSceneScriptSelect, index);
24 |
25 | app->user_input_type = WifiMarauderUserInputTypeFileName;
26 | app->user_input_file_dir = strdup(MARAUDER_APP_FOLDER_SCRIPTS);
27 | app->user_input_file_extension = strdup("json");
28 | scene_manager_next_scene(app->scene_manager, WifiMarauderSceneUserInput);
29 | }
30 |
31 | void wifi_marauder_scene_script_select_on_enter(void* context) {
32 | WifiMarauderApp* app = context;
33 | Submenu* submenu = app->submenu;
34 |
35 | File* dir_scripts = storage_file_alloc(app->storage);
36 | if(storage_dir_open(dir_scripts, MARAUDER_APP_FOLDER_SCRIPTS)) {
37 | FileInfo file_info;
38 | char file_path[255];
39 | app->script_list_count = 0;
40 | // Goes through the files in the folder counting the ones that end with the json extension
41 | while(storage_dir_read(dir_scripts, &file_info, file_path, 255)) {
42 | app->script_list_count++;
43 | }
44 | if(app->script_list_count > 0) {
45 | submenu_set_header(submenu, "Select a script:");
46 | app->script_list = malloc(app->script_list_count * sizeof(FuriString*));
47 | storage_dir_close(dir_scripts);
48 | storage_dir_open(dir_scripts, MARAUDER_APP_FOLDER_SCRIPTS);
49 | // Read the files again from the beginning, adding the scripts in the list
50 | int script_index = 0;
51 | while(storage_dir_read(dir_scripts, &file_info, file_path, 255)) {
52 | app->script_list[script_index] = furi_string_alloc();
53 | path_extract_filename_no_ext(file_path, app->script_list[script_index]);
54 | submenu_add_item(
55 | submenu,
56 | furi_string_get_cstr(app->script_list[script_index]),
57 | script_index,
58 | wifi_marauder_scene_script_select_callback,
59 | app);
60 | script_index++;
61 | }
62 | } else {
63 | submenu_set_header(submenu, "No script found");
64 | }
65 | submenu_add_item(
66 | submenu, "[+] ADD SCRIPT", 99, wifi_marauder_scene_script_select_add_callback, app);
67 | storage_dir_close(dir_scripts);
68 | }
69 | storage_file_free(dir_scripts);
70 |
71 | submenu_set_selected_item(
72 | submenu, scene_manager_get_scene_state(app->scene_manager, WifiMarauderSceneScriptSelect));
73 | view_dispatcher_switch_to_view(app->view_dispatcher, WifiMarauderAppViewSubmenu);
74 | }
75 |
76 | bool wifi_marauder_scene_script_select_on_event(void* context, SceneManagerEvent event) {
77 | UNUSED(context);
78 | UNUSED(event);
79 | return false;
80 | }
81 |
82 | void wifi_marauder_scene_script_select_on_exit(void* context) {
83 | WifiMarauderApp* app = context;
84 | submenu_reset(app->submenu);
85 |
86 | for(int i = 0; i < app->script_list_count; i++) {
87 | furi_string_free(app->script_list[i]);
88 | }
89 | free(app->script_list);
90 | }
91 |
--------------------------------------------------------------------------------
/scenes/wifi_marauder_scene_script_settings.c:
--------------------------------------------------------------------------------
1 | #include "../wifi_marauder_app_i.h"
2 |
3 | enum ScriptSettingsOption {
4 | ScriptSettingsOptionRepeat,
5 | ScriptSettingsOptionSavePcap,
6 | ScriptSettingsOptionEnableLed
7 | };
8 |
9 | const char* option_values[3] = {"No", "Yes", "Default"};
10 |
11 | static void wifi_marauder_scene_script_settings_enter_callback(void* context, uint32_t index) {
12 | WifiMarauderApp* app = context;
13 | // Accept script repeat value
14 | if(index == ScriptSettingsOptionRepeat) {
15 | scene_manager_set_scene_state(app->scene_manager, WifiMarauderSceneScriptSettings, index);
16 | app->user_input_type = WifiMarauderUserInputTypeNumber;
17 | app->user_input_number_reference = &app->script->repeat;
18 | scene_manager_next_scene(app->scene_manager, WifiMarauderSceneUserInput);
19 | }
20 | }
21 |
22 | static void wifi_marauder_scene_script_settings_change_callback(VariableItem* item) {
23 | WifiMarauderApp* app = variable_item_get_context(item);
24 |
25 | uint8_t current_option = variable_item_list_get_selected_item_index(app->var_item_list);
26 | uint8_t option_value_index = variable_item_get_current_value_index(item);
27 |
28 | switch(current_option) {
29 | case ScriptSettingsOptionSavePcap:
30 | variable_item_set_current_value_text(item, option_values[option_value_index]);
31 | app->script->save_pcap = option_value_index;
32 | break;
33 | case ScriptSettingsOptionEnableLed:
34 | variable_item_set_current_value_text(item, option_values[option_value_index]);
35 | app->script->enable_led = option_value_index;
36 | break;
37 | }
38 | }
39 |
40 | void wifi_marauder_scene_script_settings_on_enter(void* context) {
41 | WifiMarauderApp* app = context;
42 | VariableItemList* var_item_list = app->var_item_list;
43 | variable_item_list_set_enter_callback(
44 | app->var_item_list, wifi_marauder_scene_script_settings_enter_callback, app);
45 |
46 | // Script repeat option
47 | VariableItem* repeat_item = variable_item_list_add(app->var_item_list, "Repeat", 1, NULL, app);
48 | char repeat_str[32];
49 | snprintf(repeat_str, sizeof(repeat_str), "%d", app->script->repeat);
50 | variable_item_set_current_value_text(repeat_item, repeat_str);
51 |
52 | // Save PCAP option
53 | VariableItem* save_pcap_item = variable_item_list_add(
54 | app->var_item_list,
55 | "Save PCAP",
56 | 3,
57 | wifi_marauder_scene_script_settings_change_callback,
58 | app);
59 | variable_item_set_current_value_index(save_pcap_item, app->script->save_pcap);
60 | variable_item_set_current_value_text(save_pcap_item, option_values[app->script->save_pcap]);
61 |
62 | // Enable board LED option
63 | VariableItem* enable_led_item = variable_item_list_add(
64 | app->var_item_list,
65 | "Enable LED",
66 | 3,
67 | wifi_marauder_scene_script_settings_change_callback,
68 | app);
69 | variable_item_set_current_value_index(enable_led_item, app->script->enable_led);
70 | variable_item_set_current_value_text(enable_led_item, option_values[app->script->enable_led]);
71 |
72 | variable_item_list_set_selected_item(
73 | var_item_list,
74 | scene_manager_get_scene_state(app->scene_manager, WifiMarauderSceneScriptSettings));
75 | view_dispatcher_switch_to_view(app->view_dispatcher, WifiMarauderAppViewVarItemList);
76 | }
77 |
78 | bool wifi_marauder_scene_script_settings_on_event(void* context, SceneManagerEvent event) {
79 | UNUSED(context);
80 | UNUSED(event);
81 | return false;
82 | }
83 |
84 | void wifi_marauder_scene_script_settings_on_exit(void* context) {
85 | WifiMarauderApp* app = context;
86 | variable_item_list_reset(app->var_item_list);
87 | }
88 |
--------------------------------------------------------------------------------
/scenes/wifi_marauder_scene_script_stage_add.c:
--------------------------------------------------------------------------------
1 | #include "../wifi_marauder_app_i.h"
2 |
3 | // Scan
4 | static void wifi_marauder_scene_script_stage_add_scan_callback(void* context, uint32_t index) {
5 | UNUSED(index);
6 | WifiMarauderApp* app = context;
7 |
8 | WifiMarauderScriptStageScan* stage =
9 | (WifiMarauderScriptStageScan*)malloc(sizeof(WifiMarauderScriptStageScan));
10 | stage->type = WifiMarauderScriptScanTypeAp;
11 | stage->timeout = WIFI_MARAUDER_DEFAULT_TIMEOUT_SCAN;
12 |
13 | wifi_marauder_script_add_stage(app->script, WifiMarauderScriptStageTypeScan, stage);
14 | scene_manager_previous_scene(app->scene_manager);
15 | }
16 |
17 | // Select
18 | static void wifi_marauder_scene_script_stage_add_select_callback(void* context, uint32_t index) {
19 | UNUSED(index);
20 | WifiMarauderApp* app = context;
21 |
22 | WifiMarauderScriptStageSelect* stage =
23 | (WifiMarauderScriptStageSelect*)malloc(sizeof(WifiMarauderScriptStageSelect));
24 | stage->type = WifiMarauderScriptSelectTypeAp;
25 | stage->filter = strdup("all");
26 |
27 | wifi_marauder_script_add_stage(app->script, WifiMarauderScriptStageTypeSelect, stage);
28 | scene_manager_previous_scene(app->scene_manager);
29 | }
30 |
31 | // Deauth
32 | static void wifi_marauder_scene_script_stage_add_deauth_callback(void* context, uint32_t index) {
33 | UNUSED(index);
34 | WifiMarauderApp* app = context;
35 |
36 | WifiMarauderScriptStageDeauth* stage =
37 | (WifiMarauderScriptStageDeauth*)malloc(sizeof(WifiMarauderScriptStageDeauth));
38 | stage->timeout = WIFI_MARAUDER_DEFAULT_TIMEOUT_DEAUTH;
39 |
40 | wifi_marauder_script_add_stage(app->script, WifiMarauderScriptStageTypeDeauth, stage);
41 | scene_manager_previous_scene(app->scene_manager);
42 | }
43 |
44 | // Probe
45 | static void wifi_marauder_scene_script_stage_add_probe_callback(void* context, uint32_t index) {
46 | UNUSED(index);
47 | WifiMarauderApp* app = context;
48 |
49 | WifiMarauderScriptStageProbe* stage =
50 | (WifiMarauderScriptStageProbe*)malloc(sizeof(WifiMarauderScriptStageProbe));
51 | stage->timeout = WIFI_MARAUDER_DEFAULT_TIMEOUT_PROBE;
52 |
53 | wifi_marauder_script_add_stage(app->script, WifiMarauderScriptStageTypeProbe, stage);
54 | scene_manager_previous_scene(app->scene_manager);
55 | }
56 |
57 | // Sniff RAW
58 | static void wifi_marauder_scene_script_stage_add_sniffraw_callback(void* context, uint32_t index) {
59 | UNUSED(index);
60 | WifiMarauderApp* app = context;
61 |
62 | WifiMarauderScriptStageSniffRaw* stage =
63 | (WifiMarauderScriptStageSniffRaw*)malloc(sizeof(WifiMarauderScriptStageSniffRaw));
64 | stage->timeout = WIFI_MARAUDER_DEFAULT_TIMEOUT_SNIFF;
65 |
66 | wifi_marauder_script_add_stage(app->script, WifiMarauderScriptStageTypeSniffRaw, stage);
67 | scene_manager_previous_scene(app->scene_manager);
68 | }
69 |
70 | // Sniff Beacon
71 | static void
72 | wifi_marauder_scene_script_stage_add_sniffbeacon_callback(void* context, uint32_t index) {
73 | UNUSED(index);
74 | WifiMarauderApp* app = context;
75 |
76 | WifiMarauderScriptStageSniffBeacon* stage =
77 | (WifiMarauderScriptStageSniffBeacon*)malloc(sizeof(WifiMarauderScriptStageSniffBeacon));
78 | stage->timeout = WIFI_MARAUDER_DEFAULT_TIMEOUT_SNIFF;
79 |
80 | wifi_marauder_script_add_stage(app->script, WifiMarauderScriptStageTypeSniffBeacon, stage);
81 | scene_manager_previous_scene(app->scene_manager);
82 | }
83 |
84 | // Sniff Deauth
85 | static void
86 | wifi_marauder_scene_script_stage_add_sniffdeauth_callback(void* context, uint32_t index) {
87 | UNUSED(index);
88 | WifiMarauderApp* app = context;
89 |
90 | WifiMarauderScriptStageSniffDeauth* stage =
91 | (WifiMarauderScriptStageSniffDeauth*)malloc(sizeof(WifiMarauderScriptStageSniffDeauth));
92 | stage->timeout = WIFI_MARAUDER_DEFAULT_TIMEOUT_SNIFF;
93 |
94 | wifi_marauder_script_add_stage(app->script, WifiMarauderScriptStageTypeSniffDeauth, stage);
95 | scene_manager_previous_scene(app->scene_manager);
96 | }
97 |
98 | // Sniff Esp
99 | static void wifi_marauder_scene_script_stage_add_sniffesp_callback(void* context, uint32_t index) {
100 | UNUSED(index);
101 | WifiMarauderApp* app = context;
102 |
103 | WifiMarauderScriptStageSniffEsp* stage =
104 | (WifiMarauderScriptStageSniffEsp*)malloc(sizeof(WifiMarauderScriptStageSniffEsp));
105 | stage->timeout = WIFI_MARAUDER_DEFAULT_TIMEOUT_SNIFF;
106 |
107 | wifi_marauder_script_add_stage(app->script, WifiMarauderScriptStageTypeSniffEsp, stage);
108 | scene_manager_previous_scene(app->scene_manager);
109 | }
110 |
111 | // Sniff PMKID
112 | static void
113 | wifi_marauder_scene_script_stage_add_sniffpmkid_callback(void* context, uint32_t index) {
114 | UNUSED(index);
115 | WifiMarauderApp* app = context;
116 |
117 | WifiMarauderScriptStageSniffPmkid* stage =
118 | (WifiMarauderScriptStageSniffPmkid*)malloc(sizeof(WifiMarauderScriptStageSniffPmkid));
119 | stage->channel = 0;
120 | stage->force_deauth = WifiMarauderScriptBooleanTrue;
121 | stage->timeout = WIFI_MARAUDER_DEFAULT_TIMEOUT_SNIFF;
122 |
123 | wifi_marauder_script_add_stage(app->script, WifiMarauderScriptStageTypeSniffPmkid, stage);
124 | scene_manager_previous_scene(app->scene_manager);
125 | }
126 |
127 | // Sniff Pwn
128 | static void wifi_marauder_scene_script_stage_add_sniffpwn_callback(void* context, uint32_t index) {
129 | UNUSED(index);
130 | WifiMarauderApp* app = context;
131 |
132 | WifiMarauderScriptStageSniffPwn* stage =
133 | (WifiMarauderScriptStageSniffPwn*)malloc(sizeof(WifiMarauderScriptStageSniffPwn));
134 | stage->timeout = WIFI_MARAUDER_DEFAULT_TIMEOUT_SNIFF;
135 |
136 | wifi_marauder_script_add_stage(app->script, WifiMarauderScriptStageTypeSniffPwn, stage);
137 | scene_manager_previous_scene(app->scene_manager);
138 | }
139 |
140 | // Beacon list
141 | static void
142 | wifi_marauder_scene_script_stage_add_beaconlist_callback(void* context, uint32_t index) {
143 | UNUSED(index);
144 | WifiMarauderApp* app = context;
145 |
146 | WifiMarauderScriptStageBeaconList* stage =
147 | (WifiMarauderScriptStageBeaconList*)malloc(sizeof(WifiMarauderScriptStageBeaconList));
148 | stage->ssids = NULL;
149 | stage->ssid_count = 0;
150 | stage->random_ssids = 0;
151 | stage->timeout = WIFI_MARAUDER_DEFAULT_TIMEOUT_BEACON;
152 |
153 | wifi_marauder_script_add_stage(app->script, WifiMarauderScriptStageTypeBeaconList, stage);
154 | scene_manager_previous_scene(app->scene_manager);
155 | }
156 |
157 | // Beacon AP
158 | static void wifi_marauder_scene_script_stage_add_beaconap_callback(void* context, uint32_t index) {
159 | UNUSED(index);
160 | WifiMarauderApp* app = context;
161 |
162 | WifiMarauderScriptStageBeaconAp* stage =
163 | (WifiMarauderScriptStageBeaconAp*)malloc(sizeof(WifiMarauderScriptStageBeaconAp));
164 | stage->timeout = WIFI_MARAUDER_DEFAULT_TIMEOUT_BEACON;
165 |
166 | wifi_marauder_script_add_stage(app->script, WifiMarauderScriptStageTypeBeaconAp, stage);
167 | scene_manager_previous_scene(app->scene_manager);
168 | }
169 |
170 | // Exec
171 | static void wifi_marauder_scene_script_stage_add_exec_callback(void* context, uint32_t index) {
172 | UNUSED(index);
173 | WifiMarauderApp* app = context;
174 |
175 | WifiMarauderScriptStageExec* stage =
176 | (WifiMarauderScriptStageExec*)malloc(sizeof(WifiMarauderScriptStageExec));
177 | stage->command = NULL;
178 |
179 | wifi_marauder_script_add_stage(app->script, WifiMarauderScriptStageTypeExec, stage);
180 | scene_manager_previous_scene(app->scene_manager);
181 | }
182 |
183 | // Delay
184 | static void wifi_marauder_scene_script_stage_add_delay_callback(void* context, uint32_t index) {
185 | UNUSED(index);
186 | WifiMarauderApp* app = context;
187 |
188 | WifiMarauderScriptStageDelay* stage =
189 | (WifiMarauderScriptStageDelay*)malloc(sizeof(WifiMarauderScriptStageDelay));
190 | stage->timeout = 0;
191 |
192 | wifi_marauder_script_add_stage(app->script, WifiMarauderScriptStageTypeDelay, stage);
193 | scene_manager_previous_scene(app->scene_manager);
194 | }
195 |
196 | void wifi_marauder_scene_script_stage_add_on_enter(void* context) {
197 | WifiMarauderApp* app = context;
198 | Submenu* submenu = app->submenu;
199 | submenu_set_header(submenu, "Add stage");
200 |
201 | int menu_index = 0;
202 | submenu_add_item(
203 | submenu, "[+] Scan", menu_index++, wifi_marauder_scene_script_stage_add_scan_callback, app);
204 | submenu_add_item(
205 | submenu,
206 | "[+] Select",
207 | menu_index++,
208 | wifi_marauder_scene_script_stage_add_select_callback,
209 | app);
210 | submenu_add_item(
211 | submenu,
212 | "[+] Deauth",
213 | menu_index++,
214 | wifi_marauder_scene_script_stage_add_deauth_callback,
215 | app);
216 | submenu_add_item(
217 | submenu,
218 | "[+] Probe",
219 | menu_index++,
220 | wifi_marauder_scene_script_stage_add_probe_callback,
221 | app);
222 | submenu_add_item(
223 | submenu,
224 | "[+] Sniff RAW",
225 | menu_index++,
226 | wifi_marauder_scene_script_stage_add_sniffraw_callback,
227 | app);
228 | submenu_add_item(
229 | submenu,
230 | "[+] Sniff Beacon",
231 | menu_index++,
232 | wifi_marauder_scene_script_stage_add_sniffbeacon_callback,
233 | app);
234 | submenu_add_item(
235 | submenu,
236 | "[+] Sniff Deauth",
237 | menu_index++,
238 | wifi_marauder_scene_script_stage_add_sniffdeauth_callback,
239 | app);
240 | submenu_add_item(
241 | submenu,
242 | "[+] Sniff Esp",
243 | menu_index++,
244 | wifi_marauder_scene_script_stage_add_sniffesp_callback,
245 | app);
246 | submenu_add_item(
247 | submenu,
248 | "[+] Sniff PMKID",
249 | menu_index++,
250 | wifi_marauder_scene_script_stage_add_sniffpmkid_callback,
251 | app);
252 | submenu_add_item(
253 | submenu,
254 | "[+] Sniff Pwnagotchi",
255 | menu_index++,
256 | wifi_marauder_scene_script_stage_add_sniffpwn_callback,
257 | app);
258 | submenu_add_item(
259 | submenu,
260 | "[+] Beacon List",
261 | menu_index++,
262 | wifi_marauder_scene_script_stage_add_beaconlist_callback,
263 | app);
264 | submenu_add_item(
265 | submenu,
266 | "[+] Beacon AP",
267 | menu_index++,
268 | wifi_marauder_scene_script_stage_add_beaconap_callback,
269 | app);
270 | submenu_add_item(
271 | submenu,
272 | "[+] Custom command",
273 | menu_index++,
274 | wifi_marauder_scene_script_stage_add_exec_callback,
275 | app);
276 | submenu_add_item(
277 | submenu,
278 | "[+] Delay",
279 | menu_index++,
280 | wifi_marauder_scene_script_stage_add_delay_callback,
281 | app);
282 |
283 | submenu_set_selected_item(
284 | submenu, scene_manager_get_scene_state(app->scene_manager, WifiMarauderSceneScriptEdit));
285 | view_dispatcher_switch_to_view(app->view_dispatcher, WifiMarauderAppViewSubmenu);
286 | }
287 |
288 | bool wifi_marauder_scene_script_stage_add_on_event(void* context, SceneManagerEvent event) {
289 | UNUSED(context);
290 | UNUSED(event);
291 | return false;
292 | }
293 |
294 | void wifi_marauder_scene_script_stage_add_on_exit(void* context) {
295 | WifiMarauderApp* app = context;
296 | submenu_reset(app->submenu);
297 | }
298 |
--------------------------------------------------------------------------------
/scenes/wifi_marauder_scene_script_stage_edit.c:
--------------------------------------------------------------------------------
1 | #include "../wifi_marauder_app_i.h"
2 |
3 | void wifi_marauder_scene_script_stage_edit_create_list_strings(
4 | WifiMarauderApp* app,
5 | char** strings,
6 | int string_count) {
7 | // Deallocates the existing list
8 | WifiMarauderScriptStageListItem* current_item = app->script_stage_edit_first_item;
9 | while(current_item != NULL) {
10 | WifiMarauderScriptStageListItem* next_item = current_item->next_item;
11 | free(current_item->value);
12 | free(current_item);
13 | current_item = next_item;
14 | }
15 |
16 | // Create a new list with numbers
17 | WifiMarauderScriptStageListItem* first_item = NULL;
18 | WifiMarauderScriptStageListItem* previous_item = NULL;
19 | for(int i = 0; i < string_count; i++) {
20 | WifiMarauderScriptStageListItem* item = malloc(sizeof(WifiMarauderScriptStageListItem));
21 | item->value = strdup(strings[i]);
22 | item->next_item = NULL;
23 |
24 | if(previous_item == NULL) {
25 | first_item = item;
26 | } else {
27 | previous_item->next_item = item;
28 | }
29 | previous_item = item;
30 | }
31 |
32 | app->script_stage_edit_first_item = first_item;
33 | }
34 |
35 | void wifi_marauder_scene_script_stage_edit_create_list_numbers(
36 | WifiMarauderApp* app,
37 | int* numbers,
38 | int number_count) {
39 | // Deallocates the existing list
40 | WifiMarauderScriptStageListItem* current_item = app->script_stage_edit_first_item;
41 | while(current_item != NULL) {
42 | WifiMarauderScriptStageListItem* next_item = current_item->next_item;
43 | free(current_item->value);
44 | free(current_item);
45 | current_item = next_item;
46 | }
47 |
48 | // Create a new list with numbers
49 | WifiMarauderScriptStageListItem* first_item = NULL;
50 | WifiMarauderScriptStageListItem* previous_item = NULL;
51 | for(int i = 0; i < number_count; i++) {
52 | char number_str[32];
53 | snprintf(number_str, sizeof(number_str), "%d", numbers[i]);
54 |
55 | WifiMarauderScriptStageListItem* item = malloc(sizeof(WifiMarauderScriptStageListItem));
56 | item->value = strdup(number_str);
57 | item->next_item = NULL;
58 |
59 | if(previous_item == NULL) {
60 | first_item = item;
61 | } else {
62 | previous_item->next_item = item;
63 | }
64 | previous_item = item;
65 | }
66 |
67 | app->script_stage_edit_first_item = first_item;
68 | }
69 |
70 | static void
71 | wifi_marauder_scene_script_stage_edit_list_enter_callback(void* context, uint32_t index) {
72 | WifiMarauderApp* app = context;
73 | const WifiMarauderScriptMenuItem* menu_item = &app->script_stage_menu->items[index];
74 |
75 | // Fixed delete item
76 | if(index == app->script_stage_menu->num_items) {
77 | uint32_t deleted_stage_index =
78 | scene_manager_get_scene_state(app->scene_manager, WifiMarauderSceneScriptEdit);
79 | if(deleted_stage_index > 0) {
80 | scene_manager_set_scene_state(
81 | app->scene_manager, WifiMarauderSceneScriptEdit, deleted_stage_index - 1);
82 | }
83 | WifiMarauderScriptStage* previous_stage = NULL;
84 | WifiMarauderScriptStage* current_stage = app->script->first_stage;
85 | uint32_t current_stage_index = 0;
86 |
87 | while(current_stage != NULL && current_stage_index < deleted_stage_index) {
88 | previous_stage = current_stage;
89 | current_stage = current_stage->next_stage;
90 | current_stage_index++;
91 | }
92 |
93 | // Delete the stage
94 | if(current_stage != NULL) {
95 | if(previous_stage != NULL) {
96 | if(current_stage->next_stage != NULL) {
97 | previous_stage->next_stage = current_stage->next_stage;
98 | } else {
99 | previous_stage->next_stage = NULL;
100 | app->script->last_stage = previous_stage;
101 | }
102 | } else {
103 | if(current_stage->next_stage != NULL) {
104 | app->script->first_stage = current_stage->next_stage;
105 | } else {
106 | app->script->first_stage = NULL;
107 | app->script->last_stage = NULL;
108 | }
109 | }
110 | }
111 | app->script_edit_selected_stage = NULL;
112 |
113 | scene_manager_previous_scene(app->scene_manager);
114 | return;
115 | }
116 |
117 | if(menu_item->select_callback == NULL) {
118 | return;
119 | }
120 | if(menu_item->type == WifiMarauderScriptMenuItemTypeNumber) {
121 | // Accepts user number input, assigning the value to the reference passed as a parameter
122 | menu_item->select_callback(app);
123 | scene_manager_set_scene_state(app->scene_manager, WifiMarauderSceneScriptStageEdit, index);
124 | app->user_input_type = WifiMarauderUserInputTypeNumber;
125 | scene_manager_next_scene(app->scene_manager, WifiMarauderSceneUserInput);
126 | } else if(menu_item->type == WifiMarauderScriptMenuItemTypeString) {
127 | // Accepts user string input, assigning the value to the reference passed as a parameter
128 | menu_item->select_callback(app);
129 | scene_manager_set_scene_state(app->scene_manager, WifiMarauderSceneScriptStageEdit, index);
130 | app->user_input_type = WifiMarauderUserInputTypeString;
131 | scene_manager_next_scene(app->scene_manager, WifiMarauderSceneUserInput);
132 | } else if(menu_item->type == WifiMarauderScriptMenuItemTypeListString) {
133 | // Accepts the strings that compose the list
134 | menu_item->select_callback(app);
135 | wifi_marauder_scene_script_stage_edit_create_list_strings(
136 | app,
137 | *app->script_stage_edit_strings_reference,
138 | *app->script_stage_edit_string_count_reference);
139 | scene_manager_set_scene_state(app->scene_manager, WifiMarauderSceneScriptStageEdit, index);
140 | scene_manager_next_scene(app->scene_manager, WifiMarauderSceneScriptStageEditList);
141 | } else if(menu_item->type == WifiMarauderScriptMenuItemTypeListNumber) {
142 | // Accepts the numbers that compose the list
143 | menu_item->select_callback(app);
144 | wifi_marauder_scene_script_stage_edit_create_list_numbers(
145 | app,
146 | *app->script_stage_edit_numbers_reference,
147 | *app->script_stage_edit_number_count_reference);
148 | scene_manager_set_scene_state(app->scene_manager, WifiMarauderSceneScriptStageEdit, index);
149 | scene_manager_next_scene(app->scene_manager, WifiMarauderSceneScriptStageEditList);
150 | }
151 | }
152 |
153 | void wifi_marauder_scene_script_stage_edit_on_enter(void* context) {
154 | WifiMarauderApp* app = context;
155 | VariableItemList* var_item_list = app->var_item_list;
156 |
157 | variable_item_list_set_enter_callback(
158 | app->var_item_list, wifi_marauder_scene_script_stage_edit_list_enter_callback, app);
159 | app->script_stage_menu =
160 | wifi_marauder_script_stage_menu_create(app->script_edit_selected_stage->type);
161 |
162 | if(app->script_stage_menu->items != NULL) {
163 | for(uint32_t i = 0; i < app->script_stage_menu->num_items; i++) {
164 | WifiMarauderScriptMenuItem* stage_item = &app->script_stage_menu->items[i];
165 |
166 | // Changes the list item to handle it in callbacks
167 | VariableItem* list_item = variable_item_list_add(
168 | app->var_item_list,
169 | stage_item->name,
170 | stage_item->num_options,
171 | stage_item->change_callback,
172 | app);
173 |
174 | variable_item_list_set_selected_item(app->var_item_list, i);
175 | if(stage_item->setup_callback != NULL) {
176 | stage_item->setup_callback(list_item);
177 | }
178 | if(stage_item->change_callback != NULL) {
179 | stage_item->change_callback(list_item);
180 | }
181 | }
182 | }
183 |
184 | variable_item_list_add(app->var_item_list, "[-] DELETE STAGE", 0, NULL, app);
185 |
186 | variable_item_list_set_selected_item(
187 | var_item_list,
188 | scene_manager_get_scene_state(app->scene_manager, WifiMarauderSceneScriptStageEdit));
189 | view_dispatcher_switch_to_view(app->view_dispatcher, WifiMarauderAppViewVarItemList);
190 | }
191 |
192 | bool wifi_marauder_scene_script_stage_edit_on_event(void* context, SceneManagerEvent event) {
193 | UNUSED(context);
194 | UNUSED(event);
195 | return false;
196 | }
197 |
198 | void wifi_marauder_scene_script_stage_edit_on_exit(void* context) {
199 | WifiMarauderApp* app = context;
200 | wifi_marauder_script_stage_menu_free(app->script_stage_menu);
201 | app->script_stage_menu = NULL;
202 | variable_item_list_reset(app->var_item_list);
203 | }
204 |
--------------------------------------------------------------------------------
/scenes/wifi_marauder_scene_settings_init.c:
--------------------------------------------------------------------------------
1 | #include "../wifi_marauder_app_i.h"
2 |
3 | const char* Y = "Y";
4 | const char* N = "N";
5 |
6 | #define PROMPT_PCAPS 0
7 | #define PROMPT_LOGS 1
8 |
9 | void wifi_marauder_scene_settings_init_widget_callback(
10 | GuiButtonType result,
11 | InputType type,
12 | void* context) {
13 | WifiMarauderApp* app = context;
14 | if(type == InputTypeShort) {
15 | view_dispatcher_send_custom_event(app->view_dispatcher, result);
16 | }
17 | }
18 |
19 | void wifi_marauder_scene_settings_init_setup_widget(WifiMarauderApp* app) {
20 | Widget* widget = app->widget;
21 |
22 | widget_reset(widget);
23 |
24 | widget_add_button_element(
25 | widget, GuiButtonTypeLeft, "No", wifi_marauder_scene_settings_init_widget_callback, app);
26 | widget_add_button_element(
27 | widget, GuiButtonTypeRight, "Yes", wifi_marauder_scene_settings_init_widget_callback, app);
28 |
29 | if(app->which_prompt == PROMPT_PCAPS) {
30 | widget_add_string_element(widget, 0, 0, AlignLeft, AlignTop, FontPrimary, "Save pcaps?");
31 | widget_add_text_scroll_element(
32 | widget,
33 | 0,
34 | 12,
35 | 128,
36 | 38,
37 | "With compatible marauder\nfirmware, you can choose to\nsave captures (pcaps) to the\nflipper sd card here:\n" MARAUDER_APP_FOLDER_USER_PCAPS
38 | "\n\nYou can change this setting in the app at any time. Would\nyou like to enable this feature now?");
39 | } else {
40 | widget_add_string_element(widget, 0, 0, AlignLeft, AlignTop, FontPrimary, "Save logs?");
41 | widget_add_text_scroll_element(
42 | widget,
43 | 0,
44 | 12,
45 | 128,
46 | 38,
47 | "This app supports saving text\nlogs of console output to the\nflipper sd card here:\n" MARAUDER_APP_FOLDER_USER_LOGS
48 | "\n\nYou can change this setting in the app at any time. Would\nyou like to enable this feature now?");
49 | }
50 | }
51 |
52 | void wifi_marauder_scene_settings_init_on_enter(void* context) {
53 | WifiMarauderApp* app = context;
54 |
55 | app->which_prompt = PROMPT_PCAPS;
56 | wifi_marauder_scene_settings_init_setup_widget(app);
57 |
58 | view_dispatcher_switch_to_view(app->view_dispatcher, WifiMarauderAppViewWidget);
59 | }
60 |
61 | bool wifi_marauder_scene_settings_init_on_event(void* context, SceneManagerEvent event) {
62 | WifiMarauderApp* app = context;
63 | bool consumed = false;
64 |
65 | if(event.type == SceneManagerEventTypeCustom) {
66 | // get which button press: "Yes" or "No"
67 | if(event.event == GuiButtonTypeRight) {
68 | // Yes
69 | if(app->which_prompt == PROMPT_PCAPS) {
70 | app->ok_to_save_pcaps = true;
71 | } else {
72 | app->ok_to_save_logs = true;
73 | }
74 | } else if(event.event == GuiButtonTypeLeft) {
75 | // No
76 | if(app->which_prompt == PROMPT_PCAPS) {
77 | app->ok_to_save_pcaps = false;
78 | } else {
79 | app->ok_to_save_logs = false;
80 | }
81 | }
82 |
83 | // save setting to file, load next widget or scene
84 | if(app->which_prompt == PROMPT_PCAPS) {
85 | if(storage_file_open(
86 | app->save_pcap_setting_file,
87 | SAVE_PCAP_SETTING_FILEPATH,
88 | FSAM_WRITE,
89 | FSOM_CREATE_ALWAYS)) {
90 | const char* ok = app->ok_to_save_pcaps ? Y : N;
91 | storage_file_write(app->save_pcap_setting_file, ok, sizeof(ok));
92 | } else {
93 | dialog_message_show_storage_error(app->dialogs, "Cannot save settings");
94 | }
95 | storage_file_close(app->save_pcap_setting_file);
96 | // same scene, different-looking widget
97 | app->which_prompt = PROMPT_LOGS;
98 | wifi_marauder_scene_settings_init_setup_widget(app);
99 | } else {
100 | if(storage_file_open(
101 | app->save_logs_setting_file,
102 | SAVE_LOGS_SETTING_FILEPATH,
103 | FSAM_WRITE,
104 | FSOM_CREATE_ALWAYS)) {
105 | const char* ok = app->ok_to_save_logs ? Y : N;
106 | storage_file_write(app->save_logs_setting_file, ok, sizeof(ok));
107 | } else {
108 | dialog_message_show_storage_error(app->dialogs, "Cannot save settings");
109 | }
110 | storage_file_close(app->save_logs_setting_file);
111 | // go back to start scene (main menu)
112 | app->need_to_prompt_settings_init = false;
113 | scene_manager_previous_scene(app->scene_manager);
114 | }
115 | consumed = true;
116 | }
117 |
118 | return consumed;
119 | }
120 |
121 | void wifi_marauder_scene_settings_init_on_exit(void* context) {
122 | WifiMarauderApp* app = context;
123 | widget_reset(app->widget);
124 | if(storage_file_is_open(app->save_pcap_setting_file)) {
125 | storage_file_close(app->save_pcap_setting_file);
126 | }
127 | if(storage_file_is_open(app->save_logs_setting_file)) {
128 | storage_file_close(app->save_logs_setting_file);
129 | }
130 | }
131 |
--------------------------------------------------------------------------------
/scenes/wifi_marauder_scene_sniffpmkid_options.c:
--------------------------------------------------------------------------------
1 | #include "../wifi_marauder_app_i.h"
2 |
3 | enum SubmenuIndex {
4 | SubmenuIndexPassive,
5 | SubmenuIndexActive,
6 | SubmenuIndexTargetedPassive,
7 | SubmenuIndexTargetedActive,
8 | SubmenuIndexChannelPassive,
9 | SubmenuIndexChannelActive,
10 | };
11 |
12 | static void wifi_marauder_scene_sniffpmkid_options_callback(void* context, uint32_t index) {
13 | WifiMarauderApp* app = context;
14 |
15 | app->is_custom_tx_string = false; // this will be set if needed by text input
16 | switch(index) {
17 | case SubmenuIndexPassive:
18 | app->selected_tx_string = "sniffpmkid";
19 | scene_manager_set_scene_state(
20 | app->scene_manager, WifiMarauderSceneSniffPmkidOptions, index);
21 | scene_manager_next_scene(app->scene_manager, WifiMarauderSceneConsoleOutput);
22 | break;
23 | case SubmenuIndexActive:
24 | app->selected_tx_string = "sniffpmkid -d";
25 | scene_manager_set_scene_state(
26 | app->scene_manager, WifiMarauderSceneSniffPmkidOptions, index);
27 | scene_manager_next_scene(app->scene_manager, WifiMarauderSceneConsoleOutput);
28 | break;
29 | case SubmenuIndexTargetedPassive:
30 | app->selected_tx_string = "sniffpmkid -l";
31 | scene_manager_set_scene_state(
32 | app->scene_manager, WifiMarauderSceneSniffPmkidOptions, index);
33 | scene_manager_next_scene(app->scene_manager, WifiMarauderSceneConsoleOutput);
34 | break;
35 | case SubmenuIndexTargetedActive:
36 | app->selected_tx_string = "sniffpmkid -d -l";
37 | scene_manager_set_scene_state(
38 | app->scene_manager, WifiMarauderSceneSniffPmkidOptions, index);
39 | scene_manager_next_scene(app->scene_manager, WifiMarauderSceneConsoleOutput);
40 | break;
41 | case SubmenuIndexChannelPassive:
42 | app->selected_tx_string = "sniffpmkid -c";
43 | scene_manager_set_scene_state(
44 | app->scene_manager, WifiMarauderSceneSniffPmkidOptions, index);
45 | scene_manager_next_scene(app->scene_manager, WifiMarauderSceneTextInput);
46 | break;
47 | case SubmenuIndexChannelActive:
48 | app->selected_tx_string = "sniffpmkid -d -c";
49 | scene_manager_set_scene_state(
50 | app->scene_manager, WifiMarauderSceneSniffPmkidOptions, index);
51 | scene_manager_next_scene(app->scene_manager, WifiMarauderSceneTextInput);
52 | break;
53 | }
54 | }
55 |
56 | void wifi_marauder_scene_sniffpmkid_options_on_enter(void* context) {
57 | WifiMarauderApp* app = context;
58 |
59 | Submenu* submenu = app->submenu;
60 |
61 | submenu_set_header(submenu, "Sniff PMKID");
62 | submenu_add_item(
63 | submenu,
64 | "Passive",
65 | SubmenuIndexPassive,
66 | wifi_marauder_scene_sniffpmkid_options_callback,
67 | app);
68 | submenu_add_item(
69 | submenu,
70 | "Active (Force Deauth)",
71 | SubmenuIndexActive,
72 | wifi_marauder_scene_sniffpmkid_options_callback,
73 | app);
74 | submenu_add_item(
75 | submenu,
76 | "Targeted Passive (List)",
77 | SubmenuIndexTargetedPassive,
78 | wifi_marauder_scene_sniffpmkid_options_callback,
79 | app);
80 | submenu_add_item(
81 | submenu,
82 | "Targeted Active (List)",
83 | SubmenuIndexTargetedActive,
84 | wifi_marauder_scene_sniffpmkid_options_callback,
85 | app);
86 | submenu_add_item(
87 | submenu,
88 | "On Channel # - Passive",
89 | SubmenuIndexChannelPassive,
90 | wifi_marauder_scene_sniffpmkid_options_callback,
91 | app);
92 | submenu_add_item(
93 | submenu,
94 | "On Channel # - Active",
95 | SubmenuIndexChannelActive,
96 | wifi_marauder_scene_sniffpmkid_options_callback,
97 | app);
98 |
99 | submenu_set_selected_item(
100 | submenu,
101 | scene_manager_get_scene_state(app->scene_manager, WifiMarauderSceneSniffPmkidOptions));
102 | view_dispatcher_switch_to_view(app->view_dispatcher, WifiMarauderAppViewSubmenu);
103 | }
104 |
105 | bool wifi_marauder_scene_sniffpmkid_options_on_event(void* context, SceneManagerEvent event) {
106 | //WifiMarauderApp* app = context;
107 | UNUSED(context);
108 | UNUSED(event);
109 | bool consumed = false;
110 |
111 | return consumed;
112 | }
113 |
114 | void wifi_marauder_scene_sniffpmkid_options_on_exit(void* context) {
115 | WifiMarauderApp* app = context;
116 | submenu_reset(app->submenu);
117 | }
118 |
--------------------------------------------------------------------------------
/scenes/wifi_marauder_scene_start.c:
--------------------------------------------------------------------------------
1 | //** Includes sniffbt and sniffskim for compatible ESP32-WROOM hardware.
2 | //wifi_marauder_app_i.h also changed **//
3 | #include "../wifi_marauder_app_i.h"
4 |
5 | // For each command, define whether additional arguments are needed
6 | // (enabling text input to fill them out), and whether the console
7 | // text box should focus at the start of the output or the end
8 | typedef enum { NO_ARGS = 0, INPUT_ARGS, TOGGLE_ARGS } InputArgs;
9 |
10 | typedef enum { FOCUS_CONSOLE_END = 0, FOCUS_CONSOLE_START, FOCUS_CONSOLE_TOGGLE } FocusConsole;
11 |
12 | #define SHOW_STOPSCAN_TIP (true)
13 | #define NO_TIP (false)
14 |
15 | #define MAX_OPTIONS (13)
16 | typedef struct {
17 | const char* item_string;
18 | const char* options_menu[MAX_OPTIONS];
19 | int num_options_menu;
20 | const char* actual_commands[MAX_OPTIONS];
21 | InputArgs needs_keyboard;
22 | FocusConsole focus_console;
23 | bool show_stopscan_tip;
24 | } WifiMarauderItem;
25 |
26 | // NUM_MENU_ITEMS defined in wifi_marauder_app_i.h - if you add an entry here, increment it!
27 | const WifiMarauderItem items[NUM_MENU_ITEMS] = {
28 | {"View Log from", {"start", "end"}, 2, {"", ""}, NO_ARGS, FOCUS_CONSOLE_TOGGLE, NO_TIP},
29 | {"Scan",
30 | {"all", "ap", "station"},
31 | 3,
32 | {"scanall", "scanap", "scansta"},
33 | NO_ARGS,
34 | FOCUS_CONSOLE_END,
35 | SHOW_STOPSCAN_TIP},
36 | {"SSID",
37 | {"add rand", "add name", "remove"},
38 | 3,
39 | {"ssid -a -g", "ssid -a -n", "ssid -r"},
40 | INPUT_ARGS,
41 | FOCUS_CONSOLE_START,
42 | NO_TIP},
43 | {"List",
44 | {"ap", "ssid", "station", "airtag"},
45 | 4,
46 | {"list -a", "list -s", "list -c", "list -t"},
47 | NO_ARGS,
48 | FOCUS_CONSOLE_START,
49 | NO_TIP},
50 | {"AP Info",
51 | {""},
52 | 1,
53 | {"info -a"},
54 | INPUT_ARGS,
55 | FOCUS_CONSOLE_END,
56 | NO_TIP},
57 | {"Select",
58 | {"ap", "ssid", "station"},
59 | 3,
60 | {"select -a", "select -s", "select -c"},
61 | INPUT_ARGS,
62 | FOCUS_CONSOLE_END,
63 | NO_TIP},
64 | {"Clear List",
65 | {"ap", "ssid", "station"},
66 | 3,
67 | {"clearlist -a", "clearlist -s", "clearlist -c"},
68 | NO_ARGS,
69 | FOCUS_CONSOLE_END,
70 | NO_TIP},
71 | {"Attack",
72 | {"deauth",
73 | "probe",
74 | "rickroll",
75 | "sour apple",
76 | "swiftpair spam",
77 | "samsung spam",
78 | "google spam",
79 | "flipper spam",
80 | "bt spam all"},
81 | 9,
82 | {"attack -t deauth",
83 | "attack -t probe",
84 | "attack -t rickroll",
85 | "blespam -t apple",
86 | "blespam -t windows",
87 | "blespam -t samsung",
88 | "blespam -t google",
89 | "blespam -t flipper",
90 | "blespam -t all"},
91 | NO_ARGS,
92 | FOCUS_CONSOLE_END,
93 | SHOW_STOPSCAN_TIP},
94 | {"Spoof Airtag",
95 | {""},
96 | 1,
97 | {"spoofat -t"},
98 | INPUT_ARGS,
99 | FOCUS_CONSOLE_END,
100 | NO_TIP},
101 | {"Wardrive",
102 | {"ap", "station", "bt", "bt cont"},
103 | 4,
104 | {"wardrive", "wardrive -s", "btwardrive", "btwardrive -c"},
105 | NO_ARGS,
106 | FOCUS_CONSOLE_END,
107 | SHOW_STOPSCAN_TIP},
108 | {"Evil Portal",
109 | {"start", "set html"},
110 | 2,
111 | {"evilportal -c start", "evilportal -c sethtml"},
112 | TOGGLE_ARGS,
113 | FOCUS_CONSOLE_END,
114 | SHOW_STOPSCAN_TIP},
115 | {"Load Evil Portal HTML file",
116 | {""},
117 | 1,
118 | {"evilportal -c sethtmlstr"},
119 | NO_ARGS,
120 | FOCUS_CONSOLE_END,
121 | NO_TIP},
122 | {"Targeted Deauth",
123 | {"station", "manual"},
124 | 2,
125 | {"attack -t deauth -c", "attack -t deauth -s"},
126 | TOGGLE_ARGS,
127 | FOCUS_CONSOLE_END,
128 | SHOW_STOPSCAN_TIP},
129 | {"Beacon Spam",
130 | {"ap list", "ssid list", "random"},
131 | 3,
132 | {"attack -t beacon -a", "attack -t beacon -l", "attack -t beacon -r"},
133 | NO_ARGS,
134 | FOCUS_CONSOLE_END,
135 | SHOW_STOPSCAN_TIP},
136 | {"Sniff",
137 | {"beacon", "deauth", "pmkid", "probe", "pwn", "raw", "bt", "skim", "airtag", "flipper", "packetcount", "pineapple", "multissid"},
138 | 13,
139 | {"sniffbeacon",
140 | "sniffdeauth",
141 | "sniffpmkid",
142 | "sniffprobe",
143 | "sniffpwn",
144 | "sniffraw",
145 | "sniffbt",
146 | "sniffskim",
147 | "sniffbt -t airtag",
148 | "sniffbt -t flipper",
149 | "packetcount",
150 | "sniffpinescan",
151 | "sniffmultissid"},
152 | NO_ARGS,
153 | FOCUS_CONSOLE_END,
154 | SHOW_STOPSCAN_TIP},
155 | {"Signal Monitor", {""}, 1, {"sigmon"}, NO_ARGS, FOCUS_CONSOLE_END, SHOW_STOPSCAN_TIP},
156 | {"Channel",
157 | {"get", "set"},
158 | 2,
159 | {"channel", "channel -s"},
160 | TOGGLE_ARGS,
161 | FOCUS_CONSOLE_END,
162 | NO_TIP},
163 | {"LED", {"hex", "pattern"}, 2, {"led -s", "led -p"}, INPUT_ARGS, FOCUS_CONSOLE_END, NO_TIP},
164 | {"GPS Data",
165 | {"stream", "fix", "sats", "lat", "lon", "alt", "date"},
166 | 7,
167 | {"gpsdata",
168 | "gps -g fix",
169 | "gps -g sat",
170 | "gps -g lat",
171 | "gps -g lon",
172 | "gps -g alt",
173 | "gps -g date"},
174 | NO_ARGS,
175 | FOCUS_CONSOLE_END,
176 | NO_TIP},
177 | {"Settings",
178 | {"display", "restore", "ForcePMKID", "ForceProbe", "SavePCAP", "EnableLED", "other"},
179 | 7,
180 | {"settings",
181 | "settings -r",
182 | "settings -s ForcePMKID enable",
183 | "settings -s ForceProbe enable",
184 | "settings -s SavePCAP enable",
185 | "settings -s EnableLED enable",
186 | "settings -s"},
187 | TOGGLE_ARGS,
188 | FOCUS_CONSOLE_START,
189 | NO_TIP},
190 | {"List SD", {""}, 1, {"ls /"}, INPUT_ARGS, FOCUS_CONSOLE_END, NO_TIP},
191 | {"Update", {"sd"}, 1, {"update -s"}, NO_ARGS, FOCUS_CONSOLE_END, NO_TIP},
192 | {"Reboot", {""}, 1, {"reboot"}, NO_ARGS, FOCUS_CONSOLE_END, NO_TIP},
193 | {"Help", {""}, 1, {"help"}, NO_ARGS, FOCUS_CONSOLE_START, SHOW_STOPSCAN_TIP},
194 | {"Info", {""}, 1, {"info"}, NO_ARGS, FOCUS_CONSOLE_START, NO_TIP},
195 | {"Scripts", {""}, 1, {""}, NO_ARGS, FOCUS_CONSOLE_END, NO_TIP},
196 | {"Save to flipper sdcard", // keep as last entry or change logic in callback below
197 | {""},
198 | 1,
199 | {""},
200 | NO_ARGS,
201 | FOCUS_CONSOLE_START,
202 | NO_TIP},
203 | };
204 |
205 | static void wifi_marauder_scene_start_var_list_enter_callback(void* context, uint32_t index) {
206 | furi_assert(context);
207 | WifiMarauderApp* app = context;
208 |
209 | furi_assert(index < NUM_MENU_ITEMS);
210 | const WifiMarauderItem* item = &items[index];
211 |
212 | const int selected_option_index = app->selected_option_index[index];
213 | furi_assert(selected_option_index < item->num_options_menu);
214 | app->selected_tx_string = item->actual_commands[selected_option_index];
215 | app->is_command = (1 <= index);
216 | app->is_custom_tx_string = false;
217 | app->selected_menu_index = index;
218 | app->focus_console_start = (item->focus_console == FOCUS_CONSOLE_TOGGLE) ?
219 | (selected_option_index == 0) :
220 | item->focus_console;
221 | app->show_stopscan_tip = item->show_stopscan_tip;
222 |
223 | if(!app->is_command && selected_option_index == 0) {
224 | // View Log from start
225 | view_dispatcher_send_custom_event(app->view_dispatcher, WifiMarauderEventStartLogViewer);
226 | return;
227 | }
228 |
229 | if(app->selected_tx_string &&
230 | strncmp("sniffpmkid", app->selected_tx_string, strlen("sniffpmkid")) == 0) {
231 | // sniffpmkid submenu
232 | view_dispatcher_send_custom_event(
233 | app->view_dispatcher, WifiMarauderEventStartSniffPmkidOptions);
234 | return;
235 | }
236 |
237 | // Select automation script
238 | if(index == NUM_MENU_ITEMS - 2) {
239 | view_dispatcher_send_custom_event(
240 | app->view_dispatcher, WifiMarauderEventStartScriptSelect);
241 | return;
242 | }
243 |
244 | if(index == NUM_MENU_ITEMS - 1) {
245 | // "Save to flipper sdcard" special case - start SettingsInit widget
246 | view_dispatcher_send_custom_event(
247 | app->view_dispatcher, WifiMarauderEventStartSettingsInit);
248 | return;
249 | }
250 |
251 | bool needs_keyboard = (item->needs_keyboard == TOGGLE_ARGS) ? (selected_option_index != 0) :
252 | item->needs_keyboard;
253 | if(needs_keyboard) {
254 | view_dispatcher_send_custom_event(app->view_dispatcher, WifiMarauderEventStartKeyboard);
255 | } else {
256 | view_dispatcher_send_custom_event(app->view_dispatcher, WifiMarauderEventStartConsole);
257 | }
258 | }
259 |
260 | static void wifi_marauder_scene_start_var_list_change_callback(VariableItem* item) {
261 | furi_assert(item);
262 |
263 | WifiMarauderApp* app = variable_item_get_context(item);
264 | furi_assert(app);
265 |
266 | const WifiMarauderItem* menu_item = &items[app->selected_menu_index];
267 | uint8_t item_index = variable_item_get_current_value_index(item);
268 | furi_assert(item_index < menu_item->num_options_menu);
269 | variable_item_set_current_value_text(item, menu_item->options_menu[item_index]);
270 | app->selected_option_index[app->selected_menu_index] = item_index;
271 | }
272 |
273 | void wifi_marauder_scene_start_on_enter(void* context) {
274 | WifiMarauderApp* app = context;
275 | VariableItemList* var_item_list = app->var_item_list;
276 |
277 | variable_item_list_set_enter_callback(
278 | var_item_list, wifi_marauder_scene_start_var_list_enter_callback, app);
279 |
280 | VariableItem* item;
281 | for(int i = 0; i < NUM_MENU_ITEMS; ++i) {
282 | item = variable_item_list_add(
283 | var_item_list,
284 | items[i].item_string,
285 | items[i].num_options_menu,
286 | wifi_marauder_scene_start_var_list_change_callback,
287 | app);
288 | variable_item_set_current_value_index(item, app->selected_option_index[i]);
289 | variable_item_set_current_value_text(
290 | item, items[i].options_menu[app->selected_option_index[i]]);
291 | }
292 |
293 | variable_item_list_set_selected_item(
294 | var_item_list, scene_manager_get_scene_state(app->scene_manager, WifiMarauderSceneStart));
295 |
296 | view_dispatcher_switch_to_view(app->view_dispatcher, WifiMarauderAppViewVarItemList);
297 |
298 | // Wait, if the user hasn't initialized sdcard settings, let's prompt them once (then come back here)
299 | if(app->need_to_prompt_settings_init) {
300 | scene_manager_next_scene(app->scene_manager, WifiMarauderSceneSettingsInit);
301 | }
302 | }
303 |
304 | bool wifi_marauder_scene_start_on_event(void* context, SceneManagerEvent event) {
305 | UNUSED(context);
306 | WifiMarauderApp* app = context;
307 | bool consumed = false;
308 |
309 | if(event.type == SceneManagerEventTypeCustom) {
310 | if(event.event == WifiMarauderEventStartKeyboard) {
311 | scene_manager_set_scene_state(
312 | app->scene_manager, WifiMarauderSceneStart, app->selected_menu_index);
313 | scene_manager_next_scene(app->scene_manager, WifiMarauderSceneTextInput);
314 | } else if(event.event == WifiMarauderEventStartConsole) {
315 | scene_manager_set_scene_state(
316 | app->scene_manager, WifiMarauderSceneStart, app->selected_menu_index);
317 | scene_manager_next_scene(app->scene_manager, WifiMarauderSceneConsoleOutput);
318 | } else if(event.event == WifiMarauderEventStartSettingsInit) {
319 | scene_manager_set_scene_state(
320 | app->scene_manager, WifiMarauderSceneStart, app->selected_menu_index);
321 | scene_manager_next_scene(app->scene_manager, WifiMarauderSceneSettingsInit);
322 | } else if(event.event == WifiMarauderEventStartLogViewer) {
323 | scene_manager_set_scene_state(
324 | app->scene_manager, WifiMarauderSceneStart, app->selected_menu_index);
325 | scene_manager_next_scene(app->scene_manager, WifiMarauderSceneLogViewer);
326 | } else if(event.event == WifiMarauderEventStartScriptSelect) {
327 | scene_manager_set_scene_state(
328 | app->scene_manager, WifiMarauderSceneStart, app->selected_menu_index);
329 | scene_manager_next_scene(app->scene_manager, WifiMarauderSceneScriptSelect);
330 | } else if(event.event == WifiMarauderEventStartSniffPmkidOptions) {
331 | scene_manager_set_scene_state(
332 | app->scene_manager, WifiMarauderSceneStart, app->selected_menu_index);
333 | scene_manager_next_scene(app->scene_manager, WifiMarauderSceneSniffPmkidOptions);
334 | }
335 | consumed = true;
336 | } else if(event.type == SceneManagerEventTypeTick) {
337 | app->selected_menu_index = variable_item_list_get_selected_item_index(app->var_item_list);
338 | consumed = true;
339 | } else if(event.type == SceneManagerEventTypeBack) {
340 | scene_manager_stop(app->scene_manager);
341 | view_dispatcher_stop(app->view_dispatcher);
342 | consumed = true;
343 | }
344 |
345 | return consumed;
346 | }
347 |
348 | void wifi_marauder_scene_start_on_exit(void* context) {
349 | WifiMarauderApp* app = context;
350 | variable_item_list_reset(app->var_item_list);
351 | }
352 |
--------------------------------------------------------------------------------
/scenes/wifi_marauder_scene_text_input.c:
--------------------------------------------------------------------------------
1 | #include "../wifi_marauder_app_i.h"
2 |
3 | void wifi_marauder_scene_text_input_callback(void* context) {
4 | WifiMarauderApp* app = context;
5 |
6 | switch(app->special_case_input_step) {
7 | case 0: // most commands
8 | view_dispatcher_send_custom_event(app->view_dispatcher, WifiMarauderEventStartConsole);
9 | break;
10 | case 1: // special case for deauth: save source MAC
11 | view_dispatcher_send_custom_event(app->view_dispatcher, WifiMarauderEventSaveSourceMac);
12 | break;
13 | case 2: // special case for deauth: save destination MAC
14 | view_dispatcher_send_custom_event(
15 | app->view_dispatcher, WifiMarauderEventSaveDestinationMac);
16 | break;
17 | default:
18 | break;
19 | }
20 | }
21 |
22 | void wifi_marauder_scene_text_input_on_enter(void* context) {
23 | WifiMarauderApp* app = context;
24 |
25 | if(0 ==
26 | strncmp("attack -t deauth -s", app->selected_tx_string, strlen("attack -t deauth -s"))) {
27 | // Special case for manual deauth input
28 | app->special_case_input_step = 1;
29 | bzero(app->text_input_store, WIFI_MARAUDER_TEXT_INPUT_STORE_SIZE);
30 | } else if(false == app->is_custom_tx_string) {
31 | // Most commands
32 | app->special_case_input_step = 0;
33 |
34 | // Fill text input with selected string so that user can add to it
35 | size_t length = strlen(app->selected_tx_string);
36 | furi_assert(length < WIFI_MARAUDER_TEXT_INPUT_STORE_SIZE);
37 | bzero(app->text_input_store, WIFI_MARAUDER_TEXT_INPUT_STORE_SIZE);
38 | strncpy(app->text_input_store, app->selected_tx_string, length);
39 |
40 | // Add space - because flipper keyboard currently doesn't have a space
41 | app->text_input_store[length] = ' ';
42 | app->text_input_store[length + 1] = '\0';
43 | app->is_custom_tx_string = true;
44 | }
45 |
46 | // Setup view
47 | WIFI_TextInput* text_input = app->text_input;
48 | // Add help message to header
49 | if(app->special_case_input_step == 1) {
50 | wifi_text_input_set_header_text(text_input, "Enter source MAC");
51 | } else if(0 == strncmp("ssid -a -g", app->selected_tx_string, strlen("ssid -a -g"))) {
52 | wifi_text_input_set_header_text(text_input, "Enter # SSIDs to generate");
53 | } else if(0 == strncmp("ssid -a -n", app->selected_tx_string, strlen("ssid -a -n"))) {
54 | wifi_text_input_set_header_text(text_input, "Enter SSID name to add");
55 | } else if(0 == strncmp("ssid -r", app->selected_tx_string, strlen("ssid -r"))) {
56 | wifi_text_input_set_header_text(text_input, "Remove target from SSID list");
57 | } else if(0 == strncmp("select -a", app->selected_tx_string, strlen("select -a"))) {
58 | wifi_text_input_set_header_text(text_input, "Add target from AP list");
59 | } else if(0 == strncmp("select -s", app->selected_tx_string, strlen("select -s"))) {
60 | wifi_text_input_set_header_text(text_input, "Add target from SSID list");
61 | } else {
62 | wifi_text_input_set_header_text(text_input, "Add command arguments");
63 | }
64 | wifi_text_input_set_result_callback(
65 | text_input,
66 | wifi_marauder_scene_text_input_callback,
67 | app,
68 | app->text_input_store,
69 | WIFI_MARAUDER_TEXT_INPUT_STORE_SIZE,
70 | false);
71 |
72 | view_dispatcher_switch_to_view(app->view_dispatcher, WifiMarauderAppViewTextInput);
73 | }
74 |
75 | bool wifi_marauder_scene_text_input_on_event(void* context, SceneManagerEvent event) {
76 | WifiMarauderApp* app = context;
77 | bool consumed = false;
78 |
79 | if(event.type == SceneManagerEventTypeCustom) {
80 | if(event.event == WifiMarauderEventStartConsole) {
81 | // Point to custom string to send
82 | app->selected_tx_string = app->text_input_store;
83 | scene_manager_next_scene(app->scene_manager, WifiMarauderSceneConsoleOutput);
84 | consumed = true;
85 | } else if(event.event == WifiMarauderEventSaveSourceMac) {
86 | if(12 != strlen(app->text_input_store)) {
87 | wifi_text_input_set_header_text(app->text_input, "MAC must be 12 hex chars!");
88 | } else {
89 | snprintf(
90 | app->special_case_input_src_addr,
91 | sizeof(app->special_case_input_src_addr),
92 | "%c%c:%c%c:%c%c:%c%c:%c%c:%c%c",
93 | app->text_input_store[0],
94 | app->text_input_store[1],
95 | app->text_input_store[2],
96 | app->text_input_store[3],
97 | app->text_input_store[4],
98 | app->text_input_store[5],
99 | app->text_input_store[6],
100 | app->text_input_store[7],
101 | app->text_input_store[8],
102 | app->text_input_store[9],
103 | app->text_input_store[10],
104 | app->text_input_store[11]);
105 |
106 | // Advance scene to input destination MAC, clear text input
107 | app->special_case_input_step = 2;
108 | bzero(app->text_input_store, WIFI_MARAUDER_TEXT_INPUT_STORE_SIZE);
109 | wifi_text_input_set_header_text(app->text_input, "Enter destination MAC");
110 | }
111 | consumed = true;
112 | } else if(event.event == WifiMarauderEventSaveDestinationMac) {
113 | if(12 != strlen(app->text_input_store)) {
114 | wifi_text_input_set_header_text(app->text_input, "MAC must be 12 hex chars!");
115 | } else {
116 | snprintf(
117 | app->special_case_input_dst_addr,
118 | sizeof(app->special_case_input_dst_addr),
119 | "%c%c:%c%c:%c%c:%c%c:%c%c:%c%c",
120 | app->text_input_store[0],
121 | app->text_input_store[1],
122 | app->text_input_store[2],
123 | app->text_input_store[3],
124 | app->text_input_store[4],
125 | app->text_input_store[5],
126 | app->text_input_store[6],
127 | app->text_input_store[7],
128 | app->text_input_store[8],
129 | app->text_input_store[9],
130 | app->text_input_store[10],
131 | app->text_input_store[11]);
132 |
133 | // Construct command with source and destination MACs
134 | snprintf(
135 | app->text_input_store,
136 | WIFI_MARAUDER_TEXT_INPUT_STORE_SIZE,
137 | "attack -t deauth -s %18s -d %18s",
138 | app->special_case_input_src_addr,
139 | app->special_case_input_dst_addr);
140 | app->selected_tx_string = app->text_input_store;
141 | scene_manager_next_scene(app->scene_manager, WifiMarauderSceneConsoleOutput);
142 | }
143 | consumed = true;
144 | }
145 | }
146 |
147 | return consumed;
148 | }
149 |
150 | void wifi_marauder_scene_text_input_on_exit(void* context) {
151 | WifiMarauderApp* app = context;
152 |
153 | wifi_text_input_reset(app->text_input);
154 | }
155 |
--------------------------------------------------------------------------------
/scenes/wifi_marauder_scene_user_input.c:
--------------------------------------------------------------------------------
1 | #include "../wifi_marauder_app_i.h"
2 |
3 | bool wifi_marauder_scene_user_input_validator_number_callback(
4 | const char* text,
5 | FuriString* error,
6 | void* context) {
7 | UNUSED(context);
8 | for(int i = 0; text[i] != '\0'; i++) {
9 | if(text[i] < '0' || text[i] > '9') {
10 | furi_string_printf(error, "This is not\na valid\nnumber!");
11 | return false;
12 | }
13 | }
14 | return true;
15 | }
16 |
17 | bool wifi_marauder_scene_user_input_validator_file_callback(
18 | const char* text,
19 | FuriString* error,
20 | void* context) {
21 | UNUSED(context);
22 | if(strlen(text) == 0) {
23 | furi_string_printf(error, "File name\ncannot be\nblank!");
24 | return false;
25 | }
26 | return true;
27 | }
28 |
29 | void wifi_marauder_scene_user_input_ok_callback(void* context) {
30 | WifiMarauderApp* app = context;
31 |
32 | File* file = NULL;
33 | char* file_path = NULL;
34 |
35 | switch(app->user_input_type) {
36 | // Writes the string value of the reference
37 | case WifiMarauderUserInputTypeString:
38 | if(app->user_input_string_reference != NULL) {
39 | strncpy(
40 | *app->user_input_string_reference,
41 | app->text_input_store,
42 | strlen(app->text_input_store) + 1);
43 | app->user_input_string_reference = NULL;
44 | }
45 | break;
46 | // Writes the numerical value of the reference
47 | case WifiMarauderUserInputTypeNumber:
48 | if(app->user_input_number_reference != NULL) {
49 | *app->user_input_number_reference = atoi(app->text_input_store);
50 | app->user_input_number_reference = NULL;
51 | }
52 | break;
53 | // Creates a file with the name entered by the user, if it does not exist
54 | case WifiMarauderUserInputTypeFileName:
55 | file = storage_file_alloc(app->storage);
56 | // Use application directory if not specified
57 | if(app->user_input_file_dir == NULL) {
58 | app->user_input_file_dir = strdup(MARAUDER_APP_FOLDER);
59 | }
60 | if(app->user_input_file_extension != NULL) {
61 | size_t file_path_len = strlen(app->user_input_file_dir) +
62 | strlen(app->text_input_store) +
63 | strlen(app->user_input_file_extension) + 3;
64 | file_path = (char*)malloc(file_path_len);
65 | snprintf(
66 | file_path,
67 | file_path_len,
68 | "%s/%s.%s",
69 | app->user_input_file_dir,
70 | app->text_input_store,
71 | app->user_input_file_extension);
72 | } else {
73 | size_t file_path_len =
74 | strlen(app->user_input_file_dir) + strlen(app->text_input_store) + 2;
75 | file_path = (char*)malloc(file_path_len);
76 | snprintf(
77 | file_path, file_path_len, "%s/%s", app->user_input_file_dir, app->text_input_store);
78 | }
79 | if(storage_file_open(file, file_path, FSAM_WRITE, FSOM_CREATE_NEW)) {
80 | storage_file_close(file);
81 | }
82 | // Free memory
83 | free(app->user_input_file_dir);
84 | app->user_input_file_dir = NULL;
85 | free(app->user_input_file_extension);
86 | app->user_input_file_extension = NULL;
87 | free(file_path);
88 | storage_file_free(file);
89 | break;
90 | default:
91 | break;
92 | }
93 |
94 | view_dispatcher_send_custom_event(app->view_dispatcher, WifiMarauderEventPrevScene);
95 | }
96 |
97 | void wifi_marauder_scene_user_input_on_enter(void* context) {
98 | WifiMarauderApp* app = context;
99 |
100 | switch(app->user_input_type) {
101 | // Loads the string value of the reference
102 | case WifiMarauderUserInputTypeString:
103 | wifi_text_input_set_header_text(app->text_input, "Enter value:");
104 | wifi_text_input_set_validator(app->text_input, NULL, app);
105 | if(app->user_input_string_reference != NULL) {
106 | strncpy(
107 | app->text_input_store,
108 | *app->user_input_string_reference,
109 | strlen(*app->user_input_string_reference) + 1);
110 | }
111 | break;
112 | // Loads the numerical value of the reference
113 | case WifiMarauderUserInputTypeNumber:
114 | wifi_text_input_set_header_text(app->text_input, "Enter a valid number:");
115 | wifi_text_input_set_validator(
116 | app->text_input, wifi_marauder_scene_user_input_validator_number_callback, app);
117 | if(app->user_input_number_reference != NULL) {
118 | char number_str[32];
119 | snprintf(number_str, sizeof(number_str), "%d", *app->user_input_number_reference);
120 | strncpy(app->text_input_store, number_str, strlen(number_str) + 1);
121 | }
122 | break;
123 | // File name
124 | case WifiMarauderUserInputTypeFileName:
125 | wifi_text_input_set_header_text(app->text_input, "Enter file name:");
126 | wifi_text_input_set_validator(
127 | app->text_input, wifi_marauder_scene_user_input_validator_file_callback, app);
128 | break;
129 | default:
130 | scene_manager_previous_scene(app->scene_manager);
131 | return;
132 | }
133 |
134 | wifi_text_input_set_result_callback(
135 | app->text_input,
136 | wifi_marauder_scene_user_input_ok_callback,
137 | app,
138 | app->text_input_store,
139 | WIFI_MARAUDER_TEXT_INPUT_STORE_SIZE,
140 | false);
141 |
142 | view_dispatcher_switch_to_view(app->view_dispatcher, WifiMarauderAppViewTextInput);
143 | }
144 |
145 | bool wifi_marauder_scene_user_input_on_event(void* context, SceneManagerEvent event) {
146 | WifiMarauderApp* app = context;
147 |
148 | bool consumed = false;
149 |
150 | if(event.type == SceneManagerEventTypeCustom) {
151 | if(event.event == WifiMarauderEventPrevScene) {
152 | scene_manager_previous_scene(app->scene_manager);
153 | consumed = true;
154 | }
155 | }
156 |
157 | return consumed;
158 | }
159 |
160 | void wifi_marauder_scene_user_input_on_exit(void* context) {
161 | WifiMarauderApp* app = context;
162 | memset(app->text_input_store, 0, sizeof(app->text_input_store));
163 | wifi_text_input_reset(app->text_input);
164 | }
165 |
--------------------------------------------------------------------------------
/screenshots/marauder-save-pcaps.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/justcallmekoko/flipperzero-wifi-marauder/316258b8c708c1f2a67a2c087aa6d16348ed76f5/screenshots/marauder-save-pcaps.png
--------------------------------------------------------------------------------
/screenshots/marauder-script-demo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/justcallmekoko/flipperzero-wifi-marauder/316258b8c708c1f2a67a2c087aa6d16348ed76f5/screenshots/marauder-script-demo.png
--------------------------------------------------------------------------------
/screenshots/marauder-topmenu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/justcallmekoko/flipperzero-wifi-marauder/316258b8c708c1f2a67a2c087aa6d16348ed76f5/screenshots/marauder-topmenu.png
--------------------------------------------------------------------------------
/script/menu/wifi_marauder_script_stage_menu.c:
--------------------------------------------------------------------------------
1 | #include "wifi_marauder_script_stage_menu.h"
2 |
3 | WifiMarauderScriptStageMenu*
4 | wifi_marauder_script_stage_menu_create(WifiMarauderScriptStageType stage_type) {
5 | WifiMarauderScriptStageMenu* script_stage_menu = malloc(sizeof(WifiMarauderScriptStageMenu));
6 |
7 | switch(stage_type) {
8 | #define ADD_STAGE(name, id) \
9 | case WifiMarauderScriptStageType##id: \
10 | wifi_marauder_script_stage_menu_##name##_load(script_stage_menu); \
11 | break;
12 |
13 | #include "wifi_marauder_script_stage_menu_config.h"
14 | #undef ADD_STAGE
15 | }
16 | return script_stage_menu;
17 | }
18 |
19 | void wifi_marauder_script_stage_menu_free(WifiMarauderScriptStageMenu* stage_menu) {
20 | if(stage_menu == NULL) {
21 | return;
22 | }
23 | for(uint32_t i = 0; i < stage_menu->num_items; i++) {
24 | WifiMarauderScriptMenuItem* item = &(stage_menu->items[i]);
25 | for(int j = 0; j < item->num_options; j++) {
26 | free(item->options[j]);
27 | }
28 | free(item->name);
29 | }
30 | free(stage_menu->items);
31 | free(stage_menu);
32 | }
33 |
--------------------------------------------------------------------------------
/script/menu/wifi_marauder_script_stage_menu.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include "../wifi_marauder_script.h"
5 |
6 | #define ITEM_EDIT_MAX_OPTIONS (12)
7 |
8 | typedef void (*VariableItemSetupCallback)(VariableItem* item);
9 | typedef void (*VariableItemSelectCallback)(void* context);
10 |
11 | typedef enum WifiMarauderScriptMenuItemType {
12 | WifiMarauderScriptMenuItemTypeString,
13 | WifiMarauderScriptMenuItemTypeNumber,
14 | WifiMarauderScriptMenuItemTypeOptionsString,
15 | WifiMarauderScriptMenuItemTypeOptionsNumber,
16 | WifiMarauderScriptMenuItemTypeListString,
17 | WifiMarauderScriptMenuItemTypeListNumber
18 | } WifiMarauderScriptMenuItemType;
19 |
20 | typedef struct WifiMarauderScriptMenuItem {
21 | char* name;
22 | WifiMarauderScriptMenuItemType type;
23 | int num_options;
24 | char* options[ITEM_EDIT_MAX_OPTIONS];
25 | VariableItemSetupCallback setup_callback;
26 | VariableItemChangeCallback change_callback;
27 | VariableItemSelectCallback select_callback;
28 | } WifiMarauderScriptMenuItem;
29 |
30 | typedef struct WifiMarauderScriptStageMenu {
31 | WifiMarauderScriptMenuItem* items;
32 | uint32_t num_items;
33 | } WifiMarauderScriptStageMenu;
34 |
35 | #define ADD_STAGE(name, id) \
36 | void wifi_marauder_script_stage_menu_##name##_load(WifiMarauderScriptStageMenu*);
37 | #include "wifi_marauder_script_stage_menu_config.h"
38 | #undef ADD_STAGE
39 |
40 | WifiMarauderScriptStageMenu*
41 | wifi_marauder_script_stage_menu_create(WifiMarauderScriptStageType stage_type);
42 | void wifi_marauder_script_stage_menu_free(WifiMarauderScriptStageMenu* list);
43 |
--------------------------------------------------------------------------------
/script/menu/wifi_marauder_script_stage_menu_beaconap.c:
--------------------------------------------------------------------------------
1 | #include "../../wifi_marauder_app_i.h"
2 |
3 | void wifi_marauder_beaconap_stage_timeout_setup_callback(VariableItem* item) {
4 | WifiMarauderApp* app = variable_item_get_context(item);
5 | WifiMarauderScriptStageBeaconAp* stage = app->script_edit_selected_stage->stage;
6 | char timeout_str[32];
7 | snprintf(timeout_str, sizeof(timeout_str), "%d", stage->timeout);
8 | variable_item_set_current_value_text(item, timeout_str);
9 | }
10 |
11 | void wifi_marauder_beaconap_stage_timeout_select_callback(void* context) {
12 | WifiMarauderApp* app = context;
13 | WifiMarauderScriptStageBeaconAp* stage_beaconap = app->script_edit_selected_stage->stage;
14 | app->user_input_number_reference = &stage_beaconap->timeout;
15 | }
16 |
17 | void wifi_marauder_script_stage_menu_beaconap_load(WifiMarauderScriptStageMenu* stage_menu) {
18 | stage_menu->num_items = 1;
19 | stage_menu->items = malloc(1 * sizeof(WifiMarauderScriptMenuItem));
20 |
21 | stage_menu->items[0] = (WifiMarauderScriptMenuItem){
22 | .name = "Timeout",
23 | .type = WifiMarauderScriptMenuItemTypeNumber,
24 | .num_options = 1,
25 | .setup_callback = wifi_marauder_beaconap_stage_timeout_setup_callback,
26 | .select_callback = wifi_marauder_beaconap_stage_timeout_select_callback};
27 | }
--------------------------------------------------------------------------------
/script/menu/wifi_marauder_script_stage_menu_beaconlist.c:
--------------------------------------------------------------------------------
1 | #include "../../wifi_marauder_app_i.h"
2 |
3 | void wifi_marauder_beaconlist_stage_ssids_select_callback(void* context) {
4 | WifiMarauderApp* app = context;
5 | WifiMarauderScriptStageBeaconList* stage_beaconlist = app->script_edit_selected_stage->stage;
6 | app->script_stage_edit_strings_reference = &stage_beaconlist->ssids;
7 | app->script_stage_edit_string_count_reference = &stage_beaconlist->ssid_count;
8 | }
9 |
10 | void wifi_marauder_beaconlist_stage_random_ssids_setup_callback(VariableItem* item) {
11 | WifiMarauderApp* app = variable_item_get_context(item);
12 | WifiMarauderScriptStageBeaconList* stage = app->script_edit_selected_stage->stage;
13 | char random_ssids_str[32];
14 | snprintf(random_ssids_str, sizeof(random_ssids_str), "%d", stage->random_ssids);
15 | variable_item_set_current_value_text(item, random_ssids_str);
16 | }
17 |
18 | void wifi_marauder_beaconlist_stage_random_ssids_select_callback(void* context) {
19 | WifiMarauderApp* app = context;
20 | WifiMarauderScriptStageBeaconList* stage_beaconlist = app->script_edit_selected_stage->stage;
21 | app->user_input_number_reference = &stage_beaconlist->random_ssids;
22 | }
23 |
24 | void wifi_marauder_beaconlist_stage_timeout_setup_callback(VariableItem* item) {
25 | WifiMarauderApp* app = variable_item_get_context(item);
26 | WifiMarauderScriptStageBeaconList* stage = app->script_edit_selected_stage->stage;
27 | char timeout_str[32];
28 | snprintf(timeout_str, sizeof(timeout_str), "%d", stage->timeout);
29 | variable_item_set_current_value_text(item, timeout_str);
30 | }
31 |
32 | void wifi_marauder_beaconlist_stage_timeout_select_callback(void* context) {
33 | WifiMarauderApp* app = context;
34 | WifiMarauderScriptStageBeaconList* stage_beaconlist = app->script_edit_selected_stage->stage;
35 | app->user_input_number_reference = &stage_beaconlist->timeout;
36 | }
37 |
38 | void wifi_marauder_script_stage_menu_beaconlist_load(WifiMarauderScriptStageMenu* stage_menu) {
39 | stage_menu->num_items = 3;
40 | stage_menu->items = malloc(3 * sizeof(WifiMarauderScriptMenuItem));
41 |
42 | stage_menu->items[0] = (WifiMarauderScriptMenuItem){
43 | .name = strdup("SSIDs"),
44 | .type = WifiMarauderScriptMenuItemTypeListString,
45 | .num_options = 1,
46 | .select_callback = wifi_marauder_beaconlist_stage_ssids_select_callback};
47 | stage_menu->items[1] = (WifiMarauderScriptMenuItem){
48 | .name = strdup("Generate random"),
49 | .type = WifiMarauderScriptMenuItemTypeNumber,
50 | .num_options = 1,
51 | .setup_callback = wifi_marauder_beaconlist_stage_random_ssids_setup_callback,
52 | .select_callback = wifi_marauder_beaconlist_stage_random_ssids_select_callback};
53 | stage_menu->items[2] = (WifiMarauderScriptMenuItem){
54 | .name = strdup("Timeout"),
55 | .type = WifiMarauderScriptMenuItemTypeNumber,
56 | .num_options = 1,
57 | .setup_callback = wifi_marauder_beaconlist_stage_timeout_setup_callback,
58 | .select_callback = wifi_marauder_beaconlist_stage_timeout_select_callback};
59 | }
--------------------------------------------------------------------------------
/script/menu/wifi_marauder_script_stage_menu_config.h:
--------------------------------------------------------------------------------
1 | ADD_STAGE(scan, Scan)
2 | ADD_STAGE(select, Select)
3 | ADD_STAGE(deauth, Deauth)
4 | ADD_STAGE(probe, Probe)
5 | ADD_STAGE(sniffraw, SniffRaw)
6 | ADD_STAGE(sniffbeacon, SniffBeacon)
7 | ADD_STAGE(sniffdeauth, SniffDeauth)
8 | ADD_STAGE(sniffesp, SniffEsp)
9 | ADD_STAGE(sniffpmkid, SniffPmkid)
10 | ADD_STAGE(sniffpwn, SniffPwn)
11 | ADD_STAGE(beaconlist, BeaconList)
12 | ADD_STAGE(beaconap, BeaconAp)
13 | ADD_STAGE(exec, Exec)
14 | ADD_STAGE(delay, Delay)
--------------------------------------------------------------------------------
/script/menu/wifi_marauder_script_stage_menu_deauth.c:
--------------------------------------------------------------------------------
1 | #include "../../wifi_marauder_app_i.h"
2 |
3 | void wifi_marauder_deauth_stage_timeout_setup_callback(VariableItem* item) {
4 | WifiMarauderApp* app = variable_item_get_context(item);
5 | WifiMarauderScriptStageDeauth* stage = app->script_edit_selected_stage->stage;
6 | char timeout_str[32];
7 | snprintf(timeout_str, sizeof(timeout_str), "%d", stage->timeout);
8 | variable_item_set_current_value_text(item, timeout_str);
9 | }
10 |
11 | void wifi_marauder_deauth_stage_timeout_select_callback(void* context) {
12 | WifiMarauderApp* app = context;
13 | WifiMarauderScriptStageDeauth* stage_deauth = app->script_edit_selected_stage->stage;
14 | app->user_input_number_reference = &stage_deauth->timeout;
15 | }
16 |
17 | void wifi_marauder_script_stage_menu_deauth_load(WifiMarauderScriptStageMenu* stage_menu) {
18 | stage_menu->num_items = 1;
19 | stage_menu->items = malloc(1 * sizeof(WifiMarauderScriptMenuItem));
20 |
21 | stage_menu->items[0] = (WifiMarauderScriptMenuItem){
22 | .name = strdup("Timeout"),
23 | .type = WifiMarauderScriptMenuItemTypeNumber,
24 | .num_options = 1,
25 | .setup_callback = wifi_marauder_deauth_stage_timeout_setup_callback,
26 | .select_callback = wifi_marauder_deauth_stage_timeout_select_callback};
27 | }
--------------------------------------------------------------------------------
/script/menu/wifi_marauder_script_stage_menu_delay.c:
--------------------------------------------------------------------------------
1 | #include "../../wifi_marauder_app_i.h"
2 |
3 | void wifi_marauder_delay_stage_timeout_setup_callback(VariableItem* item) {
4 | WifiMarauderApp* app = variable_item_get_context(item);
5 | WifiMarauderScriptStageDelay* stage = app->script_edit_selected_stage->stage;
6 | char timeout_str[32];
7 | snprintf(timeout_str, sizeof(timeout_str), "%d", stage->timeout);
8 | variable_item_set_current_value_text(item, timeout_str);
9 | }
10 |
11 | void wifi_marauder_delay_stage_timeout_select_callback(void* context) {
12 | WifiMarauderApp* app = context;
13 | WifiMarauderScriptStageDelay* stage_delay = app->script_edit_selected_stage->stage;
14 | app->user_input_number_reference = &stage_delay->timeout;
15 | }
16 |
17 | void wifi_marauder_script_stage_menu_delay_load(WifiMarauderScriptStageMenu* stage_menu) {
18 | stage_menu->num_items = 1;
19 | stage_menu->items = malloc(1 * sizeof(WifiMarauderScriptMenuItem));
20 |
21 | stage_menu->items[0] = (WifiMarauderScriptMenuItem){
22 | .name = strdup("Timeout"),
23 | .type = WifiMarauderScriptMenuItemTypeNumber,
24 | .num_options = 1,
25 | .setup_callback = wifi_marauder_delay_stage_timeout_setup_callback,
26 | .select_callback = wifi_marauder_delay_stage_timeout_select_callback};
27 | }
--------------------------------------------------------------------------------
/script/menu/wifi_marauder_script_stage_menu_exec.c:
--------------------------------------------------------------------------------
1 | #include "../../wifi_marauder_app_i.h"
2 |
3 | void wifi_marauder_exec_stage_filter_setup_callback(VariableItem* item) {
4 | WifiMarauderApp* app = variable_item_get_context(item);
5 | WifiMarauderScriptStageExec* stage = app->script_edit_selected_stage->stage;
6 | if(stage->command != NULL) {
7 | variable_item_set_current_value_text(item, stage->command);
8 | }
9 | }
10 |
11 | void wifi_marauder_exec_stage_filter_select_callback(void* context) {
12 | WifiMarauderApp* app = context;
13 | WifiMarauderScriptStageExec* stage_select = app->script_edit_selected_stage->stage;
14 | if(stage_select->command == NULL) {
15 | stage_select->command = malloc(128);
16 | }
17 | app->user_input_string_reference = &stage_select->command;
18 | }
19 |
20 | void wifi_marauder_script_stage_menu_exec_load(WifiMarauderScriptStageMenu* stage_menu) {
21 | stage_menu->num_items = 1;
22 | stage_menu->items = malloc(1 * sizeof(WifiMarauderScriptMenuItem));
23 |
24 | stage_menu->items[0] = (WifiMarauderScriptMenuItem){
25 | .name = strdup("Command"),
26 | .type = WifiMarauderScriptMenuItemTypeString,
27 | .num_options = 1,
28 | .setup_callback = wifi_marauder_exec_stage_filter_setup_callback,
29 | .select_callback = wifi_marauder_exec_stage_filter_select_callback};
30 | }
--------------------------------------------------------------------------------
/script/menu/wifi_marauder_script_stage_menu_probe.c:
--------------------------------------------------------------------------------
1 | #include "../../wifi_marauder_app_i.h"
2 |
3 | void wifi_marauder_probe_stage_timeout_setup_callback(VariableItem* item) {
4 | WifiMarauderApp* app = variable_item_get_context(item);
5 | WifiMarauderScriptStageProbe* stage = app->script_edit_selected_stage->stage;
6 | char timeout_str[32];
7 | snprintf(timeout_str, sizeof(timeout_str), "%d", stage->timeout);
8 | variable_item_set_current_value_text(item, timeout_str);
9 | }
10 |
11 | void wifi_marauder_probe_stage_timeout_select_callback(void* context) {
12 | WifiMarauderApp* app = context;
13 | WifiMarauderScriptStageProbe* stage_probe = app->script_edit_selected_stage->stage;
14 | app->user_input_number_reference = &stage_probe->timeout;
15 | }
16 |
17 | void wifi_marauder_script_stage_menu_probe_load(WifiMarauderScriptStageMenu* stage_menu) {
18 | stage_menu->num_items = 1;
19 | stage_menu->items = malloc(1 * sizeof(WifiMarauderScriptMenuItem));
20 |
21 | stage_menu->items[0] = (WifiMarauderScriptMenuItem){
22 | .name = strdup("Timeout"),
23 | .type = WifiMarauderScriptMenuItemTypeNumber,
24 | .num_options = 1,
25 | .setup_callback = wifi_marauder_probe_stage_timeout_setup_callback,
26 | .select_callback = wifi_marauder_probe_stage_timeout_select_callback};
27 | }
--------------------------------------------------------------------------------
/script/menu/wifi_marauder_script_stage_menu_scan.c:
--------------------------------------------------------------------------------
1 | #include "../../wifi_marauder_app_i.h"
2 |
3 | void wifi_marauder_scan_stage_type_setup_callback(VariableItem* item) {
4 | WifiMarauderApp* app = variable_item_get_context(item);
5 | WifiMarauderScriptStageScan* stage = app->script_edit_selected_stage->stage;
6 | variable_item_set_current_value_index(item, stage->type);
7 | }
8 |
9 | void wifi_marauder_scan_stage_type_change_callback(VariableItem* item) {
10 | WifiMarauderApp* app = variable_item_get_context(item);
11 |
12 | // Get menu item
13 | uint8_t current_stage_index = variable_item_list_get_selected_item_index(app->var_item_list);
14 | const WifiMarauderScriptMenuItem* menu_item =
15 | &app->script_stage_menu->items[current_stage_index];
16 |
17 | // Defines the text of the selected option
18 | uint8_t option_index = variable_item_get_current_value_index(item);
19 | variable_item_set_current_value_text(item, menu_item->options[option_index]);
20 |
21 | // Updates the attribute value of the current stage
22 | WifiMarauderScriptStageScan* stage = app->script_edit_selected_stage->stage;
23 | stage->type = option_index;
24 | }
25 |
26 | void wifi_marauder_scan_stage_channel_setup_callback(VariableItem* item) {
27 | WifiMarauderApp* app = variable_item_get_context(item);
28 | WifiMarauderScriptStageScan* stage = app->script_edit_selected_stage->stage;
29 | if(stage->channel >= 0 && stage->channel < 12) {
30 | variable_item_set_current_value_index(item, stage->channel);
31 | } else {
32 | variable_item_set_current_value_index(item, 0);
33 | }
34 | }
35 |
36 | void wifi_marauder_scan_stage_channel_change_callback(VariableItem* item) {
37 | WifiMarauderApp* app = variable_item_get_context(item);
38 |
39 | // Get menu item
40 | uint8_t current_stage_index = variable_item_list_get_selected_item_index(app->var_item_list);
41 | const WifiMarauderScriptMenuItem* menu_item =
42 | &app->script_stage_menu->items[current_stage_index];
43 |
44 | // Defines the text of the selected option
45 | uint8_t option_index = variable_item_get_current_value_index(item);
46 | variable_item_set_current_value_text(item, menu_item->options[option_index]);
47 |
48 | // Updates the attribute value of the current stage
49 | WifiMarauderScriptStageScan* stage = app->script_edit_selected_stage->stage;
50 | stage->channel = option_index;
51 | }
52 |
53 | void wifi_marauder_scan_stage_timeout_setup_callback(VariableItem* item) {
54 | WifiMarauderApp* app = variable_item_get_context(item);
55 | WifiMarauderScriptStageScan* stage = app->script_edit_selected_stage->stage;
56 | char timeout_str[32];
57 | snprintf(timeout_str, sizeof(timeout_str), "%d", stage->timeout);
58 | variable_item_set_current_value_text(item, timeout_str);
59 | }
60 |
61 | void wifi_marauder_scan_stage_timeout_select_callback(void* context) {
62 | WifiMarauderApp* app = context;
63 | WifiMarauderScriptStageScan* stage_scan = app->script_edit_selected_stage->stage;
64 | app->user_input_number_reference = &stage_scan->timeout;
65 | }
66 |
67 | void wifi_marauder_script_stage_menu_scan_load(WifiMarauderScriptStageMenu* stage_menu) {
68 | stage_menu->num_items = 3;
69 | stage_menu->items = malloc(3 * sizeof(WifiMarauderScriptMenuItem));
70 |
71 | stage_menu->items[0] = (WifiMarauderScriptMenuItem){
72 | .name = strdup("Type"),
73 | .type = WifiMarauderScriptMenuItemTypeOptionsString,
74 | .num_options = 2,
75 | .options = {"ap", "station"},
76 | .setup_callback = wifi_marauder_scan_stage_type_setup_callback,
77 | .change_callback = wifi_marauder_scan_stage_type_change_callback,
78 | };
79 | stage_menu->items[1] = (WifiMarauderScriptMenuItem){
80 | .name = strdup("Channel"),
81 | .type = WifiMarauderScriptMenuItemTypeOptionsNumber,
82 | .num_options = 12,
83 | .options = {"none", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11"},
84 | .setup_callback = wifi_marauder_scan_stage_channel_setup_callback,
85 | .change_callback = wifi_marauder_scan_stage_channel_change_callback,
86 | };
87 | stage_menu->items[2] = (WifiMarauderScriptMenuItem){
88 | .name = strdup("Timeout"),
89 | .type = WifiMarauderScriptMenuItemTypeNumber,
90 | .num_options = 1,
91 | .setup_callback = wifi_marauder_scan_stage_timeout_setup_callback,
92 | .select_callback = wifi_marauder_scan_stage_timeout_select_callback};
93 | }
--------------------------------------------------------------------------------
/script/menu/wifi_marauder_script_stage_menu_select.c:
--------------------------------------------------------------------------------
1 | #include "../../wifi_marauder_app_i.h"
2 |
3 | void wifi_marauder_select_stage_type_setup_callback(VariableItem* item) {
4 | WifiMarauderApp* app = variable_item_get_context(item);
5 | WifiMarauderScriptStageSelect* stage = app->script_edit_selected_stage->stage;
6 | variable_item_set_current_value_index(item, stage->type);
7 | }
8 |
9 | void wifi_marauder_select_stage_type_change_callback(VariableItem* item) {
10 | WifiMarauderApp* app = variable_item_get_context(item);
11 |
12 | // Get menu item
13 | uint8_t current_stage_index = variable_item_list_get_selected_item_index(app->var_item_list);
14 | const WifiMarauderScriptMenuItem* menu_item =
15 | &app->script_stage_menu->items[current_stage_index];
16 |
17 | // Defines the text of the selected option
18 | uint8_t option_index = variable_item_get_current_value_index(item);
19 | variable_item_set_current_value_text(item, menu_item->options[option_index]);
20 |
21 | // Updates the attribute value of the current stage
22 | WifiMarauderScriptStageSelect* stage = app->script_edit_selected_stage->stage;
23 | stage->type = option_index;
24 | }
25 |
26 | void wifi_marauder_select_stage_filter_setup_callback(VariableItem* item) {
27 | WifiMarauderApp* app = variable_item_get_context(item);
28 | WifiMarauderScriptStageSelect* stage = app->script_edit_selected_stage->stage;
29 |
30 | if(stage->filter != NULL) {
31 | variable_item_set_current_value_index(item, 0);
32 | variable_item_set_current_value_text(item, stage->filter);
33 | } else {
34 | variable_item_set_current_value_index(item, 1);
35 | }
36 | }
37 |
38 | void wifi_marauder_select_stage_filter_change_callback(VariableItem* item) {
39 | WifiMarauderApp* app = variable_item_get_context(item);
40 | WifiMarauderScriptStageSelect* stage = app->script_edit_selected_stage->stage;
41 |
42 | // Clears the filter if you change the option. Flipper input box does not accept blank text
43 | if(variable_item_get_current_value_index(item) == 1) {
44 | stage->filter = NULL;
45 | variable_item_set_current_value_index(item, 0);
46 | variable_item_set_values_count(item, 1);
47 | }
48 |
49 | if(stage->filter != NULL) {
50 | variable_item_set_current_value_text(item, stage->filter);
51 | } else {
52 | variable_item_set_current_value_text(item, "");
53 | }
54 | }
55 |
56 | void wifi_marauder_select_stage_filter_select_callback(void* context) {
57 | WifiMarauderApp* app = context;
58 | WifiMarauderScriptStageSelect* stage_select = app->script_edit_selected_stage->stage;
59 | if(stage_select->filter == NULL) {
60 | stage_select->filter = malloc(128);
61 | }
62 | app->user_input_string_reference = &stage_select->filter;
63 | }
64 |
65 | void wifi_marauder_select_stage_indexes_select_callback(void* context) {
66 | WifiMarauderApp* app = context;
67 | WifiMarauderScriptStageSelect* stage_select = app->script_edit_selected_stage->stage;
68 | app->script_stage_edit_numbers_reference = &stage_select->indexes;
69 | app->script_stage_edit_number_count_reference = &stage_select->index_count;
70 | }
71 |
72 | void wifi_marauder_script_stage_menu_select_load(WifiMarauderScriptStageMenu* stage_menu) {
73 | stage_menu->num_items = 3;
74 | stage_menu->items = malloc(3 * sizeof(WifiMarauderScriptMenuItem));
75 |
76 | stage_menu->items[0] = (WifiMarauderScriptMenuItem){
77 | .name = strdup("Type"),
78 | .type = WifiMarauderScriptMenuItemTypeOptionsString,
79 | .num_options = 2,
80 | .options = {"ap", "station"},
81 | .setup_callback = wifi_marauder_select_stage_type_setup_callback,
82 | .change_callback = wifi_marauder_select_stage_type_change_callback};
83 | stage_menu->items[1] = (WifiMarauderScriptMenuItem){
84 | .name = strdup("Filter"),
85 | .type = WifiMarauderScriptMenuItemTypeString,
86 | .num_options = 2,
87 | .setup_callback = wifi_marauder_select_stage_filter_setup_callback,
88 | .change_callback = wifi_marauder_select_stage_filter_change_callback,
89 | .select_callback = wifi_marauder_select_stage_filter_select_callback};
90 | stage_menu->items[2] = (WifiMarauderScriptMenuItem){
91 | .name = strdup("Indexes"),
92 | .type = WifiMarauderScriptMenuItemTypeListNumber,
93 | .num_options = 1,
94 | .select_callback = wifi_marauder_select_stage_indexes_select_callback};
95 | }
--------------------------------------------------------------------------------
/script/menu/wifi_marauder_script_stage_menu_sniffbeacon.c:
--------------------------------------------------------------------------------
1 | #include "../../wifi_marauder_app_i.h"
2 |
3 | void wifi_marauder_sniffbeacon_stage_timeout_setup_callback(VariableItem* item) {
4 | WifiMarauderApp* app = variable_item_get_context(item);
5 | WifiMarauderScriptStageSniffBeacon* stage = app->script_edit_selected_stage->stage;
6 | char timeout_str[32];
7 | snprintf(timeout_str, sizeof(timeout_str), "%d", stage->timeout);
8 | variable_item_set_current_value_text(item, timeout_str);
9 | }
10 |
11 | void wifi_marauder_sniffbeacon_stage_timeout_select_callback(void* context) {
12 | WifiMarauderApp* app = context;
13 | WifiMarauderScriptStageSniffBeacon* stage_sniffbeacon = app->script_edit_selected_stage->stage;
14 | app->user_input_number_reference = &stage_sniffbeacon->timeout;
15 | }
16 |
17 | void wifi_marauder_script_stage_menu_sniffbeacon_load(WifiMarauderScriptStageMenu* stage_menu) {
18 | stage_menu->num_items = 1;
19 | stage_menu->items = malloc(1 * sizeof(WifiMarauderScriptMenuItem));
20 |
21 | stage_menu->items[0] = (WifiMarauderScriptMenuItem){
22 | .name = strdup("Timeout"),
23 | .type = WifiMarauderScriptMenuItemTypeNumber,
24 | .num_options = 1,
25 | .setup_callback = wifi_marauder_sniffbeacon_stage_timeout_setup_callback,
26 | .select_callback = wifi_marauder_sniffbeacon_stage_timeout_select_callback};
27 | }
--------------------------------------------------------------------------------
/script/menu/wifi_marauder_script_stage_menu_sniffdeauth.c:
--------------------------------------------------------------------------------
1 | #include "../../wifi_marauder_app_i.h"
2 |
3 | void wifi_marauder_sniffdeauth_stage_timeout_setup_callback(VariableItem* item) {
4 | WifiMarauderApp* app = variable_item_get_context(item);
5 | WifiMarauderScriptStageSniffDeauth* stage = app->script_edit_selected_stage->stage;
6 | char timeout_str[32];
7 | snprintf(timeout_str, sizeof(timeout_str), "%d", stage->timeout);
8 | variable_item_set_current_value_text(item, timeout_str);
9 | }
10 |
11 | void wifi_marauder_sniffdeauth_stage_timeout_select_callback(void* context) {
12 | WifiMarauderApp* app = context;
13 | WifiMarauderScriptStageSniffDeauth* stage_sniffdeauth = app->script_edit_selected_stage->stage;
14 | app->user_input_number_reference = &stage_sniffdeauth->timeout;
15 | }
16 |
17 | void wifi_marauder_script_stage_menu_sniffdeauth_load(WifiMarauderScriptStageMenu* stage_menu) {
18 | stage_menu->num_items = 1;
19 | stage_menu->items = malloc(1 * sizeof(WifiMarauderScriptMenuItem));
20 |
21 | stage_menu->items[0] = (WifiMarauderScriptMenuItem){
22 | .name = strdup("Timeout"),
23 | .type = WifiMarauderScriptMenuItemTypeNumber,
24 | .num_options = 1,
25 | .setup_callback = wifi_marauder_sniffdeauth_stage_timeout_setup_callback,
26 | .select_callback = wifi_marauder_sniffdeauth_stage_timeout_select_callback};
27 | }
--------------------------------------------------------------------------------
/script/menu/wifi_marauder_script_stage_menu_sniffesp.c:
--------------------------------------------------------------------------------
1 | #include "../../wifi_marauder_app_i.h"
2 |
3 | void wifi_marauder_sniffesp_stage_timeout_setup_callback(VariableItem* item) {
4 | WifiMarauderApp* app = variable_item_get_context(item);
5 | WifiMarauderScriptStageSniffEsp* stage = app->script_edit_selected_stage->stage;
6 | char timeout_str[32];
7 | snprintf(timeout_str, sizeof(timeout_str), "%d", stage->timeout);
8 | variable_item_set_current_value_text(item, timeout_str);
9 | }
10 |
11 | void wifi_marauder_sniffesp_stage_timeout_select_callback(void* context) {
12 | WifiMarauderApp* app = context;
13 | WifiMarauderScriptStageSniffEsp* stage_sniffesp = app->script_edit_selected_stage->stage;
14 | app->user_input_number_reference = &stage_sniffesp->timeout;
15 | }
16 |
17 | void wifi_marauder_script_stage_menu_sniffesp_load(WifiMarauderScriptStageMenu* stage_menu) {
18 | stage_menu->num_items = 1;
19 | stage_menu->items = malloc(1 * sizeof(WifiMarauderScriptMenuItem));
20 |
21 | stage_menu->items[0] = (WifiMarauderScriptMenuItem){
22 | .name = strdup("Timeout"),
23 | .type = WifiMarauderScriptMenuItemTypeNumber,
24 | .num_options = 1,
25 | .setup_callback = wifi_marauder_sniffesp_stage_timeout_setup_callback,
26 | .select_callback = wifi_marauder_sniffesp_stage_timeout_select_callback};
27 | }
--------------------------------------------------------------------------------
/script/menu/wifi_marauder_script_stage_menu_sniffpmkid.c:
--------------------------------------------------------------------------------
1 | #include "../../wifi_marauder_app_i.h"
2 |
3 | static void wifi_marauder_sniffpmkid_stage_hop_channels_setup_callback(VariableItem* item) {
4 | WifiMarauderApp* app = variable_item_get_context(item);
5 | WifiMarauderScriptStageSniffPmkid* stage = app->script_edit_selected_stage->stage;
6 | variable_item_set_current_value_index(item, stage->hop_channels);
7 | }
8 |
9 | static void wifi_marauder_sniffpmkid_stage_hop_channels_change_callback(VariableItem* item) {
10 | WifiMarauderApp* app = variable_item_get_context(item);
11 |
12 | uint8_t current_stage_index = variable_item_list_get_selected_item_index(app->var_item_list);
13 | const WifiMarauderScriptMenuItem* menu_item =
14 | &app->script_stage_menu->items[current_stage_index];
15 |
16 | uint8_t option_index = variable_item_get_current_value_index(item);
17 | variable_item_set_current_value_text(item, menu_item->options[option_index]);
18 |
19 | WifiMarauderScriptStageSniffPmkid* stage = app->script_edit_selected_stage->stage;
20 | stage->hop_channels = option_index;
21 | }
22 |
23 | static void wifi_marauder_sniffpmkid_stage_force_deauth_setup_callback(VariableItem* item) {
24 | WifiMarauderApp* app = variable_item_get_context(item);
25 | WifiMarauderScriptStageSniffPmkid* stage = app->script_edit_selected_stage->stage;
26 | variable_item_set_current_value_index(item, stage->force_deauth);
27 | }
28 |
29 | static void wifi_marauder_sniffpmkid_stage_force_deauth_change_callback(VariableItem* item) {
30 | WifiMarauderApp* app = variable_item_get_context(item);
31 |
32 | // Get menu item
33 | uint8_t current_stage_index = variable_item_list_get_selected_item_index(app->var_item_list);
34 | const WifiMarauderScriptMenuItem* menu_item =
35 | &app->script_stage_menu->items[current_stage_index];
36 |
37 | // Defines the text of the selected option
38 | uint8_t option_index = variable_item_get_current_value_index(item);
39 | variable_item_set_current_value_text(item, menu_item->options[option_index]);
40 |
41 | // Updates the attribute value of the current stage
42 | WifiMarauderScriptStageSniffPmkid* stage = app->script_edit_selected_stage->stage;
43 | stage->force_deauth = option_index;
44 | }
45 |
46 | static void wifi_marauder_sniffpmkid_stage_channel_setup_callback(VariableItem* item) {
47 | WifiMarauderApp* app = variable_item_get_context(item);
48 | WifiMarauderScriptStageSniffPmkid* stage = app->script_edit_selected_stage->stage;
49 | if(stage->channel >= 0 && stage->channel < 12) {
50 | variable_item_set_current_value_index(item, stage->channel);
51 | } else {
52 | variable_item_set_current_value_index(item, 0);
53 | }
54 | }
55 |
56 | static void wifi_marauder_sniffpmkid_stage_channel_change_callback(VariableItem* item) {
57 | WifiMarauderApp* app = variable_item_get_context(item);
58 |
59 | // Get menu item
60 | uint8_t current_stage_index = variable_item_list_get_selected_item_index(app->var_item_list);
61 | const WifiMarauderScriptMenuItem* menu_item =
62 | &app->script_stage_menu->items[current_stage_index];
63 |
64 | // Defines the text of the selected option
65 | uint8_t option_index = variable_item_get_current_value_index(item);
66 | variable_item_set_current_value_text(item, menu_item->options[option_index]);
67 |
68 | // Updates the attribute value of the current stage
69 | WifiMarauderScriptStageSniffPmkid* stage = app->script_edit_selected_stage->stage;
70 | stage->channel = option_index;
71 | }
72 |
73 | static void wifi_marauder_sniffpmkid_stage_timeout_setup_callback(VariableItem* item) {
74 | WifiMarauderApp* app = variable_item_get_context(item);
75 | WifiMarauderScriptStageSniffPmkid* stage = app->script_edit_selected_stage->stage;
76 | char timeout_str[32];
77 | snprintf(timeout_str, sizeof(timeout_str), "%d", stage->timeout);
78 | variable_item_set_current_value_text(item, timeout_str);
79 | }
80 |
81 | static void wifi_marauder_sniffpmkid_stage_timeout_select_callback(void* context) {
82 | WifiMarauderApp* app = context;
83 | WifiMarauderScriptStageSniffPmkid* stage_sniffpmkid = app->script_edit_selected_stage->stage;
84 | app->user_input_number_reference = &stage_sniffpmkid->timeout;
85 | }
86 |
87 | void wifi_marauder_script_stage_menu_sniffpmkid_load(WifiMarauderScriptStageMenu* stage_menu) {
88 | stage_menu->num_items = 4;
89 | stage_menu->items = malloc(4 * sizeof(WifiMarauderScriptMenuItem));
90 |
91 | stage_menu->items[0] = (WifiMarauderScriptMenuItem){
92 | .name = strdup("Force deauth"),
93 | .type = WifiMarauderScriptMenuItemTypeOptionsString,
94 | .num_options = 2,
95 | .options = {"no", "yes"},
96 | .setup_callback = wifi_marauder_sniffpmkid_stage_force_deauth_setup_callback,
97 | .change_callback = wifi_marauder_sniffpmkid_stage_force_deauth_change_callback};
98 | stage_menu->items[1] = (WifiMarauderScriptMenuItem){
99 | .name = strdup("Channel"),
100 | .type = WifiMarauderScriptMenuItemTypeOptionsNumber,
101 | .num_options = 12,
102 | .options = {"none", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11"},
103 | .setup_callback = wifi_marauder_sniffpmkid_stage_channel_setup_callback,
104 | .change_callback = wifi_marauder_sniffpmkid_stage_channel_change_callback};
105 | stage_menu->items[2] = (WifiMarauderScriptMenuItem){
106 | .name = strdup("Timeout"),
107 | .type = WifiMarauderScriptMenuItemTypeNumber,
108 | .num_options = 1,
109 | .setup_callback = wifi_marauder_sniffpmkid_stage_timeout_setup_callback,
110 | .select_callback = wifi_marauder_sniffpmkid_stage_timeout_select_callback};
111 | stage_menu->items[3] = (WifiMarauderScriptMenuItem){
112 | .name = strdup("Hop Channels"),
113 | .type = WifiMarauderScriptMenuItemTypeOptionsString,
114 | .num_options = 2,
115 | .options = {"no", "yes"},
116 | .setup_callback = wifi_marauder_sniffpmkid_stage_hop_channels_setup_callback,
117 | .change_callback = wifi_marauder_sniffpmkid_stage_hop_channels_change_callback};
118 | }
--------------------------------------------------------------------------------
/script/menu/wifi_marauder_script_stage_menu_sniffpwn.c:
--------------------------------------------------------------------------------
1 | #include "../../wifi_marauder_app_i.h"
2 |
3 | void wifi_marauder_sniffpwn_stage_timeout_setup_callback(VariableItem* item) {
4 | WifiMarauderApp* app = variable_item_get_context(item);
5 | WifiMarauderScriptStageSniffPwn* stage = app->script_edit_selected_stage->stage;
6 | char timeout_str[32];
7 | snprintf(timeout_str, sizeof(timeout_str), "%d", stage->timeout);
8 | variable_item_set_current_value_text(item, timeout_str);
9 | }
10 |
11 | void wifi_marauder_sniffpwn_stage_timeout_select_callback(void* context) {
12 | WifiMarauderApp* app = context;
13 | WifiMarauderScriptStageSniffPwn* stage_sniffpwn = app->script_edit_selected_stage->stage;
14 | app->user_input_number_reference = &stage_sniffpwn->timeout;
15 | }
16 |
17 | void wifi_marauder_script_stage_menu_sniffpwn_load(WifiMarauderScriptStageMenu* stage_menu) {
18 | stage_menu->num_items = 1;
19 | stage_menu->items = malloc(1 * sizeof(WifiMarauderScriptMenuItem));
20 |
21 | stage_menu->items[0] = (WifiMarauderScriptMenuItem){
22 | .name = strdup("Timeout"),
23 | .type = WifiMarauderScriptMenuItemTypeNumber,
24 | .num_options = 1,
25 | .setup_callback = wifi_marauder_sniffpwn_stage_timeout_setup_callback,
26 | .select_callback = wifi_marauder_sniffpwn_stage_timeout_select_callback};
27 | }
--------------------------------------------------------------------------------
/script/menu/wifi_marauder_script_stage_menu_sniffraw.c:
--------------------------------------------------------------------------------
1 | #include "../../wifi_marauder_app_i.h"
2 |
3 | void wifi_marauder_sniffraw_stage_timeout_setup_callback(VariableItem* item) {
4 | WifiMarauderApp* app = variable_item_get_context(item);
5 | WifiMarauderScriptStageSniffRaw* stage = app->script_edit_selected_stage->stage;
6 | char timeout_str[32];
7 | snprintf(timeout_str, sizeof(timeout_str), "%d", stage->timeout);
8 | variable_item_set_current_value_text(item, timeout_str);
9 | }
10 |
11 | void wifi_marauder_sniffraw_stage_timeout_select_callback(void* context) {
12 | WifiMarauderApp* app = context;
13 | WifiMarauderScriptStageSniffRaw* stage_sniffraw = app->script_edit_selected_stage->stage;
14 | app->user_input_number_reference = &stage_sniffraw->timeout;
15 | }
16 |
17 | void wifi_marauder_script_stage_menu_sniffraw_load(WifiMarauderScriptStageMenu* stage_menu) {
18 | stage_menu->num_items = 1;
19 | stage_menu->items = malloc(1 * sizeof(WifiMarauderScriptMenuItem));
20 |
21 | stage_menu->items[0] = (WifiMarauderScriptMenuItem){
22 | .name = strdup("Timeout"),
23 | .type = WifiMarauderScriptMenuItemTypeNumber,
24 | .num_options = 1,
25 | .setup_callback = wifi_marauder_sniffraw_stage_timeout_setup_callback,
26 | .select_callback = wifi_marauder_sniffraw_stage_timeout_select_callback};
27 | }
--------------------------------------------------------------------------------
/script/wifi_marauder_script.h:
--------------------------------------------------------------------------------
1 | /*
2 | * ----------------------------------------------------------------------------------------------------
3 | * STEPS TO ADD A NEW STAGE:
4 | *
5 | * wifi_marauder_script.h
6 | * - Complement WifiMarauderScriptStageType enum with new stage
7 | * - Create struct WifiMarauderScriptStage???? for the new stage
8 | *
9 | * wifi_marauder_script.c
10 | * - Change _wifi_marauder_script_load_stages() to load new stage
11 | * - Change wifi_marauder_script_save_json() to support the new stage
12 | * - Add case to free memory in wifi_marauder_script_free()
13 | *
14 | * wifi_marauder_script_executor.c
15 | * - Create function "void _wifi_marauder_script_execute_????(WifiMarauderScriptStage????* stage)"
16 | * - Add case in wifi_marauder_script_execute_stage()
17 | *
18 | * wifi_marauder_scene_script_edit.c
19 | * - Add case in wifi_marauder_scene_script_edit_on_enter()
20 | *
21 | * wifi_marauder_scene_script_stage_add.c
22 | * - Create stage creation function and add in wifi_marauder_scene_script_stage_add_on_enter()
23 | *
24 | * wifi_marauder_script_stage_menu_config.h
25 | * - Add the new stage and implement its functions in a new file
26 | *
27 | * ----------------------------------------------------------------------------------------------------
28 | * SCRIPT SYNTAX (In order of execution):
29 | * {
30 | * "meta": {
31 | * "description": "My script",
32 | * "repeat": times the script will repeat (default 1),
33 | * "enableLed": true (default) | false,
34 | * "savePcap": true (default) | false
35 | * },
36 | * "stages": {
37 | * "scan": {
38 | * "type": "ap" | "station",
39 | * "timeout": seconds,
40 | * "channel": 1-11
41 | * },
42 | * "select": {
43 | * "type": "ap" | "station" | "ssid",
44 | * "filter": "all" | "contains -f '{SSID fragment}' or equals '{SSID}' or ...",
45 | * "indexes": [0, 1, 2, 3...],
46 | * },
47 | * "deauth": {
48 | * "timeout": seconds
49 | * },
50 | * "probe": {
51 | * "timeout": seconds
52 | * },
53 | * "sniffRaw": {
54 | * "timeout": seconds
55 | * },
56 | * "sniffBeacon": {
57 | * "timeout": seconds
58 | * },
59 | * "sniffDeauth": {
60 | * "timeout": seconds
61 | * },
62 | * "sniffEsp": {
63 | * "timeout": seconds
64 | * },
65 | * "sniffPmkid": {
66 | * "forceDeauth": true (default) | false,
67 | * "channel": 1-11,
68 | * "timeout": seconds
69 | * },
70 | * "sniffPwn": {
71 | * "timeout": seconds
72 | * },
73 | * "beaconList": {
74 | * "ssids": [
75 | * "SSID 1",
76 | * "SSID 2",
77 | * "SSID 3"
78 | * ],
79 | * "generate": number of random SSIDs that will be generated,
80 | * "timeout": seconds
81 | * }
82 | * "beaconAp": {
83 | * "timeout": seconds
84 | * }
85 | * "exec": {
86 | * "command": Command (eg: "clearlist -a")
87 | * }
88 | * "delay": {
89 | * "timeout": seconds
90 | * }
91 | * }
92 | * }
93 | *
94 | * Note: It is possible to inform "stages" as an array, allowing ordering and repetition of stages of the same type:
95 | * "stages": [
96 | * {
97 | * "beaconList": { "ssids": ["SSID 1", "SSID 2"] }
98 | * },
99 | * {
100 | * "beaconList": { "generate": 4 }
101 | * },
102 | * ]
103 | * ----------------------------------------------------------------------------------------------------
104 | */
105 |
106 | #pragma once
107 |
108 | #include
109 | #include "cJSON.h"
110 |
111 | #define WIFI_MARAUDER_DEFAULT_TIMEOUT_SCAN 15
112 | #define WIFI_MARAUDER_DEFAULT_TIMEOUT_DEAUTH 30
113 | #define WIFI_MARAUDER_DEFAULT_TIMEOUT_PROBE 60
114 | #define WIFI_MARAUDER_DEFAULT_TIMEOUT_SNIFF 60
115 | #define WIFI_MARAUDER_DEFAULT_TIMEOUT_BEACON 60
116 |
117 | typedef enum {
118 | WifiMarauderScriptBooleanFalse = 0,
119 | WifiMarauderScriptBooleanTrue = 1,
120 | WifiMarauderScriptBooleanUndefined = 2
121 | } WifiMarauderScriptBoolean;
122 |
123 | typedef enum {
124 | WifiMarauderScriptStageTypeScan,
125 | WifiMarauderScriptStageTypeSelect,
126 | WifiMarauderScriptStageTypeDeauth,
127 | WifiMarauderScriptStageTypeProbe,
128 | WifiMarauderScriptStageTypeSniffRaw,
129 | WifiMarauderScriptStageTypeSniffBeacon,
130 | WifiMarauderScriptStageTypeSniffDeauth,
131 | WifiMarauderScriptStageTypeSniffEsp,
132 | WifiMarauderScriptStageTypeSniffPmkid,
133 | WifiMarauderScriptStageTypeSniffPwn,
134 | WifiMarauderScriptStageTypeBeaconList,
135 | WifiMarauderScriptStageTypeBeaconAp,
136 | WifiMarauderScriptStageTypeExec,
137 | WifiMarauderScriptStageTypeDelay,
138 | } WifiMarauderScriptStageType;
139 |
140 | typedef enum {
141 | WifiMarauderScriptScanTypeAp = 0,
142 | WifiMarauderScriptScanTypeStation = 1
143 | } WifiMarauderScriptScanType;
144 |
145 | typedef enum {
146 | WifiMarauderScriptSelectTypeAp,
147 | WifiMarauderScriptSelectTypeStation,
148 | WifiMarauderScriptSelectTypeSsid
149 | } WifiMarauderScriptSelectType;
150 |
151 | // Stages
152 | typedef struct WifiMarauderScriptStage {
153 | WifiMarauderScriptStageType type;
154 | void* stage;
155 | struct WifiMarauderScriptStage* next_stage;
156 | } WifiMarauderScriptStage;
157 |
158 | typedef struct WifiMarauderScriptStageScan {
159 | WifiMarauderScriptScanType type;
160 | int channel;
161 | int timeout;
162 | } WifiMarauderScriptStageScan;
163 |
164 | typedef struct WifiMarauderScriptStageSelect {
165 | WifiMarauderScriptSelectType type;
166 | char* filter;
167 | int* indexes;
168 | int index_count;
169 | // TODO: Implement a feature to not select the same items in the next iteration of the script
170 | bool allow_repeat;
171 | } WifiMarauderScriptStageSelect;
172 |
173 | typedef struct WifiMarauderScriptStageDeauth {
174 | int timeout;
175 | } WifiMarauderScriptStageDeauth;
176 |
177 | typedef struct WifiMarauderScriptStageProbe {
178 | int timeout;
179 | } WifiMarauderScriptStageProbe;
180 |
181 | typedef struct WifiMarauderScriptStageSniffRaw {
182 | int timeout;
183 | } WifiMarauderScriptStageSniffRaw;
184 |
185 | typedef struct WifiMarauderScriptStageSniffBeacon {
186 | int timeout;
187 | } WifiMarauderScriptStageSniffBeacon;
188 |
189 | typedef struct WifiMarauderScriptStageSniffDeauth {
190 | int timeout;
191 | } WifiMarauderScriptStageSniffDeauth;
192 |
193 | typedef struct WifiMarauderScriptStageSniffEsp {
194 | int timeout;
195 | } WifiMarauderScriptStageSniffEsp;
196 |
197 | typedef struct WifiMarauderScriptStageSniffPmkid {
198 | bool force_deauth;
199 | bool hop_channels;
200 | int channel;
201 | int timeout;
202 | } WifiMarauderScriptStageSniffPmkid;
203 |
204 | typedef struct WifiMarauderScriptStageSniffPwn {
205 | int timeout;
206 | } WifiMarauderScriptStageSniffPwn;
207 |
208 | typedef struct WifiMarauderScriptStageBeaconList {
209 | char** ssids;
210 | int ssid_count;
211 | int random_ssids;
212 | int timeout;
213 | } WifiMarauderScriptStageBeaconList;
214 |
215 | typedef struct WifiMarauderScriptStageBeaconAp {
216 | int timeout;
217 | } WifiMarauderScriptStageBeaconAp;
218 |
219 | typedef struct WifiMarauderScriptStageExec {
220 | char* command;
221 | } WifiMarauderScriptStageExec;
222 |
223 | typedef struct WifiMarauderScriptStageDelay {
224 | int timeout;
225 | } WifiMarauderScriptStageDelay;
226 |
227 | // Script
228 | typedef struct WifiMarauderScript {
229 | char* name;
230 | char* description;
231 | WifiMarauderScriptStage* first_stage;
232 | WifiMarauderScriptStage* last_stage;
233 | WifiMarauderScriptBoolean enable_led;
234 | WifiMarauderScriptBoolean save_pcap;
235 | int repeat;
236 | } WifiMarauderScript;
237 |
238 | typedef struct WifiMarauderScriptStageListItem {
239 | char* value;
240 | struct WifiMarauderScriptStageListItem* next_item;
241 | } WifiMarauderScriptStageListItem;
242 |
243 | WifiMarauderScript* wifi_marauder_script_alloc();
244 | WifiMarauderScript* wifi_marauder_script_create(const char* script_name);
245 | WifiMarauderScript* wifi_marauder_script_parse_raw(const char* script_raw);
246 | WifiMarauderScript* wifi_marauder_script_parse_json(Storage* storage, const char* file_path);
247 | void wifi_marauder_script_save_json(
248 | Storage* storage,
249 | const char* file_path,
250 | WifiMarauderScript* script);
251 | void wifi_marauder_script_add_stage(
252 | WifiMarauderScript* script,
253 | WifiMarauderScriptStageType stage_type,
254 | void* stage_data);
255 | bool wifi_marauder_script_has_stage(
256 | WifiMarauderScript* script,
257 | WifiMarauderScriptStageType stage_type);
258 | void wifi_marauder_script_free(WifiMarauderScript* script);
259 |
--------------------------------------------------------------------------------
/script/wifi_marauder_script_executor.c:
--------------------------------------------------------------------------------
1 | #include "../wifi_marauder_app_i.h"
2 | #include "wifi_marauder_script_executor.h"
3 |
4 | void _wifi_marauder_script_delay(WifiMarauderScriptWorker* worker, uint32_t delay_secs) {
5 | for(uint32_t i = 0; i < delay_secs && worker->is_running; i++) furi_delay_ms(1000);
6 | }
7 |
8 | void _send_stop(WifiMarauderScriptWorker* worker) {
9 | const char stop_command[] = "stopscan\n";
10 | wifi_marauder_uart_tx(worker->uart, (uint8_t*)(stop_command), strlen(stop_command));
11 | }
12 |
13 | void _send_line_break(WifiMarauderScriptWorker* worker) {
14 | wifi_marauder_uart_tx(worker->uart, (uint8_t*)("\n"), 1);
15 | }
16 |
17 | void _send_channel_select(WifiMarauderScriptWorker* worker, int channel) {
18 | char command[30];
19 | _send_line_break(worker);
20 | snprintf(command, sizeof(command), "channel -s %d\n", channel);
21 | wifi_marauder_uart_tx(worker->uart, (uint8_t*)(command), strlen(command));
22 | }
23 |
24 | void _wifi_marauder_script_execute_scan(
25 | WifiMarauderScriptStageScan* stage,
26 | WifiMarauderScriptWorker* worker) {
27 | char command[15];
28 | // Set channel
29 | if(stage->channel > 0) {
30 | _send_channel_select(worker, stage->channel);
31 | }
32 | // Start scan
33 | if(stage->type == WifiMarauderScriptScanTypeAp) {
34 | snprintf(command, sizeof(command), "scanap\n");
35 | } else {
36 | snprintf(command, sizeof(command), "scansta\n");
37 | }
38 | wifi_marauder_uart_tx(worker->uart, (uint8_t*)(command), strlen(command));
39 | _wifi_marauder_script_delay(worker, stage->timeout);
40 | _send_stop(worker);
41 | }
42 |
43 | void _wifi_marauder_script_execute_select(
44 | WifiMarauderScriptStageSelect* stage,
45 | WifiMarauderScriptWorker* worker) {
46 | const char* select_type = NULL;
47 | switch(stage->type) {
48 | case WifiMarauderScriptSelectTypeAp:
49 | select_type = "-a";
50 | break;
51 | case WifiMarauderScriptSelectTypeStation:
52 | select_type = "-c";
53 | break;
54 | case WifiMarauderScriptSelectTypeSsid:
55 | select_type = "-s";
56 | break;
57 | default:
58 | return; // invalid stage
59 | }
60 |
61 | char command[256];
62 | size_t command_length = 0;
63 |
64 | if(stage->indexes != NULL && stage->index_count > 0) {
65 | command_length = snprintf(command, sizeof(command), "select %s ", select_type);
66 |
67 | for(int i = 0; i < stage->index_count; i++) {
68 | int index = stage->indexes[i];
69 | command_length += snprintf(
70 | command + command_length, sizeof(command) - command_length, "%d, ", index);
71 | }
72 |
73 | // Remove the trailing comma and space
74 | command_length -= 2;
75 | command[command_length] = '\n';
76 | command_length++;
77 | } else if(stage->filter == NULL || strcmp(stage->filter, "all") == 0) {
78 | command_length = snprintf(command, sizeof(command), "select %s all\n", select_type);
79 | } else {
80 | command_length = snprintf(
81 | command, sizeof(command), "select %s -f \"%s\"\n", select_type, stage->filter);
82 | }
83 |
84 | wifi_marauder_uart_tx(worker->uart, (uint8_t*)command, command_length);
85 | }
86 |
87 | void _wifi_marauder_script_execute_deauth(
88 | WifiMarauderScriptStageDeauth* stage,
89 | WifiMarauderScriptWorker* worker) {
90 | const char attack_command[] = "attack -t deauth\n";
91 | wifi_marauder_uart_tx(worker->uart, (uint8_t*)(attack_command), strlen(attack_command));
92 | _wifi_marauder_script_delay(worker, stage->timeout);
93 | _send_stop(worker);
94 | }
95 |
96 | void _wifi_marauder_script_execute_probe(
97 | WifiMarauderScriptStageProbe* stage,
98 | WifiMarauderScriptWorker* worker) {
99 | const char attack_command[] = "attack -t probe\n";
100 | wifi_marauder_uart_tx(worker->uart, (uint8_t*)(attack_command), strlen(attack_command));
101 | _wifi_marauder_script_delay(worker, stage->timeout);
102 | _send_stop(worker);
103 | }
104 |
105 | void _wifi_marauder_script_execute_sniff_raw(
106 | WifiMarauderScriptStageSniffRaw* stage,
107 | WifiMarauderScriptWorker* worker) {
108 | const char sniff_command[] = "sniffraw";
109 | wifi_marauder_uart_tx(worker->uart, (uint8_t*)sniff_command, strlen(sniff_command));
110 | if(((WifiMarauderScript*)worker->context)->save_pcap != WifiMarauderScriptBooleanFalse) {
111 | wifi_marauder_uart_tx(worker->uart, (uint8_t*)(" -serial\n"), strlen(" -serial\n"));
112 | } else {
113 | wifi_marauder_uart_tx(worker->uart, (uint8_t*)("\n"), 1);
114 | }
115 | _wifi_marauder_script_delay(worker, stage->timeout);
116 | _send_stop(worker);
117 | }
118 |
119 | void _wifi_marauder_script_execute_sniff_beacon(
120 | WifiMarauderScriptStageSniffBeacon* stage,
121 | WifiMarauderScriptWorker* worker) {
122 | const char sniff_command[] = "sniffbeacon";
123 | wifi_marauder_uart_tx(worker->uart, (uint8_t*)sniff_command, strlen(sniff_command));
124 | if(((WifiMarauderScript*)worker->context)->save_pcap != WifiMarauderScriptBooleanFalse) {
125 | wifi_marauder_uart_tx(worker->uart, (uint8_t*)(" -serial\n"), strlen(" -serial\n"));
126 | } else {
127 | wifi_marauder_uart_tx(worker->uart, (uint8_t*)("\n"), 1);
128 | }
129 | _wifi_marauder_script_delay(worker, stage->timeout);
130 | _send_stop(worker);
131 | }
132 |
133 | void _wifi_marauder_script_execute_sniff_deauth(
134 | WifiMarauderScriptStageSniffDeauth* stage,
135 | WifiMarauderScriptWorker* worker) {
136 | const char sniff_command[] = "sniffdeauth";
137 | wifi_marauder_uart_tx(worker->uart, (uint8_t*)sniff_command, strlen(sniff_command));
138 | if(((WifiMarauderScript*)worker->context)->save_pcap != WifiMarauderScriptBooleanFalse) {
139 | wifi_marauder_uart_tx(worker->uart, (uint8_t*)(" -serial\n"), strlen(" -serial\n"));
140 | } else {
141 | wifi_marauder_uart_tx(worker->uart, (uint8_t*)("\n"), 1);
142 | }
143 | _wifi_marauder_script_delay(worker, stage->timeout);
144 | _send_stop(worker);
145 | }
146 |
147 | void _wifi_marauder_script_execute_sniff_esp(
148 | WifiMarauderScriptStageSniffEsp* stage,
149 | WifiMarauderScriptWorker* worker) {
150 | const char sniff_command[] = "sniffesp";
151 | wifi_marauder_uart_tx(worker->uart, (uint8_t*)sniff_command, strlen(sniff_command));
152 | if(((WifiMarauderScript*)worker->context)->save_pcap != WifiMarauderScriptBooleanFalse) {
153 | wifi_marauder_uart_tx(worker->uart, (uint8_t*)(" -serial\n"), strlen(" -serial\n"));
154 | } else {
155 | wifi_marauder_uart_tx(worker->uart, (uint8_t*)("\n"), 1);
156 | }
157 | _wifi_marauder_script_delay(worker, stage->timeout);
158 | _send_stop(worker);
159 | }
160 |
161 | void _wifi_marauder_script_execute_sniff_pmkid(
162 | WifiMarauderScriptStageSniffPmkid* stage,
163 | WifiMarauderScriptWorker* worker) {
164 | // If channel hopping is enabled, loop through channels 1-11
165 | if(stage->hop_channels) {
166 | for(int i = 1; i <= 11; i++) {
167 | char attack_command[50] = "sniffpmkid";
168 | int len = strlen(attack_command);
169 |
170 | len += snprintf(attack_command + len, sizeof(attack_command) - len, " -c %d", i);
171 | if(stage->force_deauth) {
172 | len += snprintf(attack_command + len, sizeof(attack_command) - len, " -d");
173 | }
174 |
175 | if(((WifiMarauderScript*)worker->context)->save_pcap !=
176 | WifiMarauderScriptBooleanFalse) {
177 | len += snprintf(attack_command + len, sizeof(attack_command) - len, " -serial\n");
178 | } else {
179 | len += snprintf(attack_command + len, sizeof(attack_command) - len, "\n");
180 | }
181 | wifi_marauder_uart_tx(worker->uart, (uint8_t*)attack_command, len);
182 | _wifi_marauder_script_delay(worker, stage->timeout);
183 | _send_stop(worker);
184 | }
185 | } else {
186 | char attack_command[50] = "sniffpmkid";
187 | int len = strlen(attack_command);
188 |
189 | if(stage->channel > 0) {
190 | len += snprintf(
191 | attack_command + len, sizeof(attack_command) - len, " -c %d", stage->channel);
192 | }
193 |
194 | if(stage->force_deauth) {
195 | len += snprintf(attack_command + len, sizeof(attack_command) - len, " -d");
196 | }
197 | if(((WifiMarauderScript*)worker->context)->save_pcap != WifiMarauderScriptBooleanFalse) {
198 | len += snprintf(attack_command + len, sizeof(attack_command) - len, " -serial\n");
199 | } else {
200 | len += snprintf(attack_command + len, sizeof(attack_command) - len, "\n");
201 | }
202 | wifi_marauder_uart_tx(worker->uart, (uint8_t*)attack_command, len);
203 | _wifi_marauder_script_delay(worker, stage->timeout);
204 | _send_stop(worker);
205 | }
206 | }
207 |
208 | void _wifi_marauder_script_execute_sniff_pwn(
209 | WifiMarauderScriptStageSniffPwn* stage,
210 | WifiMarauderScriptWorker* worker) {
211 | const char sniff_command[] = "sniffpwn";
212 | wifi_marauder_uart_tx(worker->uart, (uint8_t*)sniff_command, strlen(sniff_command));
213 | if(((WifiMarauderScript*)worker->context)->save_pcap != WifiMarauderScriptBooleanFalse) {
214 | wifi_marauder_uart_tx(worker->uart, (uint8_t*)(" -serial\n"), strlen(" -serial\n"));
215 | } else {
216 | wifi_marauder_uart_tx(worker->uart, (uint8_t*)("\n"), 1);
217 | }
218 | _wifi_marauder_script_delay(worker, stage->timeout);
219 | _send_stop(worker);
220 | }
221 |
222 | void _wifi_marauder_script_execute_beacon_list(
223 | WifiMarauderScriptStageBeaconList* stage,
224 | WifiMarauderScriptWorker* worker) {
225 | const char clearlist_command[] = "clearlist -s\n";
226 | wifi_marauder_uart_tx(worker->uart, (uint8_t*)(clearlist_command), strlen(clearlist_command));
227 |
228 | char command[100];
229 | char* ssid;
230 |
231 | for(int i = 0; i < stage->ssid_count; i++) {
232 | ssid = stage->ssids[i];
233 | snprintf(command, sizeof(command), "ssid -a -n \"%s\"", ssid);
234 | wifi_marauder_uart_tx(worker->uart, (uint8_t*)(command), strlen(command));
235 | _send_line_break(worker);
236 | }
237 | if(stage->random_ssids > 0) {
238 | char add_random_command[50];
239 | snprintf(
240 | add_random_command,
241 | sizeof(add_random_command),
242 | "ssid -a -r -g %d\n",
243 | stage->random_ssids);
244 | wifi_marauder_uart_tx(
245 | worker->uart, (uint8_t*)add_random_command, strlen(add_random_command));
246 | }
247 | const char attack_command[] = "attack -t beacon -l\n";
248 | wifi_marauder_uart_tx(worker->uart, (uint8_t*)(attack_command), strlen(attack_command));
249 | _wifi_marauder_script_delay(worker, stage->timeout);
250 | _send_stop(worker);
251 | }
252 |
253 | void _wifi_marauder_script_execute_beacon_ap(
254 | WifiMarauderScriptStageBeaconAp* stage,
255 | WifiMarauderScriptWorker* worker) {
256 | const char command[] = "attack -t beacon -a\n";
257 | wifi_marauder_uart_tx(worker->uart, (uint8_t*)command, strlen(command));
258 | _wifi_marauder_script_delay(worker, stage->timeout);
259 | _send_stop(worker);
260 | }
261 |
262 | void _wifi_marauder_script_execute_exec(
263 | WifiMarauderScriptStageExec* stage,
264 | WifiMarauderScriptWorker* worker) {
265 | if(stage->command != NULL) {
266 | wifi_marauder_uart_tx(worker->uart, (uint8_t*)stage->command, strlen(stage->command));
267 | _send_line_break(worker);
268 | }
269 | }
270 |
271 | void _wifi_marauder_script_execute_delay(
272 | WifiMarauderScriptStageDelay* stage,
273 | WifiMarauderScriptWorker* worker) {
274 | _wifi_marauder_script_delay(worker, stage->timeout);
275 | }
276 |
277 | void wifi_marauder_script_execute_start(void* context) {
278 | furi_assert(context);
279 | WifiMarauderScriptWorker* worker = context;
280 | WifiMarauderScript* script = worker->script;
281 | char command[100];
282 |
283 | // Enables or disables the LED according to script settings
284 | if(script->enable_led != WifiMarauderScriptBooleanUndefined) {
285 | snprintf(
286 | command,
287 | sizeof(command),
288 | "settings -s EnableLED %s",
289 | script->enable_led ? "enable" : "disable");
290 | wifi_marauder_uart_tx(worker->uart, (uint8_t*)command, strlen(command));
291 | _send_line_break(worker);
292 | }
293 |
294 | // Enables or disables PCAP saving according to script settings
295 | if(script->save_pcap != WifiMarauderScriptBooleanUndefined) {
296 | snprintf(
297 | command,
298 | sizeof(command),
299 | "settings -s SavePCAP %s",
300 | script->save_pcap ? "enable" : "disable");
301 | wifi_marauder_uart_tx(worker->uart, (uint8_t*)command, strlen(command));
302 | _send_line_break(worker);
303 | }
304 | }
305 |
306 | void wifi_marauder_script_execute_stage(WifiMarauderScriptStage* stage, void* context) {
307 | furi_assert(context);
308 | WifiMarauderScriptWorker* worker = context;
309 | void* stage_data = stage->stage;
310 |
311 | switch(stage->type) {
312 | case WifiMarauderScriptStageTypeScan:
313 | _wifi_marauder_script_execute_scan((WifiMarauderScriptStageScan*)stage_data, worker);
314 | break;
315 | case WifiMarauderScriptStageTypeSelect:
316 | _wifi_marauder_script_execute_select((WifiMarauderScriptStageSelect*)stage_data, worker);
317 | break;
318 | case WifiMarauderScriptStageTypeDeauth:
319 | _wifi_marauder_script_execute_deauth((WifiMarauderScriptStageDeauth*)stage_data, worker);
320 | break;
321 | case WifiMarauderScriptStageTypeProbe:
322 | _wifi_marauder_script_execute_probe((WifiMarauderScriptStageProbe*)stage_data, worker);
323 | break;
324 | case WifiMarauderScriptStageTypeSniffRaw:
325 | _wifi_marauder_script_execute_sniff_raw(
326 | (WifiMarauderScriptStageSniffRaw*)stage_data, worker);
327 | break;
328 | case WifiMarauderScriptStageTypeSniffBeacon:
329 | _wifi_marauder_script_execute_sniff_beacon(
330 | (WifiMarauderScriptStageSniffBeacon*)stage_data, worker);
331 | break;
332 | case WifiMarauderScriptStageTypeSniffDeauth:
333 | _wifi_marauder_script_execute_sniff_deauth(
334 | (WifiMarauderScriptStageSniffDeauth*)stage_data, worker);
335 | break;
336 | case WifiMarauderScriptStageTypeSniffEsp:
337 | _wifi_marauder_script_execute_sniff_esp(
338 | (WifiMarauderScriptStageSniffEsp*)stage_data, worker);
339 | break;
340 | case WifiMarauderScriptStageTypeSniffPmkid:
341 | _wifi_marauder_script_execute_sniff_pmkid(
342 | (WifiMarauderScriptStageSniffPmkid*)stage_data, worker);
343 | break;
344 | case WifiMarauderScriptStageTypeSniffPwn:
345 | _wifi_marauder_script_execute_sniff_pwn(
346 | (WifiMarauderScriptStageSniffPwn*)stage_data, worker);
347 | break;
348 | case WifiMarauderScriptStageTypeBeaconList:
349 | _wifi_marauder_script_execute_beacon_list(
350 | (WifiMarauderScriptStageBeaconList*)stage_data, worker);
351 | break;
352 | case WifiMarauderScriptStageTypeBeaconAp:
353 | _wifi_marauder_script_execute_beacon_ap(
354 | (WifiMarauderScriptStageBeaconAp*)stage_data, worker);
355 | break;
356 | case WifiMarauderScriptStageTypeExec:
357 | _wifi_marauder_script_execute_exec((WifiMarauderScriptStageExec*)stage_data, worker);
358 | break;
359 | case WifiMarauderScriptStageTypeDelay:
360 | _wifi_marauder_script_execute_delay((WifiMarauderScriptStageDelay*)stage_data, worker);
361 | break;
362 | }
363 | }
--------------------------------------------------------------------------------
/script/wifi_marauder_script_executor.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "wifi_marauder_script.h"
4 |
5 | void wifi_marauder_script_execute_start(void* context);
6 | void wifi_marauder_script_execute_stage(WifiMarauderScriptStage* stage, void* context);
7 |
--------------------------------------------------------------------------------
/script/wifi_marauder_script_worker.c:
--------------------------------------------------------------------------------
1 | #include "../wifi_marauder_app_i.h"
2 | #include "wifi_marauder_script_worker.h"
3 |
4 | WifiMarauderScriptWorker* wifi_marauder_script_worker_alloc(WifiMarauderUart* uart) {
5 | WifiMarauderScriptWorker* worker = malloc(sizeof(WifiMarauderScriptWorker));
6 | if(worker == NULL) {
7 | return NULL;
8 | }
9 | worker->callback_start = NULL;
10 | worker->callback_stage = NULL;
11 | worker->worker_thread = NULL;
12 | worker->uart = uart;
13 | worker->is_running = false;
14 | return worker;
15 | }
16 |
17 | int32_t _wifi_marauder_script_worker_task(void* worker) {
18 | WifiMarauderScriptWorker* script_worker = worker;
19 | WifiMarauderScript* script = script_worker->script;
20 | if(script == NULL) {
21 | return WifiMarauderScriptWorkerStatusInvalidScript;
22 | }
23 |
24 | // Setup
25 | script_worker->callback_start(script_worker->context);
26 | if(!script_worker->is_running) {
27 | return WifiMarauderScriptWorkerStatusForceExit;
28 | }
29 |
30 | // Stages
31 | for(int i = 0; i < script->repeat; i++) {
32 | WifiMarauderScriptStage* current_stage = script->first_stage;
33 | while(current_stage != NULL && script_worker->is_running) {
34 | script_worker->callback_stage(current_stage, script_worker->context);
35 | current_stage = current_stage->next_stage;
36 | }
37 | if(!script_worker->is_running) {
38 | return WifiMarauderScriptWorkerStatusForceExit;
39 | }
40 | }
41 |
42 | script_worker->is_running = false;
43 |
44 | return WifiMarauderScriptWorkerStatusSuccess;
45 | }
46 |
47 | bool wifi_marauder_script_worker_start(
48 | WifiMarauderScriptWorker* instance,
49 | WifiMarauderScript* script) {
50 | if(!instance || !script) {
51 | return false;
52 | }
53 | instance->callback_start = wifi_marauder_script_execute_start;
54 | instance->callback_stage = wifi_marauder_script_execute_stage;
55 | instance->script = script;
56 | instance->context = instance;
57 | instance->is_running = true;
58 | instance->worker_thread = furi_thread_alloc_ex(
59 | "WifiMarauderScriptWorker", 1024, _wifi_marauder_script_worker_task, instance);
60 | if(!instance->worker_thread) {
61 | return false;
62 | }
63 | furi_thread_start(instance->worker_thread);
64 | return true;
65 | }
66 |
67 | void wifi_marauder_script_worker_free(WifiMarauderScriptWorker* worker) {
68 | if(worker != NULL) {
69 | if(worker->worker_thread != NULL) {
70 | worker->is_running = false;
71 | furi_thread_join(worker->worker_thread);
72 | furi_thread_free(worker->worker_thread);
73 | }
74 | free(worker);
75 | }
76 | }
--------------------------------------------------------------------------------
/script/wifi_marauder_script_worker.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "wifi_marauder_script.h"
4 |
5 | typedef enum {
6 | WifiMarauderScriptWorkerStatusSuccess = 0,
7 | WifiMarauderScriptWorkerStatusInvalidScript = 1,
8 | WifiMarauderScriptWorkerStatusForceExit = 2
9 | } WifiMarauderScriptWorkerStatus;
10 |
11 | typedef struct WifiMarauderScriptWorker {
12 | WifiMarauderScript* script;
13 | FuriThread* worker_thread;
14 | WifiMarauderUart* uart;
15 | void (*callback_start)(void*);
16 | void (*callback_stage)(WifiMarauderScriptStage*, void*);
17 | void* context;
18 | bool is_running;
19 | } WifiMarauderScriptWorker;
20 |
21 | /**
22 | * @brief Allocates a new instance of WifiMarauderScriptWorker.
23 | *
24 | * @return A pointer to the allocated instance or NULL if allocation fails.
25 | */
26 | WifiMarauderScriptWorker* wifi_marauder_script_worker_alloc();
27 |
28 | /**
29 | * @brief Starts the execution of the worker and sets the callback function to be called after each stage is executed.
30 | *
31 | * @param instance A pointer to the instance of WifiMarauderScriptWorker to start.
32 | * @param script Script to be executed
33 | * @return True if the worker was successfully started, false otherwise.
34 | */
35 | bool wifi_marauder_script_worker_start(
36 | WifiMarauderScriptWorker* instance,
37 | WifiMarauderScript* script);
38 |
39 | /**
40 | * @brief Frees the memory used by the instance of WifiMarauderScriptWorker.
41 | *
42 | * @param script A pointer to the instance of WifiMarauderScriptWorker to free.
43 | */
44 | void wifi_marauder_script_worker_free(WifiMarauderScriptWorker* script);
45 |
--------------------------------------------------------------------------------
/wifi_10px.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/justcallmekoko/flipperzero-wifi-marauder/316258b8c708c1f2a67a2c087aa6d16348ed76f5/wifi_10px.png
--------------------------------------------------------------------------------
/wifi_marauder_app.c:
--------------------------------------------------------------------------------
1 | #include "wifi_marauder_app_i.h"
2 |
3 | #include
4 | #include
5 | #include
6 |
7 | static bool wifi_marauder_app_custom_event_callback(void* context, uint32_t event) {
8 | furi_assert(context);
9 | WifiMarauderApp* app = context;
10 | return scene_manager_handle_custom_event(app->scene_manager, event);
11 | }
12 |
13 | static bool wifi_marauder_app_back_event_callback(void* context) {
14 | furi_assert(context);
15 | WifiMarauderApp* app = context;
16 | return scene_manager_handle_back_event(app->scene_manager);
17 | }
18 |
19 | static void wifi_marauder_app_tick_event_callback(void* context) {
20 | furi_assert(context);
21 | WifiMarauderApp* app = context;
22 | scene_manager_handle_tick_event(app->scene_manager);
23 | }
24 |
25 | WifiMarauderApp* wifi_marauder_app_alloc() {
26 | WifiMarauderApp* app = malloc(sizeof(WifiMarauderApp));
27 |
28 | app->gui = furi_record_open(RECORD_GUI);
29 | app->dialogs = furi_record_open(RECORD_DIALOGS);
30 | app->storage = furi_record_open(RECORD_STORAGE);
31 | app->capture_file = storage_file_alloc(app->storage);
32 | app->log_file = storage_file_alloc(app->storage);
33 | app->save_pcap_setting_file = storage_file_alloc(app->storage);
34 | app->save_logs_setting_file = storage_file_alloc(app->storage);
35 |
36 | app->view_dispatcher = view_dispatcher_alloc();
37 | app->scene_manager = scene_manager_alloc(&wifi_marauder_scene_handlers, app);
38 | view_dispatcher_enable_queue(app->view_dispatcher);
39 | view_dispatcher_set_event_callback_context(app->view_dispatcher, app);
40 |
41 | view_dispatcher_set_custom_event_callback(
42 | app->view_dispatcher, wifi_marauder_app_custom_event_callback);
43 | view_dispatcher_set_navigation_event_callback(
44 | app->view_dispatcher, wifi_marauder_app_back_event_callback);
45 | view_dispatcher_set_tick_event_callback(
46 | app->view_dispatcher, wifi_marauder_app_tick_event_callback, 100);
47 |
48 | view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen);
49 |
50 | app->var_item_list = variable_item_list_alloc();
51 | view_dispatcher_add_view(
52 | app->view_dispatcher,
53 | WifiMarauderAppViewVarItemList,
54 | variable_item_list_get_view(app->var_item_list));
55 |
56 | for(int i = 0; i < NUM_MENU_ITEMS; ++i) {
57 | app->selected_option_index[i] = 0;
58 | }
59 |
60 | app->special_case_input_step = 0;
61 |
62 | app->text_box = text_box_alloc();
63 | view_dispatcher_add_view(
64 | app->view_dispatcher, WifiMarauderAppViewConsoleOutput, text_box_get_view(app->text_box));
65 | app->text_box_store = furi_string_alloc();
66 | furi_string_reserve(app->text_box_store, WIFI_MARAUDER_TEXT_BOX_STORE_SIZE);
67 |
68 | app->text_input = wifi_text_input_alloc();
69 | view_dispatcher_add_view(
70 | app->view_dispatcher,
71 | WifiMarauderAppViewTextInput,
72 | wifi_text_input_get_view(app->text_input));
73 |
74 | app->widget = widget_alloc();
75 | view_dispatcher_add_view(
76 | app->view_dispatcher, WifiMarauderAppViewWidget, widget_get_view(app->widget));
77 |
78 | app->has_saved_logs_this_session = false;
79 |
80 | // if user hasn't confirmed whether to save pcaps and logs to sdcard, then prompt when scene starts
81 | app->need_to_prompt_settings_init =
82 | (!storage_file_exists(app->storage, SAVE_PCAP_SETTING_FILEPATH) ||
83 | !storage_file_exists(app->storage, SAVE_LOGS_SETTING_FILEPATH));
84 |
85 | // Submenu
86 | app->submenu = submenu_alloc();
87 | view_dispatcher_add_view(
88 | app->view_dispatcher, WifiMarauderAppViewSubmenu, submenu_get_view(app->submenu));
89 |
90 | scene_manager_next_scene(app->scene_manager, WifiMarauderSceneStart);
91 |
92 | return app;
93 | }
94 |
95 | void wifi_marauder_make_app_folder(WifiMarauderApp* app) {
96 | furi_assert(app);
97 |
98 | if(!storage_simply_mkdir(app->storage, MARAUDER_APP_FOLDER)) {
99 | dialog_message_show_storage_error(app->dialogs, "Cannot create\napp folder");
100 | }
101 |
102 | if(!storage_simply_mkdir(app->storage, MARAUDER_APP_FOLDER_PCAPS)) {
103 | dialog_message_show_storage_error(app->dialogs, "Cannot create\npcaps folder");
104 | }
105 |
106 | if(!storage_simply_mkdir(app->storage, MARAUDER_APP_FOLDER_DUMPS)) {
107 | dialog_message_show_storage_error(app->dialogs, "Cannot create\ndumps folder");
108 | }
109 |
110 | if(!storage_simply_mkdir(app->storage, MARAUDER_APP_FOLDER_LOGS)) {
111 | dialog_message_show_storage_error(app->dialogs, "Cannot create\nlogs folder");
112 | }
113 |
114 | if(!storage_simply_mkdir(app->storage, MARAUDER_APP_FOLDER_SCRIPTS)) {
115 | dialog_message_show_storage_error(app->dialogs, "Cannot create\nscripts folder");
116 | }
117 |
118 | if(!storage_simply_mkdir(app->storage, MARAUDER_APP_FOLDER_HTML)) {
119 | dialog_message_show_storage_error(app->dialogs, "Cannot create\nhtml folder");
120 | }
121 | }
122 |
123 | void wifi_marauder_load_settings(WifiMarauderApp* app) {
124 | if(storage_file_open(
125 | app->save_pcap_setting_file,
126 | SAVE_PCAP_SETTING_FILEPATH,
127 | FSAM_READ,
128 | FSOM_OPEN_EXISTING)) {
129 | char ok[1];
130 | storage_file_read(app->save_pcap_setting_file, ok, sizeof(ok));
131 | app->ok_to_save_pcaps = ok[0] == 'Y';
132 | }
133 | storage_file_close(app->save_pcap_setting_file);
134 |
135 | if(storage_file_open(
136 | app->save_logs_setting_file,
137 | SAVE_LOGS_SETTING_FILEPATH,
138 | FSAM_READ,
139 | FSOM_OPEN_EXISTING)) {
140 | char ok[1];
141 | storage_file_read(app->save_logs_setting_file, ok, sizeof(ok));
142 | app->ok_to_save_logs = ok[0] == 'Y';
143 | }
144 | storage_file_close(app->save_logs_setting_file);
145 | }
146 |
147 | void wifi_marauder_app_free(WifiMarauderApp* app) {
148 | furi_assert(app);
149 |
150 | // Views
151 | view_dispatcher_remove_view(app->view_dispatcher, WifiMarauderAppViewVarItemList);
152 | view_dispatcher_remove_view(app->view_dispatcher, WifiMarauderAppViewConsoleOutput);
153 | view_dispatcher_remove_view(app->view_dispatcher, WifiMarauderAppViewTextInput);
154 | view_dispatcher_remove_view(app->view_dispatcher, WifiMarauderAppViewWidget);
155 | view_dispatcher_remove_view(app->view_dispatcher, WifiMarauderAppViewSubmenu);
156 |
157 | widget_free(app->widget);
158 | text_box_free(app->text_box);
159 | furi_string_free(app->text_box_store);
160 | wifi_text_input_free(app->text_input);
161 | submenu_free(app->submenu);
162 | variable_item_list_free(app->var_item_list);
163 | storage_file_free(app->capture_file);
164 | storage_file_free(app->log_file);
165 | storage_file_free(app->save_pcap_setting_file);
166 | storage_file_free(app->save_logs_setting_file);
167 |
168 | // View dispatcher
169 | view_dispatcher_free(app->view_dispatcher);
170 | scene_manager_free(app->scene_manager);
171 |
172 | wifi_marauder_uart_free(app->uart);
173 |
174 | // Close records
175 | furi_record_close(RECORD_GUI);
176 | furi_record_close(RECORD_STORAGE);
177 | furi_record_close(RECORD_DIALOGS);
178 |
179 | free(app);
180 | }
181 |
182 | int32_t wifi_marauder_app(void* p) {
183 | UNUSED(p);
184 | // Disable expansion protocol to avoid interference with UART Handle
185 | Expansion* expansion = furi_record_open(RECORD_EXPANSION);
186 | expansion_disable(expansion);
187 |
188 | uint8_t attempts = 0;
189 | bool otg_was_enabled = furi_hal_power_is_otg_enabled();
190 | while(!furi_hal_power_is_otg_enabled() && attempts++ < 5) {
191 | furi_hal_power_enable_otg();
192 | furi_delay_ms(10);
193 | }
194 | furi_delay_ms(200);
195 |
196 | WifiMarauderApp* wifi_marauder_app = wifi_marauder_app_alloc();
197 |
198 | wifi_marauder_make_app_folder(wifi_marauder_app);
199 | wifi_marauder_load_settings(wifi_marauder_app);
200 |
201 | wifi_marauder_app->uart = wifi_marauder_usart_init(wifi_marauder_app);
202 |
203 | view_dispatcher_run(wifi_marauder_app->view_dispatcher);
204 |
205 | wifi_marauder_app_free(wifi_marauder_app);
206 |
207 | if(furi_hal_power_is_otg_enabled() && !otg_was_enabled) {
208 | furi_hal_power_disable_otg();
209 | }
210 |
211 | // Return previous state of expansion
212 | expansion_enable(expansion);
213 | furi_record_close(RECORD_EXPANSION);
214 |
215 | return 0;
216 | }
217 |
--------------------------------------------------------------------------------
/wifi_marauder_app.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #ifdef __cplusplus
4 | extern "C" {
5 | #endif
6 |
7 | #define WIFI_MARAUDER_APP_VERSION "v0.7.2"
8 |
9 | typedef struct WifiMarauderApp WifiMarauderApp;
10 |
11 | #ifdef __cplusplus
12 | }
13 | #endif
14 |
--------------------------------------------------------------------------------
/wifi_marauder_app_i.h:
--------------------------------------------------------------------------------
1 | //** Includes sniffbt and sniffskim for compatible ESP32-WROOM hardware.
2 | // wifi_marauder_scene_start.c also changed **//
3 | #pragma once
4 |
5 | #include "wifi_marauder_app.h"
6 | #include "scenes/wifi_marauder_scene.h"
7 | #include "wifi_marauder_custom_event.h"
8 | #include "wifi_marauder_uart.h"
9 | #include "wifi_marauder_ep.h"
10 | #include "file/sequential_file.h"
11 | #include "script/wifi_marauder_script.h"
12 | #include "script/wifi_marauder_script_worker.h"
13 | #include "script/wifi_marauder_script_executor.h"
14 | #include "script/menu/wifi_marauder_script_stage_menu.h"
15 |
16 | #include
17 | #include
18 | #include
19 | #include
20 | #include
21 | #include
22 | #include
23 | #include "wifi_marauder_text_input.h"
24 |
25 | #include
26 | #include
27 | #include
28 | #include
29 |
30 | #define NUM_MENU_ITEMS (27)
31 |
32 | #define WIFI_MARAUDER_TEXT_BOX_STORE_SIZE (4096)
33 | #define WIFI_MARAUDER_TEXT_INPUT_STORE_SIZE (512)
34 |
35 | #define MARAUDER_APP_FOLDER_USER "apps_data/marauder"
36 | #define MARAUDER_APP_FOLDER EXT_PATH(MARAUDER_APP_FOLDER_USER)
37 | #define MARAUDER_APP_FOLDER_HTML MARAUDER_APP_FOLDER "/html"
38 | #define MARAUDER_APP_FOLDER_PCAPS MARAUDER_APP_FOLDER "/pcaps"
39 | #define MARAUDER_APP_FOLDER_DUMPS MARAUDER_APP_FOLDER "/dumps"
40 | #define MARAUDER_APP_FOLDER_LOGS MARAUDER_APP_FOLDER "/logs"
41 | #define MARAUDER_APP_FOLDER_USER_PCAPS MARAUDER_APP_FOLDER_USER "/pcaps"
42 | #define MARAUDER_APP_FOLDER_USER_LOGS MARAUDER_APP_FOLDER_USER "/logs"
43 | #define MARAUDER_APP_FOLDER_SCRIPTS MARAUDER_APP_FOLDER "/scripts"
44 | #define MARAUDER_APP_SCRIPT_PATH(file_name) MARAUDER_APP_FOLDER_SCRIPTS "/" file_name ".json"
45 | #define SAVE_PCAP_SETTING_FILEPATH MARAUDER_APP_FOLDER "/save_pcaps_here.setting"
46 | #define SAVE_LOGS_SETTING_FILEPATH MARAUDER_APP_FOLDER "/save_logs_here.setting"
47 |
48 | typedef enum WifiMarauderUserInputType {
49 | WifiMarauderUserInputTypeString,
50 | WifiMarauderUserInputTypeNumber,
51 | WifiMarauderUserInputTypeFileName
52 | } WifiMarauderUserInputType;
53 |
54 | struct WifiMarauderApp {
55 | Gui* gui;
56 | ViewDispatcher* view_dispatcher;
57 | SceneManager* scene_manager;
58 |
59 | char text_input_store[WIFI_MARAUDER_TEXT_INPUT_STORE_SIZE + 1];
60 | FuriString* text_box_store;
61 | size_t text_box_store_strlen;
62 | TextBox* text_box;
63 | WIFI_TextInput* text_input;
64 | Storage* storage;
65 | File* capture_file;
66 | File* log_file;
67 | char log_file_path[100];
68 | File* save_pcap_setting_file;
69 | File* save_logs_setting_file;
70 | bool need_to_prompt_settings_init;
71 | int which_prompt;
72 | bool ok_to_save_pcaps;
73 | bool ok_to_save_logs;
74 | bool has_saved_logs_this_session;
75 | DialogsApp* dialogs;
76 |
77 | VariableItemList* var_item_list;
78 | Widget* widget;
79 | Submenu* submenu;
80 | int open_log_file_page;
81 | int open_log_file_num_pages;
82 |
83 | WifiMarauderUart* uart;
84 | int selected_menu_index;
85 | int selected_option_index[NUM_MENU_ITEMS];
86 | const char* selected_tx_string;
87 | bool is_command;
88 | bool is_custom_tx_string;
89 | bool focus_console_start;
90 | bool show_stopscan_tip;
91 | bool is_writing_pcap;
92 | bool is_writing_log;
93 |
94 | // User input
95 | WifiMarauderUserInputType user_input_type;
96 | char** user_input_string_reference;
97 | int* user_input_number_reference;
98 | char* user_input_file_dir;
99 | char* user_input_file_extension;
100 |
101 | // Automation script
102 | WifiMarauderScript* script;
103 | WifiMarauderScriptWorker* script_worker;
104 | FuriString** script_list;
105 | int script_list_count;
106 | WifiMarauderScriptStage* script_edit_selected_stage;
107 | WifiMarauderScriptStageMenu* script_stage_menu;
108 | WifiMarauderScriptStageListItem* script_stage_edit_first_item;
109 | char*** script_stage_edit_strings_reference;
110 | int* script_stage_edit_string_count_reference;
111 | int** script_stage_edit_numbers_reference;
112 | int* script_stage_edit_number_count_reference;
113 |
114 | // For input source and destination MAC in targeted deauth attack
115 | int special_case_input_step;
116 | char special_case_input_src_addr[20];
117 | char special_case_input_dst_addr[20];
118 | };
119 |
120 | // Supported commands:
121 | // https://github.com/justcallmekoko/ESP32Marauder/wiki/cli
122 | // Scan
123 | // -> If list is empty, then start a new scanap. (Tap any button to stop.)
124 | // -> If there's a list, provide option to rescan and dump list of targets to select.
125 | // -> Press BACK to go back to top-level.
126 | // Attack
127 | // -> Beacon
128 | // -> Deauth
129 | // -> Probe
130 | // -> Rickroll
131 | // Sniff
132 | // -> Beacon
133 | // -> Deauth
134 | // -> ESP
135 | // -> PMKID
136 | // -> Pwnagotchi
137 | // Channel
138 | // Update
139 | // Reboot
140 |
141 | typedef enum {
142 | WifiMarauderAppViewVarItemList,
143 | WifiMarauderAppViewConsoleOutput,
144 | WifiMarauderAppViewTextInput,
145 | WifiMarauderAppViewWidget,
146 | WifiMarauderAppViewSubmenu,
147 | } WifiMarauderAppView;
148 |
--------------------------------------------------------------------------------
/wifi_marauder_custom_event.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | typedef enum {
4 | WifiMarauderEventRefreshConsoleOutput = 0,
5 | WifiMarauderEventStartConsole,
6 | WifiMarauderEventStartKeyboard,
7 | WifiMarauderEventSaveSourceMac,
8 | WifiMarauderEventSaveDestinationMac,
9 | WifiMarauderEventStartSettingsInit,
10 | WifiMarauderEventStartLogViewer,
11 | WifiMarauderEventStartScriptSelect,
12 | WifiMarauderEventStartSniffPmkidOptions,
13 | WifiMarauderEventPrevScene
14 | } WifiMarauderCustomEvent;
15 |
--------------------------------------------------------------------------------
/wifi_marauder_ep.c:
--------------------------------------------------------------------------------
1 | #include "wifi_marauder_ep.h"
2 |
3 | // returns success (if true, then caller needs to free(the_html))
4 | bool wifi_marauder_ep_read_html_file(WifiMarauderApp* app, uint8_t** the_html, size_t* html_size) {
5 | // browse for files
6 | FuriString* predefined_filepath = furi_string_alloc_set_str(MARAUDER_APP_FOLDER_HTML);
7 | FuriString* selected_filepath = furi_string_alloc();
8 | DialogsFileBrowserOptions browser_options;
9 | dialog_file_browser_set_basic_options(&browser_options, ".html", &I_Text_10x10);
10 | if(!dialog_file_browser_show(
11 | app->dialogs, selected_filepath, predefined_filepath, &browser_options)) {
12 | return false;
13 | }
14 |
15 | File* index_html = storage_file_alloc(app->storage);
16 | if(!storage_file_open(
17 | index_html, furi_string_get_cstr(selected_filepath), FSAM_READ, FSOM_OPEN_EXISTING)) {
18 | dialog_message_show_storage_error(app->dialogs, "Cannot open file");
19 | return false;
20 | }
21 |
22 | uint64_t size = storage_file_size(index_html);
23 |
24 | *the_html = malloc(size); // to be freed by caller
25 | uint8_t* buf_ptr = *the_html;
26 | size_t read = 0;
27 | while(read < size) {
28 | size_t to_read = size - read;
29 | if(to_read > UINT16_MAX) to_read = UINT16_MAX;
30 | uint16_t now_read = storage_file_read(index_html, buf_ptr, (uint16_t)to_read);
31 | read += now_read;
32 | buf_ptr += now_read;
33 | }
34 |
35 | *html_size = read;
36 |
37 | storage_file_close(index_html);
38 | storage_file_free(index_html);
39 |
40 | furi_string_free(selected_filepath);
41 | furi_string_free(predefined_filepath);
42 |
43 | return true;
44 | }
--------------------------------------------------------------------------------
/wifi_marauder_ep.h:
--------------------------------------------------------------------------------
1 | // evil portal helper
2 | #pragma once
3 |
4 | #include "wifi_marauder_app_i.h"
5 |
6 | bool wifi_marauder_ep_read_html_file(WifiMarauderApp* app, uint8_t** the_html, size_t* html_size);
--------------------------------------------------------------------------------
/wifi_marauder_text_input.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include "wifi_marauder_validators.h"
5 |
6 | #ifdef __cplusplus
7 | extern "C" {
8 | #endif
9 |
10 | /** Text input anonymous structure */
11 | typedef struct WIFI_TextInput WIFI_TextInput;
12 | typedef void (*WIFI_TextInputCallback)(void* context);
13 | typedef bool (*WIFI_TextInputValidatorCallback)(const char* text, FuriString* error, void* context);
14 |
15 | /** Allocate and initialize text input
16 | *
17 | * This text input is used to enter string
18 | *
19 | * @return WIFI_TextInput instance
20 | */
21 | WIFI_TextInput* wifi_text_input_alloc();
22 |
23 | /** Deinitialize and free text input
24 | *
25 | * @param text_input WIFI_TextInput instance
26 | */
27 | void wifi_text_input_free(WIFI_TextInput* text_input);
28 |
29 | /** Clean text input view Note: this function does not free memory
30 | *
31 | * @param text_input Text input instance
32 | */
33 | void wifi_text_input_reset(WIFI_TextInput* text_input);
34 |
35 | /** Get text input view
36 | *
37 | * @param text_input WIFI_TextInput instance
38 | *
39 | * @return View instance that can be used for embedding
40 | */
41 | View* wifi_text_input_get_view(WIFI_TextInput* text_input);
42 |
43 | /** Set text input result callback
44 | *
45 | * @param text_input WIFI_TextInput instance
46 | * @param callback callback fn
47 | * @param callback_context callback context
48 | * @param text_buffer pointer to YOUR text buffer, that we going
49 | * to modify
50 | * @param text_buffer_size YOUR text buffer size in bytes. Max string
51 | * length will be text_buffer_size-1.
52 | * @param clear_default_text clear text from text_buffer on first OK
53 | * event
54 | */
55 | void wifi_text_input_set_result_callback(
56 | WIFI_TextInput* text_input,
57 | WIFI_TextInputCallback callback,
58 | void* callback_context,
59 | char* text_buffer,
60 | size_t text_buffer_size,
61 | bool clear_default_text);
62 |
63 | void wifi_text_input_set_validator(
64 | WIFI_TextInput* text_input,
65 | WIFI_TextInputValidatorCallback callback,
66 | void* callback_context);
67 |
68 | void wifi_text_input_set_minimum_length(WIFI_TextInput* text_input, size_t minimum_length);
69 |
70 | WIFI_TextInputValidatorCallback wifi_text_input_get_validator_callback(WIFI_TextInput* text_input);
71 |
72 | void* wifi_text_input_get_validator_callback_context(WIFI_TextInput* text_input);
73 |
74 | /** Set text input header text
75 | *
76 | * @param text_input WIFI_TextInput instance
77 | * @param text text to be shown
78 | */
79 | void wifi_text_input_set_header_text(WIFI_TextInput* text_input, const char* text);
80 |
81 | #ifdef __cplusplus
82 | }
83 | #endif
--------------------------------------------------------------------------------
/wifi_marauder_uart.c:
--------------------------------------------------------------------------------
1 | #include "wifi_marauder_app_i.h"
2 | #include "wifi_marauder_uart.h"
3 |
4 | #define UART_CH (FuriHalSerialIdUsart)
5 | #define BAUDRATE (115200)
6 |
7 | struct WifiMarauderUart {
8 | WifiMarauderApp* app;
9 | FuriThread* rx_thread;
10 | FuriStreamBuffer* rx_stream;
11 | FuriStreamBuffer* pcap_stream;
12 | FuriHalSerialHandle* serial_handle;
13 | bool pcap;
14 | uint8_t mark_test_buf[11];
15 | uint8_t mark_test_idx;
16 | uint8_t rx_buf[RX_BUF_SIZE + 1];
17 | void (*handle_rx_data_cb)(uint8_t* buf, size_t len, void* context);
18 | void (*handle_rx_pcap_cb)(uint8_t* buf, size_t len, void* context);
19 | };
20 |
21 | typedef enum {
22 | WorkerEvtStop = (1 << 0),
23 | WorkerEvtRxDone = (1 << 1),
24 | WorkerEvtPcapDone = (1 << 2),
25 | } WorkerEvtFlags;
26 |
27 | void wifi_marauder_uart_set_handle_rx_data_cb(
28 | WifiMarauderUart* uart,
29 | void (*handle_rx_data_cb)(uint8_t* buf, size_t len, void* context)) {
30 | furi_assert(uart);
31 | uart->handle_rx_data_cb = handle_rx_data_cb;
32 | }
33 |
34 | void wifi_marauder_uart_set_handle_rx_pcap_cb(
35 | WifiMarauderUart* uart,
36 | void (*handle_rx_pcap_cb)(uint8_t* buf, size_t len, void* context)) {
37 | furi_assert(uart);
38 | uart->handle_rx_pcap_cb = handle_rx_pcap_cb;
39 | }
40 |
41 | #define WORKER_ALL_RX_EVENTS (WorkerEvtStop | WorkerEvtRxDone | WorkerEvtPcapDone)
42 |
43 | void wifi_marauder_uart_on_irq_cb(
44 | FuriHalSerialHandle* handle,
45 | FuriHalSerialRxEvent event,
46 | void* context) {
47 | WifiMarauderUart* uart = (WifiMarauderUart*)context;
48 |
49 | if(event == FuriHalSerialRxEventData) {
50 | uint8_t data = furi_hal_serial_async_rx(handle);
51 | const char* mark_begin = "[BUF/BEGIN]";
52 | const char* mark_close = "[BUF/CLOSE]";
53 | if(uart->mark_test_idx != 0) {
54 | // We are trying to match a marker
55 | if(data == mark_begin[uart->mark_test_idx] ||
56 | data == mark_close[uart->mark_test_idx]) {
57 | // Received char matches next char in a marker, append to test buffer
58 | uart->mark_test_buf[uart->mark_test_idx++] = data;
59 | if(uart->mark_test_idx == sizeof(uart->mark_test_buf)) {
60 | // Test buffer reached max length, parse what marker this is and discard buffer
61 | if(!memcmp(
62 | uart->mark_test_buf, (void*)mark_begin, sizeof(uart->mark_test_buf))) {
63 | uart->pcap = true;
64 | } else if(!memcmp(
65 | uart->mark_test_buf,
66 | (void*)mark_close,
67 | sizeof(uart->mark_test_buf))) {
68 | uart->pcap = false;
69 | }
70 | uart->mark_test_idx = 0;
71 | }
72 | // Don't pass to stream
73 | return;
74 | } else {
75 | // Received char doesn't match any expected next char, send current test buffer
76 | if(uart->pcap) {
77 | furi_stream_buffer_send(
78 | uart->pcap_stream, uart->mark_test_buf, uart->mark_test_idx, 0);
79 | furi_thread_flags_set(furi_thread_get_id(uart->rx_thread), WorkerEvtPcapDone);
80 | } else {
81 | furi_stream_buffer_send(
82 | uart->rx_stream, uart->mark_test_buf, uart->mark_test_idx, 0);
83 | furi_thread_flags_set(furi_thread_get_id(uart->rx_thread), WorkerEvtRxDone);
84 | }
85 | // Reset test buffer and try parsing this char from scratch
86 | uart->mark_test_idx = 0;
87 | }
88 | }
89 | // If we reach here the buffer is empty
90 | if(data == mark_begin[0]) {
91 | // Received marker start, append to test buffer
92 | uart->mark_test_buf[uart->mark_test_idx++] = data;
93 | } else {
94 | // Not a marker start and we aren't matching a marker, this is just data
95 | if(uart->pcap) {
96 | furi_stream_buffer_send(uart->pcap_stream, &data, 1, 0);
97 | furi_thread_flags_set(furi_thread_get_id(uart->rx_thread), WorkerEvtPcapDone);
98 | } else {
99 | furi_stream_buffer_send(uart->rx_stream, &data, 1, 0);
100 | furi_thread_flags_set(furi_thread_get_id(uart->rx_thread), WorkerEvtRxDone);
101 | }
102 | }
103 | }
104 | }
105 |
106 | static int32_t uart_worker(void* context) {
107 | WifiMarauderUart* uart = (void*)context;
108 |
109 | while(1) {
110 | uint32_t events =
111 | furi_thread_flags_wait(WORKER_ALL_RX_EVENTS, FuriFlagWaitAny, FuriWaitForever);
112 | furi_check((events & FuriFlagError) == 0);
113 | if(events & WorkerEvtStop) break;
114 | if(events & WorkerEvtRxDone) {
115 | size_t len = furi_stream_buffer_receive(uart->rx_stream, uart->rx_buf, RX_BUF_SIZE, 0);
116 | if(len > 0) {
117 | if(uart->handle_rx_data_cb) uart->handle_rx_data_cb(uart->rx_buf, len, uart->app);
118 | }
119 | }
120 | if(events & WorkerEvtPcapDone) {
121 | size_t len =
122 | furi_stream_buffer_receive(uart->pcap_stream, uart->rx_buf, RX_BUF_SIZE, 0);
123 | if(len > 0) {
124 | if(uart->handle_rx_pcap_cb) uart->handle_rx_pcap_cb(uart->rx_buf, len, uart->app);
125 | }
126 | }
127 | }
128 |
129 | furi_stream_buffer_free(uart->rx_stream);
130 | furi_stream_buffer_free(uart->pcap_stream);
131 |
132 | return 0;
133 | }
134 |
135 | void wifi_marauder_uart_tx(WifiMarauderUart* uart, uint8_t* data, size_t len) {
136 | furi_hal_serial_tx(uart->serial_handle, data, len);
137 | }
138 |
139 | WifiMarauderUart* wifi_marauder_uart_init(
140 | WifiMarauderApp* app,
141 | FuriHalSerialId channel,
142 | const char* thread_name) {
143 | WifiMarauderUart* uart = malloc(sizeof(WifiMarauderUart));
144 |
145 | uart->app = app;
146 | uart->rx_stream = furi_stream_buffer_alloc(RX_BUF_SIZE, 1);
147 | uart->pcap_stream = furi_stream_buffer_alloc(RX_BUF_SIZE, 1);
148 | uart->rx_thread = furi_thread_alloc();
149 | furi_thread_set_name(uart->rx_thread, thread_name);
150 | furi_thread_set_stack_size(uart->rx_thread, 1024);
151 | furi_thread_set_context(uart->rx_thread, uart);
152 | furi_thread_set_callback(uart->rx_thread, uart_worker);
153 | furi_thread_start(uart->rx_thread);
154 | uart->serial_handle = furi_hal_serial_control_acquire(channel);
155 | furi_check(uart->serial_handle);
156 | furi_hal_serial_init(uart->serial_handle, BAUDRATE);
157 | furi_hal_serial_async_rx_start(uart->serial_handle, wifi_marauder_uart_on_irq_cb, uart, false);
158 |
159 | return uart;
160 | }
161 |
162 | WifiMarauderUart* wifi_marauder_usart_init(WifiMarauderApp* app) {
163 | return wifi_marauder_uart_init(app, UART_CH, "WifiMarauderUartRxThread");
164 | }
165 |
166 | void wifi_marauder_uart_free(WifiMarauderUart* uart) {
167 | furi_assert(uart);
168 |
169 | furi_thread_flags_set(furi_thread_get_id(uart->rx_thread), WorkerEvtStop);
170 | furi_thread_join(uart->rx_thread);
171 | furi_thread_free(uart->rx_thread);
172 |
173 | furi_hal_serial_deinit(uart->serial_handle);
174 | furi_hal_serial_control_release(uart->serial_handle);
175 |
176 | free(uart);
177 | }
178 |
--------------------------------------------------------------------------------
/wifi_marauder_uart.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "furi_hal.h"
4 |
5 | #define RX_BUF_SIZE (2048)
6 |
7 | typedef struct WifiMarauderUart WifiMarauderUart;
8 |
9 | void wifi_marauder_uart_set_handle_rx_data_cb(
10 | WifiMarauderUart* uart,
11 | void (*handle_rx_data_cb)(uint8_t* buf, size_t len, void* context));
12 | void wifi_marauder_uart_set_handle_rx_pcap_cb(
13 | WifiMarauderUart* uart,
14 | void (*handle_rx_pcap_cb)(uint8_t* buf, size_t len, void* context));
15 | void wifi_marauder_uart_tx(WifiMarauderUart* uart, uint8_t* data, size_t len);
16 | WifiMarauderUart* wifi_marauder_usart_init(WifiMarauderApp* app);
17 | void wifi_marauder_uart_free(WifiMarauderUart* uart);
18 |
--------------------------------------------------------------------------------
/wifi_marauder_validators.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include "wifi_marauder_validators.h"
3 | #include
4 |
5 | struct ValidatorIsFile {
6 | char* app_path_folder;
7 | const char* app_extension;
8 | char* current_name;
9 | };
10 |
11 | bool validator_is_file_callback(const char* text, FuriString* error, void* context) {
12 | furi_assert(context);
13 | ValidatorIsFile* instance = context;
14 |
15 | if(instance->current_name != NULL) {
16 | if(strcmp(instance->current_name, text) == 0) {
17 | return true;
18 | }
19 | }
20 |
21 | bool ret = true;
22 | FuriString* path = furi_string_alloc_printf(
23 | "%s/%s%s", instance->app_path_folder, text, instance->app_extension);
24 | Storage* storage = furi_record_open(RECORD_STORAGE);
25 | if(storage_common_stat(storage, furi_string_get_cstr(path), NULL) == FSE_OK) {
26 | ret = false;
27 | furi_string_printf(error, "This name\nexists!\nChoose\nanother one.");
28 | } else {
29 | ret = true;
30 | }
31 | furi_string_free(path);
32 | furi_record_close(RECORD_STORAGE);
33 |
34 | return ret;
35 | }
36 |
37 | ValidatorIsFile* validator_is_file_alloc_init(
38 | const char* app_path_folder,
39 | const char* app_extension,
40 | const char* current_name) {
41 | ValidatorIsFile* instance = malloc(sizeof(ValidatorIsFile));
42 |
43 | instance->app_path_folder = strdup(app_path_folder);
44 | instance->app_extension = app_extension;
45 | if(current_name != NULL) {
46 | instance->current_name = strdup(current_name);
47 | }
48 |
49 | return instance;
50 | }
51 |
52 | void validator_is_file_free(ValidatorIsFile* instance) {
53 | furi_assert(instance);
54 | free(instance->app_path_folder);
55 | free(instance->current_name);
56 | free(instance);
57 | }
58 |
--------------------------------------------------------------------------------
/wifi_marauder_validators.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
5 | #ifdef __cplusplus
6 | extern "C" {
7 | #endif
8 | typedef struct ValidatorIsFile ValidatorIsFile;
9 |
10 | ValidatorIsFile* validator_is_file_alloc_init(
11 | const char* app_path_folder,
12 | const char* app_extension,
13 | const char* current_name);
14 |
15 | void validator_is_file_free(ValidatorIsFile* instance);
16 |
17 | bool validator_is_file_callback(const char* text, FuriString* error, void* context);
18 |
19 | #ifdef __cplusplus
20 | }
21 | #endif
22 |
--------------------------------------------------------------------------------