Zaplať nebo na tebe pošleme DDoS, hrozí útočníci

5. 8. 2016
Doba čtení: 4 minuty

Sdílet

Ilustrační obrázek
Autor: Depositphotos – stori
Ilustrační obrázek
Do schránek provozovatelů českých služeb se začal šířit vyděračský mail, který vyhrožuje „DDDoS“ útokem. Odborníci na bezpečnost varují před tímto nátlakem a doporučují neplatit.

V několika posledních dnech se do e-mailových schránek různých společností začaly šířit zprávy vyhrožující „DDDoS“ útokem. Autoři této výhružné zprávy požadují od uživatelů zaplacení 0,17 bitcoinu (asi 2400 Kč podle aktuálního kurzu) za to, že na danou síť nezaútočí.

Text vyděračského mailu

Tyto hrozby jsou zasílány převážně na společnosti, které mají minimálně vlastní webové stránky. E-maily jsou zasílány ve vlnách a zatím nevíme o konkrétním schématu pro výběr příjemců zpráv, řekla nám Zuzana Duračinská, bezpečnostní analytička sdružení CZ.NIC, které provozuje Národní bezpečnostní tým CSIRT.CZ. Využívány jsou pravděpodobně sesbírané e-mailové adresy, protože hrozby míří na konkrétní uživatelské adresy a ne na náhodně generované.

Známá značka Anonymous je v tomto případě pravděpodobně jen zneužívána, protože tato skupina se zaměřuje na hacktivismus a ne na vyděračské internetové aktivity. Názvy těchto skupin slouží často jako ‚brand‘ a vzhledem k jejich neorganizované oficiální struktuře není možné zjistit, zda se za hrozbou skutečně nacházejí oni nebo jde o zneužití jejich jména, vysvětluje Duračinská.

Neplaťte

Bezpečnostní experti doporučují na podobné výzvy neodpovídat a rozhodně útočníkům neplatit, byť jde o poměrně nízké částky. Vzhledem k tomu, že všem je zasílán stejný text se stejnou adresou bitcoinové peněženky, párování plateb s odesílateli je v mnoha případech nemožné. I když tedy uživatel zaplatí, nikdy nemá jistotu, že bude jeho platba skutečně spárovaná a vyhne se potenciálnímu útoku. Platby se neodporučují i z důvodů finanční podpory další činnosti útočníků, říká Duračinská.

Podle odborníků z Národního bezpečnostního týmu CSIRT.CZ je lepší se na případný útok připravit technicky. O každé vlně těchto hrozeb, o kterých se dozvíme, informujeme i prostřednictvím svých stránek. Snažíme se zároveň zjistit, nakolik jsou hrozby reálné a zda má útočník skutečně dostatek zdrojů pro vykonání útoku. V případě hrozby útokem je vhodné včas informovat poskytovatele hostingu a případně dočasně nejkritičtější služby přesunout na jiné IP adresy. V současnosti má většina hostingů přístup ke službám scrubbingových center, které případný provoz od útoku odfiltrují. Útočníci tak dnes potřebují shromáždit výrazně větší sílu než v minulosti.

Není to poprvé

Podobných výhrůžek v posledních měsících přibývá, nejsou ale ničím novým. Přibližně před rokem probíhala podobná kampaň pod hlavičkou skupiny Armada Collective. Podle Martina Žídka, technického ředitele datacentra Master Internet, byla tehdy hrozba reálná. Setkali jsme se s výhrůžkami a požadavky zaplacení pomocí bitcoinů, vysvětluje Žídek. Zákazník nezaplatil a útok skutečně přišel, ale nebyl zdaleka tak dramatický, jak se předpokládalo. Byl dost amatérsky udělaný a bylo možné jej snadno odfiltrovat pomocí statických filtrů.

Podle Žídka je těžké dát obecnou radu, jak se zachovat v případě vydírání. Já jsem pro nezaplacení a tady jsme to riskovali a vyšlo to. Ale je to tím, že v rámci této konkrétní kampaně nebylo riziko nijak vysoké, což jsme však předem nemohli vědět. Zmiňuje také, že požadovaná částka v bitcoinech nebyla zrovna malá – začínala na 20 BTC, tedy asi 200 000 Kč. Detailní rozbor této vyděračské kampaně naleznete ve zprávě Radware.

bitcoin_smenarna

Text mailu tehdy vypadal takto:

From: Armada Collective [mailto:[email protected]]
Sent: Friday, October 09, 2015 5:11 PM
To: xxxx
Subject: RANSOM REQUEST: DDoS ATTACK

FORWARD THIS MAIL TO WHOEVER IS IMPORTANT IN YOUR COMPANY AND CAN MAKE
DECISION!

We are Armada Collective.

All your servers will be DDoS-ed starting Monday if you don't pay 20
Bitcoins @ 18jUnzQKhTUiPVepLk7NRBD5gC2so1RXPc

When we say all, we mean all - users will not be able to access sites
host with you at all.

Right now we will start 15 minutes attack on your site's IP. It will not
be hard, we will not crash it at the moment to try to minimize eventual
damage, which we want to avoid at this moment. It's just to prove that
this is not a hoax. Check your logs!

If you don't pay by Monday, attack will start, price to stop will
increase to 40 BTC and will go up 20 BTC for every day of attack.

If you report this to media and try to get some free publicity by using
our name, instead of paying, attack will start permanently and will last
for a long time.

This is not a joke.

Our attacks are extremely powerful - sometimes over 1 Tbps per second.
So, no cheap protection will help.

Prevent it all with just 20 BTC @ 18jUnzQKhTUiPVepLk7NRBD5gC2so1RXPc

DO not reply, we will probably not read. Pay and we will know its you.
AND YOU WILL NEVER AGAIN HEAR FROM US!

BItcoin is anonymous, nobody will ever know you cooperated.

Aktivitu této skupiny potvrzuje i Zuzana Duračinská. Armada Collective je doposud asi nejaktivnější seskupení, které využívalo hrozbu DDoS útoku. Mělo reálnou sílu a dokázalo pomocí botnetů vygenerovat poměrně silný útok. V lednu 2016 proběhlo zatčení členů této skupiny. Jejich „značka“ se ale objevuje nadále. Hrozby od Armada Collective se objevily znovu, ale pokud víme, nepodařilo se jim vygenerovat dostatečnou sílu útoku.

Autor článku

Petr Krčmář pracuje jako šéfredaktor serveru Root.cz. Studoval počítače a média, takže je rozpolcen mezi dva obory. Snaží se dělat obojí, jak nejlépe umí.

'; document.getElementById('outstream-iframe').onload = function () { setupIframe(); } replayScreen = document.getElementById('iinfoOutstreamReplay'); iinfoOutstreamPosition = document.getElementById('iinfoOutstreamPosition'); outstreamContainer = document.getElementsByClassName('outstream-container')[0]; setupReplayScreen(); } function setupIframe() { outstreamDocument = document.getElementById('outstream-iframe').contentWindow.document; let el = outstreamDocument.createElement('style'); outstreamDocument.head.appendChild(el); el.innerText = "#adContainer>div:nth-of-type(1),#adContainer>div:nth-of-type(1) > iframe { width: 99% !important;height: 99% !important;max-width: 100%;}#videoContent,body{ width:100vw;height:100vh}body{ font-family:'Helvetica Neue',Arial,sans-serif}#videoContent{ overflow:hidden;background:#000}#adMuteBtn{ width:35px;height:35px;border:0;background:0 0;display:none;position:absolute;fill:rgba(230,230,230,1);bottom:-5px;right:25px}"; videoContent = outstreamDocument.getElementById('contentElement'); videoContent.style.display = 'none'; videoContent.volume = 1; videoContent.muted = false; if ( location.href.indexOf('rejstriky.finance.cz') !== -1 || location.href.indexOf('finance-rejstrik') !== -1 || location.href.indexOf('firmy.euro.cz') !== -1 || location.href.indexOf('euro-rejstrik') !== -1 || location.href.indexOf('/rejstrik/') !== -1 || location.href.indexOf('/rejstrik-firem/') !== -1) { outstreamDirectPlayed = true; soundAllowed = true; iinfoVastUrlIndex = 0; } if (!outstreamDirectPlayed) { console.log('OUTSTREAM direct'); setUpIMA(true); } else { if (soundAllowed) { const playPromise = videoContent.play(); if (playPromise !== undefined) { playPromise.then(function () { console.log('OUTSTREAM sound allowed'); setUpIMA(false); }).catch(function () { console.log('OUTSTREAM sound forbidden'); renderBanner(); }); } } else { renderBanner(); } } } function getWrapper() { let articleWrapper = document.querySelector('.rs-outstream-placeholder'); // Outstream Placeholder from RedSys manipulation if (articleWrapper && articleWrapper.style.display !== 'block') { articleWrapper.innerHTML = ""; articleWrapper.style.display = 'block'; } // Don't render OutStream on homepages if (articleWrapper === null) { if (document.querySelector('body.p-index')) { return null; } } if (articleWrapper === null) { articleWrapper = document.getElementById('iinfo-outstream'); } if (articleWrapper === null) { articleWrapper = document.querySelector('.layout-main__content .detail__article p:nth-of-type(6)'); } if (articleWrapper === null) { // Euro, Autobible, Zdravi articleWrapper = document.querySelector('.o-article .o-article__text p:nth-of-type(6)'); } if (articleWrapper === null) { articleWrapper = document.getElementById('sidebar'); } if (!articleWrapper) { console.error("Outstream wrapper of article was not found."); } return articleWrapper; } function setupDimensions() { outstreamWidth = Math.min(iinfoOutstreamPosition.offsetWidth, 480); outstreamHeight = Math.min(iinfoOutstreamPosition.offsetHeight, 320); } /** * Sets up IMA ad display container, ads loader, and makes an ad request. */ function setUpIMA(direct) { google.ima.settings.setDisableCustomPlaybackForIOS10Plus(true); google.ima.settings.setLocale('cs'); google.ima.settings.setNumRedirects(10); // Create the ad display container. createAdDisplayContainer(); // Create ads loader. adsLoader = new google.ima.AdsLoader(adDisplayContainer); // Listen and respond to ads loaded and error events. adsLoader.addEventListener( google.ima.AdsManagerLoadedEvent.Type.ADS_MANAGER_LOADED, onAdsManagerLoaded, false); adsLoader.addEventListener( google.ima.AdErrorEvent.Type.AD_ERROR, onAdError, false); // An event listener to tell the SDK that our content video // is completed so the SDK can play any post-roll ads. const contentEndedListener = function () { adsLoader.contentComplete(); }; videoContent.onended = contentEndedListener; // Request video ads. const adsRequest = new google.ima.AdsRequest(); if (direct) { adsRequest.adTagUrl = directVast; console.log('Outstream DIRECT CAMPAING advert: ' + directVast); videoContent.muted = true; videoContent.volume = 0; outstreamDirectPlayed = true; } else { adsRequest.adTagUrl = iinfoVastUrls[iinfoVastUrlIndex]; console.log('Outstream advert: ' + iinfoVastUrls[iinfoVastUrlIndex]); videoContent.muted = false; videoContent.volume = 1; } // Specify the linear and nonlinear slot sizes. This helps the SDK to // select the correct creative if multiple are returned. // adsRequest.linearAdSlotWidth = outstreamWidth; // adsRequest.linearAdSlotHeight = outstreamHeight; adsRequest.nonLinearAdSlotWidth = 0; adsRequest.nonLinearAdSlotHeight = 0; adsLoader.requestAds(adsRequest); } function setupReplayScreen() { replayScreen.addEventListener('click', function () { iinfoOutstreamPosition.remove(); iinfoVastUrlIndex = 0; outstreamInit(); }); } /** * Sets the 'adContainer' div as the IMA ad display container. */ function createAdDisplayContainer() { // We assume the adContainer is the DOM id of the element that will house // the ads. outstreamDocument.getElementById('videoContent').style.display = 'none'; adDisplayContainer = new google.ima.AdDisplayContainer( outstreamDocument.getElementById('adContainer'), videoContent); } function unmuteAdvert() { adVolume = !adVolume; if (adVolume) { adsManager.setVolume(0.3); outstreamDocument.getElementById('adMuteBtn').innerHTML = ''; } else { adsManager.setVolume(0); outstreamDocument.getElementById('adMuteBtn').innerHTML = ''; } } /** * Loads the video content and initializes IMA ad playback. */ function playAds() { // Initialize the container. Must be done through a user action on mobile // devices. videoContent.load(); adDisplayContainer.initialize(); // setupDimensions(); try { // Initialize the ads manager. Ad rules playlist will start at this time. adsManager.init(1920, 1080, google.ima.ViewMode.NORMAL); // Call play to start showing the ad. Single video and overlay ads will // start at this time; the call will be ignored for ad rules. adsManager.start(); // window.addEventListener('resize', function (event) { // if (adsManager) { // setupDimensions(); // adsManager.resize(outstreamWidth, outstreamHeight, google.ima.ViewMode.NORMAL); // } // }); } catch (adError) { // An error may be thrown if there was a problem with the VAST response. // videoContent.play(); } } /** * Handles the ad manager loading and sets ad event listeners. * @param { !google.ima.AdsManagerLoadedEvent } adsManagerLoadedEvent */ function onAdsManagerLoaded(adsManagerLoadedEvent) { // Get the ads manager. const adsRenderingSettings = new google.ima.AdsRenderingSettings(); adsRenderingSettings.restoreCustomPlaybackStateOnAdBreakComplete = true; adsRenderingSettings.loadVideoTimeout = 12000; // videoContent should be set to the content video element. adsManager = adsManagerLoadedEvent.getAdsManager(videoContent, adsRenderingSettings); // Add listeners to the required events. adsManager.addEventListener(google.ima.AdErrorEvent.Type.AD_ERROR, onAdError); adsManager.addEventListener( google.ima.AdEvent.Type.CONTENT_PAUSE_REQUESTED, onContentPauseRequested); adsManager.addEventListener( google.ima.AdEvent.Type.CONTENT_RESUME_REQUESTED, onContentResumeRequested); adsManager.addEventListener( google.ima.AdEvent.Type.ALL_ADS_COMPLETED, onAdEvent); // Listen to any additional events, if necessary. adsManager.addEventListener(google.ima.AdEvent.Type.LOADED, onAdEvent); adsManager.addEventListener(google.ima.AdEvent.Type.STARTED, onAdEvent); adsManager.addEventListener(google.ima.AdEvent.Type.COMPLETE, onAdEvent); playAds(); } /** * Handles actions taken in response to ad events. * @param { !google.ima.AdEvent } adEvent */ function onAdEvent(adEvent) { // Retrieve the ad from the event. Some events (for example, // ALL_ADS_COMPLETED) don't have ad object associated. const ad = adEvent.getAd(); console.log('Outstream event: ' + adEvent.type); switch (adEvent.type) { case google.ima.AdEvent.Type.LOADED: // This is the first event sent for an ad - it is possible to // determine whether the ad is a video ad or an overlay. if (!ad.isLinear()) { // Position AdDisplayContainer correctly for overlay. // Use ad.width and ad.height. videoContent.play(); } outstreamDocument.getElementById('adContainer').style.width = '100%'; outstreamDocument.getElementById('adContainer').style.maxWidth = '640px'; outstreamDocument.getElementById('adContainer').style.height = '360px'; break; case google.ima.AdEvent.Type.STARTED: window.addEventListener('scroll', onActiveView); // This event indicates the ad has started - the video player // can adjust the UI, for example display a pause button and // remaining time. if (ad.isLinear()) { // For a linear ad, a timer can be started to poll for // the remaining time. intervalTimer = setInterval( function () { // Example: const remainingTime = adsManager.getRemainingTime(); // adsManager.pause(); }, 300); // every 300ms } outstreamDocument.getElementById('adMuteBtn').style.display = 'block'; break; case google.ima.AdEvent.Type.ALL_ADS_COMPLETED: if (ad.isLinear()) { clearInterval(intervalTimer); } if (outstreamLastError === 303) { if (isBanner) { renderBanner(); } else { replayScreen.style.display = 'flex'; } } break; case google.ima.AdEvent.Type.COMPLETE: // This event indicates the ad has finished - the video player // can perform appropriate UI actions, such as removing the timer for // remaining time detection. if (ad.isLinear()) { clearInterval(intervalTimer); } if (isBanner) { renderBanner(); } else { replayScreen.style.display = 'flex'; } break; } } /** * Handles ad errors. * @param { !google.ima.AdErrorEvent } adErrorEvent */ function onAdError(adErrorEvent) { // Handle the error logging. console.log(adErrorEvent.getError()); outstreamLastError = adErrorEvent.getError().getErrorCode(); if (!loadNext()) { renderBanner(); } } function renderBanner() { if (isBanner) { console.log('Outstream: Render Banner'); iinfoOutstreamPosition.innerHTML = ""; iinfoOutstreamPosition.style.height = "330px"; iinfoOutstreamPosition.appendChild(bannerDiv); } else { console.log('Outstream: Banner is not set'); } } function loadNext() { iinfoVastUrlIndex++; if (iinfoVastUrlIndex < iinfoVastUrls.length) { iinfoOutstreamPosition.remove(); outstreamInit(); } else { return false; } adVolume = 1; return true; } /** * Pauses video content and sets up ad UI. */ function onContentPauseRequested() { videoContent.pause(); // This function is where you should setup UI for showing ads (for example, // display ad timer countdown, disable seeking and more.) // setupUIForAds(); } /** * Resumes video content and removes ad UI. */ function onContentResumeRequested() { videoContent.play(); // This function is where you should ensure that your UI is ready // to play content. It is the responsibility of the Publisher to // implement this function when necessary. // setupUIForContent(); } function onActiveView() { if (outstreamContainer) { const containerOffset = outstreamContainer.getBoundingClientRect(); const windowHeight = window.innerHeight; if (containerOffset.top < windowHeight/1 && containerOffset.bottom > 0.0) { if (outstreamPaused) { adsManager.resume(); outstreamPaused = false; } return true; } else { if (!outstreamPaused) { adsManager.pause(); outstreamPaused = true; } } } return false; } let outstreamInitInterval; if (typeof cpexPackage !== "undefined") { outstreamInitInterval = setInterval(tryToInitializeOutstream, 100); } else { const wrapper = getWrapper(); if (wrapper) { let outstreamInitialized = false; window.addEventListener('scroll', () => { if (!outstreamInitialized) { const containerOffset = wrapper.getBoundingClientRect(); const windowHeight = window.innerHeight; if (containerOffset.top < windowHeight / 1 && containerOffset.bottom > 0.0) { outstreamInit(); outstreamInitialized = true; } } }); } } function tryToInitializeOutstream() { const wrapper = getWrapper(); if (wrapper) { const containerOffset = wrapper.getBoundingClientRect(); const windowHeight = window.innerHeight; if (containerOffset.top < windowHeight / 1 && containerOffset.bottom > 0.0) { if (cpexPackage.adserver.displayed) { clearInterval(outstreamInitInterval); outstreamInit(); } } } else { clearInterval(outstreamInitInterval); } } }
OSZAR »