Kas Zonel on värske PHP versioon? Alati. Aga sinul?

Kommunikeerides turvaprobleeme tasuks vältida asjatu paanika tekitamist – anna asjakohast infot ja tegele reaalsete, mitte filmistsenaariumi-riskidega.

Eile hakkas mulle erinevatest kanalitest tulema küsimusi Zone serverites kasutusel oleva PHP-alamversiooni kohta. Selle taustaks oli ühe arendusfirma poolt klientidele saadetud kiri:

Magento väljastas teadeande, et PHP’s avastati hiljuti turvaauk, mis lubab kaugkoodi täitmist andmaks täieliku kontrolli kõige üle. Siiani pole ühtegi kinnitatud rünnakut, kuid kuna Magento töötab PHP baasil soovitame kõikidel kaupmeestel võimalikult kiiresti PHP versiooni uuendada.

Turvalisuse tagamiseks võta ühendust oma projektijuhiga.

Teavituse põhjuseks on MS-ISAC 2019-087 nõuanne, mis loetleb üles hulga värskete PHP versioonidega paigatud turvanõrkusi – tõsi, ükski neist ei ole selline, mis annaks alust erakorraliseks paanikaks.

Kas see võiks mõjutada sinu veebirakendust?

Väga vähetõenäoline. Tõsi, kui anda PHP koodile (nt Magentole) ette konkreetse turvanõrkuse ärakasutamiseks sobilikud andmed, siis on tõesti võimalik kutsuda esile olukord, kus andmed käivitatakse koodina ja ründajal on võimalik server üle võtta.

Selleks peab aga küberkurjategija andmed väga spetsiifilisse kohta sokutama, nende lihtsalt otsilahtrisse või tarne-aadressiks sisestamisest ei piisa. Ehk on vaja ka turva-nõrkust Magentos või mõnes teises veebirakenduses, mis kasutajalt tulnud andmed kontrollimatult kasutusele võtab.

Seega hoopis olulisem oleks mõelda selle peale, et Magento 25. juunil väljastatud versioonid paikasid 75 turvanõrkust, nende hulgas hulga kriitilisi. Siinkohal on vahest paras hetk kasutada tuntud kaasamis-vormelit:

Hea kaupmees! Kas sinul on jaanipäevased turvapaigad paigaldamata? Kirjuta kommentaaridesse oma e-poe aadress ja võid võita auhindu, mille on välja pannud MageCart grupeeringud!

Lisaks: Magento 1.x ametlik tugi lõppeb 20.06.2020

Veelgi olulisem on mõelda selle peale, et Magento 1.x end-of-support saabub 20. juunil 2020 – pärast seda rohkem ametlikke turvapaiku ei väljastata.

Mis ilmselt pole paljudele kaupmeestele ka suuremaks mureks, sest pea iga kord, kui ma mõne poe aadressi https://www.magereport.com/ testi sisestan saan teada, et paigaldamata on kõik viimase paari aasta jooksul väljastatud paigad.

Kui ma selle väikse iroonilise märkuse tegemata jätaks… tabaks mind väga sügav masendus. Naljast paremini aitab mõistagi soovitus “Turvalisuse tagamiseks võta ühendust oma projektijuhiga.” – ja palun räägi temaga ennekõike oma e-poe tarkvara versiooni-uuendusest ja paikamisest.

Aga ikkagi, kas Zonel on värske PHP?

Otseloomulikult. Zone tugevus on meie hallatud serveriplatvorm ja sa võid olla kindel, et misiganes veebirakenduse alla jääv komponent – kernel, operatsioonisüsteem, MariaDB, Apache, PHP jne – on pideva jälgimise all. Teavitused turvanõrkustest ja paikadest jooksevad vastavale sise-chati-kanalile, nende võimalik mõju serveripargile selgitatakse välja ja sõltuvalt riskihinnangust tehakse uuendused lähima korralise hoolduse käigus või võetakse ette erakorraline hooldus.

Enamasti teeme hooldustöid öösel 01-06 vahel, aga on olnud ka juhtumeid, kus hommikul avaldatud teoreetilise ohu kohta oli lõunaks turvafoorumites levimas proof-of-concept ründekood ja kõik Virtuaalservereid majutavad serverid said restardi keset kibedat tööpäeva.

Ehk kui sinu Magento – või mistahes muu veebirakendus – on majutatud Zones, siis jagunevad vastutused niimoodi:

Meie uut ZoneOS platvormi kasutavates serverites on täna (13.09.2019) kasutusel:

PHP 5.6.40-pl6-zoneos (cgi-fcgi) (built: Aug 23 2019 12:31:16)
PHP 7.0.33-pl6-zoneos (cgi-fcgi) (built: Aug 23 2019 12:34:44)
PHP 7.1.32-pl1-zoneos (cgi-fcgi) (built: Sep  2 2019 08:57:28)
PHP 7.2.22-pl1-zoneos (cgi-fcgi) (built: Sep  2 2019 08:59:20)
PHP 7.3.9-pl1-zoneos (cgi-fcgi) (built: Sep  2 2019 08:59:57)
PHP 7.4.0RC1 (cgi-fcgi) (built: Sep  4 2019 08:59:55)

Vanemates serverites on valik selline:

PHP 4.4.9 (cgi-fcgi) (built: Sep 17 2013 03:15:34)
PHP 5.1.6 (cgi-fcgi) (built: Sep 23 2013 07:14:11)
PHP 5.2.17 (cgi-fcgi) (built: Jul 11 2016 10:55:56)
PHP 5.3.29 (cgi-fcgi) (built: Nov 10 2016 10:13:49)
PHP 5.4.45 (cgi-fcgi) (built: Nov 10 2016 10:32:41)
PHP 5.5.38 (cgi-fcgi) (built: Apr  1 2018 21:47:01)
PHP 5.6.40 (cgi-fcgi) (built: Feb  8 2019 10:00:13)
PHP 7.0.33 (cgi-fcgi) (built: Sep 13 2019 11:22:05)
PHP 7.1.32 (cgi-fcgi) (built: Sep  2 2019 22:22:28)
PHP 7.2.22 (cgi-fcgi) (built: Sep  3 2019 08:42:57)
PHP 7.3.9 (cgi-fcgi) (built: Sep  3 2019 09:33:50)

Vahet märkad? Uues ZoneOS’is ei ole enam PHP versioone, mis vanemad kui 5.6 ning seda väga proosalisel põhjusel – need on surnud. Schluss! Kaput!

Täpsemalt öeldes on tänaseks surnud ka PHP 5.6 ja 7.0 … ning PHP 7.1 turva-uuendusi antakse välja 1. detsembrini 2019 ehk napid 2.5 kuud:

Aga kas sinul on värske PHP?

Vot nüüd jõudsime olulise küsimuseni :.) Tõenäoliselt mitte.

Kuna iga uue PHP versiooniga kaob osa vanemaid funktsioone ja kohati muutub ka keele süntaks, ei saa me ise sinu veebi poolt kasutatavat versiooni vahetada ilma riskita, et veeb katki läheb.

Näiteks Magento 1.x puhul on olemas isegi PHP 7.2 tugi (kui paigaldada 2018.a lõpus välja tulnud paigad) – aga me näeme oma serverites hulgaliselt Magentosid, mis kasutavad PHP 5.6 või vanemat.

Kuna head turva-paanikat ei tohi raisku lasta, siis kordame veidi laiendatult soovitust:

Turvalisuse tagamiseks võta ühendust oma veebimeistri, -arendaja või projektijuhiga ning palu paigata veebirakendus ning viia see üle värskeimale võimalikule PHP versioonile.

Õigupoolest… saab versiooni vahetada ka ise – ja kui midagi katki läheb saab vana tagasi panna (sh juhul, kui tegemist oli tavapäraselt valikus mitte-oleva versiooniga). Iseteeninduses on juba aastaid punane nupp:

Ning kui sellel klikkida avaneb järgmine vaade:

Ouch! Ilmneb, et ka minu enda kontol oli blogiposti kirjutamise ajal vana PHP versiooni kasutavaid veebe, nii ammuseid kliente kui tööandjaid… ja sekka mõned Zone enda iidsed teenused, mis tänaseks kinni pandud.

Kuidas aga ilma katki-tegemise riskita testida, kas veeb uuema versiooniga toimivad? Sellest juba järgmisel nädalal, püsige kanalil 🙂

WAF ehk veebirakenduse tulemüür

Enamus veebilehtede vastu suunatud rünnakutest kasutab ära mõnda koodis olevat nõrkust, neist levinuimad on ebapiisav kasutajaõiguste või külastaja poolt sisestatud andmete kontroll.

Näiteks võiks kujutada ette olukorda, kus sisestades kommunaalteenuste ettevõtte näitude teatamise lehel aadressi lahtrisse ' OR 1=1;-- kuvatakse kõigi klientide aadressid ja eelmised näidud… sest täpselt selline näeb välja andmebaasi- ehk SQL-süst. Või siis tehakse WordPressi pihta päring, mis lisab õigusi mitte kontrolliva plugina seadistuste kaudu lehele külastajaid kuhugi edasi suunava Javascripti koodi.

Sellised koodi-vead on ka põhjus, miks tuleb kõike avalikus internetis kättesaadavat praktiliselt igapäevaselt uuendada: iga paigatud turvaprobleem  toob hiljemalt 24 tunni jooksul kaasa skannerite laine, mis otsivad haavatavaid veebe.

Lisaks aga on haavatavused, mis ei pruugi veel paika omada – sest arendaja pole probleemist teadlik, ei ole jõudnud seda paigata… või on paigatud, aga uuemas versioonis ja veebi ülemviimine sellele osutub töömahukaks.


Veebirakenduse tulemüür

Sellistel puhkudel võib abi olla veebirakenduse tulemüürist ehk WAFist (web application firewall), mis proovib kahtlased päringud tuvastada ja blokeerida. Zone Virtuaalserverites on kasutusel ModSecurity ning nüüd saab mugavalt aktiveerida ka OWASP ModSecurity Core Rule Set (CRS) tulemüürireegleid:

Valida saab logimise või blokeerimise ja logimise vahel. Kui on plaan ja võimekus logisid analüüsida, siis tasub loomulikult alustada logimisest ning vältida ausate kasutajate häirimist vale-positiivsete tuvastustega… Aga lihtsam on lülitada blokeerimine sisse ning funktsionaalsused läbi testida.

Igal juhul soovitame kontrollida, et sisse oleksid lülitatud ka reaalajas serverisse jõudvad logid.

Umbes 10 minutiga jõuab seadistus Virtuaalserverisse ja kui seejärel proovida näiteks WP otsingusse sisestada ' OR 1=1;-- peaks tulemuseks olema Error403:

Selle tulemusel tekkiavad /logs/apache.ssl.error.log faili järgmised read (loetavuse huvides natuke puhastatud):

[2019-08-21 09:17:19.367098] [client 217.146.xx.x] ModSecurity: Warning. detected SQLi using libinjection with fingerprint 's&1;c' [file "REQUEST-942-APPLICATION-ATTACK-SQLI.conf"] [line "64"] [id "942100"] [data "Matched Data: s&1;c found within ARGS:s: ' OR 1=1;--"] [severity "CRITICAL"] [uri "/"] [unique_id "XVzh78ean2NKORtLccJqvgAAAAM"]

[2019-08-21 09:17:19.367352] [client 217.146.xx.x] ModSecurity: Access denied with code 403 (phase 2). Inbound Anomaly Score Exceeded (Total Inbound Score: 5 - SQLI=5,XSS=0,RFI=0,LFI=0,RCE=0,PHPI=0,HTTP=0,SESS=0)

Logist on näha nii põhjus (SQLi ehk andmebaasisüst), reegli number (942100), selle trigerdanud andmed ja lisaks ka reeglit sisaldanud OWASP CRS faili nimi.

99,99% juhtudest on selline päring seotud turvanõrkuse otsimise või ärakasutamisega, aga vähemalt teoorias võib SQL-friikidele mõeldud poes olla müügil sellenimeline t-särk – samuti võiks tulemüür takistada selle blogipostituse salvestamist.

Lahenduseks on reeglite valikuline väljalülitamine. Selleks saab Virtuaalserveri halduses pea- või alamdomeeni seadetes lisada Apache direktiivide ploki, mille sisuks on loetelu reeglitest:

Vajadusel saab ühele reale sobitada ka rohkem reegleid (tühikuga eraldatuna) või numbrivahemiku (jutumärkides), hea mõte on lisada juurde #-märgiga algav kommentaari-rida ning ümbritseda blokk IfModule tingimusega:

<IfModule mod_security2.c>
  # Keelame särgiotsingut takistavad reeglid:
  SecRuleRemoveById 942100 942140 "942160-942170"
</IfModule>

Kuidas tuvastada vale-positiivseid?

Kasutaja kaebuse peale logides tuhnimine on vaevarikas töö – pealegi ei ole kuvatav veateade ilus ega informatiivne. Mina olen testimiseks kasutanud vealehte, mida kuvatakse päringu blokeerimisel ning mis saadab juhul, kui kasutaja brauseris on JavaScript olemas, teate e-postile ja/või Slacki kanalisse.

Keerulisemate rünnete puhul võib toimuda ka JavaScripti interpreteerimine, lisaks ei piira see lahendus teavituste hulka ehk seda saab kasutada siht-aadressi teavitustega ülekoormamiseks.

Vealehe koodi leiab https://github.com/zone-eu/waf-handler, seadistamis-juhised sealtsamast.

Tulemuseks sellised teavitused:

Kas WAF on hõbekuul, mis lahendab kõik veebirakenduste turvaprobleemid?

Kindlasti mitte – Clarified Security‘s veebirakenduste turvalist arendust õpetav, läbistustestimise ja punase tiimi ehk ründaja rollis veebe lammutav Elar Lang palus kindlasti lisada:

WAF on kasulik “teise liini kaitsemeetmena” ja raskendab ründe läbi viimist ning hoiab heal juhul eemal teadaolevatele turvaaukudele keskendnud skänneritega “skriptijõnglased” AGA:

WAF ei tee korda programmikoodis olevaid turvaauke, need vajavad ikkagi parandamist.

Olles olnud Elari punase veebitiimi tubli töö sihtmärk Locked Shields küberõppusel võin vaid nõustuda – tänu WAFile võib mõni teine veeb osutuda lihtsamini rünnatavaks, aga see ei muuda sind kuulikindlaks.

.EE tsoonifail lõpuks avalik, aga mis hinnaga?

Vahetult jaani-nädalavahetuse eel teavitas Eesti Interneti SA  oma kauaoodatud otsusest asuda avaldama .EE tippdomeeni “tsoonifaili”. Tsoon muutub kõigile kättesaadavaks 5. juulist. Meie arvates on tegemist väärt täiendusega Eestis vabalt avalikus kasutuses olevatele avaandmetele.

Ühe tippdomeeni “tsoonifaili” sisus pole iseenesest midagi müstilist, tegemist on loendiga selle DNS süsteemi teenindatavatest domeenidest, viidetest neid teenindavatele nimeserveritele ja viimastega seotud IP aadressidele.

Tsoonifail ei sisalda endas domeeniomanike andmeid, domeenide aegumiskuupäevi ega muud põnevat. Need andmed asuvad tippdomeeni registri andmebaasis, kust neid on võimalik pärida kasutades WHOIS protokolli (https://tools.ietf.org/html/rfc3912). Seetõttu võib muretsejate rahustamiseks tõdeda, et märkimist väärt täiendavaid andmekaitseriske tsoonifaili avalikustamine domeenide kasutajatele kaasa ei too.

Kui tähte närida, siis ei ole isegi tegemist failiga, vaid DNS süsteemis andmete vahetamiseks kasutatava autoriteetsete andmete edastusprotokolli (AXFR – https://tools.ietf.org/html/rfc5936) väljundiga, mida igaüks saab soovi korral vaadata ja soovi korral ka faili salvestada.

Lisaks on tsoonifaili sisu, vähemalt suures osas, olnud võimalik tuletada või sellega võrdseid andmeid koguda ka muudel viisidel:

* DNS jõurünnete kaudu, pärides DNS süsteemist automaatselt genereeritud stringe (‘aa.ee’, ‘ab.ee’, ‘ac.ee’ jne)
* sõnastikurünnete abil, pärides sõnastikest pärit stringe (‘aa.ee’, ‘aabe.ee’, ‘aabits.ee’ jne)
* kombineerides jõu- või sõnastikuründeid keerukamate algoritmidega (nagu Markovi-ahelad jms)
* rünnates DNSSEC-i poolt kasutatavaid NSEC3 räsisid (NSEC3 hash breaking)
* veebilehtedelt ja mujalt infot kokku kraapides (Rapid7 Open Data)
* otsimootoritest infot küsides
* lõppkasutajate rekursiivseid nimeserveripäringuid monitoorides
* väljastatud TLS sertifikaate monitoorides (Certificate Transparency)
* ülaltoodud meetodeid kasutades kogutud andmete müüjatelt
* jne

Tsoonifailide sisu levimisele on kaasa aidanud ka juhuslikud andmelekked, näiteks nimeserveri administraatori tehtud näpuvead AXFR õiguste delegeerimisel, mis aastaid tagasi tingisid ka .EE tsooni sisu ajutise avaldamise.

Ülaltoodud põhjustel on “tsoonifaili” sisu saladuses püsimine alati olnud pigem näiline, mitte praktiline ja sõltunud suuresti selle sisust huvitatu tehnilistest oskustest ja motivatsioonitasemest. Kuna parim motivaator on alati raha, siis on seni täpseimad andmekogud olnud domeenidega kauplejate käsutuses. Näiteks NSEC3 räside murdmiseks vajalik kallis graafikakaart võib sellistele kodanikele end ühel või teisel moel reaalselt ära tasuda.

Loodan, et ülaltoodut ei tõlgendata eksklikult minu seisukohana, et tsoonifailide avalikustamisel ei ole mingit reaalset väärtust. Vastupidi, minu arvates on see positiivne areng, sest loob kõigile internetiolelusest huvitatud osapooltele uusi võimalusi uuringuteks, innovatsiooniks ja muuks väärtusloomeks. Samuti tasandab see taaskord mänguvälja ja toob laiema kasutajaskonnani töövahendi, mis seni on olnud vaid “valitute” privileeg.

Samal seisukohal on meie naaberriikidest olnud Rootsi, kes avalikustas oma .SE ja .NU tippdomeenide tsoonid 2016. aastal (Internetstiftelsen Zone Data) ja pole otsust pidanud kahetsema. Arvata on, et Eesti ja Rootsi eeskuju järgivad lähiaastatel nii mõnedki Euroopa tippdomeenide registrid.

Tänase seisuga on tsoonifailide avalikustamises suuremaid riske näinud intellektuaalse omandiga tegelejad: patendivolinikud, kaubamärkide kaitsmisega tegelevad juristid, turundajad jne. Nimelt ei meeldi neile potentsiaal, et kavandatav uus bränd, uus ärinimi, eesootav brändide ühendamine vms lekiks liialt varakult tsoonifaili kaudu välja, kuna enne avalikustamist on registreeritud kõik vastavad seotud domeenid (nii nagu peabki). Selle riski maandamiseks on aga kõige lihtsam võimalus registreerida domeen ja mitte määrata sellele nimeserverikirjeid, siis ei ole Eesti Interneti SA-l põhjust domeeni tsoonifaili genereerida.

Oh magus iroonia…

Ülaltoodu võib tunduda ka veidi irooniline, kuna alles 2017. aastal jõudis Riigikohtu otsusega lõpule kohtuasi, mis oli seotud kellegi domeeninimede kauplemisega tegeleva kodaniku GV [ nimi toimetusele teada 🙂 ] katsega Eesti Interneti SA-lt sedasama müstilist tsoonifaili teabenõude raames välja vaielda.

Eesti Interneti SA keeldus toona andmeid GV-le väljastamast järgmise põhjendusega:

EIS ei ole teabevaldaja ja nõutud teave ei ole avalik teave. Ükski seadus ei reguleeri domeeninimede registreerimist ning EIS tegevus selle ülesande täitmisel ei rajane ühelgi õigusaktil. Teabenõudele vastamine tooks kaasa registreerijate ja kaubamärgiomanike õigushüvede tõsise riive, sest teabenõudjal on võimalik saada juurdepääs teabele, mille avalikustamine ei ole registreerijate huvides. Ka registreerijad ei ole näinud ette teabe avalikustamist.

Tsoonifaili mitteavaldamise hind oli siis Eesti Interneti SA-le õigusabikuludena 16 919,28 eurot, millest küll 4000 eurot mõisteti välja kaebajalt ehk GV-lt.

Kohtuotsuse materjalidega on võimalik tutvuda aadressil https://www.riigiteataja.ee/kohtulahendid/fail.html?fid=212711240

Loomulikult ei olnud siis veel Eesti Interneti SA käsutuses spekulantide ohjamiseks mõeldud oksjoniportaali, mille hiljutine käivitamine ilmselt  paljuski tsoonifaili avalikustamise võimaldajaks sai.

Langetame sellegipoolest solidaarselt pea kõikide kohtuasja osapoolte  kulutatud aja ja raha mälestuseks, kelle jaoks tsoonifaili avalikustamisel on olnud väga kõrge hind.

Veel TLS uuendustest

Mõned postitused tagasi kirjutasin siin TLS (Transport Layer Security) pärandversioonide hülgamisest ja TLS versiooni 1.3 kasutuselevõtust. Tänaseks on kõik sellega seotud tööd meie platvormis teostatud –
tarkvaraplatvorm toetab vaikimisi vaid parimatele praktikatele vastavaid protokolliversioone (1.2 ja 1.3), kuid oleme klientidele loonud võimaluse ajutiselt pärandversioonide (1.0 ja 1.1) tuge sisse lülitada (vt allolevat illustratsiooni 1).

Illustratsioon 1

Rõhutan siiski, et pärandversioonide kasutamine ei ole pikas perspektiivis jätkusuutlik ja põhjustab meile palju peavalu. Näiteks annavad täna mitmed infosüsteemide võrgupinu turvalisust hindavad skännerid meie klientide saitidel TLS 1.0 ja TLS 1.1 versioonide kasutamise kohta valepositiivseid hinnanguid ka siis, kui neid reaalselt ei kasutata.

Ainus pikas perspektiivis mõistlik lahendus on uuendada oma veebilehtede poole pöörduvat riist- ja tarkvara nii, et toetatud oleks ainult aktuaalsed TLS versioonid.

Veelkord ka ID-kaardiga autentimisest.

Nagu ka varem mainitud, siis TLS 1.3 kasutuselevõtuga muutus Eesti ID-kaardi autentimise kasutamine veebiserveris tehniliselt keerukamaks, sest autentimise nõudmine kataloogi tasandil ei ole enam praktiliselt võimalik.

Kuna ID-kaardi kasutuselevõtu seadistamine serveritasandil on   nüansirikkam teema, siis otsustasime selle keerukuse kasutaja eest veidi ära peita. Nii lõid meie tarkvaraarendajad Minu Zone haldusliidesesse uue “linnukese”, mille abil saab ID-kaardiga autentimise nõuet haldusliideses mõne klikiga sisse lülitada (vt ülalolevat illustratsiooni 1). Samuti on klientidel võimalik sealsamas sisse lülitada tuge tarkvaraarenduses kasutatavale testkaartidele.

Pärandversioonide juurest sujuvalt pärandteenuste juurde.

Oma esimese avaliku teenusena alustas Zone 1999. aastal tasuta veebimajutusteenuse pakkumist. Algselt said selle kasutajad endale kodulehe kujuga zone.ee/kasutajanimi, hiljem web.zone.ee/kasutajanimi.

Kasutajate nõudmiste kasvades jäi see teenus ajale jalgu ja lõime entusiastide ning õppurite jaoks hoopis Planet.ee keskkonna, mistõttu vanasse tasuta veebimajutusteenusesse kasutajate vastuvõtmine lõpetati.

Meie tehnikud otsustasid aga, et üldisele infoturbeolukorrale tuleb kasuks, kui tirime ka oma tasuta veebimajutuse pärandteenuse 21. sajandisse ja paneme selle “sõjaratsu” tööle üle turvalisema HTTPS protokolli.

Selleks tegime veelkord ühe kiire vangerduse ja võtsime HTTPS toe lubamiseks web.zone.ee nime asemel kasutusele nime webzone.ee.

Vanad aadressid suunatakse nüüd sujuvalt HTTPS ühendusele ümber.

Pahavara: üks huvitav veebiproksi

Käes on Locked Shields küberõppuse nädal … aga kui sa ei ole LSil, siis on sul kindlasti aega tegeleda päris pahavaraga.

Puhastasin nädalavahetusel järjekordset veebi, kuhu oli sisse pääsetud nõrga admin-kasutaja salasõnaga. Kuna rünne oli toimunud hiljuti, oli mugav võtta ette varukoopia ning sellega võrreldes tuvastada muutunud failid. Ilmnes, et katalooge mööda oli laiali puistatud 35 erinevat tagaust või pahavaralise funktsionaalsusega faili.

Et küberkurjategijate tööd veidi laiemal tutvustada panin välja auhinnad… ja otsustasin koodi Facebookis huvilistele lammutada anda. See blogipost ongi kokku pandud osalt Zone FB-lehe postituse ja Vabakutseliste gruppi jagatu kommentaarides olevatest lahendustest – ning osalt Zone maja-sisestest tähelepanekutest.

Kui tahad enne lahenduse lugemist (või selle kõrvale) koodi vaadata, siis:

Niisiis saab kõik alguse sogastatud koodist:

Kristjan muutis (kasutatud) funktsioonide ja muutujate nimed arusaadavaks ja lisas kommentaarid – saamaks aru, mida koodijupp teeb ja kas seda on üldse ohutu oma arvutis või serveris käivitada:

Kuna muutujas $payLoad olev laeng on URL-kodeeringus mida pahavara-tuvastajatel lihtne läbi näha, on kasutataud täiendavat teisendustabelit selle sogastamiseks:

Olgu lisatud, et algses koodis näeb see eval ehk stringis olevat PHP koodi käivitav funktsioon välja alljärgnev, kurja eval() peitmiseks lihtsamate otsingute eest on funktsiooni nimi eraldi real ning lisaks üks kommentaar:

Kui asendada funktsion eval() näiteks print()’iga saame väljundiks laengu koodi – aga mulle meeldib rohkem tulemus faili kirjutada:

file_put_contents ( '_payload.php', decodePayload( $payLoad, $characterMap ) );

Ja saamegi asuda laengut uurima. Väga levinud tava on keelata ära veateadete väljastamine, aga siin on igaks juhuks võetud maha ka skripti täitmise ajapiirang (mis sisuliselt võimaldab seda kasutada ka teenustõkestusründeks andes kõigile lubatud PHP-protsessidele midagi aegavõtvat teha):

Edasi, otsime päringust maagilist küpsist – AGA Kristjani kommentaar on väikse näpukaga, nimelt väljutakse skriptist kui leitakse mõni küpsis mille väärtus EI VASTA soovitud nimele (küpsise nimi pole seejuures oluline).

Lisaks on koodis aga üks väga tore loogikaviga mille avastas Kurt Moser meie arendustiimist, vaata kas märkad:

Nojah, seda tsüklit ei täideta ja skriptist väljumist ei toimu, kui päringuga pole kaasas ühtki küpsist. Ehk sisuliselt on kogu piirang mõttetu – funktsionaalsele osale saab ligi igaüks.

Edasi läheb huvitavamaks:

Selle jupi juures tasub kindlasti “kastist välja” mõelda – php://input on tavapäraselt kasutusel POST päringute puhul, mitte miski ei keela selle kasutamist ka GET päringus. Sellisel kujul GETi kasutamise võlu seisneb aga selles, et veebiserverid päringu keha harilikult ei logi. Aga olgu siinkohal ka tõestus Elar Langilt:

<?php
var_dump(file_get_contents('php://input'));
?>

$ curl -X GET -s --data "töötab ju" http://localhost/z-server.php
string(11) "töötab ju"

$ curl -X POST -s --data "töötab ju" http://localhost/z-server.php
string(11) "töötab ju"

Järgmise jupi võtan ma aga oma koodiredaktorist, sest see oskab vigu tuvastada:

Jahaa – funktsioon split() kuulutati iganenuks juba PHP versioonis 5.3 ja alates 7.0 on see eemaldatud (tx veelkord Kurtile!). Ehk PHP uuemate versioonide puhul see kood ei tööta ja annab viga – võinoh… kuna vigade väljastamine on ülalpool ära keelatud, siis on tulemuseks Error 500, nagu ilmselt avastas ka ründaja:

94.130.35.51 - - [27/Mar/2019:10:02:21 +0200] "GET /wp-admin/css/colors/sunrise/lngzdhkh.php HTTP/1.1" 500 3527 "" "Mozilla/5.0 (Linux; Android 7.0; SAMSUNG SM-G935F Build/NRD90M) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/5.4 Chrome/51.0.2704.106 Mobile Safari/537.36" (F9F8DACB-0.001)

Pannes split() asemele explode() saab sellest murest kergesti üle.

decrypt() on sisuliselt XOR krüpteering ehk sama võtmega saab lahti ja kinni – nagu Karl-Sander Erss FBs kommentaaris demos:

> var_dump(decrypt(decrypt('asd'))==='asd');
bool(true)

Kuivõrd võtmeks on $_SERVER[‘HTTP_HOST’]  ja $_SERVER[‘REQUEST_URI’] on ka see kergesti ära-arvatav ehk nagu eelnevalt öeldud saab sellele koodi ära kasutada kesiganes tema olemasolu teab. Nii küpsis kui krüpto on täiesti mõttetud 🙂

Aga … mida see send_data1() siis teeb? Võtab saadud parameetrid (näidisandmed ülalolevas ekraanilaksus) ja teeb nendega HTTP POST või GET-päringu… ja tagastab tulemuse ehk tegu on veebiproksiga:

function send_data1( $data ) {
   $head = "";
   foreach ( $data["headers"] as $key => $value ) {
      $head .= $key . ": " . $value . "\r\n";
   }
   $params = array(
      'http' => array(
         'method'  => $data["method"],
         'header'  => $head,
         'content' => $data["body"],
         'timeout' => $data["timeout"],
      )
   );
   $ctx = stream_context_create( $params );
   $result = @file_get_contents( $data["url"], false, $ctx );
   if ( $http_response_header ) {
      if ( strpos( $http_response_header[0], "200" ) === false ) {
         $result = "HTTP_ERROR\t" . $http_response_header[0];
      }
   } else {
      $result = "CONNECTION_ERROR";
   }
   return $result;
}

Tuleb tunnistada, et file_get_contents() kasutamine koos kontekstiga HTTP-päringu parameetrite määramiseks pole minule kunagi varem ette jäänud, aga väga huvitav meetod. Lisaks: kuna paika pannakse ka timeout ning alguses on skripti täitmise ajapiirang maha võetud… siis võib see väääääga kaua aega võtta ehk olla kasutatav DOS ründeks.

Huvitavat jagub aga veelgi: nimelt EI MÄÄRATA ära HTTP protokolli versiooni ning vaikimisi on selleks HTTP/1.0 – ning minu oletuse kohaselt kasutatakse ülevõetud servereid järgmiste serverite ründamiseks. Hmm, vaatame korraks rünnatud saidi logi, filtreerides õnnestunud HTTP/1.0 päringuid:

Ja tõepoolest, need IPd pärinevad erinevatest pilve- või veebimajutusteenustest. Võib oletada, et ründajatel on oma veebiproksi, mis kasutab ülevõetud serverites olevaid veebiproksisid. See muudab võimatuks lihtsad lahendused nagu IP-põhised piirangud – mh kaitse WordPressi wp-login.php vastu suunatud paroolide jõurünnete tõrjumise “lubame vaid kolm katset samalt IPlt” meetodil.

Tänud kõigile kaasa mõtlemast, loodetavasti saime koos targemaks 🙂