⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wifi80211.c

📁 FERRET - a broadcast analysis tool This tool is designed to demonstrate the problem of "data seap
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Copyright (c) 2007 by Errata Security */
#include "protos.h"
#include "formats.h"
#include "netframe.h"
#include "ferret.h"
#include <string.h>
#include <stdio.h>

typedef unsigned char MACADDR[6];

struct	WIFI_MGMT {
	int frame_control;
	int duration;
	MACADDR destination;
	MACADDR source;
	MACADDR bss_id;
	int frag_number;
	int seq_number;

	unsigned char *ssid;
	unsigned ssid_length;

	unsigned maxrate;
	unsigned channel;
};

const char *oui_vendor(unsigned oui)
{
	switch (oui) {
	case 0x00601d: return "Agere";
	case 0x001018: return "Broadcom";
	case 0x000347: return "Intel";
	case 0x004096: return "Aironet";
	case 0x00037f: return "Atheros";
	case 0x0050f2: return "Microsoft";
	default: return "(unknown)";
	}
}
void process_wifi_fields(struct Seaper *seap, struct NetFrame *frame, const unsigned char *px, unsigned length, unsigned offset, struct WIFI_MGMT *wifimgmt)
{
	while (offset < length) {
		unsigned tag, len;

		/* fix known bugs */
		if (offset == length-1 && px[offset] == 0x80 && memcmp(wifimgmt->source, "\x00\x02\x2d", 3) == 0)
			break;

		tag = px[offset++];
		if (offset >= length) {
			/* Fix Agere bug */
			FRAMERR(frame, "wifi parms: went past eof\n");
			break;
		}
		len = px[offset++];

		/* Fix bugs in well-known cards that cause us to go off the end */
		if (tag == 5 && memcmp(wifimgmt->source, "\x00\x02\x2d", 3) == 0 && offset+len > length)
			len = length-offset;
		if (tag == 0x80 && length-offset>3 && memcmp(px+offset, "\x00\x60\x1d", 3) == 0 && offset+len > length)
			len = length-offset;
		if (tag == 0xdd && length-offset>3 && memcmp(px+offset, "\x00\x03\x7f", 3) == 0 && offset+len > length)
			len = length-offset;

		if (offset + len > length) {
			; //FRAMERR(frame, "wifi parms: went past eof\n");
			break;
		}


		SAMPLE("IEEE802.11", "parm",REC_UNSIGNED, &tag, sizeof(tag));

		switch (tag) {
		case 0x00: /* SSID */
			wifimgmt->ssid = (unsigned char*)px+offset;
			wifimgmt->ssid_length = len;

			if (len == 0) {
				wifimgmt->ssid = (unsigned char*)"(broadcast)";
				wifimgmt->ssid_length = strlen((char*)wifimgmt->ssid);
			}
			break;
		case 1: /* SUPPORTED RATES */
		case 50: /* EXTENDED SUPPORTED RATES */
			{
				unsigned i;
				for (i=0; i<len; i++) {
					unsigned rate=0;

					rate = (px[offset+i]&0x7F) * 5;
					if (wifimgmt->maxrate < rate)
						wifimgmt->maxrate = rate;
				}
			}
			break;
		case 3: /* CHANNEL */
			if (len != 1)
				FRAMERR(frame, "wifi parms: bad channel length\n");
			if (len > 0)
				wifimgmt->channel = px[offset+len-1];
			break;
		case 5: /* TIM */
			/*TIM bug in Agere */
			if (offset + len > length)
				len = length-offset;
			break;
		case 0x06: /*IBSS */
		case 10: /*unknown*/
		case 0x0b: /* QBSS Load Element for 802.11e */
		case 150: /*unknown*/
		case 0x2a: /*ERP Information */
		case 0x2f: /*ERP infomration (why is this the same as 0x2a?) */
		case 0x2c: /*IEEE802.11e Traffic Classification (TCLAS) */
		case 0x30: /*RSN Information */
		case 0x85: /*Cisco proprietary */
			process_record(seap,
				"proto",			REC_SZ,			"WiFi",					-1,
				"op",				REC_SZ,			"unknownparm",			-1,
				"macaddr",			REC_MACADDR,	wifimgmt->source,		6,
				"wifi.tag",			REC_UNSIGNED,	&tag,					sizeof(tag),
				"wifi.value",		REC_PRINTABLE,	px+offset,				len,
				0);
			break;
		case 7: /* COUNTRY INFORMATION */
			if (tag < 3)
				FRAMERR(frame, "wifi parms: bad country info\n");
			else
			{
				char country[16];
				int country_len = len-3;
				int min_channel = px[offset+len-3];
				int max_channel = px[offset+len-2];
				int max_power = px[offset+len-1];
				char power[32];

				if (country_len > sizeof(country-1))
					country_len = sizeof(country-1);
				memcpy(country, px+offset, country_len);
				country[country_len] = '\0';

				_snprintf(power, sizeof(power), "%d-dBm", max_power);

				process_record(seap,
					"proto",			REC_SZ,			"WiFi",					-1,
					"op",				REC_SZ,			"countryinfo",			-1,
					"macaddr",			REC_MACADDR,	wifimgmt->source,		6,
					"wifi.country",		REC_SZ,			country,				-1,
					"wifi.minchannel",	REC_UNSIGNED,	&min_channel,			sizeof(min_channel),
					"wifi.maxchannel",	REC_UNSIGNED,	&max_channel,			sizeof(min_channel),
					"wifi.power",		REC_SZ,			power,					-1,
					0);
			}
			break;
		case 0x80:
		case 0xdd:
			if (len < 3) {
				FRAMERR(frame, "wifi vendor extension: too short\n");
			} else {
				unsigned oui = ex24be(px+offset);
				SAMPLE("IEEE802.11", "oui",REC_UNSIGNED, &oui, sizeof(oui));

				switch (oui) {
				case 0x00601d: /*agere*/
				case 0x001018: /*broadcom*/
				case 0x000347: /*intel*/
				case 0x004096: /*aironet*/
				case 0x00037f: /*Atheros*/
					process_record(seap,
						"proto",		REC_SZ,			"WiFi",				-1,
						"op",		REC_SZ,			"vendor",				-1,
						//"macaddr",	REC_MACADDR,	wifimgmt.source,		6,
						"vendor.name",		REC_SZ,			oui_vendor(oui),	-1,
						"vendor.oui",		REC_HEX24,		&oui,				sizeof(oui),
						"vendor.data",		REC_PRINTABLE,	px+offset+3,		len-3,
						0);
					break;
				case 0x0050f2: /*Microsoft*/
					offset += 3;
					len -= 3;
					if (len < 1) 
						FRAMERR(frame, "wifi vendor extension: too short\n");
					else {
						int tag2 = px[offset];
						offset++;
						len--;
						switch (tag2) {
						case 0x01: /* MS cypher suites */
						case 0x02:
							process_record(seap,
								"proto",		REC_SZ,				"WiFi",				-1,
								"op",			REC_SZ,				"vendor",			-1,
								//"macaddr",	REC_MACADDR,		wifimgmt.source,	6,
								"vendor.name",		REC_SZ,			oui_vendor(oui),	-1,
								"vendor.oui",		REC_HEX24,		&oui,				sizeof(oui),
								"vendor.data",		REC_PRINTABLE,	px+offset+3,		len-3,
								0);
							break;
						default:
							FRAMERR(frame, "wifi MS extension: unknown 0x%02x\n", tag2);
						}
					}
					break;
				case 0x00393: /* Apple */
					break;
				case 0x0af5: /* AirgoNet */
					break;
				default:
					FRAMERR(frame, "wifi vendor extension: unknown 0x%06x\n", oui);
				}
			}
			break;
		default:
			FRAMERR(frame, "wifi parms: unknown tag %d(0x%02x)\n", tag, tag);
		}


		offset += len;
	}

}

void process_wifi_probe(struct Seaper *seap, struct NetFrame *frame, const unsigned char *px, unsigned length)
{
	unsigned offset;
	struct	WIFI_MGMT wifimgmt;
	memset(&wifimgmt, 0, sizeof(wifimgmt));

	if (length < 24) {
		FRAMERR(frame, "wifi: truncated\n");
		return;
	}

	memcpy(wifimgmt.source, px+10, 6);

	/* Process variable tags */
	offset = 24;
	process_wifi_fields(seap, frame, px, length, offset, &wifimgmt);

	process_record(seap,
		"proto",	REC_SZ,			"WiFi",				-1,
		"op",		REC_SZ,			"probe",		-1,
		"macaddr",	REC_MACADDR,	wifimgmt.source,	6,
		"SSID",		REC_PRINTABLE,	wifimgmt.ssid,		wifimgmt.ssid_length,
		0);
}

void process_wifi_proberesponse(struct Seaper *seap, struct NetFrame *frame, const unsigned char *px, unsigned length)
{
	unsigned offset;

	struct	WIFI_MGMT wifimgmt;
	memset(&wifimgmt, 0, sizeof(wifimgmt));

	if (length < 24) {
		FRAMERR(frame, "wifi: truncated\n");
		return;
	}

	memcpy(wifimgmt.source, px+10, 6);

	/* Process variable tags */
	offset = 24;

	offset += 8; /* timestamp */

	offset += 2; /* beacon interval */

	offset += 2; /* capability information */

	process_wifi_fields(seap, frame, px, length, offset, &wifimgmt);

	{
		char maxrate[32];
		if (wifimgmt.maxrate%10)
			_snprintf(maxrate, sizeof(maxrate),"%d.%d-mbps", wifimgmt.maxrate/10, wifimgmt.maxrate%10);
		else
			_snprintf(maxrate, sizeof(maxrate),"%d-mbps", wifimgmt.maxrate/10);

		process_record(seap,
			"proto",	REC_SZ,			"WiFi",				-1,
			"op",		REC_SZ,			"probe-response",		-1,
			"macaddr",	REC_MACADDR,	wifimgmt.source,			6,
			"SSID",		REC_PRINTABLE,	wifimgmt.ssid,				wifimgmt.ssid_length,
			"maxrate",	REC_SZ,			maxrate,					-1,
			"channel",	REC_UNSIGNED,	&wifimgmt.channel,			sizeof(wifimgmt.channel),
			0);
	}
}

void process_wifi_associate_request(struct Seaper *seap, struct NetFrame *frame, const unsigned char *px, unsigned length)
{
	struct	WIFI_MGMT wifimgmt;
	memset(&wifimgmt, 0, sizeof(wifimgmt));

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -