Fi memory issues ad add new attack

This commit is contained in:
Ganapati 2022-09-04 23:32:58 +02:00
parent b6254227b9
commit 6f77f537e3
8 changed files with 192 additions and 12 deletions

View File

@ -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

View File

@ -4,6 +4,7 @@
#include "scene/flipfrid_scene_load_file.h" #include "scene/flipfrid_scene_load_file.h"
#include "scene/flipfrid_scene_select_field.h" #include "scene/flipfrid_scene_select_field.h"
#include "scene/flipfrid_scene_run_attack.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) { static void flipfrid_draw_callback(Canvas* const canvas, void* ctx) {
FlipFridState* flipfrid_state = (FlipFridState*)acquire_mutex((ValueMutex*)ctx, 100); 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: case SceneAttack:
flipfrid_scene_run_attack_on_draw(canvas, flipfrid_state); flipfrid_scene_run_attack_on_draw(canvas, flipfrid_state);
break; break;
case SceneLoadCustomUids:
flipfrid_scene_load_custom_uids_on_draw(canvas, flipfrid_state);
break;
} }
release_mutex((ValueMutex*)ctx, flipfrid_state); release_mutex((ValueMutex*)ctx, flipfrid_state);
@ -159,6 +163,9 @@ int32_t flipfrid_start(void* p) {
case SceneAttack: case SceneAttack:
flipfrid_scene_run_attack_on_event(event, flipfrid_state); flipfrid_scene_run_attack_on_event(event, flipfrid_state);
break; break;
case SceneLoadCustomUids:
flipfrid_scene_load_custom_uids_on_event(event, flipfrid_state);
break;
} }
} else if(event.evt_type == EventTypeTick) { } else if(event.evt_type == EventTypeTick) {
@ -178,6 +185,9 @@ int32_t flipfrid_start(void* p) {
case SceneAttack: case SceneAttack:
flipfrid_scene_run_attack_on_exit(flipfrid_state); flipfrid_scene_run_attack_on_exit(flipfrid_state);
break; break;
case SceneLoadCustomUids:
flipfrid_scene_load_custom_uids_on_exit(flipfrid_state);
break;
case NoneScene: case NoneScene:
break; break;
} }
@ -197,6 +207,9 @@ int32_t flipfrid_start(void* p) {
case SceneAttack: case SceneAttack:
flipfrid_scene_run_attack_on_enter(flipfrid_state); flipfrid_scene_run_attack_on_enter(flipfrid_state);
break; break;
case SceneLoadCustomUids:
flipfrid_scene_load_custom_uids_on_enter(flipfrid_state);
break;
} }
flipfrid_state->previous_scene = flipfrid_state->current_scene; flipfrid_state->previous_scene = flipfrid_state->current_scene;
} }
@ -216,6 +229,9 @@ int32_t flipfrid_start(void* p) {
case SceneAttack: case SceneAttack:
flipfrid_scene_run_attack_on_tick(flipfrid_state); flipfrid_scene_run_attack_on_tick(flipfrid_state);
break; break;
case SceneLoadCustomUids:
flipfrid_scene_load_custom_uids_on_tick(flipfrid_state);
break;
} }
view_port_update(view_port); view_port_update(view_port);
} }

View File

@ -11,6 +11,11 @@
#include <toolbox/stream/stream.h> #include <toolbox/stream/stream.h>
#include <flipper_format/flipper_format_i.h> #include <flipper_format/flipper_format_i.h>
#include <toolbox/stream/stream.h>
#include <toolbox/stream/string_stream.h>
#include <toolbox/stream/file_stream.h>
#include <toolbox/stream/buffered_file_stream.h>
#include <lib/lfrfid/lfrfid_worker.h> #include <lib/lfrfid/lfrfid_worker.h>
#include <lfrfid/protocols/lfrfid_protocols.h> #include <lfrfid/protocols/lfrfid_protocols.h>
@ -19,7 +24,8 @@
typedef enum { typedef enum {
FlipFridAttackDefaultValues, FlipFridAttackDefaultValues,
FlipFridAttackBfCustomerId, FlipFridAttackBfCustomerId,
FlipFridAttackLoadFile FlipFridAttackLoadFile,
FlipFridAttackLoadFileCustomUids,
} FlipFridAttacks; } FlipFridAttacks;
typedef enum { typedef enum {
@ -27,7 +33,8 @@ typedef enum {
SceneEntryPoint, SceneEntryPoint,
SceneSelectFile, SceneSelectFile,
SceneSelectField, SceneSelectField,
SceneAttack SceneAttack,
SceneLoadCustomUids,
} FlipFridScene; } FlipFridScene;
typedef enum { typedef enum {
@ -64,4 +71,8 @@ typedef struct {
uint8_t key_index; uint8_t key_index;
LFRFIDWorker* worker; LFRFIDWorker* worker;
ProtocolDict* dict; ProtocolDict* dict;
ProtocolId protocol;
// Used for custom dictionnary
Stream* uids_stream;
} FlipFridState; } FlipFridState;

View File

@ -3,7 +3,6 @@
string_t menu_items[4]; string_t menu_items[4];
void flipfrid_scene_entrypoint_menu_callback(FlipFridState* context, uint32_t index) { void flipfrid_scene_entrypoint_menu_callback(FlipFridState* context, uint32_t index) {
FURI_LOG_D(TAG, "MENU: %d", index);
switch(index) { switch(index) {
case FlipFridAttackDefaultValues: case FlipFridAttackDefaultValues:
context->attack = FlipFridAttackDefaultValues; context->attack = FlipFridAttackDefaultValues;
@ -20,25 +19,38 @@ void flipfrid_scene_entrypoint_menu_callback(FlipFridState* context, uint32_t in
context->current_scene = SceneSelectFile; context->current_scene = SceneSelectFile;
string_set_str(context->attack_name, "Load File"); string_set_str(context->attack_name, "Load File");
break; break;
case FlipFridAttackLoadFileCustomUids:
context->attack = FlipFridAttackLoadFileCustomUids;
context->current_scene = SceneLoadCustomUids;
string_set_str(context->attack_name, "Load Custom UIDs");
break;
default: default:
break; break;
} }
} }
void flipfrid_scene_entrypoint_on_enter(FlipFridState* context) { 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; 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_init(menu_items[i]);
} }
string_set(menu_items[0], "Default Values"); string_set(menu_items[0], "Default Values");
string_set(menu_items[1], "BF Customer ID"); string_set(menu_items[1], "BF Customer ID");
string_set(menu_items[2], "Load File"); string_set(menu_items[2], "Load File");
string_set(menu_items[3], "Load uids from file");
} }
void flipfrid_scene_entrypoint_on_exit(FlipFridState* context) { void flipfrid_scene_entrypoint_on_exit(FlipFridState* context) {
UNUSED(context); UNUSED(context);
for(uint32_t i = 0; i < 3; i++) { for(uint32_t i = 0; i < 4; i++) {
string_clear(menu_items[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) { if(event.input_type == InputTypeShort) {
switch(event.key) { switch(event.key) {
case InputKeyDown: case InputKeyDown:
if(context->menu_index < FlipFridAttackLoadFile) { if(context->menu_index < FlipFridAttackLoadFileCustomUids) {
context->menu_index++; context->menu_index++;
} }
break; break;
@ -98,7 +110,7 @@ void flipfrid_scene_entrypoint_on_draw(Canvas* canvas, FlipFridState* context) {
canvas_draw_str_aligned( canvas_draw_str_aligned(
canvas, 64, 36, AlignCenter, AlignTop, string_get_cstr(menu_items[context->menu_index])); 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_set_font(canvas, FontSecondary);
canvas_draw_str_aligned( canvas_draw_str_aligned(
canvas, canvas,

View File

@ -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);
}

View File

@ -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);

View File

@ -1,4 +1,5 @@
#include "flipfrid_scene_load_file.h" #include "flipfrid_scene_load_file.h"
#include "flipfrid_scene_entrypoint.h"
#define LFRFID_APP_EXTENSION ".rfid" #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)) { if(flipfrid_load_protocol_from_file(context)) {
context->current_scene = SceneSelectField; context->current_scene = SceneSelectField;
} else { } else {
flipfrid_scene_entrypoint_on_enter(context);
context->current_scene = SceneEntryPoint; context->current_scene = SceneEntryPoint;
} }
} }

View File

@ -1,7 +1,7 @@
#include "flipfrid_scene_run_attack.h" #include "flipfrid_scene_run_attack.h"
uint8_t counter = 0; uint8_t counter = 0;
#define TIME_BETWEEN_CARDS 5 #define TIME_BETWEEN_CARDS 1
uint8_t id_list[16][5] = { uint8_t id_list[16][5] = {
{0x00, 0x00, 0x00, 0x00, 0x00}, // Null bytes {0x00, 0x00, 0x00, 0x00, 0x00}, // Null bytes
{0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, // Only FF {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->attack_step = 0;
context->dict = protocol_dict_alloc(lfrfid_protocols, LFRFIDProtocolMax); context->dict = protocol_dict_alloc(lfrfid_protocols, LFRFIDProtocolMax);
context->worker = lfrfid_worker_alloc(context->dict); 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) { 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) { 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(context->is_attacking) {
if(1 == counter) { 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); context->worker = lfrfid_worker_alloc(context->dict);
lfrfid_worker_start_thread(context->worker); 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) { } else if(0 == counter) {
lfrfid_worker_stop(context->worker); lfrfid_worker_stop(context->worker);
lfrfid_worker_stop_thread(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; context->is_attacking = false;
notification_message(context->notify, &sequence_blink_stop); notification_message(context->notify, &sequence_blink_stop);
notification_message(context->notify, &sequence_single_vibro); notification_message(context->notify, &sequence_single_vibro);
} else { } else {
context->attack_step++; context->attack_step++;
} }
@ -98,10 +99,37 @@ void flipfrid_scene_run_attack_on_tick(FlipFridState* context) {
context->is_attacking = false; context->is_attacking = false;
notification_message(context->notify, &sequence_blink_stop); notification_message(context->notify, &sequence_blink_stop);
notification_message(context->notify, &sequence_single_vibro); notification_message(context->notify, &sequence_single_vibro);
break;
} else { } else {
context->attack_step++; context->attack_step++;
} }
break; 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; break;
case InputKeyBack: case InputKeyBack:
if(context->attack == FlipFridAttackLoadFileCustomUids) {
buffered_file_stream_close(context->uids_stream);
}
context->attack_step = 0; context->attack_step = 0;
context->is_attacking = false; context->is_attacking = false;
string_reset(context->notification_msg); string_reset(context->notification_msg);