comparison svr-session.c @ 1790:42745af83b7d

Introduce extra delay before closing unauthenticated sessions To make it harder for attackers, introduce a delay to keep an unauthenticated session open a bit longer, thus blocking a connection slot until after the delay. Without this, while there is a limit on the amount of attempts an attacker can make at the same time (MAX_UNAUTH_PER_IP), the time taken by dropbear to handle one attempt is still short and thus for each of the allowed parallel attempts many attempts can be chained one after the other. The attempt rate is then: "MAX_UNAUTH_PER_IP / <process time of one attempt>". With the delay, this rate becomes: "MAX_UNAUTH_PER_IP / UNAUTH_CLOSE_DELAY".
author Thomas De Schampheleire <thomas.de_schampheleire@nokia.com>
date Wed, 15 Feb 2017 13:53:04 +0100
parents a6da10ac64b5
children 8a78cc13eb30
comparison
equal deleted inserted replaced
1789:249681d9ecda 1790:42745af83b7d
213 void svr_dropbear_exit(int exitcode, const char* format, va_list param) { 213 void svr_dropbear_exit(int exitcode, const char* format, va_list param) {
214 char exitmsg[150]; 214 char exitmsg[150];
215 char fullmsg[300]; 215 char fullmsg[300];
216 char fromaddr[60]; 216 char fromaddr[60];
217 int i; 217 int i;
218 int add_delay = 0;
218 219
219 #if DROPBEAR_PLUGIN 220 #if DROPBEAR_PLUGIN
220 if ((ses.plugin_session != NULL)) { 221 if ((ses.plugin_session != NULL)) {
221 svr_ses.plugin_instance->delete_session(ses.plugin_session); 222 svr_ses.plugin_instance->delete_session(ses.plugin_session);
222 } 223 }
245 } else if (ses.authstate.pw_name) { 246 } else if (ses.authstate.pw_name) {
246 /* we have a potential user */ 247 /* we have a potential user */
247 snprintf(fullmsg, sizeof(fullmsg), 248 snprintf(fullmsg, sizeof(fullmsg),
248 "Exit before auth%s: (user '%s', %u fails): %s", 249 "Exit before auth%s: (user '%s', %u fails): %s",
249 fromaddr, ses.authstate.pw_name, ses.authstate.failcount, exitmsg); 250 fromaddr, ses.authstate.pw_name, ses.authstate.failcount, exitmsg);
251 add_delay = 1;
250 } else { 252 } else {
251 /* before userauth */ 253 /* before userauth */
252 snprintf(fullmsg, sizeof(fullmsg), "Exit before auth%s: %s", fromaddr, exitmsg); 254 snprintf(fullmsg, sizeof(fullmsg), "Exit before auth%s: %s", fromaddr, exitmsg);
255 add_delay = 1;
253 } 256 }
254 257
255 dropbear_log(LOG_INFO, "%s", fullmsg); 258 dropbear_log(LOG_INFO, "%s", fullmsg);
259
260 /* To make it harder for attackers, introduce a delay to keep an
261 * unauthenticated session open a bit longer, thus blocking a connection
262 * slot until after the delay. Without this, while there is a limit on
263 * the amount of attempts an attacker can make at the same time
264 * (MAX_UNAUTH_PER_IP), the time taken by dropbear to handle one attempt
265 * is still short and thus for each of the allowed parallel attempts
266 * many attempts can be chained one after the other. The attempt rate is
267 * then:
268 * "MAX_UNAUTH_PER_IP / <process time of one attempt>".
269 * With the delay, this rate becomes:
270 * "MAX_UNAUTH_PER_IP / UNAUTH_CLOSE_DELAY".
271 */
272 if ((add_delay != 0) && (UNAUTH_CLOSE_DELAY > 0)) {
273 TRACE(("svr_dropbear_exit: start delay of %d seconds", UNAUTH_CLOSE_DELAY));
274 sleep(UNAUTH_CLOSE_DELAY);
275 TRACE(("svr_dropbear_exit: end delay of %d seconds", UNAUTH_CLOSE_DELAY));
276 }
256 277
257 #if DROPBEAR_VFORK 278 #if DROPBEAR_VFORK
258 /* For uclinux only the main server process should cleanup - we don't want 279 /* For uclinux only the main server process should cleanup - we don't want
259 * forked children doing that */ 280 * forked children doing that */
260 if (svr_ses.server_pid == getpid()) 281 if (svr_ses.server_pid == getpid())