hak5 fixes
[soho-sigint.git] / client-wifi / sohosigint / sohosigint-wifi.c
1 #include <pcap.h>
2 #include <pcap.h>
3 #include <stdio.h>
4 #include <string.h>
5 #include <stdlib.h>
6 #include <errno.h>
7 #include <sys/socket.h>
8 #include <ctype.h>
9 #include <unistd.h>
10 #include "radiotap.h"
11 #include "radiotap_iter.h"
12 #include <curl/curl.h>
13 #include <json-c/json.h>
14 #include <stdbool.h>
15 #include <lorcon2/lorcon.h>
16
17 const struct pcap_pkthdr* callback_header;
18
19 time_t start = 0;
20 int element = -1;
21 int changechan=1;
22 char *ssid_buf[50][2] = { NULL, NULL };
23 char *probe_resp_buf[50][3] = { NULL, NULL };
24 char *probe_buf[50][2] = { NULL, NULL };
25
26 lorcon_t *context;
27 int lchannel = 1;
28
29 //char post_url[255] = "http://intranet.spangdorfia.com/butler/sohoinput.php";
30 char *post_url = NULL;
31
32 static uint8_t insecure = 0;
33
34 static const struct radiotap_align_size align_size_000000_00[] = {
35   [0] = { .align = 1, .size = 4, },
36   [52] = { .align = 1, .size = 4, },
37 };
38
39 typedef struct {
40   u_int8_t        it_version;
41   u_int8_t        it_pad;
42   u_int16_t       it_len;
43   u_int32_t       it_present;
44
45   u_int32_t       pad;
46   u_int8_t        flags;
47   u_int8_t        rate;
48   u_int16_t       wr_chan_freq;
49   int8_t          ant_sig;
50   int8_t          lock_quality;
51   u_int8_t        ant;
52
53 } __attribute__((__packed__)) ieee80211_radiotap;
54
55 struct json_object *obj1, *obj2, *array, *tmp1, *tmp2;
56
57 /*
58 int change_chan(context) {
59   if (changechan==1) {
60     int gchannel=0;
61     changechan=0;
62     gchannel=lorcon_get_channel(context);
63     printf("got channel %d", gchannel);
64     lchannel=gchannel+1;
65     if (lchannel == 14) {
66       lchannel=1;
67     }
68     printf("Setting channel %d\n", lchannel);
69     lorcon_set_channel(context, lchannel);
70     changechan=1;
71   }
72 }
73 */
74
75 void send_data(json_object *array) {
76
77   //printf("curl start\n");
78   CURL *curl;
79   CURLcode res;
80
81   struct curl_slist *headers = NULL;
82
83   headers = curl_slist_append(headers, "Accept: application/json");
84   headers = curl_slist_append(headers, "Content-Type: application/json");
85
86   //json_object *obj1 = json_object_new_object();
87   //json_object *jvs = json_object_new_string("1");
88   //json_object *japmac = json_object_new_string(ap_mac);
89   //json_object *jlat = json_object_new_double(lat);
90   //json_object *jlng = json_object_new_double(lng);
91
92   //json_object_object_add(obj1,"v", jvs);
93   //json_object_object_add(obj1,"ap_mac", japmac);
94   //json_object_object_add(obj1,"data", array);
95   //json_object_object_add(obj1,"lat", jlat);
96   //json_object_object_add(obj1,"lng", jlng);
97
98   curl = curl_easy_init();
99
100   if(curl) {
101
102     curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, NULL);
103     curl_easy_setopt(curl, CURLOPT_URL, post_url);
104     curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
105     curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST");
106     curl_easy_setopt(curl, CURLOPT_USERAGENT, "SoHoSIGINT");
107     curl_easy_setopt(curl, CURLOPT_POSTFIELDS, json_object_to_json_string(array));
108
109     if (insecure) {
110       curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, FALSE);
111     }
112
113     //printf("Sending this: %s\n",json_object_to_json_string(array));
114
115     //openlog(SYSLOG_NAME, LOG_PID|LOG_CONS, LOG_USER);
116     res = curl_easy_perform(curl);
117
118     if(res != CURLE_OK) {
119       printf("There was a problem sending to %s\n", post_url);
120       //syslog (LOG_INFO, "couldn't send JSON.");
121     } else {
122       //printf("sent JSON to %s\n", post_url);
123     }
124     //closelog ();
125     curl_easy_cleanup(curl);
126     curl_slist_free_all(headers);
127     //json_object_put(obj1);
128   }
129
130   curl_global_cleanup();
131   //printf("curl end\n");
132 }
133
134
135 void my_callback(u_char *args,const struct pcap_pkthdr* pkthdr,const u_char* packet) {
136
137   int err, radiotap_header_len, ssid_len, i;
138   int8_t rssi, rate, flags, fcsfail;
139   u_int16_t channel;
140   char client_mac[18];
141   char bssid_mac[18];
142   char ssid[32];
143   char tmp_channel[2];
144   char tmp_rssi[1];
145   
146   int diff;
147
148   if (start == 0) {
149     start = time(0);
150   }
151
152   time_t t0 = time(0);
153
154   if ( json_object_get_type(array) != json_type_array) {
155     //printf("type of json= %d\n", json_object_get_type(array) == json_type_array);
156     array = json_object_new_array();
157   };
158
159   struct ieee80211_radiotap_iterator iter;
160
161   radiotap_header_len = iter._max_length;
162
163   err = ieee80211_radiotap_iterator_init(&iter, (void*)packet, pkthdr->caplen, NULL);
164   if (err > 0) {
165   }
166
167   radiotap_header_len = iter._max_length;
168
169   fcsfail = 0;
170   while (!(err = ieee80211_radiotap_iterator_next(&iter))) {
171     if (iter.this_arg_index == IEEE80211_RADIOTAP_DBM_ANTSIGNAL) {
172       rssi = (int8_t)iter.this_arg[0];
173     }
174     if (iter.this_arg_index == IEEE80211_RADIOTAP_CHANNEL) {
175       channel = (*(uint16_t *)iter.this_arg);
176     }
177     if (iter.this_arg_index == IEEE80211_RADIOTAP_RATE) {
178       rate = (u_int8_t)iter.this_arg[0];
179     }
180     if (iter.this_arg_index == IEEE80211_RADIOTAP_FLAGS) {
181       flags = (*(u_int8_t *)iter.this_arg);
182       if (flags & IEEE80211_RADIOTAP_F_BADFCS) {
183         printf("bad fcs\n");
184         fcsfail=1;
185         break;
186       }
187       if (flags & IEEE80211_RADIOTAP_F_FRAG) {
188         printf("frag\n");
189       }
190       if (flags & IEEE80211_RADIOTAP_F_CFP) {
191         printf("cfp\n");
192       }
193     }
194   };
195
196   sprintf(tmp_channel, "%04x", channel);
197   sprintf(tmp_rssi, "%d", rssi);
198
199   int counter=0;
200  
201   if (pkthdr->len >= 24) {
202     u_int8_t hlen;
203     //hlen = packet[2]+(packet[3]<<8); //Usually 18 or 13 in some cases
204     hlen=36+2;
205     //hlen=38;
206     switch (packet[hlen]) {
207       case 0x40: //probe request
208         printf("probe request\n");
209
210         //while (counter<pkthdr->len) {
211         //  printf("%02x",packet[counter]);
212         //  counter++;
213         //}
214         //printf("\n");
215
216         ssid_len=packet[61+2];
217
218         memset(ssid, 0, sizeof(ssid));
219
220         if (ssid_len>0) {
221           for (i=0;i<ssid_len;++i){
222             sprintf(ssid+i, "%c", packet[64+i]);
223           }
224           //printf("dongs %s  size %d\n", ssid, sizeof(ssid));
225         } else {
226           sprintf(ssid,"[HIDDEN]");
227         }
228
229         memset(client_mac, 0, sizeof(client_mac));
230         sprintf(client_mac, "%02x:%02x:%02x:%02x:%02x:%02x", packet[46+2], packet[47+2],packet[48+2],packet[49+2],packet[50+2],packet[51+2]);
231
232         for (i=0; i<50; i++) {
233           if (probe_buf[i][0] != NULL) {
234             if ((strcoll(probe_buf[i][0], ssid) == 0 && strcoll(probe_buf[i][1], client_mac) == 0)) {
235               break;
236             }
237           }
238           if (probe_buf[i][0] == NULL) {
239               if (element < i) {
240                 element=i;
241               }
242               //printf("probe element: %d\n", element);
243               probe_buf[i][0] = strdup(ssid);
244               probe_buf[i][1] = strdup(client_mac);
245               obj2 = json_object_new_object();
246               json_object *type = json_object_new_string("40");
247               json_object *tssid = json_object_new_string(ssid);
248               json_object *tclient_mac = json_object_new_string(client_mac);
249               json_object *tchannel = json_object_new_string(tmp_channel);
250               json_object *jrssi = json_object_new_string(tmp_rssi);
251               json_object_object_add(obj2,"type", type);
252               json_object_object_add(obj2,"ssid", tssid);
253               json_object_object_add(obj2,"client_mac", tclient_mac);
254               json_object_object_add(obj2,"channel", tchannel);
255               json_object_object_add(obj2,"rssi", jrssi);
256               json_object_array_add(array,obj2);
257               break;
258             }
259         }
260         break;
261       case 0x50: //probe response
262         printf("probe response\n");
263
264         //while (counter<pkthdr->len) {
265           //printf("%02x",packet[counter]);
266           //counter++;
267         //}
268         //printf("\n");
269
270         ssid_len=packet[75];
271
272         memset(ssid, 0, sizeof(ssid));
273
274         if (ssid_len>0) {
275           for (i=0;i<ssid_len;++i){
276             sprintf(ssid+i, "%c", packet[76+i]);
277           }
278         } else {
279           sprintf(ssid,"[HIDDEN]");
280         }
281
282         //was 39-44
283         sprintf(client_mac, "%02x:%02x:%02x:%02x:%02x:%02x", packet[40+2], packet[41+2],packet[42+2],packet[43+2],packet[44+2],packet[45+2]);
284         sprintf(bssid_mac, "%02x:%02x:%02x:%02x:%02x:%02x", packet[52+2], packet[53+2],packet[54+2],packet[55+2],packet[56+2],packet[57+2]);
285
286         for (i=0; i<50; i++) {
287           if (probe_resp_buf[i][0] != NULL) {
288             if ((strcoll(probe_resp_buf[i][0], ssid) == 0 && strcoll(probe_resp_buf[i][1], client_mac) == 0)) {
289               break;
290             }
291           }
292           if (probe_resp_buf[i][0] == NULL) {
293               if (element < i) {
294                 element=i;
295               }
296               //printf("probe response element: %d\n", element);
297               probe_resp_buf[i][0] = strdup(ssid);
298               probe_resp_buf[i][1] = strdup(client_mac);
299               probe_resp_buf[i][2] = strdup(bssid_mac);
300               obj2 = json_object_new_object();
301               json_object *type = json_object_new_string("50");
302               json_object *tssid = json_object_new_string(ssid);
303               json_object *tclient_mac = json_object_new_string(client_mac);
304               json_object *tbssid_mac = json_object_new_string(bssid_mac);
305               json_object *tchannel = json_object_new_string(tmp_channel);
306               json_object *jrssi = json_object_new_string(tmp_rssi);
307               json_object_object_add(obj2,"type", type);
308               json_object_object_add(obj2,"ssid", tssid);
309               json_object_object_add(obj2,"client_mac", tclient_mac);
310               json_object_object_add(obj2,"bssid_mac", tbssid_mac);
311               json_object_object_add(obj2,"channel", tchannel);
312               json_object_object_add(obj2,"rssi", jrssi);
313               json_object_array_add(array,obj2);
314               break;
315             }
316         }
317         break;
318       case 0x80: //beacon
319         //printf("beacon\n");
320         ssid_len=packet[73+2];
321         //printf("length %d\n", ssid_len);
322         //int counter=0;
323         //while (counter<pkthdr->len) {
324         //  printf("%02x",packet[counter]);
325         //  counter++;
326         //}
327         //printf("\n");
328
329         memset(ssid, 0, sizeof(ssid));
330         
331         if (ssid_len>0) {
332           for (i=0;i<ssid_len;++i){
333             sprintf(ssid+i, "%c", packet[76+i]);
334             //sprintf(ssid[i], "%c", packet[76+i]);
335           }
336         } else {
337           sprintf(ssid,"[HIDDEN]");
338         }
339
340         if (ssid_len == 15 && strlen(ssid) == 0) {
341           sprintf(ssid,"[truncated]");
342         } 
343         //printf("debug ssid: %s  fieldlen: %d strlen: %d\n", ssid, ssid_len, strlen(ssid));
344         sprintf(client_mac, "%02x:%02x:%02x:%02x:%02x:%02x", packet[52+2], packet[53+2],packet[54+2],packet[55+2],packet[56+2],packet[57+2]);
345
346         for (i=0; i<50; i++) {
347           if (ssid_buf[i][0] != NULL) {
348             if ((strcoll(ssid_buf[i][0], ssid) == 0 && strcoll(ssid_buf[i][1], client_mac) == 0)) {
349               break;
350             }
351           }
352           if (ssid_buf[i][0] == NULL) {
353               if (element < i) {
354                 element=i;
355               }
356               //printf("ssid element: %d\n", element);
357               ssid_buf[i][0] = strdup(ssid);
358               ssid_buf[i][1] = strdup(client_mac);
359               obj2 = json_object_new_object();
360               json_object *type = json_object_new_string("80");
361               json_object *tssid = json_object_new_string(ssid);
362               json_object *tclient_mac = json_object_new_string(client_mac);
363               json_object *tchannel = json_object_new_string(tmp_channel);
364               json_object *jrssi = json_object_new_string(tmp_rssi);
365               json_object_object_add(obj2,"type", type);
366               json_object_object_add(obj2,"ssid", tssid);
367               json_object_object_add(obj2,"bssid", tclient_mac);
368               json_object_object_add(obj2,"channel", tchannel);
369               json_object_object_add(obj2,"rssi", jrssi);
370               json_object_array_add(array,obj2);
371               break;
372             }
373         }
374         break;
375       //default:
376         //printf("Got something different: %02x\n", packet[hlen]);
377         //printf("hlen: %d\n", hlen);
378         //break;
379     }
380   };
381
382   diff = (t0 - start);
383
384   if ((diff >= 5) || (element == 25)) {
385     printf("time to barf!\n");
386     //printf("size: %d\n", element);
387     //change_chan(context);
388     int gchannel=0;
389     gchannel=lorcon_get_channel(context);
390     //printf("got channel %d", gchannel);
391     lchannel=gchannel+1;
392     if (lchannel == 14) {
393       lchannel=1;
394     }
395     //printf("Setting channel %d\n", lchannel);
396     lorcon_set_channel(context, lchannel);
397
398     lorcon_set_channel(context, lchannel);
399     /*
400     for (i=0; i<34; i++) {
401       printf("barf beacons: buffer %d, ssid: %s \t\t mac: %s  channel: %s rssi: %s\n", i, ssid_buf[i][0], ssid_buf[i][1], ssid_buf[i][2], ssid_buf[i][3]);
402     }
403     for (i=0; i<34; i++) {
404       printf("barf probe reponses: buffer %d, ssid: %s \t mac: %s mac: %s  channel: %s rssi: %s\n", i, probe_resp_buf[i][0], probe_resp_buf[i][1], probe_resp_buf[i][2], probe_resp_buf[i][3], probe_resp_buf[i][4]);
405     }
406     for (i=0; i<34; i++) {
407       printf("barf probes: buffer %d, ssid: %s \t mac: %s channel: %s rssi: %s\n", i, probe_buf[i][0], probe_buf[i][1], probe_buf[i][2], probe_buf[i][3]);
408     }
409     */
410
411     if (element >= 0) {
412       //printf("barfing\n");
413       send_data(array);
414       //printf ("The json object created: %s\n",json_object_to_json_string(array));
415       json_object_put(array);
416
417       memset(ssid_buf, 0, sizeof(ssid_buf));
418       memset(probe_resp_buf, 0, sizeof(probe_resp_buf));
419       memset(probe_buf, 0, sizeof(probe_buf));
420       element=-1;
421     }
422     start = time(0);
423   }
424   //printf("rate: %d  channel: %04x  rssi: %d\n", rate, channel, rssi);
425 }
426
427 int main(int argc,char **argv)
428 {
429   int c;
430   char *dev = NULL; 
431   char *interface = NULL;
432   lorcon_driver_t *drvlist, *driver;
433   //lorcon_t *context;
434   char errbuf[PCAP_ERRBUF_SIZE];
435   pcap_t* pcap;
436   struct bpf_program fp;      /* hold compiled program     */
437   bpf_u_int32 maskp;          /* subnet mask               */
438   bpf_u_int32 netp;           /* ip                        */
439   u_char* args = NULL;
440   char filter_exp[] = "";
441   char *totpacket = NULL;
442
443   while ((c = getopt (argc, argv, "ha:i:p:")) != -1)
444     switch (c) {
445       case 'a':
446         totpacket = optarg;
447         break;
448       case 'i':
449         interface = optarg;
450         break;
451       case 'p':
452         post_url = optarg;
453         break;
454       case 'h':
455         printf("./disect -a -i\n\t-a : number of packets to sniff. (default 10)\n\t-i : wlan interface.\n\t-p : URL for your collector.\n");
456         exit(0);
457       default:
458         return 0;
459      }
460
461   if (totpacket == NULL) {
462     totpacket="-1";
463     printf("-a not specified... looping forever.\n");
464   }
465
466   if (interface == NULL) {
467     printf("You forgot -i\n");
468     exit(0);
469   }
470
471   if (post_url == NULL) {
472     printf("You forgot -p\n");
473     exit(0);
474   }
475
476   //printf ("%s %s\n", totpacket, dev);
477
478   //if(interface == NULL) {
479   //  printf("%s\n",errbuf); 
480   //  exit(1); 
481   //}
482
483   if ( (driver = lorcon_auto_driver(interface)) == NULL) {
484     printf("[!] Could not determine the driver for %s\n",interface);
485     return -1;
486   } else {
487     printf("[+]\t Driver: %s\n",driver->name);
488   }
489
490   // Create LORCON context
491   if ((context = lorcon_create(interface, driver)) == NULL) {
492     printf("[!]\t Failed to create context");
493     return -1;
494   }
495
496   // Create Monitor Mode Interface
497   if (lorcon_open_monitor(context) < 0) {
498     printf("[!]\t Could not create Monitor Mode interface!\n");
499     return -1;
500   } else {
501     printf("[+]\t Monitor Mode VAP: %s\n",lorcon_get_vap(context));
502     lorcon_free_driver_list(driver);
503   }
504
505   // Set the channel we'll be injecting on
506   lorcon_set_channel(context, lchannel);
507
508   dev=lorcon_get_vap(context);
509
510   /* ask pcap for the network address and mask of the device */
511   pcap_lookupnet(dev,&netp,&maskp,errbuf);
512
513   /* open device for reading. NOTE: defaulting to
514    * promiscuous mode*/
515   pcap = pcap_open_live(dev,2346,1,1000,errbuf);
516   pcap_set_promisc(pcap, 1);
517
518   if(pcap == NULL) {
519     printf("pcap_open_live(): %s\n",errbuf); 
520     exit(1); 
521   }
522
523   pcap_set_datalink(pcap, DLT_IEEE802_11);
524   pcap_set_datalink(pcap, DLT_IEEE802_11_RADIO_AVS);
525   pcap_set_datalink(pcap, DLT_IEEE802_11_RADIO);
526
527   //pcap_setnonblock(pcap, 1, errbuf); 
528
529   int link_layer_type = pcap_datalink(pcap);
530
531   //printf("type: %d\n", link_layer_type);
532
533   if (link_layer_type == DLT_PRISM_HEADER ||
534       link_layer_type == DLT_IEEE802_11_RADIO ||
535       link_layer_type == DLT_IEEE802_11_RADIO_AVS ||
536       link_layer_type == DLT_IEEE802_11 ||
537       link_layer_type == DLT_PPI ||
538       link_layer_type == 127 ) {
539     if (pcap_compile(pcap, &fp, filter_exp, 0, netp) == -1) {
540       fprintf(stderr, "Couldn't parse filter %s: %s\n", filter_exp, pcap_geterr(pcap));
541       exit(EXIT_FAILURE);
542     }
543     if (pcap_setfilter(pcap, &fp) == -1) {
544       fprintf(stderr, "Couldn't install filter %s: %s\n",
545         filter_exp, pcap_geterr(pcap));
546       exit(EXIT_FAILURE);
547     }
548     printf("starting\n");
549
550     pcap_loop(pcap,atoi(totpacket),my_callback,NULL);
551   } else {
552     fprintf(stderr, "Not using the Wi-Fi interface, are you testing something?\n");
553   }
554   fprintf(stdout,"\nfinished\n");
555   return 0;
556 }
557
558