wifi_marauder_script.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417
  1. #include "../wifi_marauder_app_i.h"
  2. #include "wifi_marauder_script.h"
  3. #define WIFI_MARAUDER_DEFAULT_TIMEOUT_SCAN 15
  4. #define WIFI_MARAUDER_DEFAULT_TIMEOUT_DEAUTH 30
  5. #define WIFI_MARAUDER_DEFAULT_TIMEOUT_PROBE 60
  6. #define WIFI_MARAUDER_DEFAULT_TIMEOUT_SNIFF_PMKID 60
  7. #define WIFI_MARAUDER_DEFAULT_TIMEOUT_SNIFF_BEACON 60
  8. #define WIFI_MARAUDER_DEFAULT_TIMEOUT_BEACON 60
  9. #define WIFI_MARAUDER_DEFAULT_ENABLE_LED true
  10. #define WIFI_MARAUDER_DEFAULT_SAVE_PCAP true
  11. WifiMarauderScript *wifi_marauder_script_alloc() {
  12. WifiMarauderScript *script = (WifiMarauderScript *) malloc(sizeof(WifiMarauderScript));
  13. if (script == NULL) {
  14. return NULL;
  15. }
  16. script->name = NULL;
  17. script->description = NULL;
  18. script->first_stage = NULL;
  19. script->enable_led = WIFI_MARAUDER_DEFAULT_ENABLE_LED;
  20. script->save_pcap = WIFI_MARAUDER_DEFAULT_SAVE_PCAP;
  21. script->repeat = 1;
  22. return script;
  23. }
  24. void _wifi_marauder_script_load_meta(WifiMarauderScript *script, cJSON *meta_section) {
  25. if (meta_section != NULL) {
  26. // Script description
  27. cJSON* description = cJSON_GetObjectItem(meta_section, "description");
  28. if (description != NULL) {
  29. script->description = strdup(description->valuestring);
  30. }
  31. // Enable LED
  32. cJSON* enable_led_json = cJSON_GetObjectItemCaseSensitive(meta_section, "enableLed");
  33. if (cJSON_IsBool(enable_led_json)) {
  34. script->enable_led = enable_led_json->valueint;
  35. }
  36. // Save PCAP
  37. cJSON* save_pcap_json = cJSON_GetObjectItemCaseSensitive(meta_section, "savePcap");
  38. if (cJSON_IsBool(save_pcap_json)) {
  39. script->save_pcap = save_pcap_json->valueint;
  40. }
  41. // Times the script will be repeated
  42. cJSON* repeat = cJSON_GetObjectItem(meta_section, "repeat");
  43. if (repeat != NULL) {
  44. script->repeat = repeat->valueint;
  45. }
  46. }
  47. if (script->description == NULL) {
  48. script->description = "My script";
  49. }
  50. }
  51. WifiMarauderScriptStageScan* _wifi_marauder_script_get_stage_scan(cJSON *stages) {
  52. cJSON* stage_scan = cJSON_GetObjectItem(stages, "scan");
  53. if (stage_scan == NULL) {
  54. return NULL;
  55. }
  56. cJSON* type = cJSON_GetObjectItem(stage_scan, "type");
  57. if (type == NULL) {
  58. return NULL;
  59. }
  60. WifiMarauderScriptScanType scan_type;
  61. if (strcmp(type->valuestring, "ap") == 0) {
  62. scan_type = WifiMarauderScriptScanTypeAp;
  63. } else if (strcmp(type->valuestring, "station") == 0) {
  64. scan_type = WifiMarauderScriptScanTypeStation;
  65. } else {
  66. return NULL;
  67. }
  68. cJSON* channel = cJSON_GetObjectItem(stage_scan, "channel");
  69. int scan_channel = channel != NULL ? (int)cJSON_GetNumberValue(channel) : 0;
  70. cJSON* timeout = cJSON_GetObjectItem(stage_scan, "timeout");
  71. int scan_timeout = timeout != NULL ? (int)cJSON_GetNumberValue(timeout) : WIFI_MARAUDER_DEFAULT_TIMEOUT_SCAN;
  72. WifiMarauderScriptStageScan *scan_stage = (WifiMarauderScriptStageScan*) malloc(sizeof(WifiMarauderScriptStageScan));
  73. scan_stage->type = scan_type;
  74. scan_stage->channel = scan_channel;
  75. scan_stage->timeout = scan_timeout;
  76. return scan_stage;
  77. }
  78. WifiMarauderScriptStageSelect* _wifi_marauder_script_get_stage_select(cJSON *stages) {
  79. cJSON *select_stage_json = cJSON_GetObjectItemCaseSensitive(stages, "select");
  80. if (select_stage_json == NULL) {
  81. return NULL;
  82. }
  83. cJSON *type_json = cJSON_GetObjectItemCaseSensitive(select_stage_json, "type");
  84. cJSON *filter_json = cJSON_GetObjectItemCaseSensitive(select_stage_json, "filter");
  85. cJSON *allow_repeat_json = cJSON_GetObjectItemCaseSensitive(select_stage_json, "allow_repeat");
  86. if (!cJSON_IsString(type_json) || !cJSON_IsString(filter_json)) {
  87. return NULL;
  88. }
  89. WifiMarauderScriptSelectType select_type;
  90. if (strcmp(type_json->valuestring, "ap") == 0) {
  91. select_type = WifiMarauderScriptSelectTypeAp;
  92. } else if (strcmp(type_json->valuestring, "station") == 0) {
  93. select_type = WifiMarauderScriptSelectTypeStation;
  94. } else if (strcmp(type_json->valuestring, "ssid") == 0) {
  95. select_type = WifiMarauderScriptSelectTypeSsid;
  96. } else {
  97. return NULL;
  98. }
  99. char *filter_str = strdup(filter_json->valuestring);
  100. WifiMarauderScriptStageSelect *stage_select = (WifiMarauderScriptStageSelect*) malloc(sizeof(WifiMarauderScriptStageSelect));
  101. stage_select->type = select_type;
  102. stage_select->filter = filter_str;
  103. stage_select->allow_repeat = cJSON_IsBool(allow_repeat_json) ? allow_repeat_json->valueint : true;
  104. return stage_select;
  105. }
  106. WifiMarauderScriptStageDeauth* _wifi_marauder_script_get_stage_deauth(cJSON *stages) {
  107. cJSON *deauth_stage_json = cJSON_GetObjectItemCaseSensitive(stages, "deauth");
  108. if (deauth_stage_json == NULL) {
  109. return NULL;
  110. }
  111. cJSON* timeout = cJSON_GetObjectItem(deauth_stage_json, "timeout");
  112. int deauth_timeout = timeout != NULL ? (int)cJSON_GetNumberValue(timeout) : WIFI_MARAUDER_DEFAULT_TIMEOUT_DEAUTH;
  113. WifiMarauderScriptStageDeauth *deauth_stage = (WifiMarauderScriptStageDeauth*) malloc(sizeof(WifiMarauderScriptStageDeauth));
  114. deauth_stage->timeout = deauth_timeout;
  115. return deauth_stage;
  116. }
  117. WifiMarauderScriptStageProbe* _wifi_marauder_script_get_stage_probe(cJSON *stages) {
  118. cJSON *probe_stage_json = cJSON_GetObjectItemCaseSensitive(stages, "probe");
  119. if (probe_stage_json == NULL) {
  120. return NULL;
  121. }
  122. cJSON* timeout = cJSON_GetObjectItem(probe_stage_json, "timeout");
  123. int probe_timeout = timeout != NULL ? (int)cJSON_GetNumberValue(timeout) : WIFI_MARAUDER_DEFAULT_TIMEOUT_PROBE;
  124. WifiMarauderScriptStageProbe *probe_stage = (WifiMarauderScriptStageProbe*) malloc(sizeof(WifiMarauderScriptStageProbe));
  125. probe_stage->timeout = probe_timeout;
  126. return probe_stage;
  127. }
  128. WifiMarauderScriptStageSniffBeacon* _wifi_marauder_script_get_stage_sniff_beacon(cJSON *stages) {
  129. cJSON* sniffbeacon_stage_json = cJSON_GetObjectItem(stages, "sniffbeacon");
  130. if (sniffbeacon_stage_json == NULL) {
  131. return NULL;
  132. }
  133. cJSON* timeout_json = cJSON_GetObjectItem(sniffbeacon_stage_json, "timeout");
  134. int timeout = timeout_json != NULL ? (int)cJSON_GetNumberValue(timeout_json) : WIFI_MARAUDER_DEFAULT_TIMEOUT_SNIFF_BEACON;
  135. WifiMarauderScriptStageSniffBeacon *sniff_beacon_stage = (WifiMarauderScriptStageSniffBeacon*) malloc(sizeof(WifiMarauderScriptStageSniffBeacon));
  136. sniff_beacon_stage->timeout = timeout;
  137. return sniff_beacon_stage;
  138. }
  139. WifiMarauderScriptStageSniffPmkid* _wifi_marauder_script_get_stage_sniff_pmkid(cJSON *stages) {
  140. cJSON* sniffpmkid_stage_json = cJSON_GetObjectItem(stages, "sniffpmkid");
  141. if (sniffpmkid_stage_json == NULL) {
  142. return NULL;
  143. }
  144. cJSON* channel_json = cJSON_GetObjectItem(sniffpmkid_stage_json, "channel");
  145. int channel = channel_json != NULL ? (int)cJSON_GetNumberValue(channel_json) : 0;
  146. cJSON* timeout_json = cJSON_GetObjectItem(sniffpmkid_stage_json, "timeout");
  147. int timeout = timeout_json != NULL ? (int)cJSON_GetNumberValue(timeout_json) : WIFI_MARAUDER_DEFAULT_TIMEOUT_SNIFF_PMKID;
  148. cJSON* force_deauth_json = cJSON_GetObjectItemCaseSensitive(sniffpmkid_stage_json, "forceDeauth");
  149. bool force_deauth = cJSON_IsBool(force_deauth_json) ? force_deauth_json->valueint : true;
  150. WifiMarauderScriptStageSniffPmkid *sniff_pmkid_stage = (WifiMarauderScriptStageSniffPmkid*) malloc(sizeof(WifiMarauderScriptStageSniffPmkid));
  151. sniff_pmkid_stage->channel = channel;
  152. sniff_pmkid_stage->timeout = timeout;
  153. sniff_pmkid_stage->force_deauth = force_deauth;
  154. return sniff_pmkid_stage;
  155. }
  156. WifiMarauderScriptStageBeaconList* _wifi_marauder_script_get_stage_beacon_list(cJSON *stages) {
  157. cJSON* stage_beaconlist = cJSON_GetObjectItem(stages, "beaconlist");
  158. if (stage_beaconlist == NULL) {
  159. return NULL;
  160. }
  161. WifiMarauderScriptStageBeaconList *beaconlist_stage = (WifiMarauderScriptStageBeaconList*) malloc(sizeof(WifiMarauderScriptStageBeaconList));
  162. if (beaconlist_stage == NULL) {
  163. return NULL;
  164. }
  165. cJSON* ssids = cJSON_GetObjectItem(stage_beaconlist, "ssids");
  166. if (ssids == NULL) {
  167. return NULL;
  168. }
  169. // SSID count
  170. int ssid_count = cJSON_GetArraySize(ssids);
  171. if (ssid_count == 0) {
  172. return NULL;
  173. }
  174. beaconlist_stage->ssid_count = ssid_count;
  175. // SSIDs
  176. beaconlist_stage->ssids = (char**) malloc(sizeof(char*) * ssid_count);
  177. if (beaconlist_stage->ssids == NULL) {
  178. return NULL;
  179. }
  180. for (int i = 0; i < ssid_count; i++) {
  181. cJSON* ssid = cJSON_GetArrayItem(ssids, i);
  182. if (ssid == NULL) {
  183. continue;
  184. }
  185. char* ssid_string = cJSON_GetStringValue(ssid);
  186. if (ssid_string == NULL) {
  187. continue;
  188. }
  189. beaconlist_stage->ssids[i] = (char*) malloc(sizeof(char) * (strlen(ssid_string) + 1));
  190. strcpy(beaconlist_stage->ssids[i], ssid_string);
  191. }
  192. // Timeout
  193. cJSON* timeout = cJSON_GetObjectItem(stage_beaconlist, "timeout");
  194. beaconlist_stage->timeout = timeout != NULL ? (int)cJSON_GetNumberValue(timeout) : WIFI_MARAUDER_DEFAULT_TIMEOUT_BEACON;
  195. return beaconlist_stage;
  196. }
  197. WifiMarauderScriptStage* _wifi_marauder_script_create_stage(WifiMarauderScriptStageType type, void* stage_data) {
  198. WifiMarauderScriptStage* stage = (WifiMarauderScriptStage*) malloc(sizeof(WifiMarauderScriptStage));
  199. stage->type = type;
  200. stage->stage = stage_data;
  201. stage->next_stage = NULL;
  202. return stage;
  203. }
  204. void _wifi_marauder_script_add_stage(WifiMarauderScript *script, WifiMarauderScriptStage *stage, WifiMarauderScriptStage **prev_stage) {
  205. if (*prev_stage != NULL) {
  206. (*prev_stage)->next_stage = stage;
  207. } else {
  208. script->first_stage = stage;
  209. }
  210. *prev_stage = stage;
  211. }
  212. void _wifi_marauder_script_load_stages(WifiMarauderScript *script, cJSON *stages) {
  213. WifiMarauderScriptStage *prev_stage = NULL;
  214. // Scan stage
  215. WifiMarauderScriptStageScan *stage_scan = _wifi_marauder_script_get_stage_scan(stages);
  216. if (stage_scan != NULL) {
  217. _wifi_marauder_script_add_stage(
  218. script,
  219. _wifi_marauder_script_create_stage(WifiMarauderScriptStageTypeScan, stage_scan),
  220. &prev_stage
  221. );
  222. }
  223. // Select stage
  224. WifiMarauderScriptStageSelect *stage_select = _wifi_marauder_script_get_stage_select(stages);
  225. if (stage_select != NULL) {
  226. _wifi_marauder_script_add_stage(
  227. script,
  228. _wifi_marauder_script_create_stage(WifiMarauderScriptStageTypeSelect, stage_select),
  229. &prev_stage
  230. );
  231. }
  232. // Deauth stage
  233. WifiMarauderScriptStageDeauth *stage_deauth = _wifi_marauder_script_get_stage_deauth(stages);
  234. if (stage_deauth != NULL) {
  235. _wifi_marauder_script_add_stage(
  236. script,
  237. _wifi_marauder_script_create_stage(WifiMarauderScriptStageTypeDeauth, stage_deauth),
  238. &prev_stage
  239. );
  240. }
  241. // Probe stage
  242. WifiMarauderScriptStageProbe *stage_probe = _wifi_marauder_script_get_stage_probe(stages);
  243. if (stage_probe != NULL) {
  244. _wifi_marauder_script_add_stage(
  245. script,
  246. _wifi_marauder_script_create_stage(WifiMarauderScriptStageTypeProbe, stage_probe),
  247. &prev_stage
  248. );
  249. }
  250. // Sniff beacon stage
  251. WifiMarauderScriptStageSniffBeacon *sniff_beacon = _wifi_marauder_script_get_stage_sniff_beacon(stages);
  252. if (sniff_beacon != NULL) {
  253. _wifi_marauder_script_add_stage(
  254. script,
  255. _wifi_marauder_script_create_stage(WifiMarauderScriptStageTypeSniffBeacon, sniff_beacon),
  256. &prev_stage
  257. );
  258. }
  259. // Sniff PMKID stage
  260. WifiMarauderScriptStageSniffPmkid *sniff_pmkid = _wifi_marauder_script_get_stage_sniff_pmkid(stages);
  261. if (sniff_pmkid != NULL) {
  262. _wifi_marauder_script_add_stage(
  263. script,
  264. _wifi_marauder_script_create_stage(WifiMarauderScriptStageTypeSniffPmkid, sniff_pmkid),
  265. &prev_stage
  266. );
  267. }
  268. // Beacon List stage
  269. WifiMarauderScriptStageBeaconList *stage_beacon_list = _wifi_marauder_script_get_stage_beacon_list(stages);
  270. if (stage_beacon_list != NULL) {
  271. _wifi_marauder_script_add_stage(
  272. script,
  273. _wifi_marauder_script_create_stage(WifiMarauderScriptStageTypeBeaconList, stage_beacon_list),
  274. &prev_stage
  275. );
  276. }
  277. }
  278. WifiMarauderScript *wifi_marauder_script_parse_raw(const char* json_raw) {
  279. WifiMarauderScript *script = wifi_marauder_script_alloc();
  280. if (script == NULL) {
  281. return NULL;
  282. }
  283. cJSON* json = cJSON_Parse(json_raw);
  284. if (json == NULL) {
  285. return NULL;
  286. }
  287. cJSON* meta = cJSON_GetObjectItem(json, "meta");
  288. _wifi_marauder_script_load_meta(script, meta);
  289. cJSON* stages = cJSON_GetObjectItem(json, "stages");
  290. _wifi_marauder_script_load_stages(script, stages);
  291. return script;
  292. }
  293. WifiMarauderScript *wifi_marauder_script_parse_file(const char* file_path, Storage* storage) {
  294. WifiMarauderScript *script = NULL;
  295. File* script_file = storage_file_alloc(storage);
  296. if (storage_file_open(script_file, file_path, FSAM_READ, FSOM_OPEN_EXISTING)) {
  297. uint32_t file_size = storage_file_size(script_file);
  298. char* json_buffer = (char*)malloc(file_size + 1);
  299. uint16_t bytes_read = storage_file_read(script_file, json_buffer, file_size);
  300. json_buffer[bytes_read] = '\0';
  301. script = wifi_marauder_script_parse_raw(json_buffer);
  302. if (script != NULL) {
  303. // Set script name
  304. FuriString* script_name = furi_string_alloc();
  305. path_extract_filename_no_ext(file_path, script_name);
  306. script->name = strdup(furi_string_get_cstr(script_name));
  307. furi_string_free(script_name);
  308. }
  309. storage_file_close(script_file);
  310. }
  311. storage_file_free(script_file);
  312. return script;
  313. }
  314. WifiMarauderScriptStage* wifi_marauder_script_get_stage(WifiMarauderScript* script, WifiMarauderScriptStageType stage_type) {
  315. if (script == NULL) {
  316. return NULL;
  317. }
  318. WifiMarauderScriptStage* current_stage = script->first_stage;
  319. while (current_stage != NULL) {
  320. if (current_stage->type == stage_type) {
  321. return current_stage;
  322. }
  323. current_stage = current_stage->next_stage;
  324. }
  325. return NULL;
  326. }
  327. void wifi_marauder_script_free(WifiMarauderScript *script) {
  328. if (script == NULL) {
  329. return;
  330. }
  331. WifiMarauderScriptStage *current_stage = script->first_stage;
  332. while (current_stage != NULL) {
  333. WifiMarauderScriptStage *next_stage = current_stage->next_stage;
  334. switch (current_stage->type) {
  335. case WifiMarauderScriptStageTypeScan:
  336. free(current_stage->stage);
  337. break;
  338. case WifiMarauderScriptStageTypeSelect:
  339. free(((WifiMarauderScriptStageSelect *) current_stage->stage)->filter);
  340. free(current_stage->stage);
  341. break;
  342. case WifiMarauderScriptStageTypeDeauth:
  343. free(current_stage->stage);
  344. break;
  345. case WifiMarauderScriptStageTypeProbe:
  346. free(current_stage->stage);
  347. break;
  348. case WifiMarauderScriptStageTypeSniffPmkid:
  349. free(current_stage->stage);
  350. break;
  351. case WifiMarauderScriptStageTypeSniffBeacon:
  352. free(current_stage->stage);
  353. break;
  354. case WifiMarauderScriptStageTypeBeaconList:
  355. for (int i = 0; i < ((WifiMarauderScriptStageBeaconList *) current_stage->stage)->ssid_count; i++) {
  356. free(((WifiMarauderScriptStageBeaconList *) current_stage->stage)->ssids[i]);
  357. }
  358. free(((WifiMarauderScriptStageBeaconList *) current_stage->stage)->ssids);
  359. free(current_stage->stage);
  360. break;
  361. }
  362. free(current_stage);
  363. current_stage = next_stage;
  364. }
  365. free(script->name);
  366. free(script->description);
  367. free(script);
  368. }