wifi_marauder_script.c 13 KB

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