
Компания Variti разработва защита от ботов и DDoS атаки, както и провежда стрес тестове и натоварващо тестване. На конференцията HighLoad++ 2018 разказахме как да предпазим ресурсите от различни видове атаки. Накратко: изолирайте части от системата, използвайте облачни услуги и CDN и редовно обновявайте. Но без специализирани компании с защита, ще се затрудните 🙂
Преди да прочетете текста, можете да се запознаете с кратки тези .
А ако не обичате да четете или просто искате да гледате видео, записът на нашето изложение е по-долу под спойлера.
Видеозапис на изложението

Много компании вече знаят как да извършват натоварващи тестове, но не всички правят стрес тестове. Някои наши клиенти мислят, че техният сайт е неуязвим, защото имат highload система, която добре защитава от атаки. Ние показваме, че това не е съвсем вярно.
Разбира се, преди провеждането на тестовете получаваме разрешение от клиента, с подпис и печат, и с наша помощ да се извърши DDoS атака срещу никого не може. Тестът се провежда в избрано от клиента време, когато посещаемостта на ресурса му е минимална и проблемите с достъпността няма да се отразят на клиентите. Освен това, тъй като по време на тестването винаги може да се случи нещо неочаквано, имаме постоянен контакт с клиента. Това позволява не само да съобщаваме за постигнатите резултати, но и да правим промени по време на тестването. След приключване на тестовете винаги съставяме доклад, в който посочваме откритите недостатъци и даваме препоръки за отстраняване на слабите места на сайта.
Как работим
При провеждане на тестовете, ние еймулираме ботнет. Тъй като работим с клиенти, които не са в нашите мрежи, за да теста не завърши в първата минута поради активиране на лимити или защита, подаваме натоварването не от един IP адрес, а от собствена подсет. Плюс това, за да създадем значително натоварване, имаме собствен доста мощен тестови сървър.
Постулати
Много — не означава добре
Колкото по-ниско натоварване можем да доведем ресурса до отказ, толкова по-добре. Ако успеем да направим така, че сайтът да спре да функционира от един запит на секунда или дори от един запит на минута, това е прекрасно. Защото по законите на подлостта потребителите или нападателите случайно ще попаднат точно на тази уязвимост.
Частичният отказ е по-добър от пълния
Винаги съветваме да се правят хетерогенни системи. И е необходимо да се разделят именно на физическо ниво, а не само с контейнеризация. В случай на физическо разделение, дори ако нещо на сайта откаже, е много вероятно той да не спре напълно работата си, и потребителите да запазят достъп поне до част от функционалността.
Правилната архитектура е основата на устойчивостта
Отказоустойчивостта на ресурса и способността му да издържа атаки и натоварвания трябва да бъдат закодирани в етапа на проектиране, всъщност на етапа на чертане на първите блок-схеми в бележника. Защото ако се допуснат фатални грешки, може да бъде трудно да се поправят по-късно.
Добър трябва да бъде не само кодът, но и конфигурацията
Много хора мислят, че добрата разработваща команда е гаранция за отказоустойчивост на услугата. Действително, добрата разработваща команда е необходима, но трябва да има и добро експлоатационно управление, добър DevOps. Тоест нужни са специалисти, които правилно ще конфигурират Linux и мрежата, правилно ще напишат конфигурации в nginx, ще настроят лимити и друго. В противен случай ресурсът ще работи добре само в тестова среда, а в продукция в един момент всичко ще се провали.
Разлики между натоварващо и стрес тестиране
Натоварващото тестване позволява да се открият пределите на функциониране на системата. Стрес тестирането е насочено към откриване на слаби места в системата и се използва, за да се опита да я счупи и да се види как тя ще се държи по време на отказ на определени части. При това характерът на натоварването обикновено остава неизвестен за клиента до началото на стрес теста.
Отличителни черти на L7 атаки
Видовете натоварване обикновено разделяме на натоварвания на ниво L7 и L3&4. L7 е натоварване на приложение, най-често под него се разбира само HTTP, ние обаче имаме предвид всякакво натоварване на ниво TCP протокол.
Атаките L7 имат определени отличителни черти. Първо, те идват директно в приложението, което означава, че е малко вероятно да бъдат отблъснати със средства за мрежова защита. Тези атаки използват логиката и благодарение на това много ефективно изразходват ЦПУ, памет, диск, база данни и други ресурси дори при малък трафик.
HTTP Flood
При всяка атака е по-лесно да се създаде натоварване, отколкото да се обработи, и с L7 това също е вярно. Трафикът на атаката не винаги е лесен за разграничаване от легитимния, и най-често това може да се направи по честотата на запитванията, но ако всичко е планирано грамотно, то по логовете не е възможно да се разбере къде е атаката, а къде легитимните запитвания.
В качестве первого примера рассмотрим атаку HTTP Flood. Из графика видно, что обычно такие атаки очень мощные, в примере ниже пиковое число запросов превосходило 600 тысяч в минуту.

HTTP Flood е най-простият начин за създаване на натоварване. Обикновено за него се използва някакъв инструмент за натоварващо тестване, например ApacheBench, и се задават запитвания и цел. При такъв прост подход вероятността да се сблъскате с кеширане на сървъра е голяма, но е лесно да се избегне. Например, добавяйки случайни низове в запитването, което ще принуди сървъра постоянно да предоставя нова страница.
Също така не трябва да забравяте за user-agent по време на създаването на натоварване. Много user-agent от популярни инструменти за тестване се филтрират от системните администратори, и в такъв случай натоварването може просто да не достигне до бекенда. Значително подобряване на резултата може да се постигне, като се добави по-подходящ заглавие от браузър в запитването.
Въпреки простотата на атаките HTTP Flood, те имат и свои недостатъци. Първо, за създаването на натоварване са необходими големи ресурси. Второ, тези атаки лесно се откриват, особено ако идват от един адрес. В резултат на това запитванията незабавно започват да се филтрират или от системни администратори, или дори на ниво доставчик.
Какво да търсите
За да се намали броят на заявките в секунда и в същото време да не се загуби в ефективността, е необходимо да проявите малко фантазия и да проучите сайта. Можете да натоварите не само канала или сървъра, но и отделни части на приложението, например, бази данни или файлови системи. Освен това можете да потърсите места на сайта, които извършват големи изчисления: калкулатори, страници с избор на продукти и други. Накрая, често се случва, че на сайта има определен php скрипт, който генерира страница от стотици хиляди редове. Такъв скрипт също значително натоварва сървъра и може да стане мишена за атака.
Къде да търсим
Когато сканираме ресурса преди провеждането на тестове, на първо място гледаме, разбира се, самия сайт. Търсим всевъзможни полета за въвеждане, тежки файлове — изобщо всичко, което може да създаде проблеми за ресурса и да забави работата му. Тук помагат обикновените средства за разработка в Google Chrome и Firefox, които показват времето за отговор на страницата.
Също така сканираме поддомейните. Например, има един онлайн магазин, abc.com, и той има поддомейн admin.abc.com. Най-вероятно това е админка с авторизация, но ако в нея пуснем натоварване, тя може да създаде проблеми за основния ресурс.
Сайтът може да има поддомейн api.abc.com. Най-вероятно това е ресурс за мобилни приложения. Можете да намерите приложението в App Store или Google Play, да настроите специален точка за достъп, да декомпилирате API и да регистрирате тестови акаунти. Проблемът е, че често хората смятат, че всичко, което е защитено с авторизация, е неуязвимо за атаки на отказ в обслужването. Сякаш авторизацията е най-добрата CAPTCHA, но това не е така. Правенето на 10-20 тестови акаунта е лесно, а след като ги създадем, получаваме достъп до сложната и незащитена функционалност.
Естествено, разглеждаме историята, robots.txt и WebArchive, ViewDNS, търсим стари версии на ресурса. Понякога се случва така, че разработчиците пуснат, да речем, mail2.yandex.net, а старата версия, mail.yandex.net, остава. Този mail.yandex.net спира да се поддържа, за него не се отделят ресурси за разработка, но той продължава да консумира база данни. Съответно, с помощта на старата версия можете ефективно да изчерпите ресурсите на бекенда и всичко, което стои зад верстката. Разбира се, това не става винаги, но с подобно нещо все пак се сблъскваме доста често.
Естествено, ние препарираме всички параметри на заявката и структурата на бисквитките. Можем, да кажем, да вкараме в JSON масив вътре в бисквитката някаква стойност, да създадем голяма многослойна структура и да накараме ресурса да работи безразсъдно дълго.
Натоварване при търсене
Първото, което идва наум при изследването на сайт, е да се натовари базата данни, тъй като търсенето е почти навсякъде и за съжаление, почти никъде не е защитено както трябва. За неизвестни причини разработчиците не отделят достатъчно внимание на търсенето. Но тук има една препоръка — не трябва да се правят еднотипни заявки, защото може да се сблъскате с кеширане, точно както в случая с HTTP flood.
Правенето на случайни заявки към базата данни не винаги е ефективно. Много по-добре е да се създаде списък с ключови думи, които са свързани с търсенето. Връщайки се на примера с интернет магазин: да предположим, че сайтът търгува с автомобилни гуми и позволява задаване на радиус на гумите, тип на автомобила и други параметри. Съответно комбинации от релевантни думи ще накарат базата данни да работи в много по-сложни условия.
Освен това, си струва да се използва пагинация: много по-трудно е за търсенето да предостави предпоследната страница от резултатите, отколкото първата. Тоест, с помощта на пагинация можете малко да разнообразите натоварването.
На примера по-долу показваме натоварването при търсене. Видно е, че от първата секунда на теста при скорост от десет заявки в секунда сайтът падна и не отговаряше.

Какво става, ако няма търсене?
Ако няма търсене, това не означава, че сайтът не съдържа други уязвими полета за въвеждане. Такова поле може да бъде авторизацията. В момента разработчиците обичат да правят сложни хешове, за да защитят базата от логини от атаки с радужни таблици. Това е добре, но такива хешове изискват големи ресурси на CPU. Голям поток от фалшиви авторизации води до отказ на процесора и в крайна сметка, сайтът спира да работи.
Присъствието на уебсайта на всякакви формуляри за коментари и обратна връзка е повод да изпратите много големи текстове или просто да създадете масов флууд. Понякога сайтовете приемат вложени файлове, включително в gzip формат. В такъв случай, взимаме файл с размер 1Тб, компресираме го с gzip до няколко байта или килобайта и го изпращаме на сайта. След това той се разархивира и получаваме много интересен ефект.
Rest API
Бих искал да обърна внимание на популярните напоследък услуги, като Rest API. Защитата на Rest API е значително по-трудна в сравнение с обикновен сайт. Дори и тривиалните методи за защита от опити за разбиване на пароли и друга нелегитимна активност не работят за Rest API.
Rest API е изключително лесно да се компрометира, тъй като то взаимодейства директно с базата данни. Извеждането на такава услуга от строя води до тежки последици за бизнеса. Факт е, че Rest API е свързан не само с основния сайт, но и с мобилното приложение, и с вътрешни бизнес ресурси. Ако всичко това се срине, ефектът е много по-силен отколкото при спирането на прост сайт.
Натоварване на тежък контент
Ако ни предлагат да тестваме обикновено едностранично приложение, лендинг или визитен сайт, които нямат сложна функционалност, ние търсим тежък контент. Например, големи изображения, които сървърът предоставя, бинарни файлове, pdf документация — опитваме се да изтеглим всичко това. Тези тестове натоварват файловата система и запушват каналите, поради което са ефективни. Тоест, дори да не сринете сървъра, изтегляйки голям файл с ниски скорости, просто ще запушите канала на целевия сървър и тогава ще настъпи отказ в обслужването.
На примера на такъв тест е видно, че при скорост от 30 RPS сайтът спря да отговаря или започна да издава 500-ти грешки на сървъра.

Не бива да забравяме и за настройката на сървърите. Често можем да срещнем хора, които са закупили виртуална машина, инсталирали са Apache, настроили всичко по подразбиране, добавили php приложение и по-долу можем да видим резултата.

Тук натоварването беше в корена и достигаше само 10 RPS. Изчакахме 5 минути и сърверът падна. Въпреки това, не е ясно защо е паднал, но има предположение, че просто е пренаситен с памет и затова е спряло да отговаря.
Wave based
През последните година-две атаките с вълни станаха доста популярни. Това се дължи на факта, че много организации закупуват определени устройства за защита от DDoS, които изискват време за натрупване на статистики, преди да започнат филтрирането на атаката. Тоест те не филтрират атаката през първите 30-40 секунди, тъй като натрупват данни и се обучават. Съответно, през тези 30-40 секунди на сайта могат да се насочат толкова много заявки, че ресурсът ще бъде недостъпен за дълго време, докато не се обработят всички заявки.
В случая с атаката по-долу имаше интервал от 10 минути, след което пристигна нова, изменена партида атака.

Тоест защитата се е обучила, стартирала е филтрирането, но дойде нова, съвсем различна партида атака и защитата отново започна обучение. Всъщност, филтрирането спира да работи, защитата става неефективна и сайтът е недостъпен.
За атаките с вълни са характерни много високи стойности на пика, тя може да достигне сто хиляди или милион заявки в секунда в случая с L7. Ако говорим за L3&4, то там могат да бъдат стотици гигабита трафик или, съответно, стотици mpps, ако ги смятаме в пакети.
Проблемът при такива атаки е синхронизацията. Атаките идват от ботнети, и за да се създаде много голям еднократен пик, е необходима висока степен на синхронизация. И тази координация не винаги се получава: понякога на изхода се получава някакъв параболичен пик, който изглежда доста жалко.
Не с HTTP единствено
В допълнение към HTTP на ниво L7, ние обичаме да експлоатираме и други протоколи. Обикновено, при обикновен уеб-сайт, особено при обикновен хостинг, навън излизат имейл протоколи и MySQL. Имайте предвид, че имейл протоколите са по-малко податливи на натоварване в сравнение с базите данни, но те също могат да бъдат натоварвани достатъчно ефективно и в резултат да доведат до претоварен CPU на сървера.
Ние успешно успяхме с уязвимостта в SSH от 2016 година. Сега тази уязвимост почти навсякъде е поправена, но това не означава, че в SSH не може да се подава натоварване. Може. Просто се подават огромни натоварвания на авторизации, SSH изяжда почти целия CPU на сървера и след това уеб-сайтът пада при едно-две заявки в секунда. Съответно, тези една-две заявки по логовете по никакъв начин не могат да се отличат от легитимно натоварване.
Остава актуални и множеството свързвания, които отваряме на сървърите. По-рано този проблем беше с Apache, а сега фактически се наблюдава и при nginx, тъй като той често се настройва по подразбиране. Броят на свързванията, които nginx може да поддържа отворени, е ограничен и съответно, когато достигнем това количество свързвания, новото свързване не може да бъде прието от nginx и в резултат сайтът не работи.
Нашият тестови клъстър разполага с достатъчно CPU, за да атакува SSL handshake. Всъщност, както показва практиката, ботнетите понякога също обичат да правят това. От една страна, ясно е, че без SSL не може да се мине, тъй като влияе на резултатите в Google, класирането и сигурността. От друга страна, за съжаление, SSL има проблеми с CPU.
L3&4
Когато говорим за атака на нива L3&4, обикновено говорим за атака на ниво канал. Товара почти винаги може да бъде различен от легитимен, освен ако не става въпрос за атака SYN-flood. Проблемът с атаките SYN-flood за защитните средства е в голямото количество. Максималната величина на L3&4 достигаше 1,5-2 Тбит/с. Такъв трафик е изключително труден за обработка дори от големи компании, включително Oracle и Google.
SYN и SYN-ACK са пакетите, които се използват при установяване на свързване. Поради това SYN-flood атаките трудно се различават от легитимния трафик: не е ясно дали става дума за SYN, който е дошъл за установяване на свързването, или част от флуда.
UDP-flood
Обикновено злонамеренците нямат ресурсите, с които разполагаме, затова за организиране на атаки може да се използва амплификация. Тоест злонамеренецът сканира интернет и намира уязвими или неправилно настроени сървъри, които, например, в отговор на един SYN пакет, отговарят с три SYN-ACK. Подменяйки адреса на източника с адреса на целевия сървър, може с един пакет да увеличим мощността, да кажем, три пъти и да пренасочим трафика към жертвата.

Проблемът с амплификациите е в трудно откритие. От последните примери можем да споменем известния случай с уязвимия memcached. Също така, в момента има много устройства IoT, IP-камери, които са основно настроени по подразбиране и по подразбиране те са неправилно настроени, затова именно чрез такива устройства злонамеренците най-често извършват атаки.

Неудобен SYN-flood
SYN-flood вероятно е най-интригуващият вид атака от гледна точка на разработчика. Проблемът е, че системните администратори често използват блокиране по IP за защита. И при блокирането по IP не страдат само администраторите, които действат по скриптове, но и, за съжаление, някои защитни системи, които се закупуват за големи пари.
Този метод може да се окаже катастрофален, тъй като ако злонамерени лица заменят IP адреси, компанията ще блокира собствената си подсет.
Освен това, блокирането на собствената мрежа не е трудно. Ако в офиса на клиента има Wi-Fi мрежа или ако работоспособността на ресурсите се измерва с помощта на различни инструменти за мониторинг, ние вземаме IP-адреса на тази система за мониторинг или на офисния Wi-Fi клиент и го използваме като източник. В резултат ресурсът изглежда достъпен, но целевите IP-адреси са блокирани. Така може да бъде блокирана Wi-Fi мрежата на конференцията HighLoad, където се представя новият продукт на компанията, — и това води до определени бизнес и икономически загуби.
По време на тестовете не можем да използваме амплификация чрез memcached с външни ресурси, тъй като има споразумения за подаване на трафик само към разрешени IP-адреси. Съответно използваме амплификация чрез SYN и SYN-ACK, когато за изпращане на един SYN системата отговаря с два-три SYN-ACK, и в резултат атаката се увеличава два до три пъти.
Инструменти
Един от основните инструменти, които използваме за натоварване на ниво L7, е Yandex-tank. В частност, като пушечен механизъм се използва Phantom, плюс има няколко скрипта за генериране на патрони и анализ на резултатите.
За анализа на мрежовия трафик се използва Tcpdump, а за анализа на сървъра — Nmap. За създаване на натоварване на ниво L3&4 използваме OpenSSL и малко собствена магия с библиотеката DPDK. DPDK е библиотека от Intel, която позволява работа с мрежовия интерфейс, заобикаляйки стека на Linux, и по този начин повишава ефективността. Разбира се, DPDK използваме не само на ниво L3&4, но и на ниво L7, тъй като тя позволява създаването на много високи натоварвания, в рамките на няколко милиона заявки в секунда от една машина.
Също така използваме определени генератори на трафик и специализирани инструменти, които разработваме за специфични тестове. Ако си припомним уязвимостта под SSH, то горепосоченият набор не може да бъде експлоатирован. Ако атакуваме пощенския протокол, взимаме пощенски утилити или просто пишем скриптове за тях.
Изводи
Като заключение би било добре да кажа:
- В допълнение към класическото натоварващо тестване, е необходимо задължително да се провежда и стрес-тестиране. Имаме реален пример, когато подизпълнител на партньор проведе само натоварващо тестване. То показа, че ресурсът издържа на нормално натоварване. Но след това се появи ненормално натоварване, посетителите на сайта започнаха да използват ресурса по различен начин и накрая подизпълнителят падна. Следователно, е необходимо да търсите уязвимости, дори ако вече сте защитени от DDoS атаки.
- Необходимо е да се изолират различни части на системата една от друга. Ако имате търсене, трябва да го преместите на отделни машини, тоест дори не в Docker. Защото, ако търсенето или авторизацията се провалят, поне нещо ще продължи да работи. В случая с интернет магазин, потребителите ще могат да намират стоки по каталога, да преминават от агрегатори, да купуват, ако вече са авторизирани, или да се авторизират през OAuth2.
- Не трябва да пренебрегвате всякакви облачни услуги.
- Използвайте CDN не само за оптимизация на мрежовите забавяния, но и като средство за защита от атаки за изчерпване на канала и просто флуда в статиката.
- Необходимо е да се използват специализирани услуги за защита. От L3&4 атаки на ниво канал не можете да се защитите сами, защото вероятно просто нямате достатъчно канал. От L7 атаки също няма да успеете да се отблъснете, тъй като те могат да бъдат много големи. Плюс това, търсенето на малки атаки е все пак привилегия на специализирани услуги и алгоритми.
- Редовно обновявайте. Това касае не само ядрото, но и SSH демона, особено ако те са отворени навън. Всъщност, трябва да обновявате всичко, защото сами вие вряд ли можете да проследите различни уязвимости.
Източник: habr.com
