diff options
author | Reyk Floeter <reyk@cvs.openbsd.org> | 2005-09-30 16:50:04 +0000 |
---|---|---|
committer | Reyk Floeter <reyk@cvs.openbsd.org> | 2005-09-30 16:50:04 +0000 |
commit | 6bd954e164539db60d4af401780384d6a7c13b39 (patch) | |
tree | 1e585148910e904d12c143e07d2fa50b6ada1b27 /usr.sbin/hostapd | |
parent | f90eba61558219c16a257f4788d9167eb3fbd7d6 (diff) |
implement a way to match IEEE 802.11 flooding. this will help to detect
known DoS attacks, like de-auth flooding against wireless networks.
an example is provided in the manual page.
"or could you just got for it?", deraadt@
Diffstat (limited to 'usr.sbin/hostapd')
-rw-r--r-- | usr.sbin/hostapd/handle.c | 39 | ||||
-rw-r--r-- | usr.sbin/hostapd/hostapd.conf.5 | 33 | ||||
-rw-r--r-- | usr.sbin/hostapd/hostapd.h | 6 | ||||
-rw-r--r-- | usr.sbin/hostapd/parse.y | 26 |
4 files changed, 89 insertions, 15 deletions
diff --git a/usr.sbin/hostapd/handle.c b/usr.sbin/hostapd/handle.c index 5ce37022dc4..3a2a78734b9 100644 --- a/usr.sbin/hostapd/handle.c +++ b/usr.sbin/hostapd/handle.c @@ -1,4 +1,4 @@ -/* $OpenBSD: handle.c,v 1.2 2005/07/04 16:48:55 reyk Exp $ */ +/* $OpenBSD: handle.c,v 1.3 2005/09/30 16:50:03 reyk Exp $ */ /* * Copyright (c) 2005 Reyk Floeter <reyk@vantronix.net> @@ -107,7 +107,7 @@ hostapd_handle_frame(struct hostapd_config *cfg, struct hostapd_frame *frame, u_int8_t *wfrom, *wto, *wbssid; struct timeval t_now; u_int32_t flags; - int offset; + int offset, min_rate = 0; if ((offset = hostapd_apme_offset(cfg, buf, len)) < 0) return (0); @@ -116,9 +116,11 @@ hostapd_handle_frame(struct hostapd_config *cfg, struct hostapd_frame *frame, mh = &frame->f_frame; flags = frame->f_flags; + /* Get timestamp */ + gettimeofday(&t_now, NULL); + /* Handle optional limit */ if (frame->f_limit.tv_sec || frame->f_limit.tv_usec) { - gettimeofday(&t_now, NULL); if (timercmp(&t_now, &frame->f_then, <)) return (0); timeradd(&t_now, &frame->f_limit, &frame->f_then); @@ -193,10 +195,34 @@ hostapd_handle_frame(struct hostapd_config *cfg, struct hostapd_frame *frame, if ((flags & HOSTAPD_FRAME_F_M) != 0) return (0); + /* Handle optional minimal rate */ + if (frame->f_rate && frame->f_rate_intval) { + frame->f_rate_delay = t_now.tv_sec - frame->f_last.tv_sec; + if (frame->f_rate_delay < frame->f_rate_intval) { + frame->f_rate_cnt++; + if (frame->f_rate_cnt < frame->f_rate) + min_rate = 1; + } else { + min_rate = 1; + frame->f_rate_cnt = 0; + } + } + + /* Update timestamp for the last match of this event */ + if (frame->f_rate_cnt == 0 || min_rate == 0) + bcopy(&t_now, &frame->f_last, sizeof(struct timeval)); + + /* Return if the minimal rate is not reached, yet */ + if (min_rate) + return (0); + if (hostapd_handle_action(cfg, frame, wfrom, wto, wbssid, buf, len) != 0) return (0); + /* Reset minimal rate counter after successfully handled the frame */ + frame->f_rate_cnt = 0; + return ((frame->f_flags & HOSTAPD_FRAME_F_RET_M) >> HOSTAPD_FRAME_F_RET_S); } @@ -228,7 +254,12 @@ hostapd_handle_action(struct hostapd_config *cfg, struct hostapd_frame *frame, case HOSTAPD_ACTION_LOG: /* Log frame to syslog/stderr */ - hostapd_printf("%s: ", cfg->c_apme_iface); + if (frame->f_rate && frame->f_rate_intval) { + hostapd_printf("%s: (rate: %ld/%ld sec) ", + cfg->c_apme_iface, frame->f_rate_cnt, + frame->f_rate_delay + 1); + } else + hostapd_printf("%s: ", cfg->c_apme_iface); hostapd_print_ieee80211(cfg->c_apme_dlt, frame->f_action_flags & HOSTAPD_ACTION_VERBOSE, buf, len); diff --git a/usr.sbin/hostapd/hostapd.conf.5 b/usr.sbin/hostapd/hostapd.conf.5 index a606ec91a62..8d032008bac 100644 --- a/usr.sbin/hostapd/hostapd.conf.5 +++ b/usr.sbin/hostapd/hostapd.conf.5 @@ -1,4 +1,4 @@ -.\" $OpenBSD: hostapd.conf.5,v 1.11 2005/09/29 23:57:00 reyk Exp $ +.\" $OpenBSD: hostapd.conf.5,v 1.12 2005/09/30 16:50:03 reyk Exp $ .\" .\" Copyright (c) 2004, 2005 Reyk Floeter <reyk@vantronix.net> .\" @@ -162,13 +162,14 @@ event rules are single line statements beginning with the mandatory .Ic hostap handle keywords and optional rule options, frame matching, -a specified action, and a limit: +a specified action, a limit, and a minimal rate: .Bd -filled -offset indent .Ic hostap handle .Op Ar option .Op Ar frame .Op Ar action .Op Ar limit +.Op Ar rate .Ed .Pp The optional parts are defined below. @@ -387,6 +388,10 @@ is Write informational messages to the local system log (see .Xr syslogd 8 ) or standard error. +If the +.Sx Rule Rate +has been specified, +log will print the actual rate. .It Ic node add | delete Ar lladdr Add or remove the specified node from the internal kernel node table. @@ -408,6 +413,23 @@ to protect .Xr hostapd 8 against excessive flooding with IEEE 802.11 frames. For example, beacon frames will be normally received every 100 ms. +.Ss Rule Rate +It is possible to tell +.Xr hostapd 8 +to trigger the action only after a specific +.Ic rate +of matched frames. +.Bd -filled -offset indent +.Ic rate +.Ar number +.Ar / +.Ar number +.Ic sec +.Ed +.Pp +This will help to detect excessive flooding of IEEE 802.11 frames. +For example, de-auth flooding is a DoS (Denial of Service) attack +against IEEE 802.11 wireless networks. .Ss Management Frame Subtypes The .Ar subtype @@ -519,6 +541,13 @@ wireless access point to access point communication. hostap handle type management subtype probe request \\ with log +# Detect flooding of management frames except beacons. +# This will detect some possible Denial of Service attacks +# against the IEEE 802.11 protocol. +hostap handle skip type management subtype ! beacon \\ + with log \\ + rate 100 / 10 sec + # Log rogue accesspoints via IAPP, limited to every second, # and skip further IAPP processing. hostap handle skip type management subtype beacon bssid !<myess> \\ diff --git a/usr.sbin/hostapd/hostapd.h b/usr.sbin/hostapd/hostapd.h index 95b88d9c4ae..f57496e8187 100644 --- a/usr.sbin/hostapd/hostapd.h +++ b/usr.sbin/hostapd/hostapd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: hostapd.h,v 1.6 2005/09/09 13:21:13 reyk Exp $ */ +/* $OpenBSD: hostapd.h,v 1.7 2005/09/30 16:50:03 reyk Exp $ */ /* * Copyright (c) 2004, 2005 Reyk Floeter <reyk@vantronix.net> @@ -243,7 +243,9 @@ struct hostapd_frame { HOSTAPD_FRAME_F_BSSID_N) struct hostapd_table *f_from, *f_to, *f_bssid; - struct timeval f_limit, f_then; + struct timeval f_limit, f_then, f_last; + long f_rate, f_rate_intval; + long f_rate_cnt, f_rate_delay; enum hostapd_action f_action; u_int32_t f_action_flags; diff --git a/usr.sbin/hostapd/parse.y b/usr.sbin/hostapd/parse.y index f1a275856d8..31697a4c1b2 100644 --- a/usr.sbin/hostapd/parse.y +++ b/usr.sbin/hostapd/parse.y @@ -1,4 +1,4 @@ -/* $OpenBSD: parse.y,v 1.10 2005/09/30 14:57:30 reyk Exp $ */ +/* $OpenBSD: parse.y,v 1.11 2005/09/30 16:50:03 reyk Exp $ */ /* * Copyright (c) 2004, 2005 Reyk Floeter <reyk@vantronix.net> @@ -119,7 +119,7 @@ u_int negative; %token MODE INTERFACE IAPP HOSTAP MULTICAST BROADCAST SET SEC USEC %token HANDLE TYPE SUBTYPE FROM TO BSSID WITH FRAME RADIOTAP NWID PASSIVE %token MANAGEMENT DATA PROBE BEACON ATIM ANY DS NO DIR RESEND RANDOM -%token AUTH DEAUTH ASSOC DISASSOC REASSOC REQUEST RESPONSE PCAP +%token AUTH DEAUTH ASSOC DISASSOC REASSOC REQUEST RESPONSE PCAP RATE %token ERROR CONST TABLE NODE DELETE ADD LOG VERBOSE LIMIT QUICK SKIP %token REASON UNSPECIFIED EXPIRE LEAVE ASSOC TOOMANY NOT AUTHED ASSOCED %token RESERVED RSN REQUIRED INCONSISTENT IE INVALID MIC FAILURE OPEN @@ -205,17 +205,15 @@ event : HOSTAP HANDLE } eventopt frmmatch { /* IEEE 802.11 raw frame to send as an action */ frame_ieee80211 = &frame.f_action_data.a_frame; - } action limit { - struct timeval t_now; - + } action limit rate { if ((frame_ptr = (struct hostapd_frame *)calloc(1, sizeof(struct hostapd_frame))) == NULL) { yyerror("calloc"); YYERROR; } - gettimeofday(&t_now, NULL); - timeradd(&t_now, &frame.f_limit, &frame.f_then); + gettimeofday(&frame.f_last, NULL); + timeradd(&frame.f_last, &frame.f_limit, &frame.f_then); bcopy(&frame, frame_ptr, sizeof(struct hostapd_frame)); TAILQ_INSERT_TAIL(&hostapd_cfg.c_frames, @@ -310,6 +308,19 @@ limit : /* empty */ } ; +rate : /* empty */ + | RATE number '/' number SEC + { + if (!($2 && $4)) { + yyerror("invalid rate"); + YYERROR; + } + + frame.f_rate = $2; + frame.f_rate_intval = $4; + } + ; + frmmatchtype : /* any */ | TYPE ANY | TYPE not DATA @@ -916,6 +927,7 @@ lookup(char *token) { "quick", QUICK }, { "radiotap", RADIOTAP }, { "random", RANDOM }, + { "rate", RATE }, { "reason", REASON }, { "reassoc", REASSOC }, { "request", REQUEST }, |