DDoS till räddningen: hur vi genomför stress- och belastningstester

DDoS till räddningen: hur vi genomför stress- och belastningstester

Variti utvecklar skydd mot bots och DDoS-attacker, och genomför även stress- och belastningstester. På konferensen HighLoad++ 2018 pratade vi om hur man säkrar resurser från olika typer av attacker. Kort sagt: isolera delar av systemet, använd molntjänster och CDN:er och uppdatera regelbundet. Men du kommer fortfarande inte att kunna hantera skydd utan specialiserade företag :)

Innan du läser texten kan du läsa de korta sammanfattningarna på konferensens hemsida.
Och om du inte gillar att läsa eller bara vill titta på videon, finns inspelningen av vår rapport nedan under spoilern.

Videoinspelning av rapporten

Många företag vet redan hur man gör lasttester, men inte alla gör stresstester. Vissa av våra kunder tror att deras sida är osårbar eftersom de har ett högbelastningssystem, och det skyddar väl mot attacker. Vi visar att detta inte är helt sant.
Innan vi genomför tester får vi givetvis tillstånd från kunden, signerat och stämplat, och med vår hjälp kan en DDoS-attack inte utföras på någon. Testning utförs vid en tidpunkt som kunden väljer, när trafiken till hans resurs är minimal och åtkomstproblem inte kommer att påverka kunderna. Dessutom, eftersom något alltid kan gå fel under testprocessen, har vi ständig kontakt med kunden. Detta gör att du inte bara kan rapportera uppnådda resultat, utan också att ändra något under testningen. Efter avslutad test upprättar vi alltid en rapport där vi påpekar de upptäckta bristerna och ger rekommendationer för att eliminera webbplatsens svagheter.

Hur vi arbetar

När vi testar emulerar vi ett botnät. Eftersom vi arbetar med klienter som inte finns i våra nätverk, för att säkerställa att testet inte slutar under den första minuten på grund av att gränser eller skydd utlöses, levererar vi belastningen inte från en IP, utan från vårt eget subnät. Dessutom, för att skapa en betydande belastning, har vi vår egen ganska kraftfulla testserver.

Postulat

För mycket betyder inte bra
Ju mindre belastning vi kan få en resurs till att misslyckas med, desto bättre. Om du kan få sajten att sluta fungera på en begäran per sekund, eller till och med en begäran per minut, är det bra. För enligt elakhetens lag kommer användare eller angripare av misstag att hamna i denna speciella sårbarhet.

Partiellt misslyckande är bättre än fullständigt misslyckande
Vi rekommenderar alltid att göra systemen heterogena. Dessutom är det värt att separera dem på den fysiska nivån, och inte bara genom containerisering. Vid fysisk separation, även om något misslyckas på sajten, är det stor sannolikhet att det inte slutar fungera helt, och användare kommer att fortsätta ha tillgång till åtminstone en del av funktionaliteten.

Bra arkitektur är grunden för hållbarhet
Feltoleransen för en resurs och dess förmåga att motstå attacker och belastningar bör fastställas på designstadiet, i själva verket i det skede då de första flödesschemana ritas i ett anteckningsblock. För om fatala fel smyger sig på går det att rätta till dem i framtiden, men det är väldigt svårt.

Inte bara koden ska vara bra, utan även konfigurationen
Många tycker att ett bra utvecklingsteam är en garanti för feltålig service. Ett bra utvecklingsteam är verkligen nödvändigt, men det måste också finnas bra verksamhet, bra DevOps. Det vill säga, vi behöver specialister som korrekt konfigurerar Linux och nätverket, skriver konfigurationer korrekt i nginx, sätter gränser, etc. Annars kommer resursen att fungera bra bara i testning, och någon gång kommer allt att gå sönder i produktionen.

Skillnader mellan belastnings- och stresstester
Belastningstestning låter dig identifiera gränserna för systemets funktion. Stresstester syftar till att hitta svagheter i ett system och används för att bryta detta system och se hur det kommer att bete sig när vissa delar misslyckas. I det här fallet förblir belastningens karaktär vanligtvis okänd för kunden innan stresstester påbörjas.

Utmärkande drag för L7-attacker

Vi brukar dela in typer av last i laster på nivåerna L7 och L3&4. L7 är en belastning på applikationsnivå, oftast betyder det bara HTTP, men vi menar vilken belastning som helst på TCP-protokollnivå.
L7-attacker har vissa särdrag. För det första kommer de direkt till applikationen, det vill säga det är osannolikt att de kommer att reflekteras via nätverksmedel. Sådana attacker använder logik, och på grund av detta förbrukar de CPU, minne, disk, databas och andra resurser mycket effektivt och med lite trafik.

HTTP Flood

I fallet med någon attack är belastningen lättare att skapa än att hantera, och i fallet med L7 är detta också sant. Det är inte alltid lätt att skilja attacktrafik från legitim trafik, och oftast kan detta göras efter frekvens, men om allt är korrekt planerat är det omöjligt att utifrån loggarna förstå var attacken finns och var de legitima förfrågningarna finns.
Som ett första exempel, överväg en HTTP Flood-attack. Grafen visar att sådana attacker vanligtvis är mycket kraftfulla; i exemplet nedan översteg det högsta antalet förfrågningar 600 tusen per minut.

DDoS till räddningen: hur vi genomför stress- och belastningstester

HTTP Flood är det enklaste sättet att skapa belastning. Vanligtvis krävs det något slags lasttestverktyg, som ApacheBench, och ställer in en begäran och ett mål. Med ett så enkelt tillvägagångssätt är det stor sannolikhet att köra in i servercaching, men det är lätt att kringgå det. Till exempel att lägga till slumpmässiga strängar till begäran, vilket kommer att tvinga servern att ständigt visa en ny sida.
Glöm inte heller användaragenten i processen att skapa en belastning. Många användaragenter för populära testverktyg filtreras av systemadministratörer, och i det här fallet kanske belastningen helt enkelt inte når backend. Du kan förbättra resultatet avsevärt genom att infoga en mer eller mindre giltig rubrik från webbläsaren i begäran.
Hur enkla HTTP Flood-attacker än är, de har också sina nackdelar. För det första krävs stora mängder kraft för att skapa belastningen. För det andra är sådana attacker mycket lätta att upptäcka, särskilt om de kommer från en adress. Som ett resultat börjar förfrågningar omedelbart att filtreras antingen av systemadministratörer eller till och med på leverantörsnivå.

Vad ska man söka

För att minska antalet förfrågningar per sekund utan att förlora effektivitet måste du visa lite fantasi och utforska webbplatsen. Således kan du ladda inte bara kanalen eller servern, utan även enskilda delar av applikationen, till exempel databaser eller filsystem. Du kan också leta efter platser på sajten som gör stora beräkningar: miniräknare, produktvalssidor osv. Slutligen händer det ofta att sajten har något slags PHP-skript som genererar en sida på flera hundra tusen rader. Ett sådant skript belastar också servern avsevärt och kan bli ett mål för en attack.

Var man ska leta efter

När vi skannar en resurs innan vi testar, tittar vi förstås först på själva webbplatsen. Vi letar efter alla typer av inmatningsfält, tunga filer – i allmänhet allt som kan skapa problem för resursen och bromsa dess drift. Banala utvecklingsverktyg i Google Chrome och Firefox hjälper här, som visar sidans svarstider.
Vi skannar även underdomäner. Det finns till exempel en viss webbutik, abc.com, och den har en underdomän admin.abc.com. Troligtvis är detta en adminpanel med behörighet, men om du belastar den kan det skapa problem för huvudresursen.
Webbplatsen kan ha en underdomän api.abc.com. Troligtvis är detta en resurs för mobilapplikationer. Applikationen kan hittas i App Store eller Google Play, installera en speciell åtkomstpunkt, dissekera API:et och registrera testkonton. Problemet är att folk ofta tror att allt som är skyddat av auktorisation är immunt mot överbelastningsattacker. Förmodligen är auktorisering den bästa CAPTCHA, men det är den inte. Det är enkelt att skapa 10-20 testkonton, men genom att skapa dem får vi tillgång till komplexa och dolda funktioner.
Naturligtvis tittar vi på historik, på robots.txt och WebArchive, ViewDNS, och letar efter gamla versioner av resursen. Ibland händer det att utvecklare har rullat ut, säg, mail2.yandex.net, men den gamla versionen, mail.yandex.net, finns kvar. Denna mail.yandex.net stöds inte längre, utvecklingsresurser tilldelas den inte, men den fortsätter att konsumera databasen. Följaktligen, med den gamla versionen, kan du effektivt använda resurserna i backend och allt som ligger bakom layouten. Naturligtvis händer detta inte alltid, men vi stöter fortfarande på detta ganska ofta.
Naturligtvis analyserar vi alla begärandeparametrar och cookiestrukturen. Du kan, säg, dumpa ett visst värde i en JSON-array i en cookie, skapa mycket kapsling och få resursen att fungera orimligt länge.

Sökladdning

Det första man tänker på när man undersöker en sida är att ladda databasen, eftersom nästan alla har en sökning, och för nästan alla är den tyvärr dåligt skyddad. Av någon anledning är utvecklare inte tillräckligt uppmärksamma på sökning. Men det finns en rekommendation här - du bör inte göra förfrågningar av samma typ, eftersom du kan stöta på caching, som är fallet med HTTP flood.
Att göra slumpmässiga frågor till databasen är inte heller alltid effektivt. Det är mycket bättre att skapa en lista med sökord som är relevanta för sökningen. Om vi ​​återvänder till exemplet med en onlinebutik: låt oss säga att webbplatsen säljer bildäck och låter dig ställa in däckens radie, typ av bil och andra parametrar. Följaktligen kommer kombinationer av relevanta ord att tvinga databasen att fungera under mycket mer komplexa förhållanden.
Dessutom är det värt att använda paginering: det är mycket svårare för en sökning att returnera den näst sista sidan med sökresultaten än den första. Det vill säga, med hjälp av paginering kan du diversifiera belastningen något.
Exemplet nedan visar sökbelastningen. Det kan ses att från den allra första sekunden av testet med en hastighet av tio förfrågningar per sekund gick sajten ner och svarade inte.

DDoS till räddningen: hur vi genomför stress- och belastningstester

Om det inte finns någon sökning?

Om det inte finns någon sökning betyder det inte att sidan inte innehåller andra sårbara inmatningsfält. Detta fält kan vara auktorisering. Nuförtiden gillar utvecklare att göra komplexa hash för att skydda inloggningsdatabasen från en regnbågstabellattack. Det här är bra, men sådana hashar förbrukar mycket CPU-resurser. Ett stort flöde av falska auktoriseringar leder till ett processorfel, och som ett resultat slutar webbplatsen att fungera.
Närvaron på webbplatsen av alla typer av formulär för kommentarer och feedback är en anledning att skicka mycket stora texter dit eller helt enkelt skapa en massiv översvämning. Ibland accepterar webbplatser bifogade filer, inklusive i gzip-format. I det här fallet tar vi en 1TB-fil, komprimerar den till flera byte eller kilobyte med hjälp av gzip och skickar den till webbplatsen. Sedan packas den upp och en mycket intressant effekt erhålls.

Rest API

Jag skulle vilja ägna lite uppmärksamhet åt sådana populära tjänster som Rest API. Att säkra ett Rest API är mycket svårare än en vanlig webbplats. Även triviala metoder för skydd mot brute force med lösenord och annan olaglig aktivitet fungerar inte för Rest API.
Rest API är mycket lätt att bryta eftersom det kommer åt databasen direkt. Samtidigt medför ett misslyckande av en sådan tjänst ganska allvarliga konsekvenser för näringslivet. Faktum är att Rest API vanligtvis inte bara används för huvudwebbplatsen, utan också för mobilapplikationen och vissa interna affärsresurser. Och om allt detta faller, då är effekten mycket starkare än i fallet med ett enkelt webbplatsfel.

Laddar tungt innehåll

Om vi ​​erbjuds att testa någon vanlig ensidig applikation, målsida eller visitkortswebbplats som inte har komplex funktionalitet, letar vi efter tungt innehåll. Till exempel stora bilder som servern skickar, binära filer, pdf-dokumentation – allt detta försöker vi ladda ner. Sådana tester laddar filsystemet väl och täpper till kanaler och är därför effektiva. Det vill säga, även om du inte lägger ner servern, laddar ner en stor fil med låga hastigheter, kommer du helt enkelt att täppa till målserverns kanal och sedan uppstår ett överbelastningsskydd.
Ett exempel på ett sådant test visar att vid en hastighet av 30 RPS slutade sajten att svara eller producerade 500:e serverfel.

DDoS till räddningen: hur vi genomför stress- och belastningstester

Glöm inte att ställa in servrar. Du kan ofta upptäcka att en person har köpt en virtuell maskin, installerat Apache där, konfigurerat allt som standard, installerat en PHP-applikation och nedan kan du se resultatet.

DDoS till räddningen: hur vi genomför stress- och belastningstester

Här gick belastningen till roten och uppgick till endast 10 RPS. Vi väntade 5 minuter och servern kraschade. Det är sant att det inte är helt känt varför han ramlade, men det finns ett antagande om att han helt enkelt hade för mycket minne och därför slutade svara.

Vågbaserad

Under de senaste åren eller två har vågattacker blivit ganska populära. Detta beror på det faktum att många organisationer köper vissa delar av hårdvara för DDoS-skydd, vilket kräver en viss tid för att samla statistik för att börja filtrera attacken. Det vill säga att de inte filtrerar attacken under de första 30-40 sekunderna, eftersom de samlar på sig data och lär sig. Följaktligen kan du på dessa 30-40 sekunder starta så mycket på sajten att resursen kommer att ligga länge tills alla förfrågningar är klara.
I fallet med attacken nedan var det ett intervall på 10 minuter, varefter en ny, modifierad del av attacken kom.

DDoS till räddningen: hur vi genomför stress- och belastningstester

Det vill säga, försvaret lärde sig, började filtrera, men en ny, helt annan del av attacken kom och försvaret började lära sig igen. Faktum är att filtrering slutar fungera, skyddet blir ineffektivt och webbplatsen är otillgänglig.
Vågattacker kännetecknas av mycket höga värden på toppen, det kan nå hundra tusen eller en miljon förfrågningar per sekund, i fallet med L7. Om vi ​​pratar om L3&4, så kan det finnas hundratals gigabits trafik, eller, följaktligen, hundratals mpps, om du räknar i paket.
Problemet med sådana attacker är synkronisering. Attackerna kommer från ett botnät och kräver en hög grad av synkronisering för att skapa en mycket stor engångspik. Och den här koordinationen fungerar inte alltid: ibland är resultatet någon form av parabolisk topp, som ser ganska patetisk ut.

Inte bara HTTP

Förutom HTTP på L7 vill vi gärna utnyttja andra protokoll. Som regel har en vanlig webbplats, särskilt en vanlig värd, e-postprotokoll och MySQL som sticker ut. Mailprotokoll utsätts för mindre belastning än databaser, men de kan också laddas ganska effektivt och sluta med en överbelastad CPU på servern.
Vi var ganska framgångsrika med 2016 års SSH-sårbarhet. Nu har denna sårbarhet åtgärdats för nästan alla, men det betyder inte att laddning inte kan skickas till SSH. Burk. Det är helt enkelt en enorm belastning av auktoriseringar, SSH äter upp nästan hela CPU:n på servern, och sedan kollapsar webbplatsen från en eller två förfrågningar per sekund. Följaktligen kan dessa en eller två förfrågningar baserade på loggarna inte särskiljas från en legitim belastning.
Många anslutningar som vi öppnar i servrar förblir också relevanta. Tidigare var Apache skyldig till detta, nu är nginx faktiskt skyldig till detta, eftersom det ofta är konfigurerat som standard. Antalet anslutningar som nginx kan hålla öppna är begränsat, så vi öppnar detta antal anslutningar, nginx accepterar inte längre en ny anslutning, och som ett resultat av detta fungerar inte sidan.
Vårt testkluster har tillräckligt med CPU för att attackera SSL-handskakning. I princip, som praxis visar, gillar botnät ibland att göra detta också. Å ena sidan är det uppenbart att du inte kan klara dig utan SSL, eftersom Googles resultat, rankning, säkerhet. Å andra sidan har SSL tyvärr ett CPU-problem.

L3&4

När vi talar om en attack på L3&4-nivåerna talar vi vanligtvis om en attack på länknivå. En sådan belastning kan nästan alltid skiljas från en legitim, såvida det inte är en SYN-översvämningsattack. Problemet med SYN-flood-attacker för säkerhetsverktyg är deras stora volym. Det maximala L3&4-värdet var 1,5-2 Tbit/s. Denna typ av trafik är mycket svår att hantera även för stora företag, inklusive Oracle och Google.
SYN och SYN-ACK är paket som används när en anslutning upprättas. Därför är SYN-flod svår att skilja från en legitim belastning: det är inte klart om detta är en SYN som kom att upprätta en förbindelse, eller en del av en översvämning.

UDP-flod

Vanligtvis har angripare inte de möjligheter som vi har, så förstärkning kan användas för att organisera attacker. Det vill säga att angriparen skannar internet och hittar antingen sårbara eller felaktigt konfigurerade servrar som till exempel, som svar på ett SYN-paket, svarar med tre SYN-ACK. Genom att spoofa källadressen från adressen till målservern är det möjligt att öka kraften med, till exempel, tre gånger med ett enda paket och omdirigera trafik till offret.

DDoS till räddningen: hur vi genomför stress- och belastningstester

Problemet med förstärkningar är att de är svåra att upptäcka. Nya exempel inkluderar det sensationella fallet med den sårbara memcachade. Plus, nu finns det många IoT-enheter, IP-kameror, som också oftast är konfigurerade som standard, och som standard är de felaktigt konfigurerade, vilket är anledningen till att angripare oftast gör attacker genom sådana enheter.

DDoS till räddningen: hur vi genomför stress- och belastningstester

Svår SYN-flod

SYN-flood är förmodligen den mest intressanta typen av attack ur en utvecklares synvinkel. Problemet är att systemadministratörer ofta använder IP-blockering för skydd. Dessutom påverkar IP-blockering inte bara systemadministratörer som agerar med skript, utan också, tyvärr, vissa säkerhetssystem som köps för mycket pengar.
Denna metod kan förvandlas till en katastrof, för om angripare ersätter IP-adresser kommer företaget att blockera sitt eget subnät. När brandväggen blockerar sitt eget kluster kommer utdata att misslyckas med externa interaktioner och resursen kommer att misslyckas.
Dessutom är det inte svårt att blockera ditt eget nätverk. Om kundens kontor har ett Wi-Fi-nätverk, eller om resursernas prestanda mäts med hjälp av olika övervakningssystem, tar vi IP-adressen för detta övervakningssystem eller klientens kontors Wi-Fi och använder den som en källa. I slutet verkar resursen vara tillgänglig, men mål-IP-adresserna är blockerade. Därmed kan Wi-Fi-nätverket för HighLoad-konferensen, där företagets nya produkt presenteras, blockeras, vilket medför vissa affärsmässiga och ekonomiska kostnader.
Under testning kan vi inte använda förstärkning genom memcachad med några externa resurser, eftersom det finns avtal om att skicka trafik endast till tillåtna IP-adresser. Följaktligen använder vi förstärkning genom SYN och SYN-ACK, när systemet svarar på att skicka en SYN med två eller tre SYN-ACK, och vid utgången multipliceras attacken med två eller tre gånger.

Verktyg

Ett av de viktigaste verktygen vi använder för L7-arbetsbelastning är Yandex-tank. I synnerhet används en fantom som en pistol, plus att det finns flera skript för att generera patroner och för att analysera resultaten.
Tcpdump används för att analysera nätverkstrafik och Nmap används för att analysera servern. För att skapa belastningen på L3&4-nivån används OpenSSL och lite av vår egen magi med DPDK-biblioteket. DPDK är ett bibliotek från Intel som låter dig arbeta med nätverksgränssnittet förbi Linux-stacken och därigenom öka effektiviteten. Naturligtvis använder vi DPDK inte bara på L3&4-nivå, utan även på L7-nivå, eftersom det tillåter oss att skapa ett mycket högt belastningsflöde, inom intervallet flera miljoner förfrågningar per sekund från en maskin.
Vi använder även vissa trafikgeneratorer och specialverktyg som vi skriver för specifika tester. Om vi ​​minns sårbarheten under SSH, kan ovanstående uppsättning inte utnyttjas. Om vi ​​attackerar e-postprotokollet tar vi e-postverktyg eller skriver helt enkelt skript på dem.

Resultat

Som avslutning skulle jag vilja säga:

  • Förutom klassisk belastningstestning är det nödvändigt att genomföra stresstester. Vi har ett riktigt exempel där en partners underleverantör endast utförde lastprovning. Den visade att resursen tål normal belastning. Men så dök det upp en onormal belastning, besökarna på webbplatsen började använda resursen lite annorlunda och som ett resultat lade underleverantören ner. Således är det värt att leta efter sårbarheter även om du redan är skyddad från DDoS-attacker.
  • Det är nödvändigt att isolera vissa delar av systemet från andra. Om du har en sökning måste du flytta den till separata maskiner, det vill säga inte ens till Docker. För om sökning eller auktorisering misslyckas, kommer åtminstone något att fortsätta att fungera. När det gäller en onlinebutik kommer användare att fortsätta att hitta produkter i katalogen, gå från aggregatorn, köpa om de redan är auktoriserade eller auktorisera via OAuth2.
  • Försumma inte alla typer av molntjänster.
  • Använd CDN inte bara för att optimera nätverksfördröjningar, utan också som ett skydd mot attacker mot utmattning av kanaler och helt enkelt översvämning av statisk trafik.
  • Det är nödvändigt att använda specialiserade skyddstjänster. Du kan inte skydda dig från L3&4-attacker på kanalnivå, eftersom du med största sannolikhet helt enkelt inte har en tillräcklig kanal. Du kommer sannolikt inte heller att bekämpa L7-attacker, eftersom de kan vara mycket stora. Dessutom är sökandet efter små attacker fortfarande privilegiet för specialtjänster, speciella algoritmer.
  • Uppdatera regelbundet. Detta gäller inte bara kärnan, utan även SSH-demonen, speciellt om du har dem öppna utåt. I princip behöver allt uppdateras, eftersom du sannolikt inte kommer att kunna spåra vissa sårbarheter på egen hand.

Källa: will.com

Lägg en kommentar