* Защита от online brute force атаки
Публикувано на 16 декември 2008 в раздел ОСУП.
"Brute Force" е атака, при който атакуващият изпраща множество заявки към сървъра с различни двойки от име и парола, с цел да "налучка" някоя правилна комбинация. Най-често на атака са изложени потребителски имена като "admin", "administrator", "root", и т.н. По този начин атакуващият се опитва да получи достъп до даден защитен ресурс, без да използва пробив в сигурността.
Първото и основно правило за защита срещу brute force атаки е да използваме колкото се може по-сложни пароли. Обикновено тези атаки изпробват набор от речникови думи, имена и понякога цифри. Освен това, независимо колко сложна е вашата парола, не е добра идея да я използвате за всички сайтове, на които влизате (най-малкото администратора на чуждият уеб сайт ще може да проникне във вашия личен).
Независимо колко стриктна и добра политика използваме за паролите ние не бихме искали да позволим някой да изпробва стотици комбинации от имена и пароли върху вашата система. Най-малкото не сме сигурни дали някой от нашите потребители не използва лесна за разгадаване парола - например името си в комбинация с годината на раждане: "Иван1978". Една целенасочена атака срещу този потребител би изпробвала различни комбинации от данни, които са свързани с потребителя Иван. Паролата от своя страна изглежда сигурна (съдържа и думи и цифри) и би преминала вашия валидатор. Поради тази причина е наложително да се защитите, като едновременно с това не затруднявате потребителя излишно.
1. Captcha: вече разгледахме използването на Captcha за целта за спиране на автоматизирани brute force атаки. Това е може би най-ефективният разработен досега метод за справяне с проблема на автоматизирани атаки срещу сайтове. За съжаление този подход определено затруднява потребителите, като отнема допълнително време при всяко влизане в системата. Captcha е подходяща за защита на форми, които се попълват еднократно (например форми за регистрация). Когато става дума за форми за автентикация, които се попълват ежедневно, то въпросът е спорен. Всичко зависи от това до колко конфиденциална информация пазите и дали си заслужава да затруднявате потребителя с попълването на форма с captcha всеки път. Освен това captcha не решава друг проблем - не е казано, че една brute force атака трябва да е автоматизирана. Не е изключено човек ръчно да изпробва различни комбинации от имена и пароли. Все пак не говорим за ограничения във времето... Това, което можете да направите, е да създадете брояч за невалидни опити за влизане в даден акаунт. Когато например в даден акаунт се направят повече от 10 неуспешни опита от текущото IP, при следващия опит да се изведе captcha. При успешен вход по тази схема, брояча за неуспешни опити от IP трябва да се занули. Може да въведете и общ брояч за неуспешен вход в акаунт от каквито и да е IP адреси (виж 5).
2. Блокиране на IP след определен брой неуспешни опита за влизане: можете да си съставите база от данни със списък от IP адреси, които са направили неуспешен опит за влизане в системата. За всеки IP адрес трябва да се пази и втора колона със брой неуспешни опити за достъп. По този начин, преди да извършите проверка за автентикация на данните, може да проверите дали текущото IP не е "прекалило" с грешните опити за вход в системата и ако това е така - да го пренасочите към друга страница, която му предоставя информация как да си поиска от вас загубената парола. При успешно автентикиране в системата от даден IP адрес, неговите записи в базата от данни за неуспешни влизания трябва да бъдат изтрити, за да се избегне натрупване на случайни грешки през големи интервали от време. Чрез метода за блокиране на IP се справяте не само с автоматизираните атаки, но и с атаките извършвани от човек. Честа практика (с цел редуциране на заявките за отблокиране на IP адреси към екипа за техническа поддръжка) е да не блокирате потребителите перманентно, а само за определено време (например един час).
ВНИМАНИЕ: Ако просто блокирате IP адрес, особено при ниска граница за брой неуспешни опити, рискувате да блокирате някоя голяма частна мрежа от много потребители - например голяма NAT мрежа. Затова е по-добре да блокирате този IP адрес само за акаунта, който той атакува, а не блокиране на IP адреса изцяло за цялата система.
3. Лимит на максималния брой заявки към сървъра чрез защитна стена: един IP адрес би могъл да изпрати множество заявки за автентикация към сървъра едновременно. По този начин ние все още няма да имаме запис за това IP и бихме могли да позволим на заявките да преминат "бариерата" от предишната точка. Обикновено не е разумно да натоварвате самото приложение със следене на броя заявки към него. Добре е да сложите такъв лимит на вашия http сървър и на вашата защитна стена (firewall). Например за iptables може да използвате модула "connlimit". Истината е, че тази точка не е изключително важна - хакерът трудно ще направи повече от няколко стотици едновременни заявки - повече от това тъй или иначе ще предизвика DoS атака към вашия сървър. Тоест това ограничение не е толкова свързано с brute force атаките, колкото с DoS атаките.
4. Лимит на максималния брой заявки към сървъра чрез приложението: ако все пак искате да се подсигурите и да предотвратите напълно едновременно подадените заявки за автентикация, може да организирате приложение от тип "опашка за автентикация". Всяка заявка за автентикиране се вкарва в структура от данни тип FIFO (first in - first out) и така сме сигурни, че никога няма да бъдат изпълнени няколко едновременни заявки към базата от данни. Добавянето на нов автентикационен request в опашката включва задължителна проверка за това дали няма вече съществуващ опит за автентикация в същия акаунт - не позволявайте на две заявки към един акаунт да съществуват в опашката. Този метод обаче трябва да се използва изключително внимателно и изисква сериозна оптимизация с цел бързодействие. Добре е да се погрижите да има равностойно бързодействие на базата от данни спрямо http сървъра. В противен случай рискувате да получите претрупване на опашката и много клиенти да получават timeout (DoS атака). Затова е добре в http сървъра да пазите cache от познати "лоши" IPта и да не им позволявате да влизат в опашката за автентикация повторно. Периодично трябва да филтрирате сървъра чрез защитната стена от подобни IP адреси, които правят постоянни заявки. При мултипроцесорни сървъри (каквито са почти всички нови компютри в днешно време) е добре да се възползвате от използването на нишки за съставянето на няколко опашки за автентикация (в зависимост от броя процесори на сървъра за базата от данни). Не е разумно да се лишавате напълно от бързодействието и функционалностите на сървъра си само и единствено с цел защита.
5. Политика за блокиране на акаунти: става дума за атаки от т.нар. "bot nets". Това са мрежи от различни IP адреси, които атакуват сървъра. Често това са инфектирани с вирус компютри на нищо неподозиращи потребители в Интернет. Мащабът на такава мрежа може да бъде огромен. Също така не е задължително те да атакуват по едно и също време (което всъщност би причинило по-скоро DDoS атака), а през кратки интервали. Тук тактиката с блокиране на отделно IP след неуспешен брой опити за вход би била неуспешна, защото всяко едно IP от атакуващата мрежа само за себе си има определен брой опити. Ако например сме сложили лимит от 100 неуспешни опита за IP адрес, то една мрежа от 1000 IPта би имала 100 000 опита. Когато те атакуват определен акаунт (администраторския или на някой определен потребител), би трябвало да се почувстваме застрашени, защото ще изпробват прекалено много различни комбинации от възможности (тъй като това е "targeted" атака, атакуващите обикновено са разузнали за определена информация за дадения потребител). За да се защитим от такава атака е добре да пазим допълнително поле в базата от данни, в която се съхраняват имената и паролите. Това поле трябва да съдържа общия брой неуспешни опити за влизане към дадения акаунт. Когато се извършва автентикацията е нужно да се провери този запис и ако броя опити за пробив е голям, то е добре да се направи т.нар. "заключване на потребителския акаунт" (account lockdown). Системата няма да позволи достъп до такъв потребителски акаунт, докато администратор не "отключи" акаунта. По този начин можете да съставите списък от атакувани акаунти и да се погрижите техните пароли да са достатъчно сигурни или да търсите индивидуално решение на тяхната защита.
6. Фиксиране на акаунт по IP адрес: в случай на зачестили атаки към определен акаунт може да въведете функционалност за стриктно следене на IP адреса, от който влиза. Това е честа практика при администраторските акаунти.
7. Изкуствено забавяне на процеса на автентикация: тази тактика включва забавяне на опитите за вход от страна на приложението. Например ако видим, че има повече от определен брой неуспешни опита за вход в даден акаунт, вместо да извършим следващата автентикация веднага, ние изчакваме една секунда (thread.sleep) и чак тогава пускаме заявката. Подобно действие ще направи нормалните brute force атаки срещу уеб форми безсмислени, но потенциално ще създаде нов проблем - нашата форма ще стане уязвима към DoS атака - претоварване на сървъра с процеси. Действително ако хакера започне да прави множество едновреммени заявки към нашия сървър, могат да се създадат прекалено много спящи процеси на уеб сървъра и системата ще се претовари. Затова е напълно задължително да реализирате 4 ако ще използвате тази тактика. Проблемът с DoS уязвимостта обаче ще остане при DDoS атака. Затова тази техника НЕ Е препоръчителна освен ако не притежавате сървър с много свободни ресурси.
8. Изключване на автентикациите за кратък период от време: когато имаме неуспешен вход в даден акаунт, блокираме акаунта за кратко време - например няколко секунди. Това би се справило с brute force атаките (ще ги отложи задълго във времето), но за сметка на това хакера може да блокира акаунта на даден потребител перманентно като започне да прави непрекъснати неуспешни опити през определения период. Така потребителя никога няма да може да влезне. Затова ако извършвате тази техника, тя трябва да е свързана с филтриране по IP адрес.
9. Неприемане на прекалено бързи последователни POST заявки от един IP: този филтър не зависи от потребителския акаунт - следователно е най-добре да се направи директно на ниво "уеб сървър". HTTP сървъри като Apache имат допълнителни модули, които позволяват такава техника. По този начин освен всичко друго вие намалявате проблемите с DoS атаките - прекалено бързите последователни заявки към сървъра въобще не достигат до компилиране на PHP скрипт. Тази техника е ПРЕПОРЪЧИТЕЛНА.
10. Глобален монитор срещу разпределени атаки: ако имате определен очакван (нормален) брой неуспешни опита на ден и видите многократно повишение на броя на опити за вход в системата като цяло (хакерите не атакуват един единствен акаунт с много пароли, а много различни акаунти с малък брой пароли), вие може да направите временен throttling (забавяне на процеса на автентикация) за цялата система. Това обаче отново е много опасно - може да превърнете brute force атаката в DDoS атака. Затова тази техника трябва да се прилага само ако сървъра ви има много свободни ресурси за отразяване на такава атака. По-добрият вариант е при засичане на разпределена атака да включите временно captcha за всички акаунти, независимо от броя на неуспешните опити към всеки конкретен от тях.
Задача: Реализирайте описаните практики на някой език за web програмиране. Помислете за допълнителни варианти за защита.
Относно блокирането на IP адрес, не е ли много рестриктивна мярка да се забравяна цяла мрежа? Не знам как точно стоят нещата, но поне в София почти всички провайдери слагат uesr-DNS на клиентите. От тази гледна точка не е ли по-добре да се спира само DNS?
По принцип всеки провайдър си има собствен IP-range, който използва.