Postřehy z bezpečnosti: Čína obviněna z útoku na české ministerstvo zahraničí

2. 6. 2025
Doba čtení: 7 minut

Sdílet

hacker s kapucí před třemi monitory
Autor: Depositphotos
Podíváme se na obvinění Číny z kybernetického útoku na Ministerstvo zahraničních věcí, uzákonění povinnosti hlásit výkupné placené ransomwarovým skupinám v Austrálii, nebo novinky na poli botnetů.

Vláda České republiky obvinila Čínu z kybernetického útoku

Velkou pozornost ze strany české i zahraniční bezpečnostní komunity v uplynulém týdnu získalo středeční prohlášení Vlády České republiky informující o škodlivé kybernetické kampani, která vyústila v kompromitaci jedné ze sítí Ministerstva zahraničních věcí ČR.

Za aktéra, který stál za touto kampaní, označila vláda na základě společného vyšetřování domácích zpravodajských služeb a NÚKIB skupinu APT31. Jmenovaná skupina je spojována s Ministerstvem státní bezpečnosti Čínské lidové republiky a publikované prohlášení tak explicitně přisoudilo odpovědnost za útok právě tomuto státu.

Útočnou kampaň, která probíhala nejméně od roku 2022 a při níž se škodlivým aktérům údajně podařilo získat ze sítě ministerstva e-maily a další dokumenty odsoudily vedle České republiky i NATO a EU.

Čína sama nařčení z útoku – nijak překvapivě – odmítla. Sama pak v uplynulém týdnu obvinila z kybernetických útoků na vlastní infrastrukturu skupinu s údajnými vazbami na Taiwan.

Austrálie uzákonila povinnost hlásit platby za ransomware státu

Austrálie se v pátek stala zřejmě první zemí na světě, v níž mají organizace, které se staly oběťmi ransomwaru, povinnost hlásit státu jakékoli platby výkupného kybernetickým útočníkům. Učinit tak musí ve lhůtě 72 hodin.

Uvedená povinnost se bude týkat pouze organizací s globálním obratem převyšujícím 3 miliony australských dolarů ročně (cca 42,5 milionu Kč) a organizací kritických pro fungování státu, a bude tak dopadat jen na asi 6,5 % všech australských společností. Očekává se však, že australské vládní a bezpečnostní orgány díky ní získají citelně lepší přehled o reálných počtech a dopadech ransomwarových útoků.

O uzákonění podobné povinnosti, navíc s možností explicitně ve vybraných případech zakázat platby výkupného, aktuálně uvažuje mj. Velká Británie.

Jeden hotový SSH botnet a připravovaný základ pro druhý

Společnost DarkTrace v uplynulém týdnu informovala o nedávno vytvořeném botnetu sdružujícím kompromitovaná IoT zařízení postavená nad Linuxem.

Botnet, který výzkumníci označují jako PumaBot, je tvořen malwarem napsaným v jazyce Go a cílí na embedded/IoT zařízení, přičemž již nakažené systémy kompromitují další zařízení s pomocí brute-force útoků na službu SSH. Zajímavostí při tom je, že na rozdíl od většiny obdobných botnetů nevyhledávají již nakažená zařízení cíle pro další kompromitaci samostatně, s pomocí skenování veřejných IP adresních rozsahů, ale seznam cílových adres, na které se mají zaměřit, získávají centrálně z C2 serveru.

Pokud se botnetu podaří kompromitovat nové zařízení, je takový systém do botnetu připojen s pomocí škodlivého kódu, který je spouštěn formou nové služby Systemd. Informace o aktuální velikosti botnetu výzkumníci nezveřejnili.

Přibližně ve stejné době informovala společnost GreyNoise o aktuálně probíhající útočné kampani zaměřené na routery ASUS, kterou označila jako AyySSHush.

V rámci ní se škodliví aktéři pokoušejí kompromitovat cílová zařízení s pomocí brute-force útoků i využívání specifických authentication-bypass zranitelností. Pokud se jim podaří k zařízení přihlásit, zpřístupní útočníci službu SSH na portu TCP/53282 a nainstalují do zařízení svůj veřejný klíč, díky čemuž získají možnost se s pomocí SSH k systému v budoucnu kdykoli přihlásit.

Kompromitovaných zařízení je aktuálně celosvětově cca 9000 a výzkumný tým společnosti GreyNoise předpokládá, že škodliví aktéři si s pomocí nich připravují základnu pro budoucí botnet.

Přestože jak botnet PumaBot, tak kampaň AyySSHush prozatím zřejmě postihly jen velmi malé počty zařízení, jejich existence vhodně dokumentuje pokračující potřebu dbát i v roce 2025 na zabezpečení síťových SOHO zařízení a IoT prvků užívaných v domácích i firemních prostředích…

V kontextu botnetů zaslouží zmínku nicméně i jedna pozitivní zpráva z poslední doby, a to že americkým bezpečnostním složkám spolu s řadou dalších organizací se v průběhu května podařilo zabavit infrastrukturu botnetu Danabot, který byl dlouhodobě využíván jak kyberkriminálními skupinami, tak – zřejmě – ruskými státními aktéry. V souvislosti s touto akcí byla v USA rovněž vznesena obvinění proti 16 osobám, které se měly podílet na vývoji a provozu jmenovaného botnetu.

Jak velké nebezpečí představuje obchod s cookies?

Společnost NordVPN publikovala v uplynulém týdnu závěry své analýzy zaměřené na prodej cookies, odcizených s pomocí infostealerů a dalších technik, na dark webových a telegramových tržištích. Výzkumníci v rámci svých aktivit analyzovali více než 93,7 miliard cookies nabízených k prodeji na různých platformách, přičemž se pokoušeli identifikovat mj. jejich zdroj, obsah a zda byly v době prodeje ještě „aktivní“.

Výstupy z provedeného šetření vhodně poukazují na velikost problému, který obchod s cookies představuje.

Dle zjištění výzkumníků bylo více než 16,5 % zkoumaných cookies v době analýzy stále aktivní, což je vysoce problematické zejména v kontextu jejich obsahu – dle klíčových slov, jimiž byly cookies označeny, NordVPN odhaduje, že cca 18 miliard cookies bylo spojeno s identifikačními mechanismy a cca 1,5 miliardy cookies bylo spojených s přihlašováním, autentizačními mechanismy či navázanými relacemi.

Zmínku rovněž zaslouží, že více než 4,5 miliardy cookies bylo spojeno se službami společnosti Google (Gmail, Google Drive, …) a cca 1 miliarda spojena se službami společnosti Microsoft.

Uživatelé mohou nechtěně umožnit webovým aplikacím přistupovat k celému obsahu úložiště OneDrive

Společnost Oasis Security v uplynulém týdnu poukázala na problém spojený s možným neplánovaným poskytováním vysokých oprávnění webovým aplikacím ze strany uživatelů systému OneDrive, který vhodně dokumentuje širší problém s nastavováním oprávnění při využívání komponent třetích stran.

Problém je spojen s javascriptovou komponentou OneDrive File Picker, kterou publikuje společnost Microsoft a která má umožňovat vývojářům aplikací jednoduše integrovat do svých produktů mechanismus pro výběr souborů z OneDrive, které chtějí uživatelé daným aplikacím zpřístupnit. Tato komponenta je integrována do řady populárních webových aplikací, jako například ChatGPT, Slack nebo Trello. 

Problematické na komponentě OneDrive File Picker je, že Microsoft v rámci oficiální dokumentace doporučuje vývojářům požadovat extrémně široká oprávnění (rozsahy Files.Read.All či Sites.Read.All, resp. pro upload Files.ReadWrite.All či Sites.ReadWrite.All), která fakticky umožňují přistupovat (či zapisovat) do celého obsahu úložiště OneDrive. Může se zdát, že tato doporučení ze strany Microsoftu jsou vzhledem k šíři poskytovaných oprávnění neadekvátní pro většinu případů užití, nicméně jmenovaná společnost v současnosti na straně svých systémů údajně nenabízí žádný vysoce granulární způsob přiřazování oprávnění aplikacím při použití OAuth.

Pokud tedy vývojář jmenovanou komponentu použije dle doporučení Microsoftu, snadno se může stát, že uživatel, který chce reálně zpřístupnit určité aplikaci pouze jeden vybraný soubor, nebo menší množinu souborů, danému systému zpřístupní všechna data, která má nahraná na úložišti OneDrive. Uživatel sice musí poskytovaná oprávnění explicitně potvrdit, ale jejich rozsah nemusí být z dialogu nezbytně zřejmý.

prace_s_linuxem_tip

Přestože u legitimních aplikací lze předpokládat, že nebudou poskytovaný přístup zneužívat, riziko spojené s jejich případnou kompromitací či jiným zneužitím situace je významné. Výsledky analýzy tak lze považovat za přinejmenším znepokojivé a osobám a společnostem, které se domnívají, že historicky poskytly s pomocí popsaného mechanismu nechtěně široká přístupová oprávnění ke svým datovým úložištím nějaké aplikaci, lze doporučit ověřit rozsah těchto oprávnění v nastavení relevantních uživatelských účtů.

Další zajímavosti

Pro pobavení 

Never bring tequila to a key-signing party.

Never bring tequila to a key-signing party.

Autor: Randall Munroe, podle licence: CC BY-NC 2.5

O seriálu

Tento seriál vychází střídavě za pomoci pracovníků Národního bezpečnostního týmu CSIRT.CZ provozovaného sdružením CZ.NIC a bezpečnostního týmu CESNET-CERTS sdružení CESNET, bezpečnostního týmu CDT-CERT provozovaného společností ČD - Telematika a bezpečnostních specialistů Jana Kopřivy ze společnosti Nettles Consulting a Moniky Kutějové ze sdružení TheCyberValkyries. Více o seriálu…

Neutrální ikona do widgetu na odběr článků ze seriálů

Zajímá vás toto téma? Chcete se o něm dozvědět víc?

Objednejte si upozornění na nově vydané články do vašeho mailu. Žádný článek vám tak neuteče.


Autor článku

Jan Kopřiva je specialistou na kybernetickou bezpečnost s dlouhou praxí a širokými zkušenostmi. V současnosti působí jako bezpečnostní konzultant ve společnosti Nettles Consulting a také jako jeden z odborníků ve sdružení SANS Internet Storm Center.

'; 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'; } }