cfuzz.c 12 KB

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