hak5 fixes
[soho-sigint.git] / client-wifi / sohosigint / sohosigint-wifi.c
diff --git a/client-wifi/sohosigint/sohosigint-wifi.c b/client-wifi/sohosigint/sohosigint-wifi.c
new file mode 100644 (file)
index 0000000..b675f0d
--- /dev/null
@@ -0,0 +1,558 @@
+#include <pcap.h>
+#include <pcap.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <sys/socket.h>
+#include <ctype.h>
+#include <unistd.h>
+#include "radiotap.h"
+#include "radiotap_iter.h"
+#include <curl/curl.h>
+#include <json-c/json.h>
+#include <stdbool.h>
+#include <lorcon2/lorcon.h>
+
+const struct pcap_pkthdr* callback_header;
+
+time_t start = 0;
+int element = -1;
+int changechan=1;
+char *ssid_buf[50][2] = { NULL, NULL };
+char *probe_resp_buf[50][3] = { NULL, NULL };
+char *probe_buf[50][2] = { NULL, NULL };
+
+lorcon_t *context;
+int lchannel = 1;
+
+//char post_url[255] = "http://intranet.spangdorfia.com/butler/sohoinput.php";
+char *post_url = NULL;
+
+static uint8_t insecure = 0;
+
+static const struct radiotap_align_size align_size_000000_00[] = {
+  [0] = { .align = 1, .size = 4, },
+  [52] = { .align = 1, .size = 4, },
+};
+
+typedef struct {
+  u_int8_t        it_version;
+  u_int8_t        it_pad;
+  u_int16_t       it_len;
+  u_int32_t       it_present;
+
+  u_int32_t       pad;
+  u_int8_t        flags;
+  u_int8_t        rate;
+  u_int16_t       wr_chan_freq;
+  int8_t          ant_sig;
+  int8_t          lock_quality;
+  u_int8_t        ant;
+
+} __attribute__((__packed__)) ieee80211_radiotap;
+
+struct json_object *obj1, *obj2, *array, *tmp1, *tmp2;
+
+/*
+int change_chan(context) {
+  if (changechan==1) {
+    int gchannel=0;
+    changechan=0;
+    gchannel=lorcon_get_channel(context);
+    printf("got channel %d", gchannel);
+    lchannel=gchannel+1;
+    if (lchannel == 14) {
+      lchannel=1;
+    }
+    printf("Setting channel %d\n", lchannel);
+    lorcon_set_channel(context, lchannel);
+    changechan=1;
+  }
+}
+*/
+
+void send_data(json_object *array) {
+
+  //printf("curl start\n");
+  CURL *curl;
+  CURLcode res;
+
+  struct curl_slist *headers = NULL;
+
+  headers = curl_slist_append(headers, "Accept: application/json");
+  headers = curl_slist_append(headers, "Content-Type: application/json");
+
+  //json_object *obj1 = json_object_new_object();
+  //json_object *jvs = json_object_new_string("1");
+  //json_object *japmac = json_object_new_string(ap_mac);
+  //json_object *jlat = json_object_new_double(lat);
+  //json_object *jlng = json_object_new_double(lng);
+
+  //json_object_object_add(obj1,"v", jvs);
+  //json_object_object_add(obj1,"ap_mac", japmac);
+  //json_object_object_add(obj1,"data", array);
+  //json_object_object_add(obj1,"lat", jlat);
+  //json_object_object_add(obj1,"lng", jlng);
+
+  curl = curl_easy_init();
+
+  if(curl) {
+
+    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, NULL);
+    curl_easy_setopt(curl, CURLOPT_URL, post_url);
+    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
+    curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST");
+    curl_easy_setopt(curl, CURLOPT_USERAGENT, "SoHoSIGINT");
+    curl_easy_setopt(curl, CURLOPT_POSTFIELDS, json_object_to_json_string(array));
+
+    if (insecure) {
+      curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, FALSE);
+    }
+
+    //printf("Sending this: %s\n",json_object_to_json_string(array));
+
+    //openlog(SYSLOG_NAME, LOG_PID|LOG_CONS, LOG_USER);
+    res = curl_easy_perform(curl);
+
+    if(res != CURLE_OK) {
+      printf("There was a problem sending to %s\n", post_url);
+      //syslog (LOG_INFO, "couldn't send JSON.");
+    } else {
+      //printf("sent JSON to %s\n", post_url);
+    }
+    //closelog ();
+    curl_easy_cleanup(curl);
+    curl_slist_free_all(headers);
+    //json_object_put(obj1);
+  }
+
+  curl_global_cleanup();
+  //printf("curl end\n");
+}
+
+
+void my_callback(u_char *args,const struct pcap_pkthdr* pkthdr,const u_char* packet) {
+
+  int err, radiotap_header_len, ssid_len, i;
+  int8_t rssi, rate, flags, fcsfail;
+  u_int16_t channel;
+  char client_mac[18];
+  char bssid_mac[18];
+  char ssid[32];
+  char tmp_channel[2];
+  char tmp_rssi[1];
+  
+  int diff;
+
+  if (start == 0) {
+    start = time(0);
+  }
+
+  time_t t0 = time(0);
+
+  if ( json_object_get_type(array) != json_type_array) {
+    //printf("type of json= %d\n", json_object_get_type(array) == json_type_array);
+    array = json_object_new_array();
+  };
+
+  struct ieee80211_radiotap_iterator iter;
+
+  radiotap_header_len = iter._max_length;
+
+  err = ieee80211_radiotap_iterator_init(&iter, (void*)packet, pkthdr->caplen, NULL);
+  if (err > 0) {
+  }
+
+  radiotap_header_len = iter._max_length;
+
+  fcsfail = 0;
+  while (!(err = ieee80211_radiotap_iterator_next(&iter))) {
+    if (iter.this_arg_index == IEEE80211_RADIOTAP_DBM_ANTSIGNAL) {
+      rssi = (int8_t)iter.this_arg[0];
+    }
+    if (iter.this_arg_index == IEEE80211_RADIOTAP_CHANNEL) {
+      channel = (*(uint16_t *)iter.this_arg);
+    }
+    if (iter.this_arg_index == IEEE80211_RADIOTAP_RATE) {
+      rate = (u_int8_t)iter.this_arg[0];
+    }
+    if (iter.this_arg_index == IEEE80211_RADIOTAP_FLAGS) {
+      flags = (*(u_int8_t *)iter.this_arg);
+      if (flags & IEEE80211_RADIOTAP_F_BADFCS) {
+        printf("bad fcs\n");
+        fcsfail=1;
+        break;
+      }
+      if (flags & IEEE80211_RADIOTAP_F_FRAG) {
+        printf("frag\n");
+      }
+      if (flags & IEEE80211_RADIOTAP_F_CFP) {
+        printf("cfp\n");
+      }
+    }
+  };
+
+  sprintf(tmp_channel, "%04x", channel);
+  sprintf(tmp_rssi, "%d", rssi);
+
+  int counter=0;
+  if (pkthdr->len >= 24) {
+    u_int8_t hlen;
+    //hlen = packet[2]+(packet[3]<<8); //Usually 18 or 13 in some cases
+    hlen=36+2;
+    //hlen=38;
+    switch (packet[hlen]) {
+      case 0x40: //probe request
+       printf("probe request\n");
+
+        //while (counter<pkthdr->len) {
+        //  printf("%02x",packet[counter]);
+        //  counter++;
+        //}
+        //printf("\n");
+
+        ssid_len=packet[61+2];
+
+       memset(ssid, 0, sizeof(ssid));
+
+       if (ssid_len>0) {
+          for (i=0;i<ssid_len;++i){
+            sprintf(ssid+i, "%c", packet[64+i]);
+          }
+         //printf("dongs %s  size %d\n", ssid, sizeof(ssid));
+        } else {
+          sprintf(ssid,"[HIDDEN]");
+        }
+
+        memset(client_mac, 0, sizeof(client_mac));
+        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]);
+
+        for (i=0; i<50; i++) {
+          if (probe_buf[i][0] != NULL) {
+            if ((strcoll(probe_buf[i][0], ssid) == 0 && strcoll(probe_buf[i][1], client_mac) == 0)) {
+              break;
+            }
+          }
+          if (probe_buf[i][0] == NULL) {
+              if (element < i) {
+                element=i;
+              }
+             //printf("probe element: %d\n", element);
+              probe_buf[i][0] = strdup(ssid);
+              probe_buf[i][1] = strdup(client_mac);
+              obj2 = json_object_new_object();
+              json_object *type = json_object_new_string("40");
+              json_object *tssid = json_object_new_string(ssid);
+              json_object *tclient_mac = json_object_new_string(client_mac);
+              json_object *tchannel = json_object_new_string(tmp_channel);
+              json_object *jrssi = json_object_new_string(tmp_rssi);
+              json_object_object_add(obj2,"type", type);
+              json_object_object_add(obj2,"ssid", tssid);
+              json_object_object_add(obj2,"client_mac", tclient_mac);
+              json_object_object_add(obj2,"channel", tchannel);
+              json_object_object_add(obj2,"rssi", jrssi);
+              json_object_array_add(array,obj2);
+              break;
+            }
+        }
+        break;
+      case 0x50: //probe response
+       printf("probe response\n");
+
+        //while (counter<pkthdr->len) {
+          //printf("%02x",packet[counter]);
+          //counter++;
+        //}
+        //printf("\n");
+
+        ssid_len=packet[75];
+
+       memset(ssid, 0, sizeof(ssid));
+
+       if (ssid_len>0) {
+          for (i=0;i<ssid_len;++i){
+            sprintf(ssid+i, "%c", packet[76+i]);
+          }
+        } else {
+          sprintf(ssid,"[HIDDEN]");
+        }
+
+        //was 39-44
+        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]);
+        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]);
+
+        for (i=0; i<50; i++) {
+          if (probe_resp_buf[i][0] != NULL) {
+            if ((strcoll(probe_resp_buf[i][0], ssid) == 0 && strcoll(probe_resp_buf[i][1], client_mac) == 0)) {
+              break;
+            }
+          }
+          if (probe_resp_buf[i][0] == NULL) {
+              if (element < i) {
+                element=i;
+              }
+             //printf("probe response element: %d\n", element);
+              probe_resp_buf[i][0] = strdup(ssid);
+              probe_resp_buf[i][1] = strdup(client_mac);
+              probe_resp_buf[i][2] = strdup(bssid_mac);
+              obj2 = json_object_new_object();
+              json_object *type = json_object_new_string("50");
+              json_object *tssid = json_object_new_string(ssid);
+              json_object *tclient_mac = json_object_new_string(client_mac);
+              json_object *tbssid_mac = json_object_new_string(bssid_mac);
+              json_object *tchannel = json_object_new_string(tmp_channel);
+              json_object *jrssi = json_object_new_string(tmp_rssi);
+              json_object_object_add(obj2,"type", type);
+              json_object_object_add(obj2,"ssid", tssid);
+              json_object_object_add(obj2,"client_mac", tclient_mac);
+              json_object_object_add(obj2,"bssid_mac", tbssid_mac);
+              json_object_object_add(obj2,"channel", tchannel);
+              json_object_object_add(obj2,"rssi", jrssi);
+              json_object_array_add(array,obj2);
+              break;
+            }
+        }
+        break;
+      case 0x80: //beacon
+       //printf("beacon\n");
+        ssid_len=packet[73+2];
+       //printf("length %d\n", ssid_len);
+       //int counter=0;
+       //while (counter<pkthdr->len) {
+       //  printf("%02x",packet[counter]);
+       //  counter++;
+       //}
+       //printf("\n");
+
+       memset(ssid, 0, sizeof(ssid));
+       
+        if (ssid_len>0) {
+          for (i=0;i<ssid_len;++i){
+            sprintf(ssid+i, "%c", packet[76+i]);
+           //sprintf(ssid[i], "%c", packet[76+i]);
+          }
+        } else {
+          sprintf(ssid,"[HIDDEN]");
+        }
+
+        if (ssid_len == 15 && strlen(ssid) == 0) {
+          sprintf(ssid,"[truncated]");
+        } 
+        //printf("debug ssid: %s  fieldlen: %d strlen: %d\n", ssid, ssid_len, strlen(ssid));
+        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]);
+
+        for (i=0; i<50; i++) {
+          if (ssid_buf[i][0] != NULL) {
+            if ((strcoll(ssid_buf[i][0], ssid) == 0 && strcoll(ssid_buf[i][1], client_mac) == 0)) {
+              break;
+            }
+          }
+          if (ssid_buf[i][0] == NULL) {
+              if (element < i) {
+                element=i;
+              }
+             //printf("ssid element: %d\n", element);
+              ssid_buf[i][0] = strdup(ssid);
+              ssid_buf[i][1] = strdup(client_mac);
+              obj2 = json_object_new_object();
+              json_object *type = json_object_new_string("80");
+              json_object *tssid = json_object_new_string(ssid);
+              json_object *tclient_mac = json_object_new_string(client_mac);
+              json_object *tchannel = json_object_new_string(tmp_channel);
+              json_object *jrssi = json_object_new_string(tmp_rssi);
+              json_object_object_add(obj2,"type", type);
+              json_object_object_add(obj2,"ssid", tssid);
+              json_object_object_add(obj2,"bssid", tclient_mac);
+              json_object_object_add(obj2,"channel", tchannel);
+              json_object_object_add(obj2,"rssi", jrssi);
+              json_object_array_add(array,obj2);
+              break;
+            }
+        }
+        break;
+      //default:
+        //printf("Got something different: %02x\n", packet[hlen]);
+        //printf("hlen: %d\n", hlen);
+        //break;
+    }
+  };
+
+  diff = (t0 - start);
+
+  if ((diff >= 5) || (element == 25)) {
+    printf("time to barf!\n");
+    //printf("size: %d\n", element);
+    //change_chan(context);
+    int gchannel=0;
+    gchannel=lorcon_get_channel(context);
+    //printf("got channel %d", gchannel);
+    lchannel=gchannel+1;
+    if (lchannel == 14) {
+      lchannel=1;
+    }
+    //printf("Setting channel %d\n", lchannel);
+    lorcon_set_channel(context, lchannel);
+
+    lorcon_set_channel(context, lchannel);
+    /*
+    for (i=0; i<34; i++) {
+      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]);
+    }
+    for (i=0; i<34; i++) {
+      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]);
+    }
+    for (i=0; i<34; i++) {
+      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]);
+    }
+    */
+
+    if (element >= 0) {
+      //printf("barfing\n");
+      send_data(array);
+      //printf ("The json object created: %s\n",json_object_to_json_string(array));
+      json_object_put(array);
+
+      memset(ssid_buf, 0, sizeof(ssid_buf));
+      memset(probe_resp_buf, 0, sizeof(probe_resp_buf));
+      memset(probe_buf, 0, sizeof(probe_buf));
+      element=-1;
+    }
+    start = time(0);
+  }
+  //printf("rate: %d  channel: %04x  rssi: %d\n", rate, channel, rssi);
+}
+
+int main(int argc,char **argv)
+{
+  int c;
+  char *dev = NULL; 
+  char *interface = NULL;
+  lorcon_driver_t *drvlist, *driver;
+  //lorcon_t *context;
+  char errbuf[PCAP_ERRBUF_SIZE];
+  pcap_t* pcap;
+  struct bpf_program fp;      /* hold compiled program     */
+  bpf_u_int32 maskp;          /* subnet mask               */
+  bpf_u_int32 netp;           /* ip                        */
+  u_char* args = NULL;
+  char filter_exp[] = "";
+  char *totpacket = NULL;
+
+  while ((c = getopt (argc, argv, "ha:i:p:")) != -1)
+    switch (c) {
+      case 'a':
+        totpacket = optarg;
+        break;
+      case 'i':
+        interface = optarg;
+        break;
+      case 'p':
+        post_url = optarg;
+        break;
+      case 'h':
+        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");
+        exit(0);
+      default:
+        return 0;
+     }
+
+  if (totpacket == NULL) {
+    totpacket="-1";
+    printf("-a not specified... looping forever.\n");
+  }
+
+  if (interface == NULL) {
+    printf("You forgot -i\n");
+    exit(0);
+  }
+
+  if (post_url == NULL) {
+    printf("You forgot -p\n");
+    exit(0);
+  }
+
+  //printf ("%s %s\n", totpacket, dev);
+
+  //if(interface == NULL) {
+  //  printf("%s\n",errbuf); 
+  //  exit(1); 
+  //}
+
+  if ( (driver = lorcon_auto_driver(interface)) == NULL) {
+    printf("[!] Could not determine the driver for %s\n",interface);
+    return -1;
+  } else {
+    printf("[+]\t Driver: %s\n",driver->name);
+  }
+
+  // Create LORCON context
+  if ((context = lorcon_create(interface, driver)) == NULL) {
+    printf("[!]\t Failed to create context");
+    return -1;
+  }
+
+  // Create Monitor Mode Interface
+  if (lorcon_open_monitor(context) < 0) {
+    printf("[!]\t Could not create Monitor Mode interface!\n");
+    return -1;
+  } else {
+    printf("[+]\t Monitor Mode VAP: %s\n",lorcon_get_vap(context));
+    lorcon_free_driver_list(driver);
+  }
+
+  // Set the channel we'll be injecting on
+  lorcon_set_channel(context, lchannel);
+
+  dev=lorcon_get_vap(context);
+
+  /* ask pcap for the network address and mask of the device */
+  pcap_lookupnet(dev,&netp,&maskp,errbuf);
+
+  /* open device for reading. NOTE: defaulting to
+   * promiscuous mode*/
+  pcap = pcap_open_live(dev,2346,1,1000,errbuf);
+  pcap_set_promisc(pcap, 1);
+
+  if(pcap == NULL) {
+    printf("pcap_open_live(): %s\n",errbuf); 
+    exit(1); 
+  }
+
+  pcap_set_datalink(pcap, DLT_IEEE802_11);
+  pcap_set_datalink(pcap, DLT_IEEE802_11_RADIO_AVS);
+  pcap_set_datalink(pcap, DLT_IEEE802_11_RADIO);
+
+  //pcap_setnonblock(pcap, 1, errbuf); 
+
+  int link_layer_type = pcap_datalink(pcap);
+
+  //printf("type: %d\n", link_layer_type);
+
+  if (link_layer_type == DLT_PRISM_HEADER ||
+      link_layer_type == DLT_IEEE802_11_RADIO ||
+      link_layer_type == DLT_IEEE802_11_RADIO_AVS ||
+      link_layer_type == DLT_IEEE802_11 ||
+      link_layer_type == DLT_PPI ||
+      link_layer_type == 127 ) {
+    if (pcap_compile(pcap, &fp, filter_exp, 0, netp) == -1) {
+      fprintf(stderr, "Couldn't parse filter %s: %s\n", filter_exp, pcap_geterr(pcap));
+      exit(EXIT_FAILURE);
+    }
+    if (pcap_setfilter(pcap, &fp) == -1) {
+      fprintf(stderr, "Couldn't install filter %s: %s\n",
+        filter_exp, pcap_geterr(pcap));
+      exit(EXIT_FAILURE);
+    }
+    printf("starting\n");
+
+    pcap_loop(pcap,atoi(totpacket),my_callback,NULL);
+  } else {
+    fprintf(stderr, "Not using the Wi-Fi interface, are you testing something?\n");
+  }
+  fprintf(stdout,"\nfinished\n");
+  return 0;
+}
+
+