mifare_fuzzer_scene_emulator.c 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. #include "../mifare_fuzzer_i.h"
  2. uint8_t tick_counter = 0;
  3. uint8_t attack_step = 0;
  4. uint8_t id_uid_test[9][7] = {
  5. {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17},
  6. {0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28},
  7. {0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39},
  8. {0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a},
  9. {0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b},
  10. {0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c},
  11. {0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d},
  12. {0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e},
  13. {0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f},
  14. };
  15. /// @brief mifare_fuzzer_scene_emulator_callback()
  16. /// @param event
  17. /// @param context
  18. static void mifare_fuzzer_scene_emulator_callback(MifareFuzzerEvent event, void* context) {
  19. //FURI_LOG_D(TAG, "mifare_fuzzer_scene_emulator_callback()");
  20. furi_assert(context);
  21. MifareFuzzerApp* app = context;
  22. view_dispatcher_send_custom_event(app->view_dispatcher, event);
  23. }
  24. /// @brief mifare_fuzzer_scene_emulator_on_enter()
  25. /// @param context
  26. void mifare_fuzzer_scene_emulator_on_enter(void* context) {
  27. //FURI_LOG_D(TAG, "mifare_fuzzer_scene_emulator_on_enter()");
  28. MifareFuzzerApp* app = context;
  29. MifareFuzzerEmulator* emulator = app->emulator_view;
  30. // init callback
  31. mifare_fuzzer_emulator_set_callback(emulator, mifare_fuzzer_scene_emulator_callback, app);
  32. // init ticks
  33. tick_counter = 0;
  34. mifare_fuzzer_emulator_set_tick_num(app->emulator_view, tick_counter);
  35. emulator->ticks_between_cards = MIFARE_FUZZER_DEFAULT_TICKS_BETWEEN_CARDS;
  36. mifare_fuzzer_emulator_set_ticks_between_cards(app->emulator_view, emulator->ticks_between_cards);
  37. // init default card data
  38. FuriHalNfcDevData nfc_dev_data;
  39. nfc_dev_data.atqa[0] = 0x00;
  40. nfc_dev_data.atqa[1] = 0x00;
  41. nfc_dev_data.sak = 0x00;
  42. if (app->card == MifareCardUltralight) {
  43. nfc_dev_data.uid_len = 0x07;
  44. } else {
  45. nfc_dev_data.uid_len = 0x04;
  46. }
  47. for(uint32_t i = 0; i < nfc_dev_data.uid_len; i++) {
  48. nfc_dev_data.uid[i] = 0x00;
  49. }
  50. mifare_fuzzer_emulator_set_nfc_dev_data(app->emulator_view, nfc_dev_data);
  51. // init other vars
  52. attack_step = 0;
  53. // switch to view
  54. view_dispatcher_switch_to_view(
  55. app->view_dispatcher,
  56. MifareFuzzerViewEmulator
  57. );
  58. }
  59. /// @brief mifare_fuzzer_scene_emulator_on_event()
  60. /// @param context
  61. /// @param event
  62. /// @return
  63. bool mifare_fuzzer_scene_emulator_on_event(void* context, SceneManagerEvent event) {
  64. //FURI_LOG_D(TAG, "mifare_fuzzer_scene_emulator_on_event()");
  65. FuriHalNfcDevData nfc_dev_data;
  66. MifareFuzzerApp* app = context;
  67. MifareFuzzerEmulator* emulator = app->emulator_view;
  68. bool consumed = false;
  69. if (event.type == SceneManagerEventTypeCustom) {
  70. if (event.event == MifareFuzzerEventStartAttack) {
  71. //FURI_LOG_D(TAG, "mifare_fuzzer_scene_emulator_on_event() :: MifareFuzzerEventStartAttack");
  72. // Stop worker
  73. mifare_fuzzer_worker_stop(app->worker);
  74. // Set card type
  75. // TODO: Move somewhere else, I do not like this to be there
  76. if (app->card == MifareCardClassic1k) {
  77. nfc_dev_data.atqa[0] = 0x04;
  78. nfc_dev_data.atqa[1] = 0x00;
  79. nfc_dev_data.sak = 0x08;
  80. nfc_dev_data.uid_len = 0x04;
  81. } else if (app->card == MifareCardClassic4k) {
  82. nfc_dev_data.atqa[0] = 0x02;
  83. nfc_dev_data.atqa[1] = 0x00;
  84. nfc_dev_data.sak = 0x18;
  85. nfc_dev_data.uid_len = 0x04;
  86. } else if (app->card == MifareCardUltralight) {
  87. nfc_dev_data.atqa[0] = 0x44;
  88. nfc_dev_data.atqa[1] = 0x00;
  89. nfc_dev_data.sak = 0x00;
  90. nfc_dev_data.uid_len = 0x07;
  91. }
  92. // Set UIDs
  93. if (app->attack == MifareFuzzerAttackTestValues) {
  94. // Load test UIDs
  95. for(uint8_t i = 0; i < nfc_dev_data.uid_len; i++) {
  96. nfc_dev_data.uid[i] = id_uid_test[attack_step][i];
  97. }
  98. // Next UIDs on next loop
  99. if (attack_step >= 8) {
  100. attack_step = 0;
  101. } else {
  102. attack_step++;
  103. }
  104. } else if (app->attack == MifareFuzzerAttackRandomValues) {
  105. if (app->card == MifareCardUltralight) {
  106. // First byte of a 7 byte UID is the manufacturer-code
  107. // https://github.com/Proxmark/proxmark3/blob/master/client/taginfo.c
  108. // https://stackoverflow.com/questions/37837730/mifare-cards-distinguish-between-4-byte-and-7-byte-uids
  109. // https://stackoverflow.com/questions/31233652/how-to-detect-manufacturer-from-nfc-tag-using-android
  110. // TODO: Manufacture-code must be selectable from a list
  111. // use a fixed manufacture-code for now: 0x04 = NXP Semiconductors Germany
  112. nfc_dev_data.uid[0] = 0x04;
  113. for(uint8_t i = 1; i < nfc_dev_data.uid_len; i++) {
  114. nfc_dev_data.uid[i] = (furi_hal_random_get() & 0xFF);
  115. }
  116. } else {
  117. for(uint8_t i = 0; i < nfc_dev_data.uid_len; i++) {
  118. nfc_dev_data.uid[i] = (furi_hal_random_get() & 0xFF);
  119. }
  120. }
  121. } else if (app->attack == MifareFuzzerAttackLoadUidsFromFile) {
  122. //bool end_of_list = false;
  123. // read stream
  124. while(true){
  125. furi_string_reset(app->uid_str);
  126. if(!stream_read_line(app->uids_stream, app->uid_str)) {
  127. // restart from beginning on empty line
  128. stream_rewind(app->uids_stream);
  129. continue;
  130. //end_of_list = true;
  131. }
  132. // Skip comments
  133. if(furi_string_get_char(app->uid_str, 0) == '#') continue;
  134. // Skip lines with invalid length
  135. if((furi_string_size(app->uid_str) != 9) && (furi_string_size(app->uid_str) != 15)) continue;
  136. break;
  137. }
  138. // TODO: stop on end of list?
  139. //if(end_of_list) break;
  140. // parse string to UID
  141. // TODO: a better validation on input?
  142. for(uint8_t i = 0; i < nfc_dev_data.uid_len; i++) {
  143. if (i <= ((furi_string_size(app->uid_str) - 1) / 2)) {
  144. char temp_str[3];
  145. temp_str[0] = furi_string_get_cstr(app->uid_str)[i * 2];
  146. temp_str[1] = furi_string_get_cstr(app->uid_str)[i * 2 + 1];
  147. temp_str[2] = '\0';
  148. nfc_dev_data.uid[i] = (uint8_t)strtol(temp_str, NULL, 16);
  149. } else {
  150. nfc_dev_data.uid[i] = 0x00;
  151. }
  152. }
  153. }
  154. mifare_fuzzer_worker_set_nfc_dev_data(app->worker, nfc_dev_data);
  155. mifare_fuzzer_emulator_set_nfc_dev_data(app->emulator_view, nfc_dev_data);
  156. // Reset tick_counter
  157. tick_counter = 0;
  158. mifare_fuzzer_emulator_set_tick_num(app->emulator_view, tick_counter);
  159. // Start worker
  160. mifare_fuzzer_worker_start(app->worker);
  161. } else if (event.event == MifareFuzzerEventStopAttack) {
  162. //FURI_LOG_D(TAG, "mifare_fuzzer_scene_emulator_on_event() :: MifareFuzzerEventStopAttack");
  163. // Stop worker
  164. mifare_fuzzer_worker_stop(app->worker);
  165. } else if (event.event == MifareFuzzerEventIncrementTicks) {
  166. if (!emulator->is_attacking) {
  167. if (emulator->ticks_between_cards < MIFARE_FUZZER_MAX_TICKS_BETWEEN_CARDS) {
  168. emulator->ticks_between_cards++;
  169. mifare_fuzzer_emulator_set_ticks_between_cards(app->emulator_view, emulator->ticks_between_cards);
  170. };
  171. };
  172. } else if (event.event == MifareFuzzerEventDecrementTicks) {
  173. if (!emulator->is_attacking) {
  174. if (emulator->ticks_between_cards > MIFARE_FUZZER_MIN_TICKS_BETWEEN_CARDS) {
  175. emulator->ticks_between_cards--;
  176. mifare_fuzzer_emulator_set_ticks_between_cards(app->emulator_view, emulator->ticks_between_cards);
  177. };
  178. };
  179. }
  180. consumed = true;
  181. } else if (event.type == SceneManagerEventTypeTick) {
  182. //FURI_LOG_D(TAG, "mifare_fuzzer_scene_emulator_on_event() :: SceneManagerEventTypeTick");
  183. // Used to check tick length (not perfect but enough)
  184. //FuriHalRtcDateTime curr_dt;
  185. //furi_hal_rtc_get_datetime(&curr_dt);
  186. //FURI_LOG_D(TAG, "Time is: %.2d:%.2d:%.2d", curr_dt.hour, curr_dt.minute, curr_dt.second);
  187. // If emulator is attacking
  188. if (emulator->is_attacking) {
  189. // increment tick_counter
  190. tick_counter++;
  191. mifare_fuzzer_emulator_set_tick_num(app->emulator_view, tick_counter);
  192. //FURI_LOG_D(TAG, "tick_counter is: %.2d", tick_counter);
  193. if (tick_counter >= emulator->ticks_between_cards) {
  194. // Queue event for changing UID
  195. view_dispatcher_send_custom_event(app->view_dispatcher, MifareFuzzerEventStartAttack);
  196. }
  197. }
  198. consumed = true;
  199. }
  200. return consumed;
  201. }
  202. /// @brief mifare_fuzzer_scene_emulator_on_exit()
  203. /// @param context
  204. void mifare_fuzzer_scene_emulator_on_exit(void* context) {
  205. //FURI_LOG_D(TAG, "mifare_fuzzer_scene_emulator_on_exit()");
  206. MifareFuzzerApp* app = context;
  207. mifare_fuzzer_worker_stop(app->worker);
  208. if(app->attack == MifareFuzzerAttackLoadUidsFromFile) {
  209. furi_string_reset(app->uid_str);
  210. stream_rewind(app->uids_stream);
  211. buffered_file_stream_close(app->uids_stream);
  212. }
  213. }