Muy bien, suficiente retraso; esto es lo que se me ocurrió hasta ahora
(perdón, larga publicación por delante. Sé valiente, amigo, el viaje valdrá la pena)
Combinando los métodos 3 y 4 de la publicación original en una especie de lista blanca 'difusa' o dinámica, y luego, y aquí está el truco, no bloquear las IP no incluidas en la lista blanca, simplemente estrangularlas al infierno y viceversa .
Tenga en cuenta que esta medida solo pretende frustrar este tipo de ataque muy específico. En la práctica, por supuesto, funcionaría en combinación con otros enfoques de mejores prácticas para la autenticación: limitación de nombre de usuario fijo, limitación por IP, política de contraseña segura con código, inicio de sesión de cookie sin estrangulamiento, hash todos los equivalentes de contraseña antes de guardarlos, nunca utilizando preguntas de seguridad, etc.
Suposiciones sobre el escenario de ataque
Si un atacante apunta a nombres de usuario variables, nuestra limitación de nombre de usuario no se activa. Si el atacante está usando una botnet o tiene acceso a un amplio rango de IP, nuestra limitación de IP es impotente. Si el atacante ha eliminado previamente nuestra lista de usuarios (generalmente posible en servicios web de registro abierto), no podemos detectar un ataque continuo en función de la cantidad de errores de "usuario no encontrado". Y si aplicamos una restricción restrictiva en todo el sistema (todos los nombres de usuario, todas las IP), cualquier ataque de este tipo afectará a todo nuestro sitio durante la duración del ataque más el período de limitación.
Entonces necesitamos hacer algo más.
La primera parte de la contramedida: lista blanca
De lo que podemos estar bastante seguros es que el atacante no puede detectar y falsificar dinámicamente las direcciones IP de varios miles de nuestros usuarios (+). Lo que hace factible la lista blanca . En otras palabras: para cada usuario, almacenamos una lista de las IP (hash) desde donde el usuario ha iniciado sesión (recientemente) previamente.
Por lo tanto, nuestro esquema de listas blancas funcionará como una 'puerta principal' bloqueada, donde un usuario debe estar conectado desde una de sus IP 'buenas' reconocidas para poder iniciar sesión. Un ataque de fuerza bruta en esta 'puerta principal' sería prácticamente imposible (+).
(+) a menos que el atacante 'posea' el servidor, todos los cuadros de nuestros usuarios o la conexión en sí misma, y en esos casos, ya no tenemos un problema de 'autenticación', tenemos un verdadero pull-the de tamaño de franquicia -enchufe la situación FUBAR
La segunda parte de la contramedida: aceleración de IP no reconocidas en todo el sistema
Para que una lista blanca funcione para un servicio web de registro abierto, donde los usuarios cambian de computadora con frecuencia y / o se conectan desde direcciones IP dinámicas, necesitamos mantener abierta una 'puerta de acceso' para los usuarios que se conectan desde IP no reconocidas. El truco es diseñar esa puerta para que las botnets se atasquen y los usuarios legítimos se molesten lo menos posible .
En mi esquema, esto se logra al establecer un número máximo muy restrictivo de intentos fallidos de inicio de sesión por IP no aprobadas durante, por ejemplo, un período de 3 horas (puede ser más prudente usar un período más corto o más largo según el tipo de servicio), y haciendo que esa restricción sea global , es decir. para todas las cuentas de usuario.
Incluso una fuerza bruta lenta (1-2 minutos entre intentos) se detectaría y frustraría de manera rápida y efectiva utilizando este método. Por supuesto, una fuerza bruta realmente lenta aún podría pasar desapercibida, pero velocidades demasiado lentas derrotan el propósito mismo del ataque de fuerza bruta.
Lo que espero lograr con este mecanismo de estrangulamiento es que si se alcanza el límite máximo, nuestra 'puerta de gato' se cierra por un tiempo, pero nuestra puerta principal permanece abierta para usuarios legítimos que se conectan por los medios habituales:
- Ya sea conectándose desde una de sus IP reconocidas
- O mediante el uso de una cookie de inicio de sesión persistente (desde cualquier lugar)
Los únicos usuarios legítimos que se verían afectados durante un ataque, es decir. mientras se activaba la limitación, serían los usuarios sin cookies de inicio de sesión persistentes que iniciaran sesión desde una ubicación desconocida o con una IP dinámica. Esos usuarios no podrán iniciar sesión hasta que la aceleración desaparezca (lo que podría llevar un tiempo si el atacante mantiene su botnet funcionando a pesar de la aceleración).
Para permitir que este pequeño subconjunto de usuarios se filtre a través de la puerta para gatos sellada de otro modo, incluso cuando los bots todavía la estaban golpeando, emplearía un formulario de inicio de sesión de 'respaldo' con un CAPTCHA. De modo que, cuando muestre el mensaje "Lo siento, pero no puede iniciar sesión desde esta dirección IP en este momento", incluya un enlace que diga " inicio de sesión seguro de respaldo - SOLO HUMANOS ( bots: no mentir ) ". Broma a un lado, cuando hacen clic en ese enlace, les dan un formulario de inicio de sesión autenticado reCAPTCHA que evita la limitación en todo el sitio. De esa manera, SI son humanos Y conocen el inicio de sesión + contraseña correctos (y son capaces de leer CAPTCHA), nunca se les negará el servicio, incluso si se conectan desde un host desconocido y no usan la cookie de inicio de sesión automático.
Ah, y solo para aclarar: dado que considero que los CAPTCHA son generalmente malos, la opción de inicio de sesión de 'copia de seguridad' solo aparecerá mientras la aceleración esté activa .
No se puede negar que un ataque sostenido como ese todavía constituiría una forma de ataque DoS, pero con el sistema descrito en su lugar, solo afectaría lo que sospecho que es un pequeño subconjunto de usuarios, es decir, personas que no usan el la cookie "recordarme" Y está iniciando sesión mientras ocurre un ataque Y no está iniciando sesión desde ninguna de sus IP habituales Y que no pueden leer CAPTCHA. Solo aquellos que pueden decir NO a TODOS esos criterios, específicamente los bots y las personas discapacitadas realmente desafortunadas , serán rechazados durante un ataque de bot.
EDITAR: En realidad, pensé en una forma de permitir que incluso los usuarios con problemas de CAPTCHA pasen durante un 'bloqueo': en lugar de, o como complemento del inicio de sesión de CAPTCHA de respaldo, proporcionar al usuario la opción de tener un solo uso , código de bloqueo específico del usuario enviado a su correo electrónico, que luego puede usar para evitar la limitación. Esto definitivamente cruza mi umbral de 'molestia', pero dado que solo se usa como último recurso para un pequeño subconjunto de usuarios, y dado que aún supera el bloqueo de su cuenta, sería aceptable.
(Además, tenga en cuenta que nada de esto sucede si el ataque es menos sofisticado que la desagradable versión distribuida que describí aquí. Si el ataque proviene de unas pocas IP o solo golpea algunos nombres de usuario, se frustrará mucho antes) y sin consecuencias para todo el sitio)
Entonces, esa es la contramedida que implementaré en mi biblioteca de autenticación, una vez que esté convencido de que es sólido y de que no hay una solución mucho más simple que me haya perdido. El hecho es que hay muchas maneras sutiles de hacer las cosas mal en seguridad, y no estoy por encima de hacer suposiciones falsas o lógicas irremediablemente defectuosas. Así que por favor, todos y cada uno de los comentarios, críticas y mejoras, sutilezas, etc. son muy apreciados.
Unos simples pasos:
Incluya en la lista negra ciertos nombres de usuario comunes y úselos como un honeypot. Administrador, invitado, etc. No permita que nadie cree cuentas con estos nombres, por lo que si alguien intenta iniciar sesión, sabe que alguien está haciendo algo que no debería.
Asegúrese de que cualquier persona que tenga poder real en el sitio tenga una contraseña segura. Requerir que los administradores / moderadores tengan contraseñas más largas con una combinación de letras, números y símbolos. Rechace las contraseñas trivialmente simples de los usuarios habituales con una explicación.
Una de las cosas más simples que puede hacer es avisar a las personas cuando alguien intentó iniciar sesión en su cuenta y darles un enlace para informar el incidente si no fueron ellos. Un mensaje simple cuando inician sesión como "Alguien intentó iniciar sesión en su cuenta a las 4:20 AM del miércoles, bla, bla. Haga clic aquí si no fue usted". Te permite mantener algunas estadísticas sobre los ataques. Puede intensificar las medidas de monitoreo y seguridad si observa que hay un aumento repentino de accesos fraudulentos.
fuente
Si entiendo el MO de los ataques de fuerza bruta correctamente, entonces uno o más nombres de usuario se prueban continuamente.
Hay dos sugerencias que no creo haber visto todavía aquí:
Editar : en respuesta a los comentarios sobre un acelerador de nombre de usuario: este es un acelerador específico de nombre de usuario sin tener en cuenta la fuente del ataque.
Si el nombre de usuario se estrangula, entonces se detectaría incluso un ataque de nombre de usuario coordinado (IP múltiple, conjetura simple por IP, mismo nombre de usuario). Los nombres de usuario individuales están protegidos por el acelerador, incluso si los atacantes son libres de probar otro usuario / pase durante el tiempo de espera.
Desde el punto de vista de los atacantes, durante el tiempo de espera puede ser capaz de adivinar por primera vez las 100 contraseñas y descubrir rápidamente una contraseña incorrecta por cuenta. Es posible que solo pueda realizar conjeturas de 50 segundos durante el mismo período de tiempo.
Desde el punto de vista de una cuenta de usuario, todavía se necesita el mismo número promedio de conjeturas para romper la contraseña, incluso si las conjeturas provienen de múltiples fuentes.
Para los atacantes, en el mejor de los casos, será el mismo esfuerzo romper 100 cuentas como lo haría con 1 cuenta, pero como no está acelerando en todo el sitio, puede acelerar el acelerador con bastante rapidez.
Refinamientos adicionales:
Ideas de IU (pueden no ser adecuadas en este contexto), que también pueden refinar lo anterior:
fuente
Hay tres factores de autenticación:
Por lo general, los sitios web solo aplican la política n. ° 1. Incluso la mayoría de los bancos solo aplican la política 1. En su lugar, confían en un enfoque de "sabe algo más" para la autenticación de dos factores. (IE: un usuario conoce su contraseña y el apellido de soltera de su madre). Si puede, una forma de agregar un segundo factor de autenticación no es demasiado difícil.
Si puede generar alrededor de 256 caracteres de aleatoriedad, podría estructurarlo en una tabla de 16 × 16 y luego pedirle al usuario que le dé el valor en la tabla de la celda A-14, por ejemplo. Cuando un usuario se registre o cambie su contraseña, dele la tabla y dígale que la imprima y la guarde.
La dificultad con ese enfoque es que cuando un usuario olvida su contraseña, como lo hará, no puede simplemente ofrecer el estándar "responda esta pregunta e ingrese una nueva contraseña", ya que eso también es vulnerable a la fuerza bruta. Además, no puede restablecerlo y enviarles uno nuevo, ya que su correo electrónico también podría verse comprometido. (Ver: Makeuseof.com y su dominio robado).
Otra idea (que involucra gatitos), es lo que BOA llama SiteKey (creo que marcaron el nombre). Brevemente, el usuario debe cargar una imagen cuando se registra, y cuando intenta iniciar sesión, pídale que elija su imagen entre 8 o 15 (o más) al azar. Entonces, si un usuario carga una imagen de su gatito, teóricamente solo ellos saben exactamente qué imagen es suya de todos los otros gatitos (o flores o lo que sea). La única vulnerabilidad real que tiene este enfoque es el ataque del hombre en el medio.
Una idea más (sin embargo, sin gatitos) es rastrear las IP con las que los usuarios acceden al sistema y exigirles que realicen una autenticación adicional (captcha, elegir un gatito, elegir una clave de esta tabla) cuando inician sesión desde una dirección que no tienen No antes. Además, de forma similar a GMail, permite al usuario ver desde dónde ha iniciado sesión recientemente.
Editar, nueva idea:
Otra forma de validar los intentos de inicio de sesión es verificar si el usuario proviene o no de su página de inicio de sesión. No puede verificar los referentes, ya que pueden ser falsificados fácilmente. Lo que necesita es establecer una clave en la variable _SESSION cuando el usuario ve la página de inicio de sesión, y luego verificar para asegurarse de que existe la clave cuando envía su información de inicio de sesión. Si el bot no se envía desde la página de inicio de sesión, no podrá iniciar sesión. También puede facilitar esto al involucrar a JavaScript en el proceso, ya sea usándolo para configurar una cookie o agregando información al formulario después de que se haya cargado. O bien, puede dividir el formulario en dos envíos diferentes (es decir, el usuario ingresa su nombre de usuario, envía, luego en una nueva página ingresa su contraseña y vuelve a enviar).
La clave, en este caso, es el aspecto más importante. Un método común para generarlos es una combinación de los datos del usuario, su IP y el momento en que se enviaron.
fuente
Anteriormente había respondido una pregunta muy similar en ¿Cómo puedo limitar los intentos de inicio de sesión de usuario en PHP ? Reitero la solución propuesta aquí, ya que creo que muchos de ustedes lo encontrarán informativo y útil para ver algún código real. Tenga en cuenta que el uso de un CAPTCHA podría no ser la mejor solución debido a los algoritmos cada vez más precisos que se utilizan en los destructores de CAPTCHA en la actualidad:
No puede simplemente evitar ataques DoS encadenando la aceleración a una sola IP o nombre de usuario. Demonios, ni siquiera puedes evitar los intentos de inicio de sesión de disparo rápido con este método.
¿Por qué? Porque el ataque puede abarcar múltiples direcciones IP y cuentas de usuario en aras de eludir sus intentos de estrangulamiento.
He visto en otros lugares que idealmente deberías rastrear todos los intentos fallidos de inicio de sesión en el sitio y asociarlos a una marca de tiempo, tal vez:
Decida ciertas demoras en función del número total de inicios de sesión fallidos en un período de tiempo determinado. Debe basar esto en datos estadísticos extraídos de su
failed_logins
tabla, ya que cambiarán con el tiempo según la cantidad de usuarios y cuántos de ellos pueden recordar (y escribir) su contraseña.Consulte la tabla en cada intento de inicio de sesión fallido para encontrar el número de inicios de sesión fallidos durante un período de tiempo determinado, digamos 15 minutos:
Si el número de intentos durante el período de tiempo dado supera su límite, imponga la limitación u obligue a todos los usuarios a usar un captcha (es decir, reCaptcha) hasta que el número de intentos fallidos durante el período de tiempo determinado sea inferior al umbral.
El uso de reCaptcha en un cierto umbral garantizaría que se minimizara un ataque desde múltiples frentes y que los usuarios normales del sitio no experimentarían un retraso significativo por intentos de inicio de sesión fallidos legítimos. No puedo garantizar la prevención, ya que ya se ha ampliado para que los CAPTCHA puedan ser eliminados. Existen soluciones alternativas, quizás una variante de "Nombra a este animal", que podría funcionar bastante bien como un sustituto.
fuente
Tengo que preguntar si ha realizado un análisis de costo-beneficio de este problema; Parece que está tratando de protegerse de un atacante que tiene suficiente presencia en la web para adivinar varias contraseñas, enviando quizás 3-5 solicitudes por IP (ya que ha rechazado la limitación de IP). ¿Cuánto (aproximadamente) costaría ese tipo de ataque? ¿Es más costoso que el valor de las cuentas que está tratando de proteger? ¿Cuántas botnets gigantes quieren lo que tienes?
La respuesta podría ser no, pero si lo es, espero que obtenga ayuda de un profesional de seguridad de algún tipo; la habilidad de programación (y el puntaje de StackOverflow) no se correlacionan fuertemente con los conocimientos de seguridad.
fuente
Para resumir el esquema de Jens en un diagrama de transición de pseudoestado / base de reglas:
// never throttle
// slow the bots
// humans still welcome
// a correct guess from a bot
Observaciones:
Estas observaciones cubren un tipo diferente de ataque a los que estás tratando de contrarrestar.
fuente
Parece que estás intentando defenderte de la fuerza bruta lenta y distribuida . No hay mucho que puedas hacer al respecto. Estamos utilizando una PKI y no hay inicios de sesión de contraseña. Ayuda, pero si sus clientes tienen posibilidades de estaciones de trabajo de vez en cuando, esto no es muy aplicable.
fuente
Descargo de responsabilidad: trabajo para una empresa de dos factores, pero no estoy aquí para enchufarlo. Aquí hay algunas observaciones.
Las cookies se pueden robar con XSS y el navegador vulns. Los usuarios suelen cambiar de navegador o borrar sus cookies.
Las direcciones IP de origen son simultáneamente dinámicamente variables y suplantables.
Captcha es útil, pero no autentica a un humano específico.
Múltiples métodos se pueden combinar con éxito, pero el buen gusto está en orden.
La complejidad de la contraseña es buena, cualquier cosa basada en contraseña depende de manera crítica de que las contraseñas tengan suficiente entropía. En mi humilde opinión, una contraseña segura escrita en una ubicación física segura es mejor que una contraseña débil en la memoria. Las personas saben cómo evaluar la seguridad de los documentos en papel mucho mejor de lo que saben cómo calcular la entropía efectiva en el nombre de su perro cuando se usa como contraseña para tres sitios web diferentes. Considere dar a los usuarios la posibilidad de imprimir una página grande o pequeña llena de códigos de acceso de un solo uso.
Las preguntas de seguridad como "cuál era su mascota de la escuela secundaria" son en su mayoría otra forma pésima de "algo que usted sabe", la mayoría de ellas son fácilmente adivinables o de dominio público.
Como notó, la limitación de los intentos fallidos de inicio de sesión es una compensación entre la prevención de ataques de fuerza bruta y la facilidad de DoSing una cuenta. Las políticas de bloqueo agresivo pueden reflejar una falta de confianza en la entropía de contraseña.
Personalmente, no veo el beneficio de hacer cumplir la caducidad de la contraseña en un sitio web de todos modos. El atacante obtiene su contraseña una vez, puede cambiarla y cumplir con esa política tan fácilmente como usted. Quizás un beneficio es que el usuario podría notarlo antes si el atacante cambia la contraseña de la cuenta. Aún mejor sería si el usuario fuera notificado de alguna manera antes de que el atacante obtuviera acceso. Los mensajes como "N intentos fallidos desde el último inicio de sesión" son útiles a este respecto.
La mejor seguridad proviene de un segundo factor de autenticación que está fuera de banda en relación con el primero. Como dijiste, los tokens de hardware en "algo que tienes" son geniales, pero muchos (no todos) tienen una sobrecarga administrativa real asociada con su distribución. No conozco ninguna solución biométrica "algo que seas" buena para los sitios web. Algunas soluciones de dos factores funcionan con proveedores de OpenID, algunas tienen SDK de PHP / Perl / Python.
fuente
Mi mayor recomendación es simplemente asegurarme de mantener informados a los usuarios de los intentos de inicio de sesión incorrectos en sus cuentas: es probable de su contraseña mucho más en serio si se les presenta evidencia de que alguien realmente está tratando de ingresar a su cuenta .
De hecho, atrapé a alguien que pirateó la cuenta de MySpace de mi hermano porque habían intentado ingresar a la cuenta de Gmail que configuré para él y usé la función 'restablecer mi contraseña por correo electrónico' ... que fue a mi bandeja de entrada.
fuente
¿Qué hay de requerir una contraseña de un solo uso antes de ingresar su contraseña normal? ¿Eso haría muy obvio que alguien estaba atacando antes de tener muchas oportunidades de adivinar la contraseña principal?
Mantenga un conteo / tasa global de fallas de inicio de sesión, este es el indicador de un ataque, durante un ataque sea más estricto con respecto a las fallas de inicio de sesión, por ejemplo, prohíba las IP más rápidamente.
fuente
No creo que haya una respuesta perfecta, pero me sentiría inclinado a tratar de confundir a los robots si se detecta un ataque.
Fuera de mi mente:
Cambie a una pantalla de inicio de sesión alternativa. Tiene varios espacios en blanco de nombre de usuario y contraseña que realmente aparecen, pero solo uno de ellos está en el lugar correcto. Los nombres de los campos son ALEATORIOS --una clave de sesión se envía junto con la pantalla de inicio de sesión, el servidor puede averiguar qué campos son lo. Si tiene éxito o falla, se descarta, por lo que no puede intentar un ataque de repetición; si rechaza la contraseña, obtendrá una nueva ID de sesión.
Se supone que cualquier formulario que se envíe con datos en un campo incorrecto proviene de un robot: el inicio de sesión falla, punto y esa IP se limita. Asegúrese de que los nombres de campo aleatorios nunca coincidan con los nombres de campo legítimos para que alguien que usa algo que recuerde contraseñas no sea engañoso.
A continuación, ¿qué tal un tipo diferente de captcha: tiene una serie de preguntas que no causarán problemas a un humano. Sin embargo, NO son azar. Cuando comienza el ataque, todos reciben la pregunta # 1. Después de una hora, se descarta la pregunta n. ° 1, nunca se volverá a utilizar y todos recibirán la pregunta n. ° 2, y así sucesivamente.
El atacante no puede probar la descarga de la base de datos para colocarla en su robot debido a la naturaleza desechable de las preguntas. Tiene que enviar nuevas instrucciones a su botnet en una hora para poder hacer cualquier cosa.
fuente
Dado que varias personas incluyeron CAPTCHA como un mecanismo humano alternativo, estoy agregando una pregunta anterior de StackOverflow e hilo sobre la efectividad de CAPTCHA.
¿Se ha agrietado / pirateado / OCR'd / derrotado / roto reCaptcha?
El uso de CAPTCHA no limita las mejoras de su limitación y otras sugerencias, pero creo que la cantidad de respuestas que incluyen CAPTCHA como alternativa debe considerar los métodos basados en humanos disponibles para las personas que buscan romper la seguridad.
fuente
También puede acelerar según la seguridad de la contraseña de un usuario.
Cuando un usuario registra o cambia su contraseña, usted calcula una calificación de fortaleza para su contraseña, digamos entre 1 y 10.
Algo así como "contraseña" obtiene un 1, mientras que "c6eqapRepe7et * Awr @ ch" puede obtener un puntaje de 9 o 10 y cuanto mayor sea el puntaje, más tiempo demorará la aceleración.
fuente
La primera respuesta que generalmente escucho cuando hago esta pregunta es cambiar los puertos, pero olvídate de eso y simplemente deshabilita IPv4. Si solo permite clientes de redes IPv6, ya no rezará por un escaneo de red simple y los atacantes recurrirán a las búsquedas de DNS. No ejecute en la misma dirección que su Apache (AAAA) / Sendmail (MX-> AAAA) / lo que le ha dado a todos (AAAA). Asegúrate de que tu zona no pueda ser transferida, ¿estás esperando que alguien pueda descargar tu zona?
Si los bots encuentran que su servidor configura nuevos nombres de host, simplemente agregue algunas tonterías a sus nombres de host y cambie su dirección. Deje los nombres antiguos e incluso configure ** nombres de honeypot para que la red de bots agote el tiempo de espera.
** Pruebe sus registros inversos (PTR) (bajo ip6.arpa.) Para ver si se pueden usar para poner a cero en los / 4 que tienen registros VS / 4 que no. IE Típicamente, ip6.arpa tendría ~ 32 "." S en una dirección, pero intentar con los últimos que faltan podría eludir los bloques de red que tienen registros VS otros que no. Si lleva eso más allá, es posible omitir grandes porciones del espacio de direcciones.
En el peor de los casos, los usuarios tendrán que configurar un túnel IPv6, no es como si tuvieran que ir tan lejos como VPNing en una DMZ ... Aunque uno se pregunta por qué esa no es la primera opción.
También Kerberos es genial, pero IMHO LDAP explota (¿Qué tiene de malo técnicamente NISPlus? He leído que Sun decidió que los usuarios querían LDAP y por eso dejaron NIS +). Kerberos funciona bien sin LDAP o NIS, solo tiene que administrar los usuarios host por host. El uso de Kerberos le brinda una PKI fácil de usar, si no automatizada.
fuente
Un poco tarde aquí, pero estaba pensando, asumiendo un caso difícil: el atacante usa muchas direcciones IP aleatorias, nombres de usuario aleatorios y una contraseña aleatoria seleccionada de una lista de los 10,000 más populares.
Una cosa que podría hacer, especialmente si el sistema parece estar bajo ataque, ya que hay muchos intentos de contraseña incorrecta en el sistema y especialmente si la contraseña es de baja entropía es hacer una pregunta secundaria como, por ejemplo, cuáles son los nombres de sus padres. . Si un atacante llega a un millón de cuentas probando la contraseña 'contraseña1', hay una buena posibilidad de que obtenga mucho, pero sus probabilidades de obtener también los nombres correctos reducirían drásticamente los éxitos.
fuente