const void *build_ssid_tagged_parameter(size_t *len) { const void *buf = NULL, *ssid_param = NULL; size_t ssid_len = 0, ssid_param_len = 0, buf_len = 0; if(get_ssid()) { ssid_len = strlen(get_ssid()); } ssid_param = build_tagged_parameter(SSID_TAG_NUMBER, ssid_len, &ssid_param_len); if(ssid_param) { buf_len = ssid_param_len + ssid_len; buf = malloc(buf_len); if(buf) { *len = buf_len; memset((void *) buf, 0, buf_len); memcpy((void *) buf, ssid_param, ssid_param_len); memcpy((void *) ((char *) buf+ssid_param_len), get_ssid(), ssid_len); } free((void *) ssid_param); } return buf; }
/*** newstr_link ***/ char * newstr_link(const char *interface, const unsigned int flags) { char *notifystr, *e_interface = NULL, *e_essid = NULL; char essid[IW_ESSID_MAX_SIZE + 1]; memset(&essid, 0, IW_ESSID_MAX_SIZE + 1); get_ssid(interface, essid); e_interface = g_markup_escape_text(interface, -1); if (strlen(essid) == 0) { notifystr = malloc(sizeof(TEXT_NEWLINK) + strlen(e_interface) + 4); sprintf(notifystr, TEXT_NEWLINK, e_interface, (flags & CHECK_CONNECTED) ? "up" : "down"); } else { e_essid = g_markup_escape_text(essid, -1); notifystr = malloc(sizeof(TEXT_WIRELESS) + strlen(e_interface) + 4 + strlen(e_essid)); sprintf(notifystr, TEXT_WIRELESS, e_interface, (flags & CHECK_CONNECTED) ? "up" : "down", e_essid); free(e_essid); } free(e_interface); return notifystr; }
/* Given the tagged parameter sets from a beacon packet, locate the AP's SSID and return its current channel number */ int parse_beacon_tags(const u_char *packet, size_t len) { char *ssid = NULL; const u_char *tag_data = NULL; unsigned char *ie = NULL, *channel_data = NULL; size_t ie_len = 0, ie_offset = 0, tag_len = 0, tag_offset = 0; int channel = 0; struct radio_tap_header *rt_header = NULL; rt_header = (struct radio_tap_header *) radio_header(packet, len); tag_offset = rt_header->len + sizeof(struct dot11_frame_header) + sizeof(struct beacon_management_frame); if(tag_offset < len) { tag_len = (len - tag_offset); tag_data = (const u_char *) (packet + tag_offset); /* If no SSID was manually specified, parse and save the AP SSID */ if(get_ssid() == NULL) { ie = parse_ie_data(tag_data, tag_len, (uint8_t) SSID_TAG_NUMBER, &ie_len, &ie_offset); if(ie) { /* Return data is not null terminated; allocate ie_len+1 and memcpy string */ ssid = malloc(ie_len+1); if(ssid) { memset(ssid, 0, (ie_len+1)); memcpy(ssid, ie, ie_len); set_ssid(ssid); free(ssid); } free(ie); } } ie = parse_ie_data(tag_data, tag_len, (uint8_t) RATES_TAG_NUMBER, &ie_len, &ie_offset); if(ie) { set_ap_rates(ie, ie_len); free(ie); } channel_data = parse_ie_data(tag_data, tag_len, (uint8_t) CHANNEL_TAG_NUMBER, &ie_len, &ie_offset); if(channel_data) { if(ie_len == 1) { memcpy((int *) &channel, channel_data, ie_len); } free(channel_data); } } return channel; }
/* Associate with the AP */ static void associate(void) { size_t radio_tap_len, dot11_frame_len, management_frame_len, ssid_tag_len, wps_tag_len, rates_tag_len, ht_tag_len, packet_len, offset = 0; struct radio_tap_header radio_tap; struct dot11_frame_header dot11_frame; struct association_request_management_frame management_frame; char *essid = get_ssid(); if(!essid) essid = ""; unsigned char ssid_tag[sizeof (struct tagged_parameter) + IW_ESSID_MAX_SIZE]; unsigned char rates_tag[128]; unsigned char wps_tag[sizeof (struct tagged_parameter) + WPS_TAG_SIZE]; unsigned char ht_tag[128]; radio_tap_len = build_radio_tap_header(&radio_tap); dot11_frame_len = build_dot11_frame_header(&dot11_frame, FC_ASSOCIATE); management_frame_len = build_association_management_frame(&management_frame); ssid_tag_len = build_ssid_tagged_parameter(ssid_tag, essid); rates_tag_len = build_supported_rates_tagged_parameter(rates_tag, sizeof rates_tag); wps_tag_len = build_wps_tagged_parameter(wps_tag); if(!NO_REPLAY_HTCAPS) { ht_tag_len = build_htcaps_parameter(ht_tag, sizeof ht_tag); } else { ht_tag_len = 0; } packet_len = radio_tap_len + dot11_frame_len + management_frame_len + ssid_tag_len + wps_tag_len + rates_tag_len + ht_tag_len; unsigned char packet[512]; assert(packet_len < sizeof packet); memcpy(packet, &radio_tap, radio_tap_len); offset += radio_tap_len; memcpy(packet+offset, &dot11_frame, dot11_frame_len); offset += dot11_frame_len; memcpy(packet+offset, &management_frame, management_frame_len); offset += management_frame_len; memcpy(packet+offset, ssid_tag, ssid_tag_len); offset += ssid_tag_len; memcpy(packet+offset, rates_tag, rates_tag_len); offset += rates_tag_len; memcpy(packet+offset, ht_tag, ht_tag_len); offset += ht_tag_len; memcpy(packet+offset, wps_tag, wps_tag_len); send_packet(packet, packet_len, 1); cprintf(VERBOSE, "[+] Sending association request\n"); }
/* Process auto-applied options from the database. read_ap_beacon should be called before this. */ void process_auto_options(void) { char **argv = NULL; int argc = 0, i = 0; char *bssid = NULL, *ssid = NULL; if(get_auto_detect_options()) { bssid = (char *) mac2str(get_bssid(), ':'); if(bssid) { /* If we didn't get the SSID from the beacon packet, check the database */ if(get_ssid() == NULL) { ssid = get_db_ssid(bssid); if(ssid) { set_ssid(ssid); free(ssid); } } argv = auto_detect_settings(bssid, &argc); if(argc > 1 && argv != NULL) { /* Process the command line arguments */ process_arguments(argc, argv); /* Clean up argument memory allocation */ for(i=0; i<argc; i++) { free(argv[i]); } free(argv); } free(bssid); } } return; }
int save_service_list (const service_list *sl) { struct gen_ssid_arg arg = { .ssid = "##", .ssid_len = 2, .last_pos = -1, .rc = ERR_SUCCESS, }; char *err_msg; int rc; char old_ssid[SSID_MAX_LEN]; ssize_t old_ssid_len; sqlite3_stmt *updt_stmt; if (!sl->has_service_list_tmp_table) { return ERR_SUCCESS; } /* Constructing the SSID */ if ((rc = sqlite3_exec (sl->db, "select " COLUMN_CAT_ID ", " COLUMN_DESC ", " COLUMN_POSITION " from " TABLE_SERVICE_LIST_TMP " order by " COLUMN_POSITION " asc", gen_ssid, &arg, &err_msg)) != SQLITE_ABORT && rc != SQLITE_OK) { SQLITE3_ERR_STR (err_msg, "Cannot select services to publish"); return ERR_SAVE_SERVICE_LIST; } if (rc == SQLITE_ABORT) { sqlite3_free (err_msg); l->APP_ERR (arg.rc, "Cannot publish services"); return arg.rc; } /* Preparing for reverting to the old SSID */ if ((old_ssid_len = get_ssid (old_ssid, sizeof (old_ssid))) == -1) { l->ERR ("Cannot retrieve old SSID"); return ERR_SAVE_SERVICE_LIST; } /* Give modification time to all records in the temporary table */ if (sqlite3_exec (sl->db, "update " TABLE_SERVICE_LIST_TMP " set " COLUMN_MOD_TIME " = strftime ('%s', 'now')", NULL, NULL, &err_msg)) { SQLITE3_ERR_STR (err_msg, "Cannot set service list new mod time"); return ERR_SAVE_SERVICE_LIST; } /* If there old and new records are the same, don't change the mod time */ if (sqlite3_prepare_v2 (sl->db, "update " TABLE_SERVICE_LIST_TMP " set " COLUMN_MOD_TIME " = ?" " where " COLUMN_POSITION " = ?" " and " COLUMN_CAT_ID " = ?" " and " COLUMN_DESC " = ?" " and " COLUMN_LONG_DESC " = ?" " and " COLUMN_URI " = ?", -1, &updt_stmt, NULL)) { SQLITE3_ERR (sl->db, "Cannot prepare mod time adjustment update statement"); return ERR_SAVE_SERVICE_LIST; } if ((rc = sqlite3_exec (sl->db, "select * from " TABLE_SERVICE_LIST, adjust_mod_time, updt_stmt, &err_msg))) { SQLITE3_ERR_STR (err_msg, "Cannot adjust mod time"); } if (sqlite3_finalize (updt_stmt)) { SQLITE3_ERR_STR (err_msg, "Cannot finalize mod time adjustment stmt"); return ERR_SAVE_SERVICE_LIST; } if (rc) { return ERR_SAVE_SERVICE_LIST; } /* The real saving process */ if (sqlite3_exec (sl->db, "begin exclusive", NULL, NULL, &err_msg)) { SQLITE3_ERR_STR (err_msg, "Cannot lock service list DB"); return ERR_SAVE_SERVICE_LIST; } if ((rc = set_ssid (arg.ssid, arg.ssid_len))) { l->APP_ERR (rc, "Cannot set SSID"); if (sqlite3_exec (sl->db, "rollback", NULL, NULL, &err_msg)) { SQLITE3_ERR_STR (err_msg, "Cannot unlock (rollback) service list DB"); } return rc; } if (sqlite3_exec (sl->db, "delete from " TABLE_SERVICE_LIST ";" "insert into " TABLE_SERVICE_LIST " select *" " from " TABLE_SERVICE_LIST_TMP ";" "commit", NULL, NULL, &err_msg)) { SQLITE3_ERR_STR (err_msg, "Cannot save services"); if ((rc = set_ssid (old_ssid, old_ssid_len))) { l->APP_ERR (rc, "Cannot revert back to the old SSID"); } if (sqlite3_exec (sl->db, "rollback", NULL, NULL, &err_msg)) { SQLITE3_ERR_STR (err_msg, "Cannot unlock (rollback) service list DB"); } return ERR_SAVE_SERVICE_LIST; } return ERR_SUCCESS; } /** * The callback function used with sqlite3_exec() to count the rows * of a table. The SQL select in sqlite3_exec() <strong>MUST</strong> * correct in returning only one row having only one column containing * the count to be extracted. * * @param [out] result where the counting result should be put. * @param [in] col_count the number of columns in this record. * @param [in] cols the columns of this record. * @param [in] col_names the column names of this record. * * @return 0 if there is no error or non-zero if there is one. */ static int get_row_count (void *result, int col_count, char **cols, char **col_names) { unsigned long *count = result; *count = strtoul (cols[0], NULL, 10); return 0; }
void parse_wps_settings(const u_char *packet, struct pcap_pkthdr *header, char *target, int passive, int mode, int source) { struct radio_tap_header *rt_header = NULL; struct dot11_frame_header *frame_header = NULL; struct libwps_data *wps = NULL; enum encryption_type encryption = NONE; char *bssid = NULL, *ssid = NULL, *lock_display = NULL; int wps_parsed = 0, probe_sent = 0, channel = 0, rssi = 0; static int channel_changed = 0; wps = malloc(sizeof(struct libwps_data)); memset(wps, 0, sizeof(struct libwps_data)); if(packet == NULL || header == NULL || header->len < MIN_BEACON_SIZE) { goto end; } rt_header = (struct radio_tap_header *) radio_header(packet, header->len); frame_header = (struct dot11_frame_header *) (packet + rt_header->len); /* If a specific BSSID was specified, only parse packets from that BSSID */ if(!is_target(frame_header)) { goto end; } set_ssid(NULL); bssid = (char *) mac2str(frame_header->addr3, ':'); if(bssid) { if((target == NULL) || (target != NULL && strcmp(bssid, target) == 0)) { channel = parse_beacon_tags(packet, header->len); rssi = signal_strength(packet, header->len); ssid = (char *) get_ssid(); if(target != NULL && channel_changed == 0) { ualarm(0, 0); change_channel(channel); channel_changed = 1; } if(frame_header->fc.sub_type == PROBE_RESPONSE || frame_header->fc.sub_type == SUBTYPE_BEACON) { wps_parsed = parse_wps_parameters(packet, header->len, wps); } if(!is_done(bssid) && (get_channel() == channel || source == PCAP_FILE || !get_channel())) { if(frame_header->fc.sub_type == SUBTYPE_BEACON && mode == SCAN && !passive && should_probe(bssid)) { send_probe_request(get_bssid(), get_ssid()); probe_sent = 1; } if(!insert(bssid, ssid, wps, encryption, rssi)) { update(bssid, ssid, wps, encryption); } else if(wps->version > 0) { switch(wps->locked) { case WPSLOCKED: lock_display = YES; break; case UNLOCKED: case UNSPECIFIED: lock_display = NO; break; } cprintf(INFO, "%17s %2d %.2d %d.%d %s %s\n", bssid, channel, rssi, (wps->version >> 4), (wps->version & 0x0F), lock_display, ssid); } if(probe_sent) { update_probe_count(bssid); } /* * If there was no WPS information, then the AP does not support WPS and we should ignore it from here on. * If this was a probe response, then we've gotten all WPS info we can get from this AP and should ignore it from here on. */ if(!wps_parsed || frame_header->fc.sub_type == PROBE_RESPONSE) { mark_ap_complete(bssid); } } } /* Only update received signal strength if we are on the same channel as the AP, otherwise power measurements are screwy */ if(channel == get_channel()) { update_ap_power(bssid, rssi); } free(bssid); bssid = NULL; }
void parse_wps_settings(const u_char *packet, struct pcap_pkthdr *header, char *target, int passive, int mode, int source) { struct radio_tap_header *rt_header = NULL; struct dot11_frame_header *frame_header = NULL; struct libwps_data *wps = NULL; enum encryption_type encryption = NONE; char *bssid = NULL, *ssid = NULL, *lock_display = NULL; int wps_parsed = 0, probe_sent = 0, channel = 0, rssi = 0; static int channel_changed = 0; char info_manufac[500]; char info_modelnum[500]; char info_modelserial[500]; wps = malloc(sizeof(struct libwps_data)); memset(wps, 0, sizeof(struct libwps_data)); if(packet == NULL || header == NULL || header->len < MIN_BEACON_SIZE) { goto end; } rt_header = (struct radio_tap_header *) radio_header(packet, header->len); frame_header = (struct dot11_frame_header *) (packet + rt_header->len); /* If a specific BSSID was specified, only parse packets from that BSSID */ if(!is_target(frame_header)) { goto end; } set_ssid(NULL); bssid = (char *) mac2str(frame_header->addr3, ':'); set_bssid((unsigned char *) frame_header->addr3); if(bssid) { if((target == NULL) || (target != NULL && strcmp(bssid, target) == 0)) { channel = parse_beacon_tags(packet, header->len); rssi = signal_strength(packet, header->len); ssid = (char *) get_ssid(); if(target != NULL && channel_changed == 0) { ualarm(0, 0); change_channel(channel); channel_changed = 1; } if(frame_header->fc.sub_type == PROBE_RESPONSE || frame_header->fc.sub_type == SUBTYPE_BEACON) { wps_parsed = parse_wps_parameters(packet, header->len, wps); } if(!is_done(bssid) && (get_channel() == channel || source == PCAP_FILE)) { if(frame_header->fc.sub_type == SUBTYPE_BEACON && mode == SCAN && !passive && should_probe(bssid)) { send_probe_request(get_bssid(), get_ssid()); probe_sent = 1; } if(!insert(bssid, ssid, wps, encryption, rssi)) { update(bssid, ssid, wps, encryption); } else if(wps->version > 0) { switch(wps->locked) { case WPSLOCKED: lock_display = YES; break; case UNLOCKED: case UNSPECIFIED: lock_display = NO; break; } //ideas made by kcdtv if(get_chipset_output == 1) //if(1) { if (c_fix == 0) { //no use a fixed channel cprintf(INFO,"Option (-g) REQUIRES a channel to be set with (-c)\n"); exit(0); } FILE *fgchipset=NULL; char cmd_chipset[4000]; char cmd_chipset_buf[4000]; char buffint[5]; char *aux_cmd_chipset=NULL; memset(cmd_chipset, 0, sizeof(cmd_chipset)); memset(cmd_chipset_buf, 0, sizeof(cmd_chipset_buf)); memset(info_manufac, 0, sizeof(info_manufac)); memset(info_modelnum, 0, sizeof(info_modelnum)); memset(info_modelserial, 0, sizeof(info_modelserial)); strcat(cmd_chipset,"reaver -0 -s y -vv -i "); //need option to stop reaver in m1 stage strcat(cmd_chipset,get_iface()); strcat(cmd_chipset, " -b "); strcat(cmd_chipset, mac2str(get_bssid(),':')); strcat(cmd_chipset," -c "); snprintf(buffint, sizeof(buffint), "%d",channel); strcat(cmd_chipset, buffint); //cprintf(INFO,"\n%s\n",cmd_chipset); if ((fgchipset = popen(cmd_chipset, "r")) == NULL) { printf("Error opening pipe!\n"); //return -1; } while (fgets(cmd_chipset_buf, 4000, fgchipset) != NULL) { //[P] WPS Manufacturer: xxx //[P] WPS Model Number: yyy //[P] WPS Model Serial Number: zzz //cprintf(INFO,"\n%s\n",cmd_chipset_buf); aux_cmd_chipset = strstr(cmd_chipset_buf,"[P] WPS Manufacturer:"); if(aux_cmd_chipset != NULL) { //bug fix by alxchk strncpy(info_manufac, aux_cmd_chipset+21, sizeof(info_manufac)); } aux_cmd_chipset = strstr(cmd_chipset_buf,"[P] WPS Model Number:"); if(aux_cmd_chipset != NULL) { //bug fix by alxchk strncpy(info_modelnum, aux_cmd_chipset+21, sizeof(info_modelnum)); } aux_cmd_chipset = strstr(cmd_chipset_buf,"[P] WPS Model Serial Number:"); if(aux_cmd_chipset != NULL) { //bug fix by alxchk strncpy(info_modelserial, aux_cmd_chipset+28, sizeof(info_modelserial)); } } //cprintf(INFO,"\n%s\n",info_manufac); info_manufac[strcspn ( info_manufac, "\n" )] = '\0'; info_modelnum[strcspn ( info_modelnum, "\n" )] = '\0'; info_modelserial[strcspn ( info_modelserial, "\n" )] = '\0'; if(pclose(fgchipset)) { //printf("Command not found or exited with error status\n"); //return -1; } } if (o_file_p == 0) { cprintf(INFO, "%17s %2d %.2d %d.%d %s %s\n", bssid, channel, rssi, (wps->version >> 4), (wps->version & 0x0F), lock_display, ssid); } else { if(get_chipset_output == 1) { cprintf(INFO, "%17s|%2d|%.2d|%d.%d|%s|%s|%s|%s|%s\n", bssid, channel, rssi, (wps->version >> 4), (wps->version & 0x0F), lock_display, ssid, info_manufac, info_modelnum, info_modelserial); }else { cprintf(INFO, "%17s|%2d|%.2d|%d.%d|%s|%s\n", bssid, channel, rssi, (wps->version >> 4), (wps->version & 0x0F), lock_display, ssid); } }
s32 wilc_parse_network_info(u8 *msg_buffer, struct network_info **ret_network_info) { struct network_info *network_info = NULL; u8 msg_type = 0; u8 msg_id = 0; u16 msg_len = 0; u16 wid_id = (u16)WID_NIL; u16 wid_len = 0; u8 *wid_val = NULL; msg_type = msg_buffer[0]; if ('N' != msg_type) return -EFAULT; msg_id = msg_buffer[1]; msg_len = MAKE_WORD16(msg_buffer[2], msg_buffer[3]); wid_id = MAKE_WORD16(msg_buffer[4], msg_buffer[5]); wid_len = MAKE_WORD16(msg_buffer[6], msg_buffer[7]); wid_val = &msg_buffer[8]; { u8 *msa = NULL; u16 rx_len = 0; u8 *tim_elm = NULL; u8 *ies = NULL; u16 ies_len = 0; u8 index = 0; u32 tsf_lo; u32 tsf_hi; network_info = kzalloc(sizeof(*network_info), GFP_KERNEL); if (!network_info) return -ENOMEM; network_info->rssi = wid_val[0]; msa = &wid_val[1]; rx_len = wid_len - 1; network_info->cap_info = get_cap_info(msa); network_info->tsf_lo = get_beacon_timestamp_lo(msa); tsf_lo = get_beacon_timestamp_lo(msa); tsf_hi = get_beacon_timestamp_hi(msa); network_info->tsf_hi = tsf_lo | ((u64)tsf_hi << 32); get_ssid(msa, network_info->ssid, &network_info->ssid_len); get_BSSID(msa, network_info->bssid); network_info->ch = get_current_channel_802_11n(msa, rx_len + FCS_LEN); index = MAC_HDR_LEN + TIME_STAMP_LEN; network_info->beacon_period = get_beacon_period(msa + index); index += BEACON_INTERVAL_LEN + CAP_INFO_LEN; tim_elm = get_tim_elm(msa, rx_len + FCS_LEN, index); if (tim_elm) network_info->dtim_period = tim_elm[3]; ies = &msa[TAG_PARAM_OFFSET]; ies_len = rx_len - TAG_PARAM_OFFSET; if (ies_len > 0) { network_info->ies = kmemdup(ies, ies_len, GFP_KERNEL); if (!network_info->ies) { kfree(network_info); return -ENOMEM; } } network_info->ies_len = ies_len; } *ret_network_info = network_info; return 0; }
/* Brute force all possible WPS pins for a given access point */ void crack() { unsigned char *bssid = NULL; char *pin = NULL; int fail_count = 0, loop_count = 0, sleep_count = 0, assoc_fail_count = 0; float pin_count = 0; time_t start_time = 0; enum wps_result result = 0; /* MAC CHANGER VARIABLES */ int mac_changer_counter = 0; char mac[MAC_ADDR_LEN] = { 0 }; unsigned char mac_string [] = "ZZ:ZZ:ZZ:ZZ:ZZ:ZZ"; unsigned char* new_mac = &mac_string[0]; char last_digit = '0'; if(!get_iface()) { return; } if(get_max_pin_attempts() == -1) { cprintf(CRITICAL, "[X] ERROR: This device has been blacklisted and is not supported.\n"); return; } /* Initialize network interface */ set_handle(capture_init(get_iface())); if(get_handle() != NULL) { generate_pins(); /* Restore any previously saved session */ if(get_static_p1() == NULL) { restore_session(); } /* Convert BSSID to a string */ bssid = mac2str(get_bssid(), ':'); /* * We need to get some basic info from the AP, and also want to make sure the target AP * actually exists, so wait for a beacon packet */ cprintf(INFO, "[+] Waiting for beacon from %s\n", bssid); read_ap_beacon(); process_auto_options(); /* I'm fairly certian there's a reason I put this in twice. Can't remember what it was now though... */ if(get_max_pin_attempts() == -1) { cprintf(CRITICAL, "[X] ERROR: This device has been blacklisted and is not supported.\n"); return; } /* This initial association is just to make sure we can successfully associate */ while(!reassociate()) { if(assoc_fail_count == MAX_ASSOC_FAILURES) { assoc_fail_count = 0; cprintf(CRITICAL, "[!] WARNING: Failed to associate with %s (ESSID: %s)\n", bssid, get_ssid()); } else { assoc_fail_count++; } } cprintf(INFO, "[+] Associated with %s (ESSID: %s)\n", bssid, get_ssid()); /* Used to calculate pin attempt rates */ start_time = time(NULL); /* If the key status hasn't been explicitly set by restore_session(), ensure that it is set to KEY1_WIP */ if(get_key_status() <= KEY1_WIP) { set_key_status(KEY1_WIP); } /* * If we're starting a session at KEY_DONE, that means we've already cracked the pin and the AP is being re-attacked. * Re-set the status to KEY2_WIP so that we properly enter the main cracking loop. */ else if(get_key_status() == KEY_DONE) { set_key_status(KEY2_WIP); } //copy the current mac to the new_mac variable for mac changer if (get_mac_changer() == 1) { strncpy(new_mac, mac2str(get_mac(), ':'), 16); } /* Main cracking loop */ for(loop_count=0, sleep_count=0; get_key_status() != KEY_DONE; loop_count++, sleep_count++) { //MAC Changer switch/case to define the last mac address digit if (get_mac_changer() == 1) { switch (mac_changer_counter) { case 0: last_digit = '0'; break; case 1: last_digit = '1'; break; case 2: last_digit = '2'; break; case 3: last_digit = '3'; break; case 4: last_digit = '4'; break; case 5: last_digit = '5'; break; case 6: last_digit = '6'; break; case 7: last_digit = '7'; break; case 8: last_digit = '8'; break; case 9: last_digit = '9'; break; case 10: last_digit = 'A'; break; case 11: last_digit = 'B'; break; case 12: last_digit = 'C'; break; case 13: last_digit = 'D'; break; case 14: last_digit = 'E'; break; case 15: last_digit = 'F'; mac_changer_counter = -1; break; } mac_changer_counter++; new_mac[16] = last_digit; //transform the string to a MAC and define the MAC str2mac((unsigned char *) new_mac, (unsigned char *) &mac); set_mac((unsigned char *) &mac); cprintf(WARNING, "[+] Using MAC %s \n", mac2str(get_mac(), ':')); } /* * Some APs may do brute force detection, or might not be able to handle an onslaught of WPS * registrar requests. Using a delay here can help prevent the AP from locking us out. */ pcap_sleep(get_delay()); /* Users may specify a delay after x number of attempts */ if((get_recurring_delay() > 0) && (sleep_count == get_recurring_delay_count())) { cprintf(VERBOSE, "[+] Entering recurring delay of %d seconds\n", get_recurring_delay()); pcap_sleep(get_recurring_delay()); sleep_count = 0; } /* * Some APs identify brute force attempts and lock themselves for a short period of time (typically 5 minutes). * Verify that the AP is not locked before attempting the next pin. */ while(get_ignore_locks() == 0 && is_wps_locked()) { cprintf(WARNING, "[!] WARNING: Detected AP rate limiting, waiting %d seconds before re-checking\n", get_lock_delay()); pcap_sleep(get_lock_delay()); } /* Initialize wps structure */ set_wps(initialize_wps_data()); if(!get_wps()) { cprintf(CRITICAL, "[-] Failed to initialize critical data structure\n"); break; } /* Try the next pin in the list */ pin = build_next_pin(); if(!pin) { cprintf(CRITICAL, "[-] Failed to generate the next payload\n"); break; } else { cprintf(WARNING, "[+] Trying pin %s\n", pin); } /* * Reassociate with the AP before each WPS exchange. This is necessary as some APs will * severely limit our pin attempt rate if we do not. */ assoc_fail_count = 0; while(!reassociate()) { if(assoc_fail_count == MAX_ASSOC_FAILURES) { assoc_fail_count = 0; cprintf(CRITICAL, "[!] WARNING: Failed to associate with %s (ESSID: %s)\n", bssid, get_ssid()); } else { assoc_fail_count++; } } /* * Enter receive loop. This will block until a receive timeout occurs or a * WPS transaction has completed or failed. */ result = do_wps_exchange(); switch(result) { /* * If the last pin attempt was rejected, increment * the pin counter, clear the fail counter and move * on to the next pin. */ case KEY_REJECTED: fail_count = 0; pin_count++; advance_pin_count(); break; /* Got it!! */ case KEY_ACCEPTED: break; /* Unexpected timeout or EAP failure...try this pin again */ default: cprintf(VERBOSE, "[!] WPS transaction failed (code: 0x%.2X), re-trying last pin\n", result); fail_count++; break; } /* If we've had an excessive number of message failures in a row, print a warning */ if(fail_count == WARN_FAILURE_COUNT) { cprintf(WARNING, "[!] WARNING: %d failed connections in a row\n", fail_count); fail_count = 0; pcap_sleep(get_fail_delay()); } /* Display status and save current session state every DISPLAY_PIN_COUNT loops */ if(loop_count == DISPLAY_PIN_COUNT) { save_session(); display_status(pin_count, start_time); loop_count = 0; } /* * The WPA key and other settings are stored in the globule->wps structure. If we've * recovered the WPS pin and parsed these settings, don't free this structure. It * will be freed by wpscrack_free() at the end of main(). */ if(get_key_status() != KEY_DONE) { wps_deinit(get_wps()); set_wps(NULL); } /* If we have cracked the pin, save a copy */ else { set_pin(pin); } free(pin); pin = NULL; /* If we've hit our max number of pin attempts, quit */ if((get_max_pin_attempts() > 0) && (pin_count == get_max_pin_attempts())) { cprintf(VERBOSE, "[+] Quitting after %d crack attempts\n", get_max_pin_attempts()); break; } } if(bssid) free(bssid); if(get_handle()) { pcap_close(get_handle()); set_handle(NULL); } } else { cprintf(CRITICAL, "[-] Failed to initialize interface '%s'\n", get_iface()); } }
/** * @brief parses the received 'N' message * @details * @param[in] pu8MsgBuffer The message to be parsed * @param[out] ppstrNetworkInfo pointer to pointer to the structure containing the parsed Network Info * @return Error code indicating success/failure * @note * @author mabubakr * @date 1 Mar 2012 * @version 1.0 */ s32 parse_network_info(u8 *pu8MsgBuffer, tstrNetworkInfo **ppstrNetworkInfo) { tstrNetworkInfo *pstrNetworkInfo = NULL; u8 u8MsgType = 0; u8 u8MsgID = 0; u16 u16MsgLen = 0; u16 u16WidID = (u16)WID_NIL; u16 u16WidLen = 0; u8 *pu8WidVal = NULL; u8MsgType = pu8MsgBuffer[0]; /* Check whether the received message type is 'N' */ if ('N' != u8MsgType) { PRINT_ER("Received Message format incorrect.\n"); return -EFAULT; } /* Extract message ID */ u8MsgID = pu8MsgBuffer[1]; /* Extract message Length */ u16MsgLen = MAKE_WORD16(pu8MsgBuffer[2], pu8MsgBuffer[3]); /* Extract WID ID */ u16WidID = MAKE_WORD16(pu8MsgBuffer[4], pu8MsgBuffer[5]); /* Extract WID Length */ u16WidLen = MAKE_WORD16(pu8MsgBuffer[6], pu8MsgBuffer[7]); /* Assign a pointer to the WID value */ pu8WidVal = &pu8MsgBuffer[8]; /* parse the WID value of the WID "WID_NEWORK_INFO" */ { u8 *pu8msa = NULL; u16 u16RxLen = 0; u8 *pu8TimElm = NULL; u8 *pu8IEs = NULL; u16 u16IEsLen = 0; u8 u8index = 0; u32 u32Tsf_Lo; u32 u32Tsf_Hi; pstrNetworkInfo = kzalloc(sizeof(tstrNetworkInfo), GFP_KERNEL); if (!pstrNetworkInfo) return -ENOMEM; pstrNetworkInfo->s8rssi = pu8WidVal[0]; /* Assign a pointer to msa "Mac Header Start Address" */ pu8msa = &pu8WidVal[1]; u16RxLen = u16WidLen - 1; /* parse msa*/ /* Get the cap_info */ pstrNetworkInfo->u16CapInfo = get_cap_info(pu8msa); /* Get time-stamp [Low only 32 bit] */ pstrNetworkInfo->u32Tsf = get_beacon_timestamp_lo(pu8msa); PRINT_D(CORECONFIG_DBG, "TSF :%x\n", pstrNetworkInfo->u32Tsf); /* Get full time-stamp [Low and High 64 bit] */ u32Tsf_Lo = get_beacon_timestamp_lo(pu8msa); u32Tsf_Hi = get_beacon_timestamp_hi(pu8msa); pstrNetworkInfo->u64Tsf = u32Tsf_Lo | ((u64)u32Tsf_Hi << 32); /* Get SSID */ get_ssid(pu8msa, pstrNetworkInfo->au8ssid, &pstrNetworkInfo->u8SsidLen); /* Get BSSID */ get_BSSID(pu8msa, pstrNetworkInfo->au8bssid); /* * Extract current channel information from * the beacon/probe response frame */ pstrNetworkInfo->u8channel = get_current_channel_802_11n(pu8msa, u16RxLen + FCS_LEN); /* Get beacon period */ u8index = MAC_HDR_LEN + TIME_STAMP_LEN; pstrNetworkInfo->u16BeaconPeriod = get_beacon_period(pu8msa + u8index); u8index += BEACON_INTERVAL_LEN + CAP_INFO_LEN; /* Get DTIM Period */ pu8TimElm = get_tim_elm(pu8msa, u16RxLen + FCS_LEN, u8index); if (pu8TimElm != NULL) pstrNetworkInfo->u8DtimPeriod = pu8TimElm[3]; pu8IEs = &pu8msa[MAC_HDR_LEN + TIME_STAMP_LEN + BEACON_INTERVAL_LEN + CAP_INFO_LEN]; u16IEsLen = u16RxLen - (MAC_HDR_LEN + TIME_STAMP_LEN + BEACON_INTERVAL_LEN + CAP_INFO_LEN); if (u16IEsLen > 0) { pstrNetworkInfo->pu8IEs = kmemdup(pu8IEs, u16IEsLen, GFP_KERNEL); if (!pstrNetworkInfo->pu8IEs) return -ENOMEM; } pstrNetworkInfo->u16IEsLen = u16IEsLen; } *ppstrNetworkInfo = pstrNetworkInfo; return 0; }
void zz_dissect_packet(zz_handler *zz, const struct pcap_pkthdr *packet_header, const uint8_t *packet) { struct ieee80211_radiotap_header *radiotap_header; struct ieee80211_mac_header *mac_header; struct ieee8022_llc_snap_header *llc_snap_header; struct ieee8021x_authentication_header *authentication_header; char bssid_str[ZZ_MAC_ADDR_STRING_SIZE]; char source_str[ZZ_MAC_ADDR_STRING_SIZE]; char destination_str[ZZ_MAC_ADDR_STRING_SIZE]; char station_str[ZZ_MAC_ADDR_STRING_SIZE]; zz_mac_addr bssid, source, destination, station; const uint8_t *cursor; uint32_t safe_size; int is_beacon; int is_eapol; zz_bss *bss; zz_packet_outcome outcome; const char *extra_info; /* save the timestamp of the first packet as a reference */ if (!zz->epoch) { zz->epoch = TV_TO_SEC(packet_header->ts); } /* check size */ safe_size = sizeof(struct ieee80211_radiotap_header); if (packet_header->caplen < safe_size) { log_ts("Skipping too short packet %u bytes", packet_header->caplen); return; } cursor = packet; /* get radiotap header */ radiotap_header = (struct ieee80211_radiotap_header *)cursor; cursor += le16toh(radiotap_header->length); /* variable length */ /* check size */ safe_size = (cursor - packet) + sizeof(struct ieee80211_mac_header); if (packet_header->caplen < safe_size) { log_ts("Skipping too short packet %u bytes", packet_header->caplen); return; } /* get mac header */ mac_header = (struct ieee80211_mac_header *)cursor; cursor += sizeof(struct ieee80211_mac_header) + (cursor[0] == ZZ_FCF_QOS_DATA ? 2 : 0); /* 2 bytes more for QoS */ /* possible beacon frame */ is_beacon = 0; if (!mac_header->from_ds && !mac_header->to_ds) { /* check if beacon */ if (((uint8_t *)mac_header)[0] != ZZ_FCF_BEACON) { return; } is_beacon = 1; destination = zz_mac_addr_from_array(mac_header->address_1); source = zz_mac_addr_from_array(mac_header->address_2); bssid = zz_mac_addr_from_array(mac_header->address_3); station = 0; /* n.a. */ } /* access point to station */ else if (mac_header->from_ds && !mac_header->to_ds) { destination = zz_mac_addr_from_array(mac_header->address_1); bssid = zz_mac_addr_from_array(mac_header->address_2); source = zz_mac_addr_from_array(mac_header->address_3); station = destination; } /* station to access point */ else if (mac_header->to_ds && !mac_header->from_ds){ bssid = zz_mac_addr_from_array(mac_header->address_1); source = zz_mac_addr_from_array(mac_header->address_2); destination = zz_mac_addr_from_array(mac_header->address_3); station = source; } else { log_ts("Skipping packet due to frame direction"); return; } /* prepare address representations */ zz_mac_addr_sprint(bssid_str, bssid); zz_mac_addr_sprint(source_str, source); zz_mac_addr_sprint(destination_str, destination); zz_mac_addr_sprint(station_str, station); /* lookup or create a descriptor for this bss */ if (zz_bsss_lookup(&zz->bsss, bssid, &bss)) { /* check if this bssid is filtered out just once */ bss->is_allowed = (zz_members_is_empty(&zz->setup.allowed_bssids) || zz_members_get(&zz->setup.allowed_bssids, bssid)); } /* skip unwanted access points */ if (!bss->is_allowed) { if (!is_beacon) { log_ts("%s @ %s - Skipping unwanted BSSID", station_str, bssid_str); } return; } /* save a beacon (just once per bss) */ if (is_beacon) { if (!bss->has_beacon) { int ssid_length; const char *ssid; /* dump the packet if requested */ if (zz->dumper) { pcap_dump((u_char *)zz->dumper, packet_header, packet); } /* fetch and save the ssid */ get_ssid(cursor + ZZ_BEACON_SSID_PARAMS_OFFSET, packet_header->caplen - (cursor - packet), &ssid, &ssid_length); memcpy(bss->ssid, ssid, ssid_length); bss->has_beacon = 1; zz_out("SSID discovered '%s' (%s)", bss->ssid, bssid_str); } /* anyway beacon processing stops here */ return; } /* skip blacklisted stations */ if (zz_members_get(&zz->setup.banned_stations, station)) { log_ts("%s @ %s - Skipping banned station", station_str, bssid_str); return; } /* detect broad/multicast traffic */ if (destination == ZZ_MAC_ADDR_BCAST || destination & ZZ_MAC_ADDR_MCAST_MASK) { /* for "handshaked" networks only, if explicitly requested */ if (zz->setup.dump_group_traffic && bss->n_handshakes > 0) { bss->n_data_packets++; if (zz->dumper) { pcap_dump((u_char *)zz->dumper, packet_header, packet); } } return; /* anyway the processing stops here */ } /* get llc+snap header (required by eapol) */ llc_snap_header = (struct ieee8022_llc_snap_header *)cursor; cursor += sizeof(struct ieee8022_llc_snap_header); /* check actual snap and eapol presence */ safe_size = (cursor - packet) + sizeof(struct ieee8021x_authentication_header); is_eapol = (packet_header->caplen >= safe_size && llc_snap_header->dsap == ZZ_DSAP_SNAP && llc_snap_header->ssap == ZZ_SSAP_SNAP && llc_snap_header->control == ZZ_CONTROL_SNAP && llc_snap_header->type == htobe16(ZZ_EAPOL_ETHERTYPE)); /* get eapol header (if any) */ if (is_eapol) { authentication_header = (struct ieee8021x_authentication_header *)cursor; } else { authentication_header = NULL; } /* advance the state machine and perform the needed actions */ outcome = zz_process_packet(zz, station, bssid, packet_header, authentication_header); if (outcome.ignore) { switch (outcome.ignore_reason) { case ZZ_IGNORE_REASON_RETRANSMISSION: log_ts("%s @ %s - Handshake message #%d (retransmission)", station_str, bssid_str, outcome.handshake_info); break; case ZZ_IGNORE_REASON_INVALID_EAPOL: log_ts("%s @ %s - Ignoring invalid key flags", station_str, bssid_str); break; case ZZ_IGNORE_REASON_INVALID_COUNTER: log_ts("%s @ %s - Ignoring invalid replay counter", station_str, bssid_str); break; } return; } if (outcome.dump_packet) { if (!authentication_header) { bss->n_data_packets++; } if (zz->dumper) { pcap_dump((u_char *)zz->dumper, packet_header, packet); } } if (outcome.new_client || outcome.track_client) { if (zz->setup.is_live) { /* (re)start deauthenticating this client */ zz_killer_post_message(&zz->killer, station, bssid, outcome); } } extra_info = ""; if (outcome.track_client) { switch (outcome.track_reason) { case ZZ_TRACK_REASON_ALIVE: log_ts("%s @ %s - Activity detected again", station_str, bssid_str); break; case ZZ_TRACK_REASON_FIRST_HANDSHAKE: extra_info = " (first attempt detected)"; break; case ZZ_TRACK_REASON_EXPIRATION: extra_info = " (causes restart due to expiration)"; break; case ZZ_TRACK_REASON_INVALIDATION: extra_info = " (caused restart due to invalidation)"; break; } } if (outcome.handshake_info) { log_ts("%s @ %s - Handshake message #%d%s", station_str, bssid_str, outcome.handshake_info, extra_info); } if (outcome.new_client) { zz_out("New client %s @ %s", station_str, bssid_str); } if (outcome.got_handshake) { zz_out("^_^ Full handshake for %s @ %s", station_str, bssid_str); /* stop deauthenticating this client */ if (zz->setup.is_live) { zz_killer_post_message(&zz->killer, station, bssid, outcome); } /* update stats */ bss->n_handshakes++; zz_members_add(&bss->stations, station); } }
/* * Called by pcap_loop for every packet that passes the (optional) bpf * filter */ void pckt_callback(u_char *user, const struct pcap_pkthdr *pkthdr, const u_char *packet_data) { ieee80211_hdr w_hdr; airpwn_ctx *ctx = (airpwn_ctx *)user; char ssid_name[256]; uint32_t packetlen; packetlen = pkthdr->len; // code to handle skipping past "prism monitoring header" blocks if(*((unsigned int*)packet_data) == htonl(0x44000000)){ uint32_t len = *((uint32_t*)(packet_data+4)); packet_data = packet_data + len; packetlen -= len; } // same for radiotap headers, which have a first 16 bits of 0x0000 if(*((uint16_t*)packet_data) == htons(0x0000)) { uint16_t len = *((uint16_t*)(packet_data+2)); packet_data = packet_data + len; packetlen -= len; } switch(packet_data[0]){ // data packet case 0x08: memcpy(&w_hdr, packet_data, sizeof(w_hdr)); printlog(ctx, 3, " data packet len: %u, flags: %hhu %s DS\n", pkthdr->len, w_hdr.flags, w_hdr.flags & IEEE80211_FROM_DS ? "<--" : "-->"); if(w_hdr.flags & IEEE80211_FROM_DS) // ignore packets from the AP break; if(IS_WEP(w_hdr.flags)){ // the packet is WEP encrypted uint8_t cleartext[0x10000]; int32_t clearlen; wepkey *key; printlog(ctx, 3, " WEP encrypted packet found.\n"); if(!ctx->keys) // no WEP keys so ignore this packet break; //TODO: some packets may not have a frame check sequence at the //end, need to figure this out instead of always subtracting 4 //bytes. for(key = ctx->keys; key != NULL; key = key->next){ clearlen = wep_decrypt(packet_data + IEEE80211_HDR_LEN_NO_LLC, cleartext, packetlen - IEEE80211_HDR_LEN_NO_LLC - (ctx->fcs_present ? IEEE80211_FCS_LEN : 0), key->key, key->keylen); if(clearlen > 0){ printlog(ctx, 3, " WEP decryption succesful.\n"); //dumphex(cleartext, clearlen); memcpy(&w_hdr.llc, cleartext, sizeof(LLC_hdr)); if(w_hdr.llc.type == LLC_TYPE_IP){ process_ip_packet(ctx, &w_hdr, cleartext+LLC_HDR_LEN, clearlen-LLC_HDR_LEN, key->key, key->keylen); } } else { printlog(ctx, 3, " WEP decryption failed..\n"); } } } else if(w_hdr.llc.type == LLC_TYPE_IP) process_ip_packet(ctx, &w_hdr, packet_data + IEEE80211_HDR_LEN, pkthdr->len, NULL, 0); break; case 0x80: get_ssid(packet_data, ssid_name, sizeof(ssid_name)); printlog(ctx, 4, " beacon frame (%s)\n", ssid_name); break; case 0x40: get_ssid(packet_data, ssid_name, sizeof(ssid_name)); printlog(ctx, 4, " probe request (%s)\n", ssid_name); break; case 0x50: get_ssid(packet_data, ssid_name, sizeof(ssid_name)); printlog(ctx, 4, " probe response (%s)\n", ssid_name); break; case 0xd4: printlog(ctx, 4, " acknowledgement\n"); break; case 0x48: printlog(ctx, 4, " null function\n"); break; case 0xb0: printlog(ctx, 4, " authentication\n"); break; case 0xc0: printlog(ctx, 4, " deauthentication\n"); break; case 0x30: printlog(ctx, 4, " reassociation response\n"); break; case 0xc4: printlog(ctx, 4, " clear to send\n"); break; default: printlog(ctx, 5, " *** unknown type %x\n", packet_data[0]); } }
int get_ap_rssi_data(RADIOMAP &result_map) { HANDLE hClient = NULL; DWORD dwMaxClient = 2; DWORD dwCurVersion = 0; DWORD dwResult = 0; DWORD dwRetVal = 0; WCHAR GuidString[39] = { 0 }; PWLAN_INTERFACE_INFO_LIST pIfList = NULL; PWLAN_INTERFACE_INFO pIfInfo = NULL; PWLAN_BSS_ENTRY pBssEntry = NULL; PWLAN_BSS_LIST pBssList = NULL; LocalizationNode *pLocalizationNode = NULL; std::string mac_id; std::string ret_ssid; int iRet = 0; int ret; uint i; dwResult = WlanOpenHandle(dwMaxClient, NULL, &dwCurVersion, &hClient); if (dwResult != ERROR_SUCCESS) { wprintf(L"WlanOpenHandle failed with error: %u\n", dwResult); return 1; } dwResult = WlanEnumInterfaces(hClient, NULL, &pIfList); if (dwResult != ERROR_SUCCESS) { wprintf(L"WlanEnumInterfaces failed with error: %u\n", dwResult); return 1; } else { wprintf(L"Nunber Entries: %lu\n", pIfList->dwNumberOfItems); wprintf(L"Current Index: %lu\n", pIfList->dwIndex); for (i = 0; i < (int)pIfList->dwNumberOfItems; i++) { pIfInfo = (WLAN_INTERFACE_INFO *)&pIfList->InterfaceInfo[i]; wprintf(L" Interface Index[%u]:\t %lu\n", i, i); iRet = StringFromGUID2(pIfInfo->InterfaceGuid, (LPOLESTR)&GuidString, sizeof(GuidString) / sizeof(*GuidString)); if (iRet == 0) wprintf(L"StringFromGUID2 Failed\n"); else wprintf(L" InterfaceGUID[%d]: %ws\n", i, GuidString); wprintf(L" Interface Description[%d]: %ws", i, pIfInfo->strInterfaceDescription); wprintf(L"\n"); wprintf(L" Interface State[%d]:\t ", i); switch (pIfInfo->isState) { case wlan_interface_state_not_ready: wprintf(L"Not ready\n"); break; case wlan_interface_state_connected: wprintf(L"Connected\n"); break; case wlan_interface_state_ad_hoc_network_formed: wprintf(L"First node in a ad hoc network\n"); break; case wlan_interface_state_disconnecting: wprintf(L"Disconnecting\n"); break; case wlan_interface_state_disconnected: wprintf(L"Not connected\n"); break; case wlan_interface_state_associating: wprintf(L"Attempting to associate with a network\n"); break; case wlan_interface_state_discovering: wprintf(L"Auto configuration is discovering settings for the network\n"); break; case wlan_interface_state_authenticating: wprintf(L"In process of authenticating\n"); break; default: wprintf(L"Unknown state %ld\n", pIfInfo->isState); break; } wprintf(L"\n"); const GUID * pGUID = &pIfInfo->InterfaceGuid; dwResult = WlanGetNetworkBssList(hClient, pGUID, NULL, dot11_BSS_type_any, 0, NULL, &pBssList); if (dwResult != ERROR_SUCCESS) { wprintf(L"Wlan get network bss list error: %lu\n", dwResult); return 1; } else { for (uint i = 0; i < pBssList->dwNumberOfItems; i++) { pBssEntry = &pBssList->wlanBssEntries[i]; get_mac_id(pBssEntry->dot11Bssid, mac_id); if (find_at_radiomap(mac_id, result_map, pLocalizationNode) == 0) { pLocalizationNode->add_recoder(pBssEntry->lRssi); } else if (get_ssid(pBssEntry->dot11Ssid, ret_ssid) == 0) { LocalizationNode new_ap(mac_id, ret_ssid, pBssEntry->lRssi); ret = add_to_radiomap(new_ap, result_map); if (ret != 0) { printf("ERROR: add_to_radiomap error"); exit(1); } } } } } } if (pBssList != NULL) { WlanFreeMemory(pBssList); pBssList = NULL; } if (pIfList != NULL) { WlanFreeMemory(pIfList); pIfList = NULL; } WlanCloseHandle(hClient, 0); return 0; }
void pckt_callback(u_char *user, const struct pcap_pkthdr *pkthdr, const u_char *packet_data) { airspf_ctx *ctx = (airspf_ctx *)user; airspf_trace *trace; char ssid_name[256]; uint32_t packetlen; packetlen = pkthdr->len; // code to handle skipping past "prism monitoring header" blocks if(*((unsigned int*)packet_data) == htonl(0x44000000)){ uint32_t len = *((uint32_t*)(packet_data+4)); packet_data = packet_data + len; packetlen -= len; } // same for radiotap headers, which have a first 16 bits of 0x0000 if(*((uint16_t*)packet_data) == htons(0x0000)) { uint16_t len = *((uint16_t*)(packet_data+2)); packet_data = packet_data + len; packetlen -= len; } switch(packet_data[0]){ // data packet case 0x08: trace = match_trace(pkthdr, packet_data); if(trace->is_cracked) play_spoof(trace, pkthdr, packet_data); else collect(trace, pkthdr, packet_data); response(trace, pkthdr, packet_data); break; case 0x80: get_ssid(packet_data, ssid_name, sizeof(ssid_name)); printlog(ctx, 4, " beacon frame (%s)\n", ssid_name); break; case 0x40: get_ssid(packet_data, ssid_name, sizeof(ssid_name)); printlog(ctx, 4, " probe request (%s)\n", ssid_name); break; case 0x50: get_ssid(packet_data, ssid_name, sizeof(ssid_name)); printlog(ctx, 4, " probe response (%s)\n", ssid_name); break; case 0xd4: printlog(ctx, 4, " acknowledgement\n"); break; case 0x48: printlog(ctx, 4, " null function\n"); break; case 0xb0: printlog(ctx, 4, " authentication\n"); break; case 0xc0: printlog(ctx, 4, " deauthentication\n"); break; case 0x30: printlog(ctx, 4, " reassociation response\n"); break; case 0xc4: printlog(ctx, 4, " clear to send\n"); break; default: printlog(ctx, 5, " *** unknown type %x\n", packet_data[0]); } }
/* Given the tagged parameter sets from a beacon packet, locate the AP's SSID and return its current channel number */ int parse_beacon_tags(const unsigned char *packet, size_t len) { set_vendor(0, "\0\0\0"); char *ssid = NULL; const unsigned char *tag_data = NULL; unsigned char *ie = NULL, *channel_data = NULL; size_t ie_len = 0, ie_offset = 0, tag_len = 0, tag_offset = 0; int channel = 0; struct radio_tap_header *rt_header = NULL; rt_header = (struct radio_tap_header *) radio_header(packet, len); tag_offset = end_le16toh(rt_header->len) + sizeof(struct dot11_frame_header) + sizeof(struct beacon_management_frame); if(tag_offset < len) { tag_len = (len - tag_offset); /* this actually denotes length of the entire tag data area */ tag_data = (const unsigned char *) (packet + tag_offset); /* If no SSID was manually specified, parse and save the AP SSID */ if(get_ssid() == NULL) { ie = parse_ie_data(tag_data, tag_len, (uint8_t) SSID_TAG_NUMBER, &ie_len, &ie_offset); if(ie) { /* Return data is not null terminated; allocate ie_len+1 and memcpy string */ ssid = malloc(ie_len+1); if(ssid) { memset(ssid, 0, (ie_len+1)); memcpy(ssid, ie, ie_len); set_ssid(ssid); free(ssid); } free(ie); } } ie = parse_ie_data(tag_data, tag_len, HT_CAPS_TAG_NUMBER, &ie_len, &ie_offset); if(ie) { set_ap_htcaps(ie, ie_len); free(ie); } ie = parse_ie_data(tag_data, tag_len, (uint8_t) RATES_TAG_NUMBER, &ie_len, &ie_offset); if(ie) { set_ap_rates(ie, ie_len); free(ie); } ie = parse_ie_data(tag_data, tag_len, (uint8_t) ERATES_TAG_NUMBER, &ie_len, &ie_offset); if(ie) { set_ap_ext_rates(ie, ie_len); free(ie); } channel_data = parse_ie_data(tag_data, tag_len, (uint8_t) CHANNEL_TAG_NUMBER, &ie_len, &ie_offset); if(channel_data) { if(ie_len == 1) { channel = *(uint8_t*)channel_data; } free(channel_data); } size_t ie_iterator = 0; do { const unsigned char *tag = tag_data + ie_iterator; // check for the length of the tag, and that its not microsoft if(tag[0] == VENDOR_SPECIFIC_TAG && ie_iterator+2+3 < tag_len && ((tag[1] < 11 && memcmp(tag+2, "\x00\x14\x6c", 3) && memcmp(tag+2, "\x00\x50\xf2", 3)) || (tag[1] == 30 && !(memcmp(tag+2, "\x00\x26\x86", 3))))) { set_vendor(1, tag + 2); break; } } while(get_next_ie(tag_data, tag_len, &ie_iterator)); } return channel; }