cfuzz.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429
  1. /*
  2. This is the main file. It handles sending, receiving, but also monitoring of frames.
  3. */
  4. #include <stdio.h>
  5. #include <pcap.h>
  6. #include <stdlib.h>
  7. #include <stdint.h>
  8. #include <string.h>
  9. #include <unistd.h>
  10. #include <sys/time.h>
  11. #include "cfuzz.h"
  12. #include "frameCreator.h"
  13. #include "frameDefinitions.h"
  14. #include "fuzzer.h"
  15. #define DEBUG (0)
  16. #define SUTTIMEOUTMS (30000) //30s
  17. #define SENDDISASS (1) //send dissassociation frame after association
  18. //Used for timing
  19. struct timeval tm1;
  20. struct timeval longtm;
  21. //Number of acked frames in current step
  22. int ackedFrames = 0;
  23. //Copied from Wireshark
  24. u_char radioTapHeader[36] = "\x00\x00\x24\x00\x2f\x40\x00\xa0\x20\x08\x00\x00\x00\x00\x00\x00" \
  25. "\x9d\x5c\xa0\x15\x01\x00\x00\x00\x10\x02\x6c\x09\xa0\x00\xa7\x00" \
  26. "\x00\x00\xa7\x00";
  27. //Mac address of Atheros Wi-Fi dongle
  28. //Dongle will only ACK frames to its own MAC address
  29. u_char myMAC[6] = "\x00\x0a\xeb\x2d\x72\x55";
  30. //Mac address of SUT
  31. //Is needed to ignore frames from other devices
  32. //Comment out the SUT
  33. u_char sutMAC[6] = "\xec\x9b\xf3\x1e\x19\x71"; //Galaxy S6
  34. //u_char sutMAC[6] = "\xcc\xfa\x00\xc9\xfc\xad"; //LG Optimus G
  35. //u_char sutMAC[6] = "\xd0\x17\x6a\xe8\xe9\x7a"; //Galaxy Ace
  36. //u_char sutMAC[6] = "\x12\x42\x2a\x7e\xd4\xe8"; //Orange Pi Zero
  37. //u_char sutMAC[6] = "\x00\x09\xbf\x7d\x6d\xaa"; //Nintendo DS
  38. //u_char sutMAC[6] = "\x00\x01\x4a\x93\xce\x34"; //PSP
  39. //u_char sutMAC[6] = "\xe0\xe7\x51\x45\x5e\x5d"; //DSI
  40. //u_char sutMAC[6] = "\x9c\xe6\x35\x2a\x69\x16"; //WII U
  41. //u_char sutMAC[6] = "\x6c\xad\xf8\xc8\x77\xca"; //Chromecast 1
  42. //u_char sutMAC[6] = "\xb8\x27\xeb\xf1\x89\x68"; //RPI 3
  43. //u_char sutMAC[6] = "\x84\x00\xd2\xe0\x81\xb2"; //Xperia Ray
  44. //u_char sutMAC[6] = "\x54\x60\x09\xf8\xbe\x28"; //Chromecast Audio
  45. //u_char sutMAC[6] = "\x80\x7d\x3a\x73\x81\xc7"; //Power plug
  46. //Returns filter for libpcap
  47. //we want to use as many filters here as possible, since libpcap is closer to the hardware than this user-level program
  48. //we only want to receive Probe requests, Authentication frames and Association requests, all to only our own MAC address or broadcast address in case of Probe requests
  49. //furthermore, all frames except ACK frames (have no send address) should be sent from the SUT MAC address
  50. //also, it is important not to compile and set the filter between each pcap_next. Otherwise ACK frames will be missed
  51. //when changing the filterString, the strncpy() locations should also be changed!
  52. const char *getFilterString()
  53. {
  54. //xx:xx:xx:xx:xx:xx will become myMAC, yy:yy:yy:yy:yy:yy will become sutMAC
  55. static char filterString[] = "(wlan subtype probe-req and (wlan addr1 xx:xx:xx:xx:xx:xx or wlan addr1 ff:ff:ff:ff:ff:ff) and wlan addr2 yy:yy:yy:yy:yy:yy)" \
  56. " or ( wlan addr1 xx:xx:xx:xx:xx:xx and wlan addr2 yy:yy:yy:yy:yy:yy and ( wlan subtype auth or wlan subtype assoc-req))" \
  57. " or ( wlan addr1 xx:xx:xx:xx:xx:xx and wlan subtype ack)";
  58. //convert myMAC and sutMAC to strings
  59. char myMacStr[18];
  60. char sutMacStr[18];
  61. snprintf(myMacStr, sizeof(myMacStr), "%02x:%02x:%02x:%02x:%02x:%02x",
  62. myMAC[0], myMAC[1], myMAC[2], myMAC[3], myMAC[4], myMAC[5]);
  63. snprintf(sutMacStr, sizeof(sutMacStr), "%02x:%02x:%02x:%02x:%02x:%02x",
  64. sutMAC[0], sutMAC[1], sutMAC[2], sutMAC[3], sutMAC[4], sutMAC[5]);
  65. //replace placeholder MACs in filterString with correct MACstring (hardcoded positions!)
  66. strncpy(filterString+40, myMacStr,17);
  67. strncpy(filterString+106, sutMacStr,17);
  68. strncpy(filterString+141, myMacStr,17);
  69. strncpy(filterString+174, sutMacStr,17);
  70. strncpy(filterString+260, myMacStr,17);
  71. return filterString;
  72. }
  73. //Starts timer by setting current (starting) time to tm1
  74. void startTimer()
  75. {
  76. gettimeofday(&tm1, NULL);
  77. }
  78. //Stops timer by setting current (ending) time to tm2
  79. //Then compares difference in time and returns it in milliseconds
  80. unsigned long long stopTimer()
  81. {
  82. struct timeval tm2;
  83. gettimeofday(&tm2, NULL);
  84. unsigned long long t = 1000 * (tm2.tv_sec - tm1.tv_sec) + (tm2.tv_usec - tm1.tv_usec) / 1000;
  85. return t;
  86. }
  87. //Starts timer by setting current (starting) time to longtm
  88. //Longtimer is used to determine if it was more than X seconds since the SUT sent out frames
  89. void startLongTimer()
  90. {
  91. gettimeofday(&longtm, NULL);
  92. }
  93. //Stops timer by setting current (ending) time to longtm2
  94. //Then compares difference in time and returns it in milliseconds
  95. unsigned long long stopLongTimer()
  96. {
  97. struct timeval longtm2;
  98. gettimeofday(&longtm2, NULL);
  99. unsigned long long t = 1000 * (longtm2.tv_sec - longtm.tv_sec) + (longtm2.tv_usec - longtm.tv_usec) / 1000;
  100. return t;
  101. }
  102. //Returns source address pointer location in packet
  103. u_char *getSourceAddrOfPacket(const u_char *packet)
  104. {
  105. //get header length
  106. u_char headerLength;
  107. headerLength = packet[2];
  108. //calculate offset to address
  109. const u_char *addr;
  110. int offset = headerLength;
  111. offset = offset + 10;
  112. //get pointer to address
  113. addr = packet + offset;
  114. return (u_char*) addr;
  115. }
  116. //Returns Version, Type and Subtype (one byte)
  117. u_char getFrameTypeOfPacket(const u_char *packet)
  118. {
  119. //get header length
  120. u_char headerLength;
  121. headerLength = packet[2];
  122. //calculate offset to frame type
  123. const u_char *frameType;
  124. int offset = headerLength;
  125. offset = offset + 0;
  126. //get pointer to frameType
  127. frameType = packet + offset;
  128. return *frameType;
  129. }
  130. //Sends packet using pcap. Returns status
  131. int sendPacket(pcap_t *pcap_h, u_char *packet, int size)
  132. {
  133. int sendStatus = pcap_sendpacket(pcap_h, packet, size);
  134. //when frame failed to send
  135. if (sendStatus == 1)
  136. {
  137. printf("Failed to send frame:\n");
  138. //print failed frame
  139. int printCounter = 0;
  140. for(int i = 0; i < size; i++)
  141. {
  142. printf("%02X ", packet[i]);
  143. printCounter = printCounter + 1;
  144. if (printCounter == 16)
  145. {
  146. printCounter = 0;
  147. printf("\n");
  148. }
  149. }
  150. printf("\n");
  151. }
  152. return sendStatus;
  153. }
  154. int main(int argc, char *argv[])
  155. {
  156. pcap_t *pcap_h;
  157. struct bpf_program fp;
  158. struct pcap_pkthdr header;
  159. char *dev;
  160. char errbuf[PCAP_ERRBUF_SIZE];
  161. //check argument number
  162. if(argc != 2)
  163. {
  164. printf("Usage: %s device\n", argv[0]);
  165. exit(EXIT_FAILURE);
  166. }
  167. dev = argv[1];
  168. //initialize libpcap
  169. if((pcap_h = pcap_create(dev, errbuf)) == NULL)
  170. {
  171. printf("pcap_create() failed: %s\n", errbuf);
  172. exit(EXIT_FAILURE);
  173. }
  174. if(pcap_can_set_rfmon(pcap_h) == 0)
  175. {
  176. printf("Monitor mode can not be set.\n");
  177. exit(EXIT_FAILURE);
  178. }
  179. if(pcap_set_rfmon(pcap_h, 1) != 0)
  180. {
  181. printf("Failed to set monitor mode.\n");
  182. exit(EXIT_FAILURE);
  183. }
  184. if(pcap_activate(pcap_h) != 0)
  185. {
  186. printf("pcap_activate() failed\n");
  187. exit(EXIT_FAILURE);
  188. }
  189. //compile filter for incoming packets
  190. if(pcap_compile(pcap_h, &fp, getFilterString() , 0, PCAP_NETMASK_UNKNOWN) == -1)
  191. {
  192. printf("failed pcap_compile() with error: %s\n", pcap_geterr(pcap_h));
  193. exit(EXIT_FAILURE);
  194. }
  195. //apply filter
  196. if(pcap_setfilter(pcap_h, &fp) == -1)
  197. {
  198. printf("failed pcap_setfilter() with error: %s\n", pcap_geterr(pcap_h));
  199. exit(EXIT_FAILURE);
  200. }
  201. //free memory allocated by pcap_compile()
  202. pcap_freecode(&fp);
  203. //flag to indicate if we have to listen for ACK verification
  204. int waitForACK = 0;
  205. //counter for continuous ACK fail
  206. int noACKcounter = 0;
  207. //initialize the fuzzer
  208. increaseFuzzer();
  209. //start long timer
  210. startLongTimer();
  211. //infinite listen-respond loop
  212. while (1)
  213. {
  214. //receive packet
  215. const u_char *packet = pcap_next(pcap_h, &header);
  216. unsigned long long LongtimeSincePrevPacket = stopLongTimer();
  217. if (LongtimeSincePrevPacket > SUTTIMEOUTMS)
  218. {
  219. printf("\e[31mIt took %llu ms to receive any frame from the SUT. Possible crash?\e[39m\n", LongtimeSincePrevPacket);
  220. }
  221. startLongTimer();
  222. unsigned long long timeSincePrevPacket = stopTimer();
  223. u_char frameType = getFrameTypeOfPacket(packet);
  224. u_char* sourceAddr;
  225. if (frameType != 0xd4) //ACK frames have no source address
  226. sourceAddr = getSourceAddrOfPacket(packet);
  227. //if we had to wait for an ACK, verify if current frame is an ACK
  228. if (waitForACK != 0)
  229. {
  230. //printf("Received frame of type %d\n", frameType);
  231. if (stopTimer() <= 30)
  232. {
  233. if (frameType == 0xd4)
  234. {
  235. //printf("ACKed\n");
  236. if (DEBUG)
  237. {
  238. switch (waitForACK)
  239. {
  240. case 1:
  241. {
  242. printf("Association response ACKed\n");
  243. break;
  244. }
  245. case 2:
  246. {
  247. printf("Authentication frame ACKed\n");
  248. break;
  249. }
  250. case 3:
  251. {
  252. printf("Probe response ACKed\n");
  253. break;
  254. }
  255. default:
  256. {
  257. printf("Frame ACKed\n");
  258. break;
  259. }
  260. }
  261. }
  262. //if ACK was on Ass resp frame, only then increase fuzzer
  263. if (waitForACK == 1)
  264. {
  265. //disassociate if specified
  266. if (SENDDISASS == 1)
  267. {
  268. sleep(1);
  269. int packetSize;
  270. u_char *packet = createDisAss(sutMAC, &packetSize, radioTapHeader, myMAC);
  271. sendPacket(pcap_h, packet, packetSize);
  272. free(packet); //free allocated memory
  273. packet = createDisAss(sutMAC, &packetSize, radioTapHeader, myMAC);
  274. sendPacket(pcap_h, packet, packetSize);
  275. free(packet); //free allocated memory
  276. //sleep(1);
  277. /*packet = createDisAss(sutMAC, &packetSize, radioTapHeader, myMAC);
  278. sendPacket(pcap_h, packet, packetSize);
  279. free(packet); //free allocated memory
  280. packet = createDisAss(sutMAC, &packetSize, radioTapHeader, myMAC);
  281. sendPacket(pcap_h, packet, packetSize);
  282. free(packet); //free allocated memory
  283. packet = createDisAss(sutMAC, &packetSize, radioTapHeader, myMAC);
  284. sendPacket(pcap_h, packet, packetSize);
  285. free(packet); //free allocated memory*/
  286. }
  287. }
  288. if (waitForACK == 2)
  289. {
  290. increaseFuzzer(); //fuzz next thing
  291. }
  292. ackedFrames = ackedFrames + 1; //the frame is acked, so increase counter
  293. waitForACK = 0; //we should stop waiting for ack and move on
  294. noACKcounter = 0; //reset counter
  295. if (DEBUG)
  296. {
  297. //printf("Frame ACKed, fuzzStep is now %d\n", getFuzzStep());
  298. printf("Frame ACKed\n");
  299. }
  300. }
  301. else //received other frame. Ignore and keep listening
  302. {
  303. if (DEBUG)
  304. {
  305. printf("Got other frame. Will be ignored\n");
  306. }
  307. }
  308. }
  309. else //waited more than 10 ms for ack. failed
  310. {
  311. //printf("Did not capture an ACK in time\n");
  312. noACKcounter = noACKcounter + 1;
  313. if (noACKcounter == 5)
  314. {
  315. printf("\e[31mFrame not ACKed after 5 retries, moving on\e[39m\n");
  316. noACKcounter = 0;
  317. increaseFuzzer();
  318. }
  319. if (DEBUG)
  320. {
  321. printf("Not sure if frame was ACKed\n");
  322. }
  323. waitForACK = 0;
  324. }
  325. }
  326. else //Process frame depending on type
  327. {
  328. switch(frameType)
  329. {
  330. case 0x40:
  331. {
  332. int packetSize;
  333. u_char *packet = createProbeResponse(sourceAddr, &packetSize, radioTapHeader, myMAC);
  334. sendPacket(pcap_h, packet, packetSize);
  335. free(packet); //free allocated memory
  336. waitForACK = 0;
  337. startTimer();
  338. break;
  339. }
  340. case 0xb0:
  341. {
  342. int packetSize;
  343. u_char *packet = createAuthResponse(sourceAddr, &packetSize, radioTapHeader, myMAC);
  344. sendPacket(pcap_h, packet, packetSize);
  345. free(packet); //free allocated memory
  346. waitForACK = 2;
  347. startTimer();
  348. break;
  349. }
  350. case 0x00:
  351. {
  352. int packetSize;
  353. u_char *packet = createAssResponse(sourceAddr, &packetSize, radioTapHeader, myMAC);
  354. sendPacket(pcap_h, packet, packetSize);
  355. free(packet); //free allocated memory
  356. waitForACK = 1;
  357. startTimer();
  358. break;
  359. }
  360. case 0xd4:
  361. {
  362. break;
  363. }
  364. default: break;
  365. }
  366. }
  367. }
  368. return 0;
  369. }