mifare_fuzzer_scene_emulator.c 12 KB

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