Multiplatformní botnety internetu věcí představují nové nebezpečí

4. 10. 2020

Sdílet

Autor: @ Depositphotos, stevanovicigor
Windows a Android jsou tradiční semeniště různé havěti, ale macOS a linuxové systémy se stále častěji rovněž stávají cílem hackerů.

Botnety internetu věcí se od dob Mirai posunuly. Poškození, které tento v podstatě primitivní botnet napáchal pomocí snad ještě jednodušších útoků – DDoS neboli Distributed Denial of Service – už tehdy byla majestátní.

Současný malware, který infikuje špatně zabezpečené a jinak zranitelné routery, IP kamery a řady dalších zařízení nyní, je sofistikovanější – a méně vybíravý. Na Linuxu zaměřené operační systémy už nejsou ani zdaleka v bezpečí.

Hybridní botnety jsou napsány specificky tak, aby ohrozily vícero platforem najednou. Jsou schopné zacílit linuxová zařízení, smartphony s Androidem, počítače s Windows, a dokonce i s macOS. Příkladem takové hrozby je InterPlanety Storm – IPStorm – botnet, který je tu už od začátku roku 2019 a momentálně jej tvoří kolem 13 500 tisíce infikovaných zařízení z 84 zemí.

Proč je IPStorm jiný?

Botnet se odlišuje především tím, že je postaven na protokolu IPFS. Ten slouží pro sdílení data v distribuovaném souborovém systému. Infikovaná zařízení se tak stanou součástí peer-to-peer sítě, která vzájemně interaguje na přímo. Botnet je tak, bohužel, odolnější vůči pokusům ho zneškodnit.

Dříve by něco podobného nebyl takový problém, protože jakákoliv P2P aktivita v podnikové síti byla vnímána jakožto podezřelá. Jak ale podotýkají odborníci z Anomali ve své analýze, „v současné době využívá P2P technologie stále více a více legitimních služeb. Microsoft Windows 10 má kupříkladu funkci zvanou Delivery Optimization, která umožňuje aktualizace systému v zařízeních v P2P síti.“ Botnet se právě legitimní aktivitou maskuje, úplně stejným způsobem, jakým hackeři využívají webové služby ke skrývání běžného malwaru. Botnet je postupem jeho šíření nemožné odebrat bez toho, aby byly zároveň odebrány legitimní, neškodné části P2P sítě.

IPFS je v základu open source projekt, který umožňuje mnohé, včetně nahrávání dat a webových stránek přístupných skrze prohlížeč. Nativní podporu nabízí Opera pro Android, webovou bránu IPFS využívá kupříkladu Cloudflare.

IPStorm samotný je napsán v Golangu, multiplatformním programovacím jazyce, který dokáže běžet na různých operačních systémech a architekturách procesoru. První verze IPStorm z roku 2019 cílila jen na Windows pomocí příkazů v PowerShellu, od letošního června ale firma Bitdefender upozornila na verze určené pro Linux na architekturám ARM a Darwinu, na kterém staví macOS. Nejnovější verze malwaru cílí také na zařízení s Androidem.

Jak se IPStorm šíří a jak se bránit?

Šíří se vcelku jednoduše pomocí SSH brute-force útoků. Většina botnetů získává nová zombie zařízení právě tímto způsobem, neboť hodně IoT zařízení stále trpí na slabé zabezpečení. To je obecně lepší u novějších přístrojů, ale starší zařízení bývají velmi špatně zabezpečení vlivem nedostatečné standardizace.

Na Androidu zneužívá botnet službu ADB, Android Debug Bridge. IPStorm míří primárně na Asii, 60 % nakažených zařízení je z Hong Kongu, Jižní Korey a Tchaj-wanu. Dalších 8 % tvoří Rusko, 6 % Brazílie, 5 % Kanada a Spojené Státy, 3 % Čína a první evropská země je až Švédsko, které tvoří další 3 % nakažených zařízení. Celkem je v současnosti infikovaných více než 13 500 zařízení v 84 zemích.

linux_sprava_tip

Jak se chránit? Zajistit, že k internetu připojené služby mají dostatečné zabezpečí od výrobce i ze strany vaší firmy. Projekt využívané porty ve firemní síti může pomoci odhalit zařízení internetu věcí s otevřeným rozhraním, které lze zablokovat nebo izolovat.

Speciální pozornost je dobré věnovat routerům, protože ty slouží jako vstupní brána do celé sítě. Aktualizace firmwaru, změna standardních přístupových údajů a podobně mohou významně pomoci firmu zabezpečit.

'; document.getElementById('preroll-iframe').onload = function () { setupIframe(); } prerollContainer = document.getElementsByClassName('preroll-container-iframe')[0]; } function setupIframe() { prerollDocument = document.getElementById('preroll-iframe').contentWindow.document; let el = prerollDocument.createElement('style'); prerollDocument.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:20px;right:25px}"; videoContent = prerollDocument.getElementById('contentElement'); videoContent.style.display = 'none'; videoContent.volume = 1; videoContent.muted = false; const playPromise = videoContent.play(); if (playPromise !== undefined) { playPromise.then(function () { console.log('PREROLL sound allowed'); // setUpIMA(true); videoContent.volume = 1; videoContent.muted = false; setUpIMA(); }).catch(function () { console.log('PREROLL sound forbidden'); videoContent.volume = 0; videoContent.muted = true; setUpIMA(); }); } } function setupDimensions() { prerollWidth = Math.min(iinfoPrerollPosition.offsetWidth, 480); prerollHeight = Math.min(iinfoPrerollPosition.offsetHeight, 320); } function setUpIMA() { 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(); adsRequest.adTagUrl = iinfoVastUrls[iinfoVastUrlIndex]; console.log('Preroll 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 = prerollWidth; // adsRequest.linearAdSlotHeight = prerollHeight; adsRequest.nonLinearAdSlotWidth = 0; adsRequest.nonLinearAdSlotHeight = 0; adsLoader.requestAds(adsRequest); } function createAdDisplayContainer() { // We assume the adContainer is the DOM id of the element that will house // the ads. prerollDocument.getElementById('videoContent').style.display = 'none'; adDisplayContainer = new google.ima.AdDisplayContainer( prerollDocument.getElementById('adContainer'), videoContent); } function unmutePrerollAdvert() { adVolume = !adVolume; if (adVolume) { adsManager.setVolume(0.3); prerollDocument.getElementById('adMuteBtn').innerHTML = ''; } else { adsManager.setVolume(0); prerollDocument.getElementById('adMuteBtn').innerHTML = ''; } } 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(); } 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(prerollWidth, prerollHeight, google.ima.ViewMode.NORMAL); // } // }); } catch (adError) { // An error may be thrown if there was a problem with the VAST response. // videoContent.play(); } } function onAdEvent(adEvent) { const ad = adEvent.getAd(); console.log('Preroll event: ' + adEvent.type); switch (adEvent.type) { case google.ima.AdEvent.Type.LOADED: if (!ad.isLinear()) { videoContent.play(); } prerollDocument.getElementById('adContainer').style.width = '100%'; prerollDocument.getElementById('adContainer').style.maxWidth = '640px'; prerollDocument.getElementById('adContainer').style.height = '360px'; break; case google.ima.AdEvent.Type.STARTED: window.addEventListener('scroll', onActiveView); if (ad.isLinear()) { intervalTimer = setInterval( function () { // Example: const remainingTime = adsManager.getRemainingTime(); // adsManager.pause(); }, 300); // every 300ms } prerollDocument.getElementById('adMuteBtn').style.display = 'block'; break; case google.ima.AdEvent.Type.ALL_ADS_COMPLETED: if (ad.isLinear()) { clearInterval(intervalTimer); } if (prerollLastError === 303) { playYtVideo(); } break; case google.ima.AdEvent.Type.COMPLETE: if (ad.isLinear()) { clearInterval(intervalTimer); } playYtVideo(); break; } } function onAdError(adErrorEvent) { console.log(adErrorEvent.getError()); prerollLastError = adErrorEvent.getError().getErrorCode(); if (!loadNext()) { playYtVideo(); } } function loadNext() { iinfoVastUrlIndex++; if (iinfoVastUrlIndex < iinfoVastUrls.length) { iinfoPrerollPosition.remove(); playPrerollAd(); } else { return false; } adVolume = 1; return true; } function onContentPauseRequested() { videoContent.pause(); } function onContentResumeRequested() { videoContent.play(); } function onActiveView() { if (prerollContainer) { const containerOffset = prerollContainer.getBoundingClientRect(); const windowHeight = window.innerHeight; if (containerOffset.top < windowHeight/1 && containerOffset.bottom > 0.0) { if (prerollPaused) { adsManager.resume(); prerollPaused = false; } return true; } else { if (!prerollPaused) { adsManager.pause(); prerollPaused = true; } } } return false; } function playYtVideo() { iinfoPrerollPosition.remove(); youtubeIframe.style.display = 'block'; youtubeIframe.src += '&autoplay=1&mute=1'; } }
OSZAR »