From 6f77f537e337642b2c4bb9dfe73f0d72d97ada9c Mon Sep 17 00:00:00 2001 From: Ganapati Date: Sun, 4 Sep 2022 23:32:58 +0200 Subject: [PATCH 1/2] Fi memory issues ad add new attack --- applications/flipfrid/README.md | 21 +++++ applications/flipfrid/flipfrid.c | 16 ++++ applications/flipfrid/flipfrid.h | 15 +++- .../scene/flipfrid_scene_entrypoint.c | 22 ++++-- .../scene/flipfrid_scene_load_custom_uids.c | 77 +++++++++++++++++++ .../scene/flipfrid_scene_load_custom_uids.h | 9 +++ .../flipfrid/scene/flipfrid_scene_load_file.c | 2 + .../scene/flipfrid_scene_run_attack.c | 42 ++++++++-- 8 files changed, 192 insertions(+), 12 deletions(-) create mode 100644 applications/flipfrid/README.md create mode 100644 applications/flipfrid/scene/flipfrid_scene_load_custom_uids.c create mode 100644 applications/flipfrid/scene/flipfrid_scene_load_custom_uids.h diff --git a/applications/flipfrid/README.md b/applications/flipfrid/README.md new file mode 100644 index 00000000000..51ed2fa6703 --- /dev/null +++ b/applications/flipfrid/README.md @@ -0,0 +1,21 @@ +# Flipfrid + +Basic EM4100 Fuzzer + +## Why + +Flipfrid is a simple Rfid fuzzer using EM4100 protocol (125khz). +Objective is to provide a simple to use fuzzer to test readers by emulating various cards. + +EM4100 cards use a 1 byte customer id and 4 bytes card id. + +## How + +There is 4 modes : +- Default key loop over 16 factory/default keys and emulate each one after one ; +- BF customer id. just an iteration from 0X00 to 0XFF on the first byte ; +- Load Dump file : Load an existing EM4100 dump generated by Flipperzero, select an index and bruteforce from 0X00 to 0XFF; +- Uids list: loop over a text file (one uid per line) + +TODO : +- blank screen on back press diff --git a/applications/flipfrid/flipfrid.c b/applications/flipfrid/flipfrid.c index 475ed453f57..f5f1ad3cbca 100644 --- a/applications/flipfrid/flipfrid.c +++ b/applications/flipfrid/flipfrid.c @@ -4,6 +4,7 @@ #include "scene/flipfrid_scene_load_file.h" #include "scene/flipfrid_scene_select_field.h" #include "scene/flipfrid_scene_run_attack.h" +#include "scene/flipfrid_scene_load_custom_uids.h" static void flipfrid_draw_callback(Canvas* const canvas, void* ctx) { FlipFridState* flipfrid_state = (FlipFridState*)acquire_mutex((ValueMutex*)ctx, 100); @@ -27,6 +28,9 @@ static void flipfrid_draw_callback(Canvas* const canvas, void* ctx) { case SceneAttack: flipfrid_scene_run_attack_on_draw(canvas, flipfrid_state); break; + case SceneLoadCustomUids: + flipfrid_scene_load_custom_uids_on_draw(canvas, flipfrid_state); + break; } release_mutex((ValueMutex*)ctx, flipfrid_state); @@ -159,6 +163,9 @@ int32_t flipfrid_start(void* p) { case SceneAttack: flipfrid_scene_run_attack_on_event(event, flipfrid_state); break; + case SceneLoadCustomUids: + flipfrid_scene_load_custom_uids_on_event(event, flipfrid_state); + break; } } else if(event.evt_type == EventTypeTick) { @@ -178,6 +185,9 @@ int32_t flipfrid_start(void* p) { case SceneAttack: flipfrid_scene_run_attack_on_exit(flipfrid_state); break; + case SceneLoadCustomUids: + flipfrid_scene_load_custom_uids_on_exit(flipfrid_state); + break; case NoneScene: break; } @@ -197,6 +207,9 @@ int32_t flipfrid_start(void* p) { case SceneAttack: flipfrid_scene_run_attack_on_enter(flipfrid_state); break; + case SceneLoadCustomUids: + flipfrid_scene_load_custom_uids_on_enter(flipfrid_state); + break; } flipfrid_state->previous_scene = flipfrid_state->current_scene; } @@ -216,6 +229,9 @@ int32_t flipfrid_start(void* p) { case SceneAttack: flipfrid_scene_run_attack_on_tick(flipfrid_state); break; + case SceneLoadCustomUids: + flipfrid_scene_load_custom_uids_on_tick(flipfrid_state); + break; } view_port_update(view_port); } diff --git a/applications/flipfrid/flipfrid.h b/applications/flipfrid/flipfrid.h index e1c49e71617..21b9f989eee 100644 --- a/applications/flipfrid/flipfrid.h +++ b/applications/flipfrid/flipfrid.h @@ -11,6 +11,11 @@ #include #include +#include +#include +#include +#include + #include #include @@ -19,7 +24,8 @@ typedef enum { FlipFridAttackDefaultValues, FlipFridAttackBfCustomerId, - FlipFridAttackLoadFile + FlipFridAttackLoadFile, + FlipFridAttackLoadFileCustomUids, } FlipFridAttacks; typedef enum { @@ -27,7 +33,8 @@ typedef enum { SceneEntryPoint, SceneSelectFile, SceneSelectField, - SceneAttack + SceneAttack, + SceneLoadCustomUids, } FlipFridScene; typedef enum { @@ -64,4 +71,8 @@ typedef struct { uint8_t key_index; LFRFIDWorker* worker; ProtocolDict* dict; + ProtocolId protocol; + + // Used for custom dictionnary + Stream* uids_stream; } FlipFridState; \ No newline at end of file diff --git a/applications/flipfrid/scene/flipfrid_scene_entrypoint.c b/applications/flipfrid/scene/flipfrid_scene_entrypoint.c index 3d5d0c55ff6..f30bb8e1de6 100644 --- a/applications/flipfrid/scene/flipfrid_scene_entrypoint.c +++ b/applications/flipfrid/scene/flipfrid_scene_entrypoint.c @@ -3,7 +3,6 @@ string_t menu_items[4]; void flipfrid_scene_entrypoint_menu_callback(FlipFridState* context, uint32_t index) { - FURI_LOG_D(TAG, "MENU: %d", index); switch(index) { case FlipFridAttackDefaultValues: context->attack = FlipFridAttackDefaultValues; @@ -20,25 +19,38 @@ void flipfrid_scene_entrypoint_menu_callback(FlipFridState* context, uint32_t in context->current_scene = SceneSelectFile; string_set_str(context->attack_name, "Load File"); break; + case FlipFridAttackLoadFileCustomUids: + context->attack = FlipFridAttackLoadFileCustomUids; + context->current_scene = SceneLoadCustomUids; + string_set_str(context->attack_name, "Load Custom UIDs"); + break; default: break; } } void flipfrid_scene_entrypoint_on_enter(FlipFridState* context) { + // Clear the previous payload + context->payload[0] = 0x00; + context->payload[1] = 0x00; + context->payload[2] = 0x00; + context->payload[3] = 0x00; + context->payload[4] = 0x00; + context->menu_index = 0; - for(uint32_t i = 0; i < 3; i++) { + for(uint32_t i = 0; i < 4; i++) { string_init(menu_items[i]); } string_set(menu_items[0], "Default Values"); string_set(menu_items[1], "BF Customer ID"); string_set(menu_items[2], "Load File"); + string_set(menu_items[3], "Load uids from file"); } void flipfrid_scene_entrypoint_on_exit(FlipFridState* context) { UNUSED(context); - for(uint32_t i = 0; i < 3; i++) { + for(uint32_t i = 0; i < 4; i++) { string_clear(menu_items[i]); } } @@ -52,7 +64,7 @@ void flipfrid_scene_entrypoint_on_event(FlipFridEvent event, FlipFridState* cont if(event.input_type == InputTypeShort) { switch(event.key) { case InputKeyDown: - if(context->menu_index < FlipFridAttackLoadFile) { + if(context->menu_index < FlipFridAttackLoadFileCustomUids) { context->menu_index++; } break; @@ -98,7 +110,7 @@ void flipfrid_scene_entrypoint_on_draw(Canvas* canvas, FlipFridState* context) { canvas_draw_str_aligned( canvas, 64, 36, AlignCenter, AlignTop, string_get_cstr(menu_items[context->menu_index])); - if(context->menu_index < FlipFridAttackLoadFile) { + if(context->menu_index < FlipFridAttackLoadFileCustomUids) { canvas_set_font(canvas, FontSecondary); canvas_draw_str_aligned( canvas, diff --git a/applications/flipfrid/scene/flipfrid_scene_load_custom_uids.c b/applications/flipfrid/scene/flipfrid_scene_load_custom_uids.c new file mode 100644 index 00000000000..94f36b3cc10 --- /dev/null +++ b/applications/flipfrid/scene/flipfrid_scene_load_custom_uids.c @@ -0,0 +1,77 @@ +#include "flipfrid_scene_load_custom_uids.h" +#include "flipfrid_scene_run_attack.h" +#include "flipfrid_scene_entrypoint.h" + +#define LFRFID_UIDS_EXTENSION ".txt" + +bool flipfrid_load_uids(FlipFridState* context, const char* file_path) { + bool result = false; + Storage* storage = furi_record_open(RECORD_STORAGE); + context->uids_stream = buffered_file_stream_alloc(storage); + result = + buffered_file_stream_open(context->uids_stream, file_path, FSAM_READ, FSOM_OPEN_EXISTING); + // Close if loading fails + if(!result) { + buffered_file_stream_close(context->uids_stream); + return false; + } + return result; +} + +bool flipfrid_load_custom_uids_from_file(FlipFridState* context) { + // Input events and views are managed by file_select + bool res = dialog_file_browser_show( + context->dialogs, + context->file_path, + context->file_path, + LFRFID_UIDS_EXTENSION, + true, + &I_sub1_10px, + true); + + if(res) { + res = flipfrid_load_uids(context, string_get_cstr(context->file_path)); + } + return res; +} + +void flipfrid_scene_load_custom_uids_on_enter(FlipFridState* context) { + if(flipfrid_load_custom_uids_from_file(context)) { + // Force context loading + flipfrid_scene_run_attack_on_enter(context); + context->current_scene = SceneAttack; + } else { + flipfrid_scene_entrypoint_on_enter(context); + context->current_scene = SceneEntryPoint; + } +} + +void flipfrid_scene_load_custom_uids_on_exit(FlipFridState* context) { + UNUSED(context); +} + +void flipfrid_scene_load_custom_uids_on_tick(FlipFridState* context) { + UNUSED(context); +} + +void flipfrid_scene_load_custom_uids_on_event(FlipFridEvent event, FlipFridState* context) { + if(event.evt_type == EventTypeKey) { + if(event.input_type == InputTypeShort) { + switch(event.key) { + case InputKeyDown: + case InputKeyUp: + case InputKeyLeft: + case InputKeyRight: + case InputKeyOk: + case InputKeyBack: + context->current_scene = SceneEntryPoint; + break; + } + } + } +} + +void flipfrid_scene_load_custom_uids_on_draw(Canvas* canvas, FlipFridState* context) { + UNUSED(context); + UNUSED(canvas); +} diff --git a/applications/flipfrid/scene/flipfrid_scene_load_custom_uids.h b/applications/flipfrid/scene/flipfrid_scene_load_custom_uids.h new file mode 100644 index 00000000000..a8ed982b68a --- /dev/null +++ b/applications/flipfrid/scene/flipfrid_scene_load_custom_uids.h @@ -0,0 +1,9 @@ +#pragma once +#include "../flipfrid.h" + +void flipfrid_scene_load_custom_uids_on_enter(FlipFridState* context); +void flipfrid_scene_load_custom_uids_on_exit(FlipFridState* context); +void flipfrid_scene_load_custom_uids_on_tick(FlipFridState* context); +void flipfrid_scene_load_custom_uids_on_event(FlipFridEvent event, FlipFridState* context); +void flipfrid_scene_load_custom_uids_on_draw(Canvas* canvas, FlipFridState* context); +bool flipfrid_load_custom_uids_from_file(FlipFridState* context); \ No newline at end of file diff --git a/applications/flipfrid/scene/flipfrid_scene_load_file.c b/applications/flipfrid/scene/flipfrid_scene_load_file.c index 939907ac775..357f6fb1641 100644 --- a/applications/flipfrid/scene/flipfrid_scene_load_file.c +++ b/applications/flipfrid/scene/flipfrid_scene_load_file.c @@ -1,4 +1,5 @@ #include "flipfrid_scene_load_file.h" +#include "flipfrid_scene_entrypoint.h" #define LFRFID_APP_EXTENSION ".rfid" @@ -84,6 +85,7 @@ void flipfrid_scene_load_file_on_enter(FlipFridState* context) { if(flipfrid_load_protocol_from_file(context)) { context->current_scene = SceneSelectField; } else { + flipfrid_scene_entrypoint_on_enter(context); context->current_scene = SceneEntryPoint; } } diff --git a/applications/flipfrid/scene/flipfrid_scene_run_attack.c b/applications/flipfrid/scene/flipfrid_scene_run_attack.c index 9ff311cdcaf..e7256eccabc 100644 --- a/applications/flipfrid/scene/flipfrid_scene_run_attack.c +++ b/applications/flipfrid/scene/flipfrid_scene_run_attack.c @@ -1,7 +1,7 @@ #include "flipfrid_scene_run_attack.h" uint8_t counter = 0; -#define TIME_BETWEEN_CARDS 5 +#define TIME_BETWEEN_CARDS 1 uint8_t id_list[16][5] = { {0x00, 0x00, 0x00, 0x00, 0x00}, // Null bytes {0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, // Only FF @@ -25,6 +25,7 @@ void flipfrid_scene_run_attack_on_enter(FlipFridState* context) { context->attack_step = 0; context->dict = protocol_dict_alloc(lfrfid_protocols, LFRFIDProtocolMax); context->worker = lfrfid_worker_alloc(context->dict); + context->protocol = protocol_dict_get_protocol_by_name(context->dict, "EM4100"); } void flipfrid_scene_run_attack_on_exit(FlipFridState* context) { @@ -36,14 +37,13 @@ void flipfrid_scene_run_attack_on_exit(FlipFridState* context) { } void flipfrid_scene_run_attack_on_tick(FlipFridState* context) { - ProtocolId protocol; - protocol = protocol_dict_get_protocol_by_name(context->dict, "EM4100"); if(context->is_attacking) { if(1 == counter) { - protocol_dict_set_data(context->dict, protocol, context->payload, 5); + protocol_dict_set_data(context->dict, context->protocol, context->payload, 5); + lfrfid_worker_free(context->worker); context->worker = lfrfid_worker_alloc(context->dict); lfrfid_worker_start_thread(context->worker); - lfrfid_worker_emulate_start(context->worker, protocol); + lfrfid_worker_emulate_start(context->worker, context->protocol); } else if(0 == counter) { lfrfid_worker_stop(context->worker); lfrfid_worker_stop_thread(context->worker); @@ -61,6 +61,7 @@ void flipfrid_scene_run_attack_on_tick(FlipFridState* context) { context->is_attacking = false; notification_message(context->notify, &sequence_blink_stop); notification_message(context->notify, &sequence_single_vibro); + } else { context->attack_step++; } @@ -98,10 +99,37 @@ void flipfrid_scene_run_attack_on_tick(FlipFridState* context) { context->is_attacking = false; notification_message(context->notify, &sequence_blink_stop); notification_message(context->notify, &sequence_single_vibro); + break; } else { context->attack_step++; } break; + case FlipFridAttackLoadFileCustomUids: + while(true) { + string_reset(context->data_str); + if(!stream_read_line(context->uids_stream, context->data_str)) { + context->attack_step = 0; + counter = 0; + context->is_attacking = false; + notification_message(context->notify, &sequence_blink_stop); + notification_message(context->notify, &sequence_single_vibro); + break; + }; + if(string_get_char(context->data_str, 0) == '#') continue; + if(string_size(context->data_str) != 11) continue; + break; + } + FURI_LOG_D(TAG, string_get_cstr(context->data_str)); + + // string is valid, parse it in context->payload + for(uint8_t i = 0; i < 5; i++) { + char temp_str[3]; + temp_str[0] = string_get_cstr(context->data_str)[i * 2]; + temp_str[1] = string_get_cstr(context->data_str)[i * 2 + 1]; + temp_str[2] = '\0'; + context->payload[i] = (uint8_t)strtol(temp_str, NULL, 16); + } + break; } } @@ -134,6 +162,10 @@ void flipfrid_scene_run_attack_on_event(FlipFridEvent event, FlipFridState* cont } break; case InputKeyBack: + if(context->attack == FlipFridAttackLoadFileCustomUids) { + buffered_file_stream_close(context->uids_stream); + } + context->attack_step = 0; context->is_attacking = false; string_reset(context->notification_msg); From 789230458bd7a95dc217a5c8d2a3afcd38ada7e8 Mon Sep 17 00:00:00 2001 From: Ganapati Date: Mon, 5 Sep 2022 09:39:11 +0200 Subject: [PATCH 2/2] Increase time between card to handle slow readers --- applications/flipfrid/scene/flipfrid_scene_run_attack.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/applications/flipfrid/scene/flipfrid_scene_run_attack.c b/applications/flipfrid/scene/flipfrid_scene_run_attack.c index e7256eccabc..547f9c1e124 100644 --- a/applications/flipfrid/scene/flipfrid_scene_run_attack.c +++ b/applications/flipfrid/scene/flipfrid_scene_run_attack.c @@ -1,7 +1,7 @@ #include "flipfrid_scene_run_attack.h" uint8_t counter = 0; -#define TIME_BETWEEN_CARDS 1 +#define TIME_BETWEEN_CARDS 5 uint8_t id_list[16][5] = { {0x00, 0x00, 0x00, 0x00, 0x00}, // Null bytes {0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, // Only FF